Completed
Push — master ( 6344ea...94fc66 )
by Julito
177:56 queued 121:43
created

SettingsManager   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 408
Duplicated Lines 12.25 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 6
Bugs 3 Features 0
Metric Value
c 6
b 3
f 0
dl 50
loc 408
rs 8.8
wmc 36
lcom 1
cbo 9

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
A getUrl() 0 4 1
A setUrl() 0 4 1
A installSchemas() 0 16 2
A getSchemas() 0 4 1
A getSetting() 0 11 2
A convertNameSpaceToService() 0 5 1
B load() 0 90 6
D save() 34 145 13
A getParameters() 11 11 2
A getParametersFromKeyword() 0 17 3
A transformParameters() 5 12 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\SettingsBundle\Manager;
5
6
use Chamilo\CoreBundle\Entity\AccessUrl;
7
use Chamilo\CoreBundle\Entity\Course;
8
use Chamilo\CoreBundle\Settings\PlatformSettingsSchema;
9
use Sylius\Bundle\ResourceBundle\Controller\EventDispatcherInterface;
10
use Sylius\Bundle\SettingsBundle\Event\SettingsEvent;
11
use Doctrine\Common\Cache\Cache;
12
use Doctrine\Common\Persistence\ObjectManager;
13
use Sylius\Bundle\SettingsBundle\Manager\SettingsManagerInterface;
14
use Sylius\Bundle\SettingsBundle\Model\Settings;
15
use Sylius\Bundle\SettingsBundle\Model\SettingsInterface;
16
use Sylius\Bundle\SettingsBundle\Schema\SchemaInterface;
17
use Sylius\Bundle\SettingsBundle\Schema\SchemaRegistryInterface;
18
use Sylius\Bundle\SettingsBundle\Schema\SettingsBuilder;
19
use Sylius\Component\Registry\ServiceRegistryInterface;
20
use Sylius\Component\Resource\Repository\RepositoryInterface;
21
use Symfony\Component\Validator\ConstraintViolationListInterface;
22
use Symfony\Component\Validator\Exception\ValidatorException;
23
use Symfony\Component\Validator\ValidatorInterface;
24
use Sylius\Bundle\SettingsBundle\Manager\SettingsManager as SyliusSettingsManager;
25
use Chamilo\CoreBundle\Entity\SettingsCurrent;
26
27
/**
28
 * Class SettingsManager
29
 * @package Chamilo\SettingsBundle\Manager
30
 */
31
class SettingsManager
32
{
33
    private $url;
34
35
    /**
36
     * @var ServiceRegistryInterface
37
     */
38
    private $schemaRegistry;
39
40
    /**
41
     * @var ObjectManager
42
     */
43
    private $manager;
44
45
    /**
46
     * @var FactoryInterface
47
     */
48
    private $settingsFactory;
49
50
    /**
51
     * @var EventDispatcherInterface
52
     */
53
    private $eventDispatcher;
54
55
    /**
56
     * Runtime cache for resolved parameters
57
     *
58
     * @var Settings[]
59
     */
60
    protected $resolvedSettings = array();
61
62
    public function __construct(
63
        SchemaRegistryInterface $schemaRegistry,
64
        ObjectManager $parameterManager,
65
        RepositoryInterface $parameterRepository,
66
        Cache $cache,
67
        ValidatorInterface $validator,
68
        $eventDispatcher
69
    ) {
70
        $this->schemaRegistry = $schemaRegistry;
0 ignored issues
show
Documentation Bug introduced by
It seems like $schemaRegistry of type object<Sylius\Bundle\Set...chemaRegistryInterface> is incompatible with the declared type object<Sylius\Component\...rviceRegistryInterface> of property $schemaRegistry.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
71
        $this->parameterManager = $parameterManager;
72
        $this->parameterRepository = $parameterRepository;
73
        $this->cache = $cache;
74
        $this->validator = $validator;
75
        $this->eventDispatcher = $eventDispatcher;
76
    }
77
78
    /**
79
     * @return AccessUrl
80
     */
81
    public function getUrl()
82
    {
83
        return $this->url;
84
    }
85
86
    /**
87
     * @param AccessUrl $url
88
     */
89
    public function setUrl(AccessUrl $url)
90
    {
91
        $this->url = $url;
92
    }
93
94
    /**
95
     * @param AccessUrl $url
96
     */
97
    public function installSchemas(AccessUrl $url)
98
    {
99
        $this->url = $url;
100
        $schemas = $this->getSchemas();
101
        $schemas = array_keys($schemas);
102
103
        /**
104
         * @var string $key
105
         * @var \Sylius\Bundle\SettingsBundle\Schema\SchemaInterface $schema
106
         */
107
        foreach ($schemas as $schema) {
108
109
            $settings = $this->load($schema);
110
            $this->save($schema, $settings);
111
        }
112
    }
113
114
    /**
115
     * @return array
116
     */
117
    public function getSchemas()
118
    {
119
        return $this->schemaRegistry->getSchemas();
120
    }
121
122
    /**
123
     * @param $name
124
     * @return mixed
125
     * @throws \InvalidArgumentException
126
     */
127
    public function getSetting($name)
128
    {
129
        if (false === strpos($name, '.')) {
130
            throw new \InvalidArgumentException(sprintf('Parameter must be in format "namespace.name", "%s" given.', $name));
131
        }
132
133
        list($namespace, $name) = explode('.', $name);
134
        $settings = $this->load($this->convertNameSpaceToService($namespace));
135
136
        return $settings->get($name);
137
    }
138
139
    public function convertNameSpaceToService($namespace)
140
    {
141
        //return 'chamilo_core.settings.'.$namespace;
142
        return ''.$namespace;
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function load($namespace, $namespace2 = null, $ignoreUnknown = true)
149
    {
150
        /*$schema = $this->schemaRegistry->get($schemaAlias);
151
        $resolver = $this->resolverRegistry->get($schemaAlias);
152
153
        // try to resolve settings for schema alias and namespace
154
        $settings = $resolver->resolve($schemaAlias, $namespace);
155
156
dump($settings);
157
158
        $parameters = $this->getParameters($namespace);
159
160
        $schema = $this->schemaRegistry->get($namespace);
161
162
        $settingsBuilder = new SettingsBuilder();
163
        $schema->buildSettings($settingsBuilder);
164
165
        foreach ($settingsBuilder->getTransformers() as $parameter => $transformer) {
166
            if (array_key_exists($parameter, $parameters)) {
167
                $parameters[$parameter] = $transformer->reverseTransform($parameters[$parameter]);
168
            }
169
        }
170
        $parameters = $settingsBuilder->resolve($parameters);
171
172
        return $this->resolvedSettings[$namespace] = new Settings($parameters);*/
173
174
        /*$schema = $this->schemaRegistry->get($schemaAlias);
175
        $resolver = $this->resolverRegistry->get($schemaAlias);
176
177
        // try to resolve settings for schema alias and namespace
178
        $settings = $resolver->resolve($schemaAlias, $namespace);
179
180
        if (!$settings) {
181
            $settings = $this->settingsFactory->createNew();
182
            $settings->setSchemaAlias($schemaAlias);
183
        }*/
184
185
        //$schemaAlias = 'chamilo_core.settings.'.$schemaAlias;
186
187
188
        if (isset($this->resolvedSettings[$namespace])) {
189
            return $this->resolvedSettings[$namespace];
190
        }
191
192
        if ($this->cache->contains($namespace)) {
193
            $parameters = $this->cache->fetch($namespace);
194
        } else {
195
            $parameters = $this->getParameters($namespace);
196
        }
197
198
        $schema = $this->schemaRegistry->getSchema($namespace);
199
200
        $settingsBuilder = new SettingsBuilder();
201
        $schema->buildSettings($settingsBuilder);
202
203
        $parameters = $this->transformParameters($settingsBuilder, $parameters);
204
        $parameters = $settingsBuilder->resolve($parameters);
205
206
        return $this->resolvedSettings[$namespace] = new Settings($parameters);
207
208
209
210
        $settings = $this->settingsFactory->createNew();
0 ignored issues
show
Unused Code introduced by
$settings = $this->settingsFactory->createNew(); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
211
        $settings->setSchemaAlias($schemaAlias);
212
213
        $parameters = $this->getParameters($schemaAlias);
214
215
        /** @var SchemaInterface $schema */
216
        $schema = $this->schemaRegistry->get($schemaAlias);
217
218
        // We need to get a plain parameters array since we use the options resolver on it
219
        //$parameters = $settings->getParameters();
220
221
        $settingsBuilder = new SettingsBuilder();
222
        $schema->buildSettings($settingsBuilder);
223
224
        // Remove unknown settings' parameters (e.g. From a previous version of the settings schema)
225
        if (true === $ignoreUnknown) {
226
            foreach ($parameters as $name => $value) {
227
                if (!$settingsBuilder->isDefined($name)) {
228
                    unset($parameters[$name]);
229
                }
230
            }
231
        }
232
233
        $parameters = $settingsBuilder->resolve($parameters);
234
        $settings->setParameters($parameters);
235
236
        return $settings;
237
    }
238
239
    /**
240
     * {@inheritdoc}
241
     * @throws ValidatorException
242
     */
243
    public function save($namespace, $settings)
244
    {
245
        $schema = $this->schemaRegistry->getSchema($namespace);
246
247
        $settingsBuilder = new SettingsBuilder();
248
        $schema->buildSettings($settingsBuilder);
249
250
        $parameters = $settingsBuilder->resolve($settings->getParameters());
251
252 View Code Duplication
        foreach ($settingsBuilder->getTransformers() as $parameter => $transformer) {
253
            if (array_key_exists($parameter, $parameters)) {
254
                $parameters[$parameter] = $transformer->transform($parameters[$parameter]);
255
            }
256
        }
257
258
        if (isset($this->resolvedSettings[$namespace])) {
259
            $transformedParameters = $this->transformParameters($settingsBuilder, $parameters);
260
            $this->resolvedSettings[$namespace]->setParameters($transformedParameters);
261
        }
262
263
        $persistedParameters = $this->parameterRepository->findBy(array('category' => $namespace));
264
        $persistedParametersMap = array();
265
266
        foreach ($persistedParameters as $parameter) {
267
            $persistedParametersMap[$parameter->getName()] = $parameter;
268
        }
269
270
        /** @var SettingsEvent $event */
271
        $event = $this->eventDispatcher->dispatch(
272
            SettingsEvent::PRE_SAVE,
273
            new SettingsEvent($namespace, $settings, $parameters)
274
        );
275
276
        var_dump($event);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($event); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
277
278
        /** @var \Chamilo\CoreBundle\Entity\SettingsCurrent $url */
279
        $url = $event->getArgument('url');
280
281 View Code Duplication
        foreach ($parameters as $name => $value) {
282
            if (isset($persistedParametersMap[$name])) {
283
                $persistedParametersMap[$name]->setValue($value);
284
            } else {
285
                $parameter = $this->parameterRepository->createNew();
286
287
                $parameter
288
                    ->setNamespace($namespace)
289
                    ->setName($name)
290
                    ->setValue($value)
291
                    ->setUrl($url)
292
                    ->setAccessUrlChangeable(1)
293
                    ->setAccessUrlLocked(1)
294
                ;
295
296
                /* @var $errors ConstraintViolationListInterface */
297
                $errors = $this->validator->validate($parameter);
298
                if (0 < $errors->count()) {
299
                    throw new ValidatorException($errors->get(0)->getMessage());
300
                }
301
302
                $this->parameterManager->persist($parameter);
303
            }
304
        }
305
306
        $this->parameterManager->flush();
307
308
        $this->eventDispatcher->dispatch(SettingsEvent::POST_SAVE, new SettingsEvent($namespace, $settings, $parameters));
309
310
        $this->cache->save($namespace, $parameters);
311
312
313
314
        return;
315
316
317
318
319
320
321
322
        ////
323
        $schemaAlias = $settings->getSchemaAlias();
0 ignored issues
show
Unused Code introduced by
//// $schemaAlias = $settings->getSchemaAlias(); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
324
        $schemaAliasChamilo = str_replace('chamilo_core.settings.', '', $schemaAlias);
325
326
        $schema = $this->schemaRegistry->get($schemaAlias);
327
328
        $settingsBuilder = new SettingsBuilder();
329
        $schema->buildSettings($settingsBuilder);
330
331
        $parameters = $settingsBuilder->resolve($settings->getParameters());
332
333 View Code Duplication
        foreach ($settingsBuilder->getTransformers() as $parameter => $transformer) {
334
            if (array_key_exists($parameter, $parameters)) {
335
                $parameters[$parameter] = $transformer->transform($parameters[$parameter]);
336
            }
337
        }
338
339
        /** @var \Sylius\Bundle\SettingsBundle\Event\SettingsEvent $event */
340
        $event = $this->eventDispatcher->dispatch(
341
            SettingsEvent::PRE_SAVE,
342
            new SettingsEvent($settings)
0 ignored issues
show
Bug introduced by
The call to SettingsEvent::__construct() misses some required arguments starting with $settings.
Loading history...
343
        );
344
345
        /** @var \Chamilo\CoreBundle\Entity\SettingsCurrent $url */
346
        $url = $event->getSettings()->getAccessUrl();
347
348
        foreach ($parameters as $name => $value) {
349
            if (isset($persistedParametersMap[$name])) {
350
                if ($value instanceof Course) {
351
                    $value = $value->getId();
352
                }
353
                $persistedParametersMap[$name]->setValue($value);
354
            } else {
355
                /** @var SettingsCurrent $setting */
356
                $setting = $this->settingsFactory->createNew();
357
                $setting->setSchemaAlias($schemaAlias);
358
359
                $setting
360
                    ->setNamespace($schemaAliasChamilo)
361
                    ->setName($name)
362
                    ->setValue($value)
363
                    ->setUrl($url)
364
                    ->setAccessUrlLocked(0)
365
                    ->setAccessUrlChangeable(1)
366
                ;
367
368
369
                /* @var $errors ConstraintViolationListInterface */
370
                /*$errors = $this->->validate($parameter);
371
                if (0 < $errors->count()) {
372
                    throw new ValidatorException($errors->get(0)->getMessage());
373
                }*/
374
                $this->manager->persist($setting);
375
                $this->manager->flush();
376
            }
377
        }
378
        /*$parameters = $settingsBuilder->resolve($settings->getParameters());
379
        $settings->setParameters($parameters);
380
381
        $this->eventDispatcher->dispatch(SettingsEvent::PRE_SAVE, new SettingsEvent($settings));
382
383
        $this->manager->persist($settings);
384
        $this->manager->flush();
385
386
        $this->eventDispatcher->dispatch(SettingsEvent::POST_SAVE, new SettingsEvent($settings));*/
387
    }
388
389
    /**
390
     * Load parameter from database.
391
     *
392
     * @param string $namespace
393
     *
394
     * @return array
395
     */
396 View Code Duplication
    private function getParameters($namespace)
397
    {
398
        $repo = $this->parameterRepository;
399
        //$repo = $this->manager->getRepository('ChamiloCoreBundle:SettingsCurrent');
400
        $parameters = [];
401
        foreach ($repo->findBy(array('category' => $namespace)) as $parameter) {
402
            $parameters[$parameter->getName()] = $parameter->getValue();
403
        }
404
405
        return $parameters;
406
    }
407
408
    public function getParametersFromKeyword($namespace, $keyword = '')
409
    {
410
        $criteria = array('category' => $namespace);
411
        if (!empty($keyword)) {
412
            $criteria['variable'] = $keyword;
413
        }
414
415
        $parametersFromDb = $this->parameterRepository->findBy($criteria);
416
417
        $parameters = array();
418
        /** @var \Chamilo\CoreBundle\Entity\SettingsCurrent $parameter */
419
        foreach ($parametersFromDb as $parameter) {
420
            $parameters[$parameter->getName()] = $parameter->getValue();
421
        }
422
423
        return $parameters;
424
    }
425
426
    private function transformParameters(SettingsBuilder $settingsBuilder, array $parameters)
427
    {
428
        $transformedParameters = $parameters;
429
430 View Code Duplication
        foreach ($settingsBuilder->getTransformers() as $parameter => $transformer) {
431
            if (array_key_exists($parameter, $parameters)) {
432
                $transformedParameters[$parameter] = $transformer->reverseTransform($parameters[$parameter]);
433
            }
434
        }
435
436
        return $transformedParameters;
437
    }
438
}
439