Test Failed
Push — master ( be437e...866f6c )
by Julien
07:25
created

Config   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Test Coverage

Coverage 67.44%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 37
c 1
b 0
f 1
dl 0
loc 113
ccs 29
cts 43
cp 0.6744
rs 10
wmc 20

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getModelInstance() 0 6 1
A merge() 0 17 4
A resetModelClass() 0 3 1
A getModelClass() 0 3 2
A getDateTime() 0 8 2
A setModelClass() 0 3 1
A internalMergeAppend() 0 15 6
A pathToArray() 0 13 3
1
<?php
2
3
/**
4
 * This file is part of the Zemit Framework.
5
 *
6
 * (c) Zemit Team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE.txt
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zemit\Config;
13
14
use DateTimeImmutable;
15
use Phalcon\Config\ConfigInterface as PhalconConfigInterface;
16
use Zemit\Mvc\Model;
17
use DateTimeInterface;
18
use Exception;
19
use Zemit\Mvc\ModelInterface;
20
21
class Config extends \Phalcon\Config\Config implements ConfigInterface
22
{
23
    /**
24
     * Return the element as an array
25
     */
26 115
    public function pathToArray(string $path, ?array $defaultValue = null, ?string $delimiter = null): ?array
27
    {
28 115
        $ret = $this->path($path, $defaultValue, $delimiter);
29
        
30 115
        if (is_null($ret)) {
31 3
            return null;
32
        }
33
        
34 115
        if ($ret instanceof PhalconConfigInterface) {
35 115
            return $ret->toArray();
36
        }
37
        
38 1
        return (array)$ret;
39
    }
40
    
41 2
    public function merge($toMerge, bool $append = false): PhalconConfigInterface
42
    {
43 2
        if (!$append) {
44 2
            return parent::merge($toMerge);
45
        }
46
        
47
        $source = $this->toArray();
48
        $this->clear();
49
        $toMerge = $toMerge instanceof PhalconConfigInterface ? $toMerge->toArray() : $toMerge;
50
        
51
        if (!is_array($toMerge)) {
52
            throw new \Exception('Invalid data type for merge.');
53
        }
54
        
55
        $result = $this->internalMergeAppend($source, $toMerge);
56
        $this->init($result);
57
        return $this;
58
    }
59
    
60 112
    final protected function internalMergeAppend(array $source, array $target): array
61
    {
62 112
        foreach ($target as $key => $value) {
63 112
            if (is_array($value) && isset($source[$key]) && is_array($source[$key])) {
64 112
                $source[$key] = $this->internalMergeAppend($source[$key], $value);
65
            }
66 112
            elseif (is_int($key)) {
67 112
                $source[] = $value;
68
            }
69
            else {
70 112
                $source[$key] = $value;
71
            }
72
        }
73
        
74 112
        return $source;
75
    }
76
    
77
    /**
78
     * Get a modified DateTime.
79
     * Note: This is a helper to enhance strict typings and safely use DateTime within config
80
     *
81
     * @param string $modifier The modifier string to modify the DateTime.
82
     * @param DateTimeImmutable|null $dateTime Optional. The DateTime to modify. Defaults to current DateTime if not provided.
83
     *
84
     * @return DateTimeImmutable The modified DateTime object.
85
     * @throws Exception If the modification of the DateTime fails.
86
     */
87 112
    public function getDateTime(string $modifier, ?DateTimeImmutable $dateTime = null): DateTimeImmutable
88
    {
89 112
        $dateTime ??= new DateTimeImmutable();
90 112
        $modified = $dateTime->modify($modifier);
91 112
        if ($modified === false) {
92
            throw new Exception("Failed to modify the date with the period '{$modifier}'.");
93
        }
94 112
        return $modified;
95
    }
96
    
97
    /**
98
     * Return a new model instance from class name
99
     * @todo use DI instead
100
     */
101
    public function getModelInstance(string $class): ModelInterface
102
    {
103
        $modelClass = $this->getModelClass($class);
104
        $modelInstance = new $modelClass();
105
        assert($modelInstance instanceof ModelInterface);
106
        return $modelInstance;
107
    }
108
    
109
    /**
110
     * Return the mapped model class name from $this->models->$class
111
     * @todo use DI instead
112
     */
113 54
    public function getModelClass(string $class): string
114
    {
115 54
        return $this->get('models')->get($class) ?: $class;
116
    }
117
    
118
    /**
119
     * Map a new model class
120
     * @todo use DI instead
121
     */
122 1
    public function setModelClass(string $class, string $expected): void
123
    {
124 1
        $this->get('models')->set($class, $expected);
125
    }
126
    
127
    /**
128
     * Map a new model class
129
     * @todo use DI instead
130
     */
131 1
    public function resetModelClass(string $class): void
132
    {
133 1
        $this->get('models')->set($class, $class);
134
    }
135
}
136