From cb5946544977f300c09d6c9da2e3925e9f619822 Mon Sep 17 00:00:00 2001 From: Nathan McBride Date: Wed, 1 Feb 2023 21:21:11 +1100 Subject: [PATCH 1/3] Create initial module structure --- .gitignore | 58 ++++++++++---------------------------------- composer.json | 25 +++++++++++++++++++ src/etc/module.xml | 8 ++++++ src/registration.php | 5 ++++ 4 files changed, 51 insertions(+), 45 deletions(-) create mode 100644 composer.json create mode 100644 src/etc/module.xml create mode 100644 src/registration.php diff --git a/.gitignore b/.gitignore index abe6d79..c0192c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,45 +1,13 @@ -#--------------------------# -# Magento Default Files # -#--------------------------# - -/PATCH_*.sh - -/app/etc/local.xml - -/media/* -!/media/.htaccess - -!/media/customer -/media/customer/* -!/media/customer/.htaccess - -!/media/dhl -/media/dhl/* -!/media/dhl/logo.jpg - -!/media/downloadable -/media/downloadable/* -!/media/downloadable/.htaccess - -!/media/xmlconnect -/media/xmlconnect/* - -!/media/xmlconnect/custom -/media/xmlconnect/custom/* -!/media/xmlconnect/custom/ok.gif - -!/media/xmlconnect/original -/media/xmlconnect/original/* -!/media/xmlconnect/original/ok.gif - -!/media/xmlconnect/system -/media/xmlconnect/system/* -!/media/xmlconnect/system/ok.gif - -/var/* -!/var/.htaccess - -!/var/package -/var/package/* -!/var/package/*.xml - +# Composer +/vendor/ +.metadata +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.project +.buildpath +.idea/ \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..9245b94 --- /dev/null +++ b/composer.json @@ -0,0 +1,25 @@ +{ + "name": "develodesign/typesense", + "description": "A TypeSense adapter for Magento 2", + "type": "magento2-module", + "license": "OSL-3.0", + "require": { + "algolia/algoliasearch-magento-2": "^3.9", + "typesense/typesense-php": "^2.0" + }, + "authors": [ + { + "name": "Nathan McBride", + "email": "nathan@brideo.co.uk" + }, + { + "name": "Luke Collymore", + "email": "luke@develodesign.co.uk" + } + ], + "autoload": { + "psr-4": { + "Develo\\TypeSense": "src/" + } + } +} diff --git a/src/etc/module.xml b/src/etc/module.xml new file mode 100644 index 0000000..f24a51a --- /dev/null +++ b/src/etc/module.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/registration.php b/src/registration.php new file mode 100644 index 0000000..6b69411 --- /dev/null +++ b/src/registration.php @@ -0,0 +1,5 @@ + Date: Wed, 1 Feb 2023 23:00:46 +1100 Subject: [PATCH 2/3] add adapters for the 2 main classes --- src/Adapter/Client.php | 43 ++++++++++++++++++++++++ src/Adapter/Index.php | 74 ++++++++++++++++++++++++++++++++++++++++++ src/etc/di.xml | 8 +++++ 3 files changed, 125 insertions(+) create mode 100644 src/Adapter/Client.php create mode 100644 src/Adapter/Index.php create mode 100644 src/etc/di.xml diff --git a/src/Adapter/Client.php b/src/Adapter/Client.php new file mode 100644 index 0000000..b93791c --- /dev/null +++ b/src/Adapter/Client.php @@ -0,0 +1,43 @@ +typeSenseClient = $client; + } + + /** + * @inheirtDoc + */ + public function deleteIndex($indexName) + { + return $this->typeSenseClient->collections[$indexName]->delete(); + } +} \ No newline at end of file diff --git a/src/Adapter/Index.php b/src/Adapter/Index.php new file mode 100644 index 0000000..7a31e6a --- /dev/null +++ b/src/Adapter/Index.php @@ -0,0 +1,74 @@ +client = $client; + $this->indexName = $indexName; + } + + public function addObject($content, $objectID = null) + { + if ($objectID) { + $content['id'] = $content; + } + + return $this->getDocuments()->upsert($content); + } + + public function addObjects($objects, $objectIDKeyLegacy = 'objectID') + { + return $this->getDocuments()->import($objects, ['action' => 'create']); + } + + public function deleteObjects($objects) + { + $ids = 'id:='.json_encode($objects); + + return $this->getDocuments()->delete(['filter_by' => $ids]); + } + + /** + * @return TypeSenseClient + */ + private function getClient(): TypeSenseClient + { + return $this->client->typeSenseClient; + } + + /** + * @todo none of the methods seem to be in this class but that is what is documented. + * + * @return \Devloops\Typesence\Documents + */ + private function getDocuments() + { + return $this->getClient()->collections[$this->indexName]->documents; + } +} \ No newline at end of file diff --git a/src/etc/di.xml b/src/etc/di.xml new file mode 100644 index 0000000..c3956c2 --- /dev/null +++ b/src/etc/di.xml @@ -0,0 +1,8 @@ + + + + + + + From c625249b6930213195f9ef0e3080146ee00c6fac Mon Sep 17 00:00:00 2001 From: Luke Collymore Date: Sat, 18 Feb 2023 22:14:57 +0000 Subject: [PATCH 3/3] Inital Files - currenlty indexes products only into Typesenes --- Adapter/Client.php | 89 +++++++++++++++++++ Model/Config/Source/TypeSenseIndexMethod.php | 35 ++++++++ Observer/ConfigChange.php | 84 +++++++++++++++++ .../AlgoliaSearch/Helper/AlgoliaHelper.php | 68 ++++++++++++++ composer.json | 7 +- etc/acl.xml | 16 ++++ etc/adminhtml/di.xml | 6 ++ etc/adminhtml/events.xml | 6 ++ etc/adminhtml/system.xml | 44 +++++++++ etc/config.xml | 17 ++++ etc/di.xml | 8 ++ etc/graphql/di.xml | 14 +++ {src/etc => etc}/module.xml | 3 +- etc/schema.graphqls | 8 ++ src/registration.php => registration.php | 2 +- src/Adapter/Client.php | 43 --------- src/Adapter/Index.php | 74 --------------- src/etc/di.xml | 8 -- 18 files changed, 401 insertions(+), 131 deletions(-) create mode 100644 Adapter/Client.php create mode 100644 Model/Config/Source/TypeSenseIndexMethod.php create mode 100644 Observer/ConfigChange.php create mode 100644 Plugin/Backend/Algolia/AlgoliaSearch/Helper/AlgoliaHelper.php create mode 100644 etc/acl.xml create mode 100644 etc/adminhtml/di.xml create mode 100644 etc/adminhtml/events.xml create mode 100644 etc/adminhtml/system.xml create mode 100644 etc/config.xml create mode 100644 etc/di.xml create mode 100644 etc/graphql/di.xml rename {src/etc => etc}/module.xml (71%) create mode 100644 etc/schema.graphqls rename src/registration.php => registration.php (84%) delete mode 100644 src/Adapter/Client.php delete mode 100644 src/Adapter/Index.php delete mode 100644 src/etc/di.xml diff --git a/Adapter/Client.php b/Adapter/Client.php new file mode 100644 index 0000000..cba5506 --- /dev/null +++ b/Adapter/Client.php @@ -0,0 +1,89 @@ +getValue(SELF::TYPESENSE_API_KEY,ScopeConfig::SCOPE_STORE); + $apiKey = $encryptor->decrypt($apiKey); + + $nodes = $scopeConfig->getValue(SELF::TYPESENSE_NODES,ScopeConfig::SCOPE_STORE); + + $client = new TypeSenseClient( + [ + "api_key" => $apiKey, + "nodes"=> + [ + [ + "host" => $nodes, + "port" => "443", + "protocol" => "https", + "api_key" => $apiKey + ] + ] + ] + ); + + $this->typeSenseClient = $client; + } + + /** + * @inheirtDoc + */ + public function deleteIndex($indexName) + { + return $this->typeSenseClient->collections[$indexName]->delete(); + } + + /** + * @inheirtDoc + */ + public function addData($indexName, $data) + { + return $this->typeSenseClient->collections[$indexName]->documents->create_many($data, ['action' => 'upsert']); + } + + public function getTypesenseClient(){ + return $this->typeSenseClient; + } +} + + diff --git a/Model/Config/Source/TypeSenseIndexMethod.php b/Model/Config/Source/TypeSenseIndexMethod.php new file mode 100644 index 0000000..9af75ea --- /dev/null +++ b/Model/Config/Source/TypeSenseIndexMethod.php @@ -0,0 +1,35 @@ + 'Typesense Only', + 'typesense_algolia' => 'Both Typesense and Aglolia', + 'algolia' => 'Algolia Only' + ]; + + /** + * @return array + */ + public function toOptionArray() + { + $options = []; + + foreach ($this->methods as $key => $value) { + $options[] = [ + 'value' => $key, + 'label' => __($value), + ]; + } + + return $options; + } +} diff --git a/Observer/ConfigChange.php b/Observer/ConfigChange.php new file mode 100644 index 0000000..3790a71 --- /dev/null +++ b/Observer/ConfigChange.php @@ -0,0 +1,84 @@ +request = $request; + $this->typesenseClient = $client->getTypesenseClient(); + $this->algoliaHelper = $algoliaHelper; + $this->typeSenseCollecitons = $this->typesenseClient->collections; + } + + /** + * Creates Indexes in Typesense after credentials have been updated + */ + public function execute(EventObserver $observer) + { + $indexes = $this->algoliaHelper->getIndexDataByStoreIds(); + unset($indexes[0]); //skip admin store + + $existingCollections = $this->getExistingCollections(); + + foreach($indexes as $index){ + if(!isset($existingCollections[$index["indexName"]."_products"])){ + $this->typeSenseCollecitons->create( + [ + 'name' => $index["indexName"]."_products", + 'fields' => [['name' => 'name','type' => 'string']] + ] + ); + } + } + + return $this; + } + + /** + * Gets existing collections from typesense + */ + private function getExistingCollections(){ + $collections = $this->typeSenseCollecitons->retrieve(); + $existingCollections =[]; + foreach($collections as $collection) { + $existingCollections[$collection["name"]] = $collection; + } + return $existingCollections; + } +} \ No newline at end of file diff --git a/Plugin/Backend/Algolia/AlgoliaSearch/Helper/AlgoliaHelper.php b/Plugin/Backend/Algolia/AlgoliaSearch/Helper/AlgoliaHelper.php new file mode 100644 index 0000000..46f971a --- /dev/null +++ b/Plugin/Backend/Algolia/AlgoliaSearch/Helper/AlgoliaHelper.php @@ -0,0 +1,68 @@ +typesenseClient = $client; + $this->scopeConfig = $scopeConfig; + } + + /** + * Indexes data if config is set todo, will index into algolia or typesense or both + */ + public function aroundAddObjects( + \Algolia\AlgoliaSearch\Helper\AlgoliaHelper $subject, + \Closure $proceed, + $objects, + $indexName + ) { + $result = []; + $indexMethod = $this->scopeConfig->getValue(SELF::TYPESENSE_INDEX_METHID,ScopeConfig::SCOPE_STORE); + switch ($indexMethod) { + case "algolia": + $result = $proceed(); + break; + case "typesense_algolia": + $this->typesenseClient->addData($indexName, $objects); + $result = $proceed(); + break; + case "typesense": + default: + $this->typesenseClient->addData($indexName,$objects); + break; + } + + return $result; + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 9245b94..648bfda 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "develodesign/typesense", + "name": "develo/typesense", "description": "A TypeSense adapter for Magento 2", "type": "magento2-module", "license": "OSL-3.0", @@ -18,8 +18,7 @@ } ], "autoload": { - "psr-4": { - "Develo\\TypeSense": "src/" - } + "files": ["registration.php"], + "psr-4": {"Develo\\Typesense\\": ""} } } diff --git a/etc/acl.xml b/etc/acl.xml new file mode 100644 index 0000000..4eb6b5a --- /dev/null +++ b/etc/acl.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml new file mode 100644 index 0000000..941c0a5 --- /dev/null +++ b/etc/adminhtml/di.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/etc/adminhtml/events.xml b/etc/adminhtml/events.xml new file mode 100644 index 0000000..ff83349 --- /dev/null +++ b/etc/adminhtml/events.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml new file mode 100644 index 0000000..c441d6f --- /dev/null +++ b/etc/adminhtml/system.xml @@ -0,0 +1,44 @@ + + + + + + +
+ + typesense + Develo_Typesense::config_Develo_Typesense + + + + + Enable Typesense Adapter to override Algolias indexer + Magento\Config\Model\Config\Source\Enabledisable + + + + Where should Algolia data be indexed. + Develo\Typesense\Model\Config\Source\TypeSenseIndexMethod + + + + + + + + + Magento\Config\Model\Config\Backend\Encrypted + typesense_general/settings/admin_api_key + + + + + + + + + + +
+
+
diff --git a/etc/config.xml b/etc/config.xml new file mode 100644 index 0000000..b94c588 --- /dev/null +++ b/etc/config.xml @@ -0,0 +1,17 @@ + + + + + + + 1 + + + + + diff --git a/etc/di.xml b/etc/di.xml new file mode 100644 index 0000000..61681f6 --- /dev/null +++ b/etc/di.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/etc/graphql/di.xml b/etc/graphql/di.xml new file mode 100644 index 0000000..7119d20 --- /dev/null +++ b/etc/graphql/di.xml @@ -0,0 +1,14 @@ + + + + + + general/settings/cloud_id + general/settings/admin_api_key + general/settings/search_only_key + general/settings/nodes + general/settings/enabled + + + + diff --git a/src/etc/module.xml b/etc/module.xml similarity index 71% rename from src/etc/module.xml rename to etc/module.xml index f24a51a..e9aa6f0 100644 --- a/src/etc/module.xml +++ b/etc/module.xml @@ -1,8 +1,9 @@ - + + \ No newline at end of file diff --git a/etc/schema.graphqls b/etc/schema.graphqls new file mode 100644 index 0000000..aacd7be --- /dev/null +++ b/etc/schema.graphqls @@ -0,0 +1,8 @@ + +type StoreConfig { + general_settings_cloud_id : String @doc(description: "Query by general_settings_cloud_id.") + general_settings_admin_api_key : String @doc(description: "Query by general_settings_admin_api_key.") + general_settings_search_only_key : String @doc(description: "Query by general_settings_search_only_key.") + general_settings_nodes : String @doc(description: "Query by general_settings_nodes.") + general_settings_enabled : String @doc(description: "Query by general_settings_enabled.") +} \ No newline at end of file diff --git a/src/registration.php b/registration.php similarity index 84% rename from src/registration.php rename to registration.php index 6b69411..1109820 100644 --- a/src/registration.php +++ b/registration.php @@ -2,4 +2,4 @@ use Magento\Framework\Component\ComponentRegistrar; -ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Develo_TypeSense', __DIR__); +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Develo_Typesense', __DIR__); diff --git a/src/Adapter/Client.php b/src/Adapter/Client.php deleted file mode 100644 index b93791c..0000000 --- a/src/Adapter/Client.php +++ /dev/null @@ -1,43 +0,0 @@ -typeSenseClient = $client; - } - - /** - * @inheirtDoc - */ - public function deleteIndex($indexName) - { - return $this->typeSenseClient->collections[$indexName]->delete(); - } -} \ No newline at end of file diff --git a/src/Adapter/Index.php b/src/Adapter/Index.php deleted file mode 100644 index 7a31e6a..0000000 --- a/src/Adapter/Index.php +++ /dev/null @@ -1,74 +0,0 @@ -client = $client; - $this->indexName = $indexName; - } - - public function addObject($content, $objectID = null) - { - if ($objectID) { - $content['id'] = $content; - } - - return $this->getDocuments()->upsert($content); - } - - public function addObjects($objects, $objectIDKeyLegacy = 'objectID') - { - return $this->getDocuments()->import($objects, ['action' => 'create']); - } - - public function deleteObjects($objects) - { - $ids = 'id:='.json_encode($objects); - - return $this->getDocuments()->delete(['filter_by' => $ids]); - } - - /** - * @return TypeSenseClient - */ - private function getClient(): TypeSenseClient - { - return $this->client->typeSenseClient; - } - - /** - * @todo none of the methods seem to be in this class but that is what is documented. - * - * @return \Devloops\Typesence\Documents - */ - private function getDocuments() - { - return $this->getClient()->collections[$this->indexName]->documents; - } -} \ No newline at end of file diff --git a/src/etc/di.xml b/src/etc/di.xml deleted file mode 100644 index c3956c2..0000000 --- a/src/etc/di.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - -