{"id":31847301,"url":"https://github.com/opencontentcoop/occustomfind","last_synced_at":"2026-01-20T17:57:17.640Z","repository":{"id":57032128,"uuid":"98568290","full_name":"OpencontentCoop/occustomfind","owner":"OpencontentCoop","description":null,"archived":false,"fork":false,"pushed_at":"2025-05-30T15:31:46.000Z","size":185,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-30T21:54:06.787Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpencontentCoop.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-07-27T18:26:59.000Z","updated_at":"2018-10-23T19:32:04.000Z","dependencies_parsed_at":"2025-03-29T20:22:49.239Z","dependency_job_id":"550f24c9-d8d3-4757-83c7-819f75f6204e","html_url":"https://github.com/OpencontentCoop/occustomfind","commit_stats":{"total_commits":12,"total_committers":4,"mean_commits":3.0,"dds":0.6666666666666667,"last_synced_commit":"f3be5afd276b381f5bd688dcc535cc9f2f361e0c"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/OpencontentCoop/occustomfind","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpencontentCoop%2Foccustomfind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpencontentCoop%2Foccustomfind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpencontentCoop%2Foccustomfind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpencontentCoop%2Foccustomfind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpencontentCoop","download_url":"https://codeload.github.com/OpencontentCoop/occustomfind/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpencontentCoop%2Foccustomfind/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279010944,"owners_count":26084837,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-12T09:43:17.257Z","updated_at":"2025-10-12T09:43:20.900Z","avatar_url":"https://github.com/OpencontentCoop.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"## OpenContent Custom Find\n\nL'estensione permette di indicizzare in solr contenuti custom che non sono eZContentObject.\nE' utile per creare visualizzazioni ed effettuare ricerche su tabelle esterne.\n\n### Installation\n\nAbilita l'estensione. Rigenera gli autoloads. Pulisci la cache.\n\n\n### Esempio di utilizzo\n\nSi vuole, ad esempio, indicizzare un elenco telefonico che si possiede in un file csv e che non si intende importare come ogggetti ez\nma i cui si vuole poter effettuare delle ricerche.\n\n#### Abilitare il repository in `occustomfind.ini.append.php` del tuo siteaccess o di override\n\nSi abilita inserendo identificatore e classe php del repository.\n```\n[Settings]\nAvailableRepositories[elenco_telefonico]=ElencoTelefonicoSearchableRepository\n```\n\nPrima di creare il repository creiamo la classe che rappresenta un elemento dell'elenco telefonico\n\n#### Creare la classe `ElencoTelefonicoSearchableObject`\nLa classe implementa `OCCustomSearchableObjectInterface` ed è la rappresentazione di un elemento dell'elenco telefonico\n\n```php\nclass ElencoTelefonicoSearchableObject implements OCCustomSearchableObjectInterface\n{\n    private $id;\n    private $nome;\n    private $cognome;\n    private $numeriDiTelefono;\n    private $note;\n\n    /**\n     * Il costruttore è liberamente definibile perché l'interfaccia non lo contempla.\n     *\n     * @param $id\n     * @param $nome\n     * @param $cognome\n     * @param $numeriDiTelefono\n     * @param $note\n     */\n    public function __construct($id, $nome, $cognome, $numeriDiTelefono, $note)\n    {\n        $this-\u003enome = $nome;\n        $this-\u003ecognome = $cognome;\n        $this-\u003enumeriDiTelefono = $numeriDiTelefono;\n        $this-\u003enote = $note;\n    }\n\n    /**\n     * Questo meteodo deve resituire una stringa (bada bene non un numero) che identifica il documento univocamente in solr\n     *\n     * @return string\n     */\n    public function getGuid()\n    {\n        return return 'elenco-telefonico-' . $this-\u003eid;\n    }\n\n    /**\n     * Questo metodo serve a definire i campi che solr deve indicizzare\n     * Deve resituire un array di OCCustomSearchableFieldInterface per comodità conviene usare OCCustomSearchableField\n     *\n     * OCCustomSearchableField::create è una scorciatoia per\n     * $field = new OCCustomSearchableField;\n     * $field-\u003esetName($name)-\u003esetType($type)-\u003eisMultiValue($multiValue);\n     *\n     * @return OCCustomSearchableFieldInterface[]\n     */\n    public static function getFields()\n    {\n        return array(\n            OCCustomSearchableField::create('id', 'int'),\n\n            OCCustomSearchableField::create('cognome', 'string'),\n\n            OCCustomSearchableField::create('nome', 'text'),\n\n            // scorciatoia per isMultiValue vedi OCCustomSearchableField::setType\n            OCCustomSearchableField::create('numeriDiTelefono', 'string[]'),\n\n            OCCustomSearchableField::create('note', 'text'),\n        );\n    }\n\n    /**\n     * Restituisce il valore del campo presente in $field\n     *\n     * @param OCCustomSearchableFieldInterface $field\n     *\n     * @return mixed\n     */\n    public function getFieldValue(OCCustomSearchableFieldInterface $field)\n    {\n        if ($field-\u003egetName() == 'id'){\n            return $this-\u003eid;\n\n        }elseif ($field-\u003egetName() == 'cognome') {\n            return $this-\u003ecognome;\n\n        }elseif ($field-\u003egetName() == 'nome') {\n            return $this-\u003enome;\n\n        }elseif ($field-\u003egetName() == 'numeriDiTelefono') {\n            return $this-\u003enumeriDiTelefono;\n\n        }elseif ($field-\u003egetName() == 'note') {\n            return $this-\u003enote;\n        }\n\n        return null;\n    }\n\n    /**\n     * Restiruisce la rappresentazione dell'oggetto come array\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return array(\n            'id' =\u003e $this-\u003eid,\n            'cognome' =\u003e $this-\u003ecognome,\n            'nome' =\u003e $this-\u003enome,\n            'numeriDiTelefono' =\u003e $this-\u003enumeriDiTelefono,\n            'note' =\u003e $this-\u003enote,\n        );\n    }\n\n    /**\n     * Crea l'oggetto a partire da un array\n     *\n     * @param $array\n     *\n     * @return ElencoTelefonicoSearchableObject\n     */\n    public static function fromArray($array)\n    {\n        extract($array);\n        return new ElencoTelefonicoSearchableObject($id, $nome, $cognome, $numeriDiTelefono, $note);\n    }\n\n}\n```\n\nTuttavia se si ha già una rappresentazione dell'oggetto in array chiave -\u003e valore è possibile usare la classe astratta `OCCustomSearchableObjectAbstract`\nIl risultato sarà più veloce\n\n```php\nclass ElencoTelefonicoSearchableObject extends OCCustomSearchableObjectAbstract\n{\n\n    public function getGuid()\n    {\n        return 'elenco-telefonico-' . $this-\u003eattributes['id'];\n    }\n\n    public static function getFields()\n    {\n        return array(\n            OCCustomSearchableField::create('id', 'int'),\n            OCCustomSearchableField::create('cognome', 'string'),\n            OCCustomSearchableField::create('nome', 'text'),\n            OCCustomSearchableField::create('numeriDiTelefono', 'string[]'),\n            OCCustomSearchableField::create('note', 'text'),\n        );\n    }\n}\n```\n\n\n#### Creare la classe `ElencoTelefonicoSearchableRepository`\nLa classe deve implemetare l'interfaccia `OCCustomSearchableRepositoryInterface`, ma tutto il lavoro sporco lo fa già\nla classe `OCCustomSearchableRepositoryAbstract` quindi per non rifare cose conviene estendere quest'ultima ma anche darne un'occhiata al codice...\n\n```php\nclass ElencoTelefonicoSearchableRepository extends OCCustomSearchableRepositoryAbstract\n{\n    private $csvFile;\n\n    private $csvRows;\n\n    /**\n     * Nel costruttore salvo il nome del file csv da usare\n     * Questo è solo un esempio, immagina che il nome del file csv venga caricato tramite ini\n     * Tuttavia il costruttore non può avere argomenti (non abbiamo DependyInjection qui...)\n     */\n    public function __construct()\n    {\n        $this-\u003ecsvFile = 'elenco_telefonico.csv';\n    }\n\n    /**\n     * Parsa il file e restituisce le righe\n     * @return array\n     */\n    private function getCsvRows()\n    {\n        if ($this-\u003ecsvRows === null) {\n            // il metodo parseFile deve parsare il file e restuire un array di righe\n            // in questo esempio non è implementato\n            $this-\u003ecsvRows = $this-\u003eparseFile($this-\u003ecsvFile);\n        }\n\n        return $this-\u003ecsvRows;\n    }\n\n    /**\n     * Questo metodo deve restituire la stringa dell'identificativo del repository, meglio usare quello definito nella chiave dell'ini\n     */\n    public function getIdentifier()\n    {\n        return 'elenco_telefonico';\n    }\n\n    /**\n     * Questo campo deve restituire il FQCN della classe che si vuole indicizzare (creata sopra)\n     */\n    public function availableForClass()\n    {\n        return ElencoTelefonicoSearchableObject::class;\n    }\n\n    /**\n     * Ritorna il numero totale di oggetti indicizzabili\n     * Vedi il file bin/php/updatecustomsearchindex.php\n     */\n    public function countSearchableObjects()\n    {\n        return count($this-\u003egetCsvRows());\n    }\n\n    /**\n     * Restiruisce un array di ElencoTelefonicoSearchableObject\n     * Vedi il file bin/php/updatecustomsearchindex.php\n     *\n     * Il repository deve essere paginato: in questo esempio viene simulata la paginazione\n     *\n     * I metodi richiamati non sono implemetati\n     *\n     * @param int $limit\n     * @param int $offset\n     *\n     * @return ElencoTelefonicoSearchableObject[]\n     */\n    public function fetchSearchableObjectList($limit, $offset)\n    {\n        $data = array();\n        foreach($this-\u003egetCsvRows() as $index =\u003e $row) {\n\n            if ($index \u003c $offset){\n                continue;\n            }\n\n            if (count($data) == $limit) {\n                break;\n            }\n\n            $data[] = new ElencoTelefonicoSearchableObject(\n                $this-\u003egetIdFromRow($row),\n                $this-\u003egetNomeFromRow($row),\n                $this-\u003egetCognomeFromRow($row),\n                $this-\u003egetNumeriDiTelefonoFromRow($row),\n                $this-\u003egetNoteFromRow($row)\n            );\n\n            // se invece usiamo l'approccio ad array si farà qualcosa di simile\n            // $data[] = new ElencoTelefonicoSearchableObject($this-\u003egetArrayFromRow($row));\n        }\n\n        return $data;\n    }\n\n}\n```\n\n\n#### Indicizzare il repository da script\n\n```bash\nphp extension/occustomfind/bin/php/updatecustomsearchindex.php -sbackend --repository=elenco_telefonico\n```\n\n#### Eseguire una ricerca\nPer eseguire una ricerca da php occorre usare il metodo `find` del repository a cui passare un oggetto di classe `OCCustomSearchParameters`\n\nIl risultato è un array in cui valori sono:\n - `totalCount` il totale di tutti i ElencoTelefonicoSearchableObject contemplati dalla ricerca\n - `searchHits` un array di ElencoTelefonicoSearchableObject\n - `facets` un array con chiave il campo e valore l'hash nome=\u003econteggio\n\n```\n$parameters = OCCustomSearchParameters::instance()\n\n    // la ricerca libera funziona sui campi di tipo text, se sono string occorre cercare per tutta la stringa\n    -\u003esetQuery('amico di Topolino')\n\n    // i filtri accettano array o array di array come i filters di eZFind\n    // i nomi dei campi sono quelli definiti nel ElencoTelefonicoSearchableObject::getFields\n    -\u003esetFilters(array(\n        array(\n            'and',\n            array('nome' =\u003e 'Paolino'),\n            array('cognome' =\u003e 'Paperino')\n        )\n    ))\n\n    // anche nelle faccette come nei filtri i nomi dei campi sono quelli definiti nel ElencoTelefonicoSearchableObject::getFields\n    -\u003esetFacets(array(array('field' =\u003e 'cognome')))\n\n    // ordinamento\n    // come sopra per i nomi dei campi\n    -\u003esetSort(array('cognome' =\u003e 'asc', 'nome' =\u003e 'asc'))\n\n    // limite\n    -\u003esetLimit(10)\n\n    // offset\n    -\u003esetOffset(0);\n\n$repository = new ElencoTelefonicoSearchableRepository();\n$result = $repository-\u003efind($parameters);\n```\n\nPer eseguire una ricerca via http occorre usare il modulo customfind, un po' limitato perché al momento non sono gestiti i fitri con 'or'\n\n```\nhttp://www.example.com/debug/customfind/elenco_telefonico?query=amico di Topolino\u0026filters[nome]=Paolino\u0026filters[cognome]=Paperino\u0026facets[]=cognome\u0026sort[cognome]=asc\u0026sort[nome]=asc\u0026limit10\u0026offset=0\n```\n\n\n#### Per re-indicizzare il repository da script\n\n```bash\nphp extension/occustomfind/bin/php/updatecustomsearchindex.php -sbackend --repository=elenco_telefonico --clean\n```\n\n#### Per svuotare il repository da script\n\n```bash\nphp extension/occustomfind/bin/php/trucate.php -sbackend --repository=elenco_telefonico\n```\n\n#### Per indicizzare tutti i repository\n\n```bash\nphp extension/occustomfind/bin/php/updatecustomsearchindex.php -sbackend --clean\n```\n\n#### Per re-indicizzare tutti i repository\n\n```bash\nphp extension/occustomfind/bin/php/updatecustomsearchindex.php -sbackend --clean\n```\n\n#### Per svuotare tutti i repository\n\n```bash\nphp extension/occustomfind/bin/php/truncate.php -sbackend\n```\n\n### Classi Dummy\nIn occustomfind.ini ci sono due repository di esempio che indicizzano 10 contentuti per tipo.\nPer provarli occorre abilitarli\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopencontentcoop%2Foccustomfind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopencontentcoop%2Foccustomfind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopencontentcoop%2Foccustomfind/lists"}