Completed
Push — master ( c38081...6a9f65 )
by Simonas
24:29
created

Service/SettingsManager.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 Symfony\Component\EventDispatcher\EventDispatcherInterface;
20
use ONGR\ElasticsearchBundle\Service\Repository;
21
use ONGR\ElasticsearchBundle\Service\Manager;
22
use ONGR\SettingsBundle\Document\Setting;
23
24
/**
25
 * Class SettingsManager responsible for managing settings actions.
26
 */
27
class SettingsManager
28
{
29
    /**
30
     * Symfony event dispatcher.
31
     *
32
     * @var EventDispatcherInterface
33
     */
34
    private $eventDispatcher;
35
36
    /**
37
     * Elasticsearch manager which handles setting repository.
38
     *
39
     * @var Manager
40
     */
41
    private $manager;
42
43
    /**
44
     * Settings repository.
45
     *
46
     * @var Repository
47
     */
48
    private $repo;
49
50
    /**
51
     * Cache pool container.
52
     *
53
     * @var CacheProvider
54
     */
55
    private $cache;
56
57
    /**
58
     * Cookie storage for active cookies.
59
     *
60
     * @var GenericCookie
61
     */
62
    private $activeProfilesCookie;
63
64
    /**
65
     * Active profiles setting name to store in the cache engine.
66
     *
67
     * @var string
68
     */
69
    private $activeProfilesSettingName;
70
71
    /**
72
     * @param Repository               $repo
73
     * @param EventDispatcherInterface $eventDispatcher
74
     */
75
    public function __construct(
76
        $repo,
77
        EventDispatcherInterface $eventDispatcher
78
    ) {
79
        $this->repo = $repo;
80
        $this->manager = $repo->getManager();
81
        $this->eventDispatcher = $eventDispatcher;
82
    }
83
84
    /**
85
     * @return CacheProvider
86
     */
87
    public function getCache()
88
    {
89
        return $this->cache;
90
    }
91
92
    /**
93
     * @param CacheProvider $cache
94
     */
95
    public function setCache($cache)
96
    {
97
        $this->cache = $cache;
98
    }
99
100
    /**
101
     * @return GenericCookie
102
     */
103
    public function getActiveProfilesCookie()
104
    {
105
        return $this->activeProfilesCookie;
106
    }
107
108
    /**
109
     * @param GenericCookie $activeProfilesCookie
110
     */
111
    public function setActiveProfilesCookie($activeProfilesCookie)
112
    {
113
        $this->activeProfilesCookie = $activeProfilesCookie;
114
    }
115
116
    /**
117
     * @return string
118
     */
119
    public function getActiveProfilesSettingName()
120
    {
121
        return $this->activeProfilesSettingName;
122
    }
123
124
    /**
125
     * @param string $activeProfilesSettingName
126
     */
127
    public function setActiveProfilesSettingName($activeProfilesSettingName)
128
    {
129
        $this->activeProfilesSettingName = $activeProfilesSettingName;
130
    }
131
132
    /**
133
     * Creates setting.
134
     *
135
     * @param array        $data
136
     *
137
     * @return Setting
138
     */
139
    public function create(array $data = [])
140
    {
141
        $data = array_filter($data);
142
        if (!isset($data['name']) || !isset($data['type'])) {
143
            throw new \LogicException('Missing one of the mandatory field!');
144
        }
145
146
        if (!isset($data['value'])) {
147
            $data['value'] = 0;
148
        }
149
150
        $name = $data['name'];
151
        $existingSetting = $this->get($name);
152
153
        if ($existingSetting) {
154
            throw new \LogicException(sprintf('Setting %s already exists.', $name));
155
        }
156
157
        $settingClass = $this->repo->getClassName();
158
        /** @var Setting $setting */
159
        $setting = new $settingClass();
160
161
        #TODO Introduce array populate function in Setting document instead of this foreach.
162
        foreach ($data as $key => $value) {
163
            $setting->{'set'.ucfirst($key)}($value);
164
        }
165
166
        $this->manager->persist($setting);
167
        $this->manager->commit();
168
169
        return $setting;
170
    }
171
172
    /**
173
     * Overwrites setting parameters with given name.
174
     *
175
     * @param string      $name
176
     * @param array       $data
177
     *
178
     * @return Setting
179
     */
180
    public function update($name, $data = [])
181
    {
182
        $setting = $this->get($name);
183
184
        if (!$setting) {
185
            throw new \LogicException(sprintf('Setting %s not exist.', $name));
186
        }
187
188
        #TODO Add populate function to document class
189
        foreach ($data as $key => $value) {
190
            $setting->{'set'.ucfirst($key)}($value);
191
        }
192
193
        $this->manager->persist($setting);
194
        $this->manager->commit();
195
196
        return $setting;
197
    }
198
199
    /**
200
     * Deletes a setting.
201
     *
202
     * @param string    $name
203
     *
204
     * @throws \LogicException
205
     * @return array
206
     */
207
    public function delete($name)
208
    {
209
        if ($this->has($name)) {
210
            $setting = $this->repo->findOneBy(['name' => $name]);
211
            return $this->repo->remove($setting->getId());
212
        }
213
214
        throw new \LogicException(sprintf('Setting with name %s doesn\'t exist.', $name));
215
    }
216
217
    /**
218
     * Returns setting object.
219
     *
220
     * @param string $name
221
     *
222
     * @return Setting
223
     */
224
    public function get($name)
225
    {
226
        /** @var Setting $setting */
227
        $setting = $this->repo->findOneBy(['name' => $name]);
228
229
        return $setting;
230
    }
231
232
    /**
233
     * Returns setting object.
234
     *
235
     * @param string $name
236
     *
237
     * @return bool
238
     */
239
    public function has($name)
240
    {
241
        /** @var Setting $setting */
242
        $setting = $this->repo->findOneBy(['name' => $name]);
243
244
        if ($setting) {
245
            return true;
246
        }
247
248
        return false;
249
    }
250
251
    /**
252
     * Get setting value by current active profiles setting.
253
     *
254
     * @param string $name
255
     * @param bool $default
256
     *
257
     * @return mixed
258
     */
259
    public function getValue($name, $default = null)
260
    {
261
        $setting = $this->get($name);
262
263
        if ($setting) {
264
            return $setting->getValue();
265
        }
266
267
        return $default;
268
    }
269
270
    /**
271
     * Get setting value by checking also from cache engine.
272
     *
273
     * @param string $name
274
     * @param bool   $checkWithActiveProfiles Checks if setting is in active profile.
275
     *
276
     * @return mixed
277
     */
278
    public function getCachedValue($name, $checkWithActiveProfiles = true)
279
    {
280
        if ($this->cache->contains($name)) {
281
            $setting = $this->cache->fetch($name);
282
        } elseif ($this->has($name)) {
283
            $settingDocument = $this->get($name);
284
            $setting = [
285
                'value' => $settingDocument->getValue(),
286
                'profiles' => $settingDocument->getProfile(),
287
            ];
288
            $this->cache->save($name, $setting);
289
        } else {
290
            return null;
291
        }
292
293
        if ($checkWithActiveProfiles) {
294
            $profilesFromEs = $this->getActiveProfiles();
295
            $profilesFromCookie = (array)$this->activeProfilesCookie->getValue();
296
297
            $profiles = array_merge($profilesFromEs, $profilesFromCookie);
298
            $settingProfiles = $setting['profiles'];
299
            if (count(array_intersect($profiles, $settingProfiles))) {
300
                return $setting['value'];
301
            }
302
        }
303
304
        return $setting['value'];
305
    }
306
307
    /**
308
     * Get all full profile information.
309
     *
310
     * @return array
311
     */
312
    public function getAllProfiles()
313
    {
314
        $profiles = [];
315
316
        $search = $this->repo->createSearch();
317
        $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...
318
        $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...
319
        $termAgg->addAggregation($topHitsAgg);
320
        $search->addAggregation($termAgg);
321
322
        $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...
323
324
        /** @var Setting $activeProfiles */
325
        $activeProfiles = $this->getValue($this->activeProfilesSettingName, []);
326
327
        /** @var AggregationValue $agg */
328
        foreach ($result->getAggregation('profiles') as $agg) {
329
            $settings = [];
330
            $docs = $agg->getAggregation('documents');
331
            foreach ($docs['hits']['hits'] as $doc) {
332
                $settings[] = $doc['_source']['name'];
333
            }
334
            $name = $agg->getValue('key');
335
            $profiles[] = [
336
                'active' => $activeProfiles ? in_array($agg->getValue('key'), $activeProfiles) : false,
337
                'name' => $name,
338
                'settings' => implode(', ', $settings),
339
            ];
340
        }
341
342
        return $profiles;
343
    }
344
345
    /**
346
     * Get profile names, optionally can return only active ones.
347
     *
348
     * @param bool $onlyActive
349
     *
350
     * @return array
351
     */
352
    public function getAllProfilesNameList($onlyActive = false)
353
    {
354
        $profiles = [];
355
        $allProfiles = $this->getAllProfiles();
356
357
        foreach ($allProfiles as $profile) {
358
            if ($onlyActive and !$profile['active']) {
359
                continue;
360
            }
361
362
            $profiles[] = $profile['name'];
363
        }
364
365
        return $profiles;
366
    }
367
368
    /**
369
     * Returns cached active profiles names list.
370
     *
371
     * @return array
372
     */
373
    public function getActiveProfiles()
374
    {
375
        if ($this->cache->contains($this->activeProfilesSettingName)) {
376
            return $this->cache->fetch($this->activeProfilesSettingName);
377
        }
378
379
        $profiles = $this->getAllProfilesNameList(true);
380
381
        $this->cache->save($this->activeProfilesSettingName, $profiles);
382
383
        return $profiles;
384
    }
385
}
386