Skip to content

Commit 7bf79ad

Browse files
collymoreNathan McBride
and
Nathan McBride
authored
Develop (#2)
* Create initial module structure * Inital Files - currenlty indexes products only into Typesenes --------- Co-authored-by: Nathan McBride <nathanmcbride@Nathans-iMac.modem>
1 parent 4d950d8 commit 7bf79ad

File tree

16 files changed

+446
-45
lines changed

16 files changed

+446
-45
lines changed

.gitignore

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,13 @@
1-
#--------------------------#
2-
# Magento Default Files #
3-
#--------------------------#
4-
5-
/PATCH_*.sh
6-
7-
/app/etc/local.xml
8-
9-
/media/*
10-
!/media/.htaccess
11-
12-
!/media/customer
13-
/media/customer/*
14-
!/media/customer/.htaccess
15-
16-
!/media/dhl
17-
/media/dhl/*
18-
!/media/dhl/logo.jpg
19-
20-
!/media/downloadable
21-
/media/downloadable/*
22-
!/media/downloadable/.htaccess
23-
24-
!/media/xmlconnect
25-
/media/xmlconnect/*
26-
27-
!/media/xmlconnect/custom
28-
/media/xmlconnect/custom/*
29-
!/media/xmlconnect/custom/ok.gif
30-
31-
!/media/xmlconnect/original
32-
/media/xmlconnect/original/*
33-
!/media/xmlconnect/original/ok.gif
34-
35-
!/media/xmlconnect/system
36-
/media/xmlconnect/system/*
37-
!/media/xmlconnect/system/ok.gif
38-
39-
/var/*
40-
!/var/.htaccess
41-
42-
!/var/package
43-
/var/package/*
44-
!/var/package/*.xml
45-
1+
# Composer
2+
/vendor/
3+
.metadata
4+
*.tmp
5+
*.bak
6+
*.swp
7+
*~.nib
8+
local.properties
9+
.settings/
10+
.loadpath
11+
.project
12+
.buildpath
13+
.idea/

Adapter/Client.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace Develo\Typesense\Adapter;
4+
5+
use Devloops\Typesence\Client as TypeSenseClient;
6+
use \Magento\Store\Model\ScopeInterface as ScopeConfig;
7+
use \Magento\Framework\App\Config\ScopeConfigInterface;
8+
use \Magento\Framework\Encryption\EncryptorInterface;
9+
10+
/**
11+
* Class Client
12+
*
13+
* This class should replace the AlgoliaSearch\Client implementation
14+
*
15+
* @see \AlgoliaSearch\Client
16+
* @package Develo\TypeSense\Service
17+
*/
18+
class Client
19+
{
20+
21+
/**
22+
* Config paths
23+
*/
24+
private const TYPESENSE_API_KEY = 'typesense_general/settings/admin_api_key';
25+
private const TYPESENSE_NODES = 'typesense_general/settings/nodes';
26+
27+
/**
28+
* @var TypeSenseClient
29+
*/
30+
private $typeSenseClient;
31+
32+
/**
33+
* encryptor
34+
*/
35+
private $encryptor;
36+
37+
/**
38+
* Initialise Typesense Client with Magento config
39+
*/
40+
public function __construct(
41+
EncryptorInterface $encryptor,
42+
ScopeConfigInterface $scopeConfig
43+
)
44+
{
45+
$apiKey = $scopeConfig->getValue(SELF::TYPESENSE_API_KEY,ScopeConfig::SCOPE_STORE);
46+
$apiKey = $encryptor->decrypt($apiKey);
47+
48+
$nodes = $scopeConfig->getValue(SELF::TYPESENSE_NODES,ScopeConfig::SCOPE_STORE);
49+
50+
$client = new TypeSenseClient(
51+
[
52+
"api_key" => $apiKey,
53+
"nodes"=>
54+
[
55+
[
56+
"host" => $nodes,
57+
"port" => "443",
58+
"protocol" => "https",
59+
"api_key" => $apiKey
60+
]
61+
]
62+
]
63+
);
64+
65+
$this->typeSenseClient = $client;
66+
}
67+
68+
/**
69+
* @inheirtDoc
70+
*/
71+
public function deleteIndex($indexName)
72+
{
73+
return $this->typeSenseClient->collections[$indexName]->delete();
74+
}
75+
76+
/**
77+
* @inheirtDoc
78+
*/
79+
public function addData($indexName, $data)
80+
{
81+
return $this->typeSenseClient->collections[$indexName]->documents->create_many($data, ['action' => 'upsert']);
82+
}
83+
84+
public function getTypesenseClient(){
85+
return $this->typeSenseClient;
86+
}
87+
}
88+
89+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Develo\Typesense\Model\Config\Source;
4+
5+
/**
6+
* Algolia custom sort order field
7+
*/
8+
class TypeSenseIndexMethod implements \Magento\Framework\Data\OptionSourceInterface
9+
{
10+
/**
11+
* @var array
12+
*/
13+
private $methods = [
14+
'typesense' => 'Typesense Only',
15+
'typesense_algolia' => 'Both Typesense and Aglolia',
16+
'algolia' => 'Algolia Only'
17+
];
18+
19+
/**
20+
* @return array
21+
*/
22+
public function toOptionArray()
23+
{
24+
$options = [];
25+
26+
foreach ($this->methods as $key => $value) {
27+
$options[] = [
28+
'value' => $key,
29+
'label' => __($value),
30+
];
31+
}
32+
33+
return $options;
34+
}
35+
}

Observer/ConfigChange.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace Develo\Typesense\Observer;
4+
5+
use Magento\Framework\Event\ObserverInterface;
6+
use Magento\Framework\Event\Observer as EventObserver;
7+
use Magento\Framework\App\RequestInterface;
8+
use \Develo\Typesense\Adapter\Client;
9+
use Algolia\AlgoliaSearch\Helper\Data as AlgoliaHelper;
10+
11+
class ConfigChange implements ObserverInterface
12+
{
13+
14+
/**
15+
* @var RequestInterface
16+
*/
17+
private $request;
18+
19+
/**
20+
* $var Client
21+
*/
22+
private $typesenseClient;
23+
24+
/**
25+
* $var AlgoliaHelper
26+
*/
27+
private $algoliaHelper;
28+
29+
/**
30+
* $var Devloops\Typesence\Collections
31+
*/
32+
private $typeSenseCollecitons;
33+
34+
/**
35+
* ConfigChange constructor.
36+
* @param RequestInterface $request
37+
*/
38+
public function __construct(
39+
RequestInterface $request,
40+
Client $client,
41+
AlgoliaHelper $algoliaHelper
42+
) {
43+
$this->request = $request;
44+
$this->typesenseClient = $client->getTypesenseClient();
45+
$this->algoliaHelper = $algoliaHelper;
46+
$this->typeSenseCollecitons = $this->typesenseClient->collections;
47+
}
48+
49+
/**
50+
* Creates Indexes in Typesense after credentials have been updated
51+
*/
52+
public function execute(EventObserver $observer)
53+
{
54+
$indexes = $this->algoliaHelper->getIndexDataByStoreIds();
55+
unset($indexes[0]); //skip admin store
56+
57+
$existingCollections = $this->getExistingCollections();
58+
59+
foreach($indexes as $index){
60+
if(!isset($existingCollections[$index["indexName"]."_products"])){
61+
$this->typeSenseCollecitons->create(
62+
[
63+
'name' => $index["indexName"]."_products",
64+
'fields' => [['name' => 'name','type' => 'string']]
65+
]
66+
);
67+
}
68+
}
69+
70+
return $this;
71+
}
72+
73+
/**
74+
* Gets existing collections from typesense
75+
*/
76+
private function getExistingCollections(){
77+
$collections = $this->typeSenseCollecitons->retrieve();
78+
$existingCollections =[];
79+
foreach($collections as $collection) {
80+
$existingCollections[$collection["name"]] = $collection;
81+
}
82+
return $existingCollections;
83+
}
84+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
/**
3+
* Copyright © All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Develo\Typesense\Plugin\Backend\Algolia\AlgoliaSearch\Helper;
9+
10+
use \Magento\Framework\App\Config\ScopeConfigInterface;
11+
use \Magento\Store\Model\ScopeInterface as ScopeConfig;
12+
use \Develo\Typesense\Adapter\Client;
13+
14+
class AlgoliaHelper
15+
{
16+
private const TYPESENSE_INDEX_METHID = 'typesense_general/settings/index_method';
17+
18+
/**
19+
* @var $scopeConfig
20+
*/
21+
protected $scopeConfig;
22+
23+
/**
24+
* @var Client $typesenseClient
25+
*/
26+
protected $typesenseClient;
27+
28+
/**
29+
* __construct
30+
* @param Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
31+
* @param Develo\TypeSense\Adapter\Client $client
32+
*/
33+
public function __construct(
34+
ScopeConfigInterface $scopeConfig,
35+
Client $client
36+
) {
37+
$this->typesenseClient = $client;
38+
$this->scopeConfig = $scopeConfig;
39+
}
40+
41+
/**
42+
* Indexes data if config is set todo, will index into algolia or typesense or both
43+
*/
44+
public function aroundAddObjects(
45+
\Algolia\AlgoliaSearch\Helper\AlgoliaHelper $subject,
46+
\Closure $proceed,
47+
$objects,
48+
$indexName
49+
) {
50+
$result = [];
51+
$indexMethod = $this->scopeConfig->getValue(SELF::TYPESENSE_INDEX_METHID,ScopeConfig::SCOPE_STORE);
52+
switch ($indexMethod) {
53+
case "algolia":
54+
$result = $proceed();
55+
break;
56+
case "typesense_algolia":
57+
$this->typesenseClient->addData($indexName, $objects);
58+
$result = $proceed();
59+
break;
60+
case "typesense":
61+
default:
62+
$this->typesenseClient->addData($indexName,$objects);
63+
break;
64+
}
65+
66+
return $result;
67+
}
68+
}

composer.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "develo/typesense",
3+
"description": "A TypeSense adapter for Magento 2",
4+
"type": "magento2-module",
5+
"license": "OSL-3.0",
6+
"require": {
7+
"algolia/algoliasearch-magento-2": "^3.9",
8+
"typesense/typesense-php": "^2.0"
9+
},
10+
"authors": [
11+
{
12+
"name": "Nathan McBride",
13+
"email": "nathan@brideo.co.uk"
14+
},
15+
{
16+
"name": "Luke Collymore",
17+
"email": "luke@develodesign.co.uk"
18+
}
19+
],
20+
"autoload": {
21+
"files": ["registration.php"],
22+
"psr-4": {"Develo\\Typesense\\": ""}
23+
}
24+
}

etc/acl.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" ?>
2+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
3+
<acl>
4+
<resources>
5+
<resource id="Magento_Backend::admin">
6+
<resource id="Magento_Backend::stores">
7+
<resource id="Magento_Backend::stores_settings">
8+
<resource id="Magento_Config::config">
9+
<resource id="Develo_Typesense::config_Develo_Typesense" title="general"/>
10+
</resource>
11+
</resource>
12+
</resource>
13+
</resource>
14+
</resources>
15+
</acl>
16+
</config>

etc/adminhtml/di.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" ?>
2+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
3+
<type name="Algolia\AlgoliaSearch\Helper\AlgoliaHelper">
4+
<plugin name="Develo_Typesense_Plugin_Backend_Algolia_AlgoliaSearch_Helper_AlgoliaHelper" type="Develo\Typesense\Plugin\Backend\Algolia\AlgoliaSearch\Helper\AlgoliaHelper" sortOrder="10" disabled="false"/>
5+
</type>
6+
</config>

etc/adminhtml/events.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
3+
<event name="admin_system_config_changed_section_typesense_general">
4+
<observer name="develo_typesense_admin_system_config_changed_section_typesense_general" instance="Develo\Typesense\Observer\ConfigChange"/>
5+
</event>
6+
</config>

0 commit comments

Comments
 (0)