Completed
Pull Request — master (#43)
by Rick
16:58
created

Container::remove()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 4
Bugs 0 Features 2
Metric Value
c 4
b 0
f 2
dl 0
loc 22
ccs 15
cts 15
cp 1
rs 8.6737
cc 5
eloc 11
nc 8
nop 2
crap 5
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 160
    public function __construct(array $values = [])
31
    {
32 160
        $this->values = $values;
33 160
    }
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 156
    public function has($key)
42
    {
43 156
        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 145
    public function get($key)
53
    {
54 145
        return $this->traverse($key, true);
55
    }
56
57
    /**
58
     * Removes a value from the container
59
     *
60
     * @param string $key
61
     * @param array|null $values
62
     */
63 7
    public function remove($key, &$values = null)
64
    {
65 7
        if ($values === null) {
66 7
            $values = &$this->values;
67 7
        }
68 7
        $keyParts = explode('.', $key);
69
        // check if the first part of the key exists on the array
70 7
        if (array_key_exists($keyParts[0], $values)) {
71
            // Is the part a new array?
72 4
            if (is_array($values[$keyParts[0]])) {
73
                // Recursively check the next part of the key on the found sub array
74 2
                $this->remove(implode('.', array_splice($keyParts, 1)), $values[$keyParts[0]]);
75
                // unset self if the removed child clears this array
76 2
                if (count($values[$keyParts[0]]) === 0) {
77 1
                    unset($values[$keyParts[0]]);
78 1
                }
79
            // Key is value, unset
80 2
            } else {
81 3
                unset($values[$keyParts[0]]);
82
            }
83 4
        }
84 7
    }
85
86
    /**
87
     * Set the value of $key to $value.
88
     *
89
     * @param string $key
90
     * @param mixed $value
91
     * @return $this
92
     */
93 150
    public function set($key, $value)
94
    {
95 150
        if (strpos($key, '.') !== false) {
96 4
            return $this->setTraverse($key, $value);
97
        }
98 147
        $this->values[$key] = $value;
99 147
        return $this;
100
    }
101
102
    /**
103
     * Returns a plain array representation of the Value\Container object.
104
     *
105
     * @return array
106
     */
107 160
    public function getArrayCopy()
108
    {
109 160
        return $this->values;
110
    }
111
112
    /**
113
     * Traverses the key using dot notation. Based on the second parameter, it will return the value or if it was set.
114
     *
115
     * @param string $key
116
     * @param bool $returnValue
117
     * @return mixed
118
     */
119 156
    protected function traverse($key, $returnValue = true)
120
    {
121 156
        $value = $this->values;
122 156
        foreach (explode('.', $key) as $part) {
123 156
            if (!array_key_exists($part, $value)) {
124 12
                return false;
125
            }
126 145
            $value = $value[$part];
127 145
        }
128 145
        return $returnValue ? $value : true;
129
    }
130
131
    /**
132
     * Uses dot-notation to set a value.
133
     *
134
     * @param string $key
135
     * @param mixed $value
136
     * @return $this
137
     */
138 4
    protected function setTraverse($key, $value)
139
    {
140 4
        $parts = explode('.', $key);
141 4
        $ref = &$this->values;
142
143 4
        foreach ($parts as $i => $part) {
144 4
            $ref = &$ref[$part];
145 4
        }
146
147 4
        $ref = $value;
148 4
        return $this;
149
    }
150
}
151