Completed
Branch master (21229c)
by Juuso
03:54
created

checkImplementsSearchableInterface()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
crap 2
1
<?php
2
3
namespace leinonen\Yii2Algolia;
4
5
use AlgoliaSearch\Client;
6
use AlgoliaSearch\Index;
7
use leinonen\Yii2Algolia\ActiveRecord\ActiveRecordFactory;
8
9
/**
10
 * @method setConnectTimeout(int $connectTimeout, int $timeout = 30, int $searchTimeout = 5)
11
 * @method enableRateLimitForward(string $adminAPIKey, string $endUserIP, string $rateLimitAPIKey)
12
 * @method setForwarderFor(string $ip)
13
 * @method setAlgoliaUserToken(string $token)
14
 * @method disableRateLimitForward()
15
 * @method isAlive()
16
 * @method setExtraHeader(string $key, string $value)
17
 * @method mixed multipleQueries(array $queries, string $indexNameKey = "indexName", string $strategy = "none")
18
 * @method mixed listIndexes()
19
 * @method deleteIndex(string $indexName)
20
 * @method mixed moveIndex(string $srcIndexName, string $dstIndexName)
21
 * @method mixed copyIndex(string $srcIndexName, string $dstIndexName)
22
 * @method mixed getLogs(int $offset = 0, int $length = 10, string $type = "all")
23
 * @method Index initIndex(string $indexName)
24
 * @method mixed listUserKeys()
25
 * @method mixed getUserKeyACL(string $key)
26
 * @method mixed deleteUserKey(string $key)
27
 * @method mixed addUserKey(array $obj, int $validity = 0, int $maxQueriesPerIPPerHour = 0, int $maxHitsPerQuery = 0, array $indexes = null)
28
 * @method mixed updateUserKey(string $key, array $obj, int $validity = 0, int $maxQueriesPerIPPerHour = 0, int $maxHitsPerQuery = 0, array $indexes = null)
29
 * @method mixed batch(array $requests)
30
 * @method string generateSecuredApiKey(string $privateApiKey, mixed $query, string $userToken = null)
31
 * @method string buildQuery(array $args)
32
 * @method mixed request(\AlgoliaSearch\ClientContext $context, string $method, string $path, array $params, array $data, array $hostsArray, int $connectTimeout, int $readTimeout)
33
 * @method mixed doRequest(\AlgoliaSearch\ClientContext $context, string $method, string $path, array $params, array $data, array $hostsArray, int $connectTimeout, int $readTimeout)
34
 * @method \AlgoliaSearch\PlacesIndex initPlaces(string $appId, string $appKey, array $hostsArray = null, array $options = [])
35
 * @see Client
36
 */
37
class AlgoliaManager
38
{
39
    /**
40
     * @var AlgoliaFactory
41
     */
42
    protected $factory;
43
44
    /**
45
     * @var array
46
     */
47
    protected $config;
48
49
    /**
50
     * @var null|Client
51
     */
52
    protected $client;
53
54
    /**
55
     * @var ActiveRecordFactory
56
     */
57
    protected $activeRecordFactory;
58
59
    /**
60
     * Initiates a new AlgoliaManager.
61
     *
62
     * @param AlgoliaFactory $algoliaFactory
63
     * @param ActiveRecordFactory $activeRecordFactory
64
     * @param array $config Configurations for the Algolia Client.
65
     */
66 24
    public function __construct(AlgoliaFactory $algoliaFactory, ActiveRecordFactory $activeRecordFactory, array $config = [])
67
    {
68 24
        $this->factory = $algoliaFactory;
69 24
        $this->config = $config;
70 24
        $this->activeRecordFactory = $activeRecordFactory;
71 24
    }
72
73
    /**
74
     * Returns the Algolia Client.
75
     *
76
     * @return Client
77
     */
78 7
    public function getClient()
79
    {
80 7
        if (is_null($this->client)) {
81 7
            $this->client = $this->factory->make($this->config);
82 7
        }
83
84 7
        return $this->client;
85
    }
86
87
    /**
88
     * Returns the config array.
89
     *
90
     * @return array
91
     */
92 2
    public function getConfig()
93
    {
94 2
        return $this->config;
95
    }
96
97
    /**
98
     * Indexes a searchable model to all indices.
99
     *
100
     * @param SearchableInterface $searchableModel
101
     *
102
     * @return array
103
     */
104 1
    public function pushToIndices(SearchableInterface $searchableModel)
105
    {
106 1
        $indices = $searchableModel->getIndices();
107 1
        $response = [];
108
109 1
        foreach ($indices as $index) {
110 1
            $record = $searchableModel->getAlgoliaRecord();
111 1
            $response[$index] = $this->initIndex($index)->addObject($record, $searchableModel->getObjectID());
112 1
        }
113
114 1
        return $response;
115
    }
116
117
    /**
118
     * Updates the models data in all indices.
119
     *
120
     * @param SearchableInterface $searchableModel
121
     *
122
     * @return array
123
     */
124 1
    public function updateInIndices(SearchableInterface $searchableModel)
125
    {
126 1
        $indices = $searchableModel->getIndices();
127 1
        $response = [];
128
129 1
        foreach ($indices as $index) {
130 1
            $record = $searchableModel->getAlgoliaRecord();
131 1
            $record['objectID'] = $searchableModel->getObjectID();
132 1
            $response[$index] = $this->initIndex($index)->saveObject($record);
133 1
        }
134
135 1
        return $response;
136
    }
137
138
    /**
139
     * Removes a searchable model from indices.
140
     *
141
     * @param SearchableInterface $searchableModel
142
     *
143
     * @return array
144
     * @throws \Exception
145
     */
146 1
    public function removeFromIndices(SearchableInterface $searchableModel)
147
    {
148 1
        $indices = $searchableModel->getIndices();
149 1
        $response = [];
150
151 1
        foreach ($indices as $index) {
152 1
            $objectID = $searchableModel->getObjectID();
153 1
            $response[$index] = $this->initIndex($index)->deleteObject($objectID);
154 1
        }
155
156 1
        return $response;
157
    }
158
159
    /**
160
     * Re-indexes the indices safely for the given ActiveRecord Class.
161
     *
162
     * @param string $className The name of the ActiveRecord to be indexed.
163
     *
164
     * @return array
165
     */
166 2
    public function reindex($className)
167
    {
168 2
        $this->checkImplementsSearchableInterface($className);
169 1
        $activeRecord = $this->activeRecordFactory->make($className);
170 1
        $response = [];
171
172
        /** @var SearchableInterface[] $activeRecordEntities */
173 1
        $activeRecordEntities = $activeRecord->find()->all();
174
175
        /* @var SearchableInterface $activeRecord */
176 1
        $indices = $activeRecord->getIndices();
177 1
        $records = [];
178
179 1
        foreach ($activeRecordEntities as $activeRecordEntity) {
180 1
            $record = $activeRecordEntity->getAlgoliaRecord();
181 1
            $record['objectID'] = $activeRecordEntity->getObjectID();
182 1
            $records[] = $record;
183 1
        }
184
185 1
        foreach ($indices as $index) {
186 1
            $temporaryIndexName = 'tmp_' . $index;
187
188
            /** @var Index $temporaryIndex */
189 1
            $temporaryIndex = $this->initIndex($temporaryIndexName);
190 1
            $temporaryIndex->addObjects($records);
191
192 1
            $response[$index] = $this->moveIndex($temporaryIndexName, $index);
193 1
        }
194
195 1
        return $response;
196
    }
197
198
    /**
199
     * Clears the indices for the given Class that implements SearchableInterface.
200
     *
201
     * @param string $className The name of the Class which indices are to be cleared.
202
     *
203
     * @return array
204
     */
205 2
    public function clearIndices($className)
206
    {
207 2
        $this->checkImplementsSearchableInterface($className);
208 1
        $activeRecord = $this->activeRecordFactory->make($className);
209 1
        $response = [];
210
211
        /* @var SearchableInterface $activeRecord */
212 1
        $indices = $activeRecord->getIndices();
213
214 1
        foreach ($indices as $index) {
215 1
            $response[$index] = $this->initIndex($index)->clearIndex();
216 1
        }
217
218 1
        return $response;
219
    }
220
221
    /**
222
     * Dynamically pass methods to the Algolia Client.
223
     *
224
     * @param string $method
225
     * @param array $parameters
226
     *
227
     * @return mixed
228
     */
229 6
    public function __call($method, $parameters)
230
    {
231 6
        return call_user_func_array([$this->getClient(), $method], $parameters);
232
    }
233
234
    /**
235
     * Checks if the given class implements SearchableInterface.
236
     *
237
     * @param string $class Either name or instance of the class to be checked.
238
     */
239 4
    private function checkImplementsSearchableInterface($class)
240
    {
241 4
        $reflectionClass = new \ReflectionClass($class);
242
243 4
        if (! $reflectionClass->implementsInterface(SearchableInterface::class)) {
244 2
            throw new \InvalidArgumentException("The class: {$reflectionClass->name} doesn't implement leinonen\\Yii2Algolia\\SearchableInterface");
245
        }
246 2
    }
247
}
248