Completed
Push — master ( f05f74...746c7e )
by Rick
14:39 queued 25s
created

Container::removeRecursive()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 19
ccs 12
cts 12
cp 1
rs 9.2
cc 4
eloc 10
nc 4
nop 2
crap 4
1
<?php
2
/**
3
 * Particle.
4
 *
5
 * @link      http://github.com/particle-php for the canonical source repository
6
 * @copyright Copyright (c) 2005-2015 Particle (http://particle-php.com)
7
 * @license   https://github.com/particle-php/validator/blob/master/LICENSE New BSD License
8
 */
9
namespace Particle\Filter\Value;
10
11
/**
12
 * This class is used to wrap both input as output arrays.
13
 *
14
 * @package Particle\Validator
15
 */
16
class Container
17
{
18
    /**
19
     * Contains the values (either input or output).
20
     *
21
     * @var array
22
     */
23
    protected $values = [];
24
25
    /**
26
     * Construct the Value\Container.
27
     *
28
     * @param array $values
29
     */
30 165
    public function __construct(array $values = [])
31
    {
32 165
        $this->values = $values;
33 165
    }
34
35
    /**
36
     * Determines whether or not the container has a value for key $key.
37
     *
38
     * @param string $key
39
     * @return bool
40
     */
41 159
    public function has($key)
42
    {
43 159
        return $this->traverse($key, false);
44
    }
45
46
    /**
47
     * Returns the value for the key $key, or null if the value doesn't exist.
48
     *
49
     * @param string $key
50
     * @return mixed
51
     */
52 148
    public function get($key)
53
    {
54 148
        return $this->traverse($key, true);
55
    }
56
57
    /**
58
     * Removes a value from the container
59
     *
60
     * @param string $key
61
     */
62 8
    public function remove($key)
63
    {
64 8
        $this->removeRecursive(explode('.', $key), $this->values);
65 8
    }
66
67
    /**
68
     * Set the value of $key to $value.
69
     *
70
     * @param string $key
71
     * @param mixed $value
72
     * @return $this
73
     */
74 152
    public function set($key, $value)
75
    {
76 152
        if (strpos($key, '.') !== false) {
77 4
            return $this->setTraverse($key, $value);
78
        }
79 149
        $this->values[$key] = $value;
80 149
        return $this;
81
    }
82
83
    /**
84
     * Returns a plain array representation of the Value\Container object.
85
     *
86
     * @return array
87
     */
88 165
    public function getArrayCopy()
89
    {
90 165
        return $this->values;
91
    }
92
93
    /**
94
     * Traverses the key using dot notation. Based on the second parameter, it will return the value or if it was set.
95
     *
96
     * @param string $key
97
     * @param bool $returnValue
98
     * @return mixed
99
     */
100 159
    protected function traverse($key, $returnValue = true)
101
    {
102 159
        $value = $this->values;
103 159
        foreach (explode('.', $key) as $part) {
104 159
            if (!array_key_exists($part, $value)) {
105 12
                return false;
106
            }
107 148
            $value = $value[$part];
108 148
        }
109 148
        return $returnValue ? $value : true;
110
    }
111
112
    /**
113
     * Uses dot-notation to set a value.
114
     *
115
     * @param string $key
116
     * @param mixed $value
117
     * @return $this
118
     */
119 4
    protected function setTraverse($key, $value)
120
    {
121 4
        $parts = explode('.', $key);
122 4
        $ref = &$this->values;
123
124 4
        foreach ($parts as $i => $part) {
125 4
            $ref = &$ref[$part];
126 4
        }
127
128 4
        $ref = $value;
129 4
        return $this;
130
    }
131
132
    /**
133
     * @param array $keyParts
134
     * @param array $values
135
     */
136 8
    private function removeRecursive(array $keyParts, array &$values)
137
    {
138 8
        $key = $keyParts[0];
139 8
        if (!array_key_exists($key, $values)) {
140 4
            return;
141
        }
142
143 5
        if (!is_array($values[$key])) {
144 4
            unset($values[$key]);
145 4
            return;
146
        }
147
148 3
        $this->removeRecursive(array_splice($keyParts, 1), $values[$key]);
149
150
        // unset self if the removed child clears this array
151 3
        if (count($values[$key]) === 0) {
152 2
            unset($values[$key]);
153 2
        }
154 3
    }
155
}
156