Completed
Pull Request — master (#43)
by Rick
24:49
created

Container::remove()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 5

Importance

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