2
2
3
3
namespace Algolia \AlgoliaSearch \Console \Command ;
4
4
5
+ use Algolia \AlgoliaSearch \Helper \AlgoliaHelper ;
6
+ use Algolia \AlgoliaSearch \Service \IndexNameFetcher ;
7
+ use Algolia \AlgoliaSearch \Service \StoreNameFetcher ;
8
+ use Magento \Framework \App \State ;
5
9
use Magento \Framework \Console \Cli ;
6
10
use Magento \Framework \Exception \NoSuchEntityException ;
7
11
use Symfony \Component \Console \Input \InputInterface ;
8
12
use Symfony \Component \Console \Output \OutputInterface ;
9
13
10
14
class SynonymDeduplicateCommand extends AbstractStoreCommand
11
15
{
16
+ public function __construct (
17
+ protected AlgoliaHelper $ algoliaHelper ,
18
+ protected IndexNameFetcher $ indexNameFetcher ,
19
+ protected State $ state ,
20
+ protected StoreNameFetcher $ storeNameFetcher ,
21
+ ?string $ name = null
22
+ ) {
23
+ parent ::__construct ($ state , $ storeNameFetcher , $ name );
24
+ }
25
+
12
26
protected function getCommandPrefix (): string
13
27
{
14
28
return parent ::getCommandPrefix () . 'synonyms: ' ;
@@ -56,6 +70,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
56
70
return Cli::RETURN_SUCCESS ;
57
71
}
58
72
73
+ /**
74
+ * @throws NoSuchEntityException
75
+ */
59
76
public function dedupeSynonyms (array $ storeIds = []): void
60
77
{
61
78
if (count ($ storeIds )) {
@@ -67,11 +84,66 @@ public function dedupeSynonyms(array $storeIds = []): void
67
84
}
68
85
}
69
86
87
+ /**
88
+ * @throws NoSuchEntityException
89
+ * @throws \Exception
90
+ */
70
91
public function dedupeSynonymsForStore (int $ storeId ): void
71
92
{
72
- $ this ->output ->writeln ('<info>Deduplicating synonyms for ' . $ this ->storeNameFetcher ->getStoreName ($ storeId ) . '...</info> ' );
93
+ $ this ->output ->writeln ('<info>De-duplicating synonyms for ' . $ this ->storeNameFetcher ->getStoreName ($ storeId ) . '...</info> ' );
94
+ $ indexName = $ this ->indexNameFetcher ->getProductIndexName ($ storeId );
95
+ $ settings = $ this ->algoliaHelper ->getSettings ($ indexName );
96
+ $ deduped = $ this ->dedupeSpecificSettings (['synonyms ' , 'altCorrections ' ], $ settings );
97
+
98
+ //bring over as is
99
+ $ deduped ['placeholders ' ] = $ settings ['placeholders ' ];
100
+
101
+ // Updating the synonyms requires a separate endpoint which is not currently not exposed in the PHP API client
102
+ // See https://www.algolia.com/doc/rest-api/search/#tag/Synonyms/operation/saveSynonyms
103
+ // This method will clear and then overwrite ... (does not handle one way synonyms which are not exposed in settings)
104
+ $ this ->algoliaHelper ->clearSynonyms ($ indexName );
105
+ $ this ->algoliaHelper ->setSettings ($ indexName , $ deduped , false , false );
106
+ $ this ->algoliaHelper ->waitLastTask ($ indexName );
73
107
}
74
108
109
+ /**
110
+ * @param string[] $settingNames
111
+ * @param array<string, array> $settings
112
+ * @return array
113
+ */
114
+ protected function dedupeSpecificSettings (array $ settingNames , array $ settings ): array
115
+ {
116
+ return array_filter (
117
+ array_combine (
118
+ $ settingNames ,
119
+ array_map (
120
+ function ($ settingName ) use ($ settings ) {
121
+ return isset ($ settings [$ settingName ])
122
+ ? $ this ->dedupeArrayOfArrays ($ settings [$ settingName ])
123
+ : null ;
124
+ },
125
+ $ settingNames
126
+ )
127
+ ),
128
+ function ($ val ) {
129
+ return $ val !== null ;
130
+ }
131
+ );
132
+ }
75
133
76
-
134
+ /**
135
+ * Find and remove the duplicates in an array of indexed arrays
136
+ * Does not work with associative arrays
137
+ * @param array $data
138
+ * @return array
139
+ */
140
+ protected function dedupeArrayOfArrays (array $ data ): array {
141
+ $ encoded = array_map ('json_encode ' , $ data );
142
+ $ unique = array_values (array_unique ($ encoded ));
143
+ $ decoded = array_map (function ($ item ) {
144
+ return json_decode ($ item , true ); },
145
+ $ unique
146
+ );
147
+ return $ decoded ;
148
+ }
77
149
}
0 commit comments