Completed
Push — master ( c9a513...b3d424 )
by Simonas
12s
created

SettingsManager::getActiveProfilesList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\SettingsBundle\Service;
13
14
use Doctrine\Common\Cache\CacheProvider;
15
use ONGR\CookiesBundle\Cookie\Model\GenericCookie;
16
use ONGR\ElasticsearchBundle\Result\Aggregation\AggregationValue;
17
use ONGR\ElasticsearchDSL\Aggregation\TermsAggregation;
18
use ONGR\ElasticsearchDSL\Aggregation\TopHitsAggregation;
19
use ONGR\ElasticsearchDSL\Query\TermQuery;
20
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
21
use ONGR\ElasticsearchBundle\Service\Repository;
22
use ONGR\ElasticsearchBundle\Service\Manager;
23
use ONGR\SettingsBundle\Document\Setting;
24
25
/**
26
 * Class SettingsManager responsible for managing settings actions.
27
 */
28
class SettingsManager
29
{
30
    /**
31
     * Symfony event dispatcher.
32
     *
33
     * @var EventDispatcherInterface
34
     */
35
    private $eventDispatcher;
36
37
    /**
38
     * Elasticsearch manager which handles setting repository.
39
     *
40
     * @var Manager
41
     */
42
    private $manager;
43
44
    /**
45
     * Settings repository.
46
     *
47
     * @var Repository
48
     */
49
    private $repo;
50
51
    /**
52
     * Cache pool container.
53
     *
54
     * @var CacheProvider
55
     */
56
    private $cache;
57
58
    /**
59
     * Cookie storage for active cookies.
60
     *
61
     * @var GenericCookie
62
     */
63
    private $activeProfilesCookie;
64
65
    /**
66
     * Active profiles setting name to store in the cache engine.
67
     *
68
     * @var string
69
     */
70
    private $activeProfilesSettingName;
71
72
    /**
73
     * Active profiles list collected from es, cache and cookie.
74
     *
75
     * @var array
76
     */
77
    private $activeProfilesList = [];
78
79
    /**
80
     * @param Repository               $repo
81
     * @param EventDispatcherInterface $eventDispatcher
82
     */
83
    public function __construct(
84
        $repo,
85
        EventDispatcherInterface $eventDispatcher
86
    ) {
87
        $this->repo = $repo;
88
        $this->manager = $repo->getManager();
89
        $this->eventDispatcher = $eventDispatcher;
90
    }
91
92
    /**
93
     * @return CacheProvider
94
     */
95
    public function getCache()
96
    {
97
        return $this->cache;
98
    }
99
100
    /**
101
     * @param CacheProvider $cache
102
     */
103
    public function setCache($cache)
104
    {
105
        $this->cache = $cache;
106
    }
107
108
    /**
109
     * @return GenericCookie
110
     */
111
    public function getActiveProfilesCookie()
112
    {
113
        return $this->activeProfilesCookie;
114
    }
115
116
    /**
117
     * @param GenericCookie $activeProfilesCookie
118
     */
119
    public function setActiveProfilesCookie($activeProfilesCookie)
120
    {
121
        $this->activeProfilesCookie = $activeProfilesCookie;
122
    }
123
124
    /**
125
     * @return string
126
     */
127
    public function getActiveProfilesSettingName()
128
    {
129
        return $this->activeProfilesSettingName;
130
    }
131
132
    /**
133
     * @param string $activeProfilesSettingName
134
     */
135
    public function setActiveProfilesSettingName($activeProfilesSettingName)
136
    {
137
        $this->activeProfilesSettingName = $activeProfilesSettingName;
138
    }
139
140
    /**
141
     * @return array
142
     */
143
    public function getActiveProfilesList()
144
    {
145
        return $this->activeProfilesList;
146
    }
147
148
    /**
149
     * @param array $activeProfilesList
150
     */
151
    public function setActiveProfilesList(array $activeProfilesList)
152
    {
153
        $this->activeProfilesList = $activeProfilesList;
154
    }
155
156
    /**
157
     * @param array $activeProfilesList
158
     */
159
    public function appendActiveProfilesList(array $activeProfilesList)
160
    {
161
        $this->activeProfilesList = array_merge($this->activeProfilesList, $activeProfilesList);
162
    }
163
164
    /**
165
     * Creates setting.
166
     *
167
     * @param array        $data
168
     *
169
     * @return Setting
170
     */
171
    public function create(array $data = [])
172
    {
173
        $data = array_filter($data);
174
        if (!isset($data['name']) || !isset($data['type'])) {
175
            throw new \LogicException('Missing one of the mandatory field!');
176
        }
177
178
        if (!isset($data['value'])) {
179
            $data['value'] = 0;
180
        }
181
182
        $name = $data['name'];
183
        $existingSetting = $this->get($name);
184
185
        if ($existingSetting) {
186
            throw new \LogicException(sprintf('Setting %s already exists.', $name));
187
        }
188
189
        $settingClass = $this->repo->getClassName();
190
        /** @var Setting $setting */
191
        $setting = new $settingClass();
192
193
        #TODO Introduce array populate function in Setting document instead of this foreach.
194
        foreach ($data as $key => $value) {
195
            $setting->{'set'.ucfirst($key)}($value);
196
        }
197
198
        $this->manager->persist($setting);
199
        $this->manager->commit();
200
201
        return $setting;
202
    }
203
204
    /**
205
     * Overwrites setting parameters with given name.
206
     *
207
     * @param string      $name
208
     * @param array       $data
209
     *
210
     * @return Setting
211
     */
212
    public function update($name, $data = [])
213
    {
214
        $setting = $this->get($name);
215
216
        if (!$setting) {
217
            throw new \LogicException(sprintf('Setting %s not exist.', $name));
218
        }
219
220
        #TODO Add populate function to document class
221
        foreach ($data as $key => $value) {
222
            $setting->{'set'.ucfirst($key)}($value);
223
        }
224
225
        $this->manager->persist($setting);
226
        $this->manager->commit();
227
228
        return $setting;
229
    }
230
231
    /**
232
     * Deletes a setting.
233
     *
234
     * @param string    $name
235
     *
236
     * @throws \LogicException
237
     * @return array
238
     */
239
    public function delete($name)
240
    {
241
        if ($this->has($name)) {
242
            $setting = $this->repo->findOneBy(['name' => $name]);
243
            return $this->repo->remove($setting->getId());
244
        }
245
246
        throw new \LogicException(sprintf('Setting with name %s doesn\'t exist.', $name));
247
    }
248
249
    /**
250
     * Returns setting object.
251
     *
252
     * @param string $name
253
     *
254
     * @return Setting
255
     */
256
    public function get($name)
257
    {
258
        /** @var Setting $setting */
259
        $setting = $this->repo->findOneBy(['name' => $name]);
260
261
        return $setting;
262
    }
263
264
    /**
265
     * Returns setting object.
266
     *
267
     * @param string $name
268
     *
269
     * @return bool
270
     */
271
    public function has($name)
272
    {
273
        /** @var Setting $setting */
274
        $setting = $this->repo->findOneBy(['name' => $name]);
275
276
        if ($setting) {
277
            return true;
278
        }
279
280
        return false;
281
    }
282
283
    /**
284
     * Get setting value by current active profiles setting.
285
     *
286
     * @param string $name
287
     * @param bool $default
288
     *
289
     * @return string|array|bool
290
     */
291
    public function getValue($name, $default = null)
292
    {
293
        $setting = $this->get($name);
294
295
        if ($setting) {
296
            return $setting->getValue();
297
        }
298
299
        return $default;
300
    }
301
302
    /**
303
     * Get setting value by checking also from cache engine.
304
     *
305
     * @param string $name
306
     * @param bool   $checkWithActiveProfiles Checks if setting is in active profile.
307
     *
308
     * @return mixed
309
     */
310
    public function getCachedValue($name, $checkWithActiveProfiles = true)
311
    {
312
        if ($this->cache->contains($name)) {
313
            $setting = $this->cache->fetch($name);
314
        } elseif ($this->has($name)) {
315
            $settingDocument = $this->get($name);
316
            $setting = [
317
                'value' => $settingDocument->getValue(),
318
                'profiles' => $settingDocument->getProfile(),
319
            ];
320
            $this->cache->save($name, $setting);
321
        } else {
322
            return null;
323
        }
324
325
        if ($checkWithActiveProfiles) {
326
            if (count(array_intersect($this->getActiveProfiles(), $setting['profiles']))) {
327
                return $setting['value'];
328
            }
329
330
            return null;
331
        }
332
333
        return $setting['value'];
334
    }
335
336
    /**
337
     * Get all full profile information.
338
     *
339
     * @return array
340
     */
341
    public function getAllProfiles()
342
    {
343
        $profiles = [];
344
345
        $search = $this->repo->createSearch();
346
        $topHitsAgg = new TopHitsAggregation('documents', 20);
0 ignored issues
show
Deprecated Code introduced by
The class ONGR\ElasticsearchDSL\Ag...tion\TopHitsAggregation has been deprecated with message: Aggregations was moved to it's type namespace. Add `Metric` or `Bucketing` after `Aggregation`. This class will be removed in 3.0.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
347
        $termAgg = new TermsAggregation('profiles', 'profile');
0 ignored issues
show
Deprecated Code introduced by
The class ONGR\ElasticsearchDSL\Aggregation\TermsAggregation has been deprecated with message: Aggregations was moved to it's type namespace. Add `Metric` or `Bucketing` after `Aggregation`. This class will be removed in 3.0.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
348
        $termAgg->addAggregation($topHitsAgg);
349
        $search->addAggregation($termAgg);
350
351
        $result = $this->repo->execute($search);
0 ignored issues
show
Deprecated Code introduced by
The method ONGR\ElasticsearchBundle...e\Repository::execute() has been deprecated with message: Use strict execute functions instead. e.g. executeIterator, executeRawIterator.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
352
353
        /** @var Setting $activeProfiles */
354
        $activeProfiles = $this->getValue($this->activeProfilesSettingName, []);
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a boolean|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
355
356
        /** @var AggregationValue $agg */
357
        foreach ($result->getAggregation('profiles') as $agg) {
358
            $settings = [];
359
            $docs = $agg->getAggregation('documents');
360
            foreach ($docs['hits']['hits'] as $doc) {
361
                $settings[] = $doc['_source']['name'];
362
            }
363
            $name = $agg->getValue('key');
364
            $profiles[] = [
365
                'active' => $activeProfiles ? in_array($agg->getValue('key'), (array)$activeProfiles) : false,
366
                'name' => $name,
367
                'settings' => implode(', ', $settings),
368
            ];
369
        }
370
371
        return $profiles;
372
    }
373
374
    /**
375
     * Returns profiles settings array
376
     *
377
     * @param string $profile
378
     *
379
     * @return array
380
     */
381
    public function getProfileSettings($profile)
382
    {
383
        $search = $this->repo->createSearch();
384
        $termQuery = new TermQuery('profile', $profile);
385
        $search->addQuery($termQuery);
386
        $search->setSize(1000);
387
388
        $settings = $this->repo->findArray($search);
389
390
        return $settings;
391
    }
392
393
    /**
394
     * Returns cached active profiles names list.
395
     *
396
     * @return array
397
     */
398
    public function getActiveProfiles()
399
    {
400
        if ($this->cache->contains($this->activeProfilesSettingName)) {
401
            $profiles = $this->cache->fetch($this->activeProfilesSettingName);
402
        } else {
403
            $profiles = [];
404
            $allProfiles = $this->getAllProfiles();
405
406
            foreach ($allProfiles as $profile) {
407
                if (!$profile['active']) {
408
                    continue;
409
                }
410
411
                $profiles[] = $profile['name'];
412
            }
413
414
            $this->cache->save($this->activeProfilesSettingName, $profiles);
415
        }
416
417
        $profiles = array_merge($profiles, $this->activeProfilesList);
418
419
        return $profiles;
420
    }
421
}
422