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

Config::getDateTime()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0185

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 8
ccs 5
cts 6
cp 0.8333
crap 2.0185
rs 10
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