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

Filter::filterValueWithGlobalChain()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 15
ccs 10
cts 10
cp 1
rs 9.4285
cc 3
eloc 10
nc 3
nop 3
crap 3
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/Filter/blob/master/LICENSE New BSD License
8
 */
9
namespace Particle\Filter;
10
11
use Particle\Filter\Value\Container;
12
13
/**
14
 * Class Filter
15
 *
16
 * @package Particle\Filter
17
 */
18
class Filter
19
{
20
    /**
21
     * @var array<string, Chain>
22
     */
23
    protected $chains = [];
24
25
    /**
26
     * @var Container
27
     */
28
    protected $data;
29
30
    /**
31
     * @var string|null
32
     */
33
    protected $encodingFormat = null;
34
35
    /**
36
     * @var Chain
37
     */
38
    protected $globalChain = null;
39
40
    /**
41
     * Set a filter for a value on a specific key
42
     *
43
     * @param string $key
44
     * @return FilterResource
45
     */
46 154
    public function value($key)
47
    {
48 154
        return $this->getFilterResource($key);
49
    }
50
51
    /**
52
     * Set a filter for the values on the given keys
53
     *
54
     * @param string[] $keys
55
     * @return FilterResource
56
     */
57 7
    public function values(array $keys)
58
    {
59 7
        return $this->getFilterResource($keys);
60
    }
61
62
    /**
63
     * Set a filter for all values off an array
64
     *
65
     * @return FilterResource
66
     */
67 4
    public function all()
68
    {
69 4
        return $this->getFilterResource();
70
    }
71
72
    /**
73
     * @param null|string|string[] $keys
74
     * @return FilterResource
75
     */
76 164
    public function getFilterResource($keys = null)
77
    {
78 164
        return new FilterResource($this, $keys);
79
    }
80
81
    /**
82
     * Set the encoding format for all string manipulating filter-rules.
83
     * Note: You should set the encoding format before you add filter-rules to your filter, otherwise the
84
     * encoding format would not be set on the values added before the encoding format was set.
85
     *
86
     * @param string $encodingFormat
87
     */
88 6
    public function setEncodingFormat($encodingFormat)
89
    {
90 6
        $this->encodingFormat = $encodingFormat;
91 6
    }
92
93
    /**
94
     * Set a filter rule on a chain
95
     *
96
     * @param FilterRule $rule
97
     * @param null|string $key
98
     */
99 163
    public function addFilterRule(FilterRule $rule, $key = null)
100
    {
101 163
        $this->getChain($key)->addRule($rule, $this->encodingFormat);
102 163
    }
103
104
    /**
105
     * Filter the provided data
106
     *
107
     * @param array $data
108
     * @return array
109
     */
110 165
    public function filter(array $data)
111
    {
112 165
        $data = $this->filterArrayWithGlobalChain($data);
113
114 165
        $this->data = new Container($data);
115
116 165
        $this->filterChains();
117
118 165
        return $this->data->getArrayCopy();
119
    }
120
121
    /**
122
     * Filter all set fields with a global chain, recursively
123
     *
124
     * @param array $data
125
     * @return array
126
     */
127 165
    protected function filterArrayWithGlobalChain(array $data)
128
    {
129 165
        if ($this->globalChain === null) {
130 161
            return $data;
131
        }
132
133 4
        foreach ($data as $key => $value) {
134 4
            $data = $this->filterValueWithGlobalChain($value, $key, $data);
135 4
        }
136
137 4
        return array_filter($data);
138
    }
139
140
    /**
141
     * Filters a value with the global chain
142
     *
143
     * @param mixed $value
144
     * @param string $key
145
     * @param array $data
146
     * @return array
147
     */
148 4
    protected function filterValueWithGlobalChain($value, $key, $data)
149
    {
150 4
        if (is_array($value)) {
151 2
            $data[$key] = $this->filterArrayWithGlobalChain($value);
152 2
            return $data;
153
        }
154
155 4
        $filterResult = $this->globalChain->filter(true, $value, $data);
156 4
        if ($filterResult->isNotEmpty()) {
157 4
            $data[$key] = $filterResult->getFilteredValue();
158 4
        } else {
159 2
            unset($data[$key]);
160
        }
161 4
        return $data;
162
    }
163
164
    /**
165
     * Get the filter result from a chain
166
     *
167
     * @param string $key
168
     * @param Chain $chain
169
     * @return FilterResult
170
     */
171 159
    protected function getFilterResult($key, Chain $chain)
172
    {
173 159
        if ($this->data->has($key)) {
174 148
            return $chain->filter(true, $this->data->get($key), $this->data->getArrayCopy());
175
        }
176
177 12
        return $chain->filter(false, null, $this->data->getArrayCopy());
178
    }
179
180
    /**
181
     * Filter all chains set
182
     */
183 165
    protected function filterChains()
184
    {
185 165
        foreach ($this->chains as $key => $chain) {
186 159
            $filterResult = $this->getFilterResult($key, $chain);
187 159
            if ($filterResult->isNotEmpty()) {
188 152
                $this->data->set(
189 152
                    $key,
190 152
                    $filterResult->getFilteredValue()
191 152
                );
192 152
            } else {
193 8
                $this->data->remove($key);
194
            }
195 165
        }
196 165
    }
197
198
    /**
199
     * Get a filter rule chain for a key
200
     *
201
     * @param null|string $key
202
     * @return Chain
203
     */
204 163
    protected function getChain($key)
205
    {
206
        // If no key, set global chain
207 163
        if ($key === null) {
208 4
            return $this->getGlobalChain();
209
        }
210
211
        // Return chain for key
212 159
        if (isset($this->chains[$key])) {
213 8
            return $this->chains[$key];
214
        }
215 159
        return $this->chains[$key] = $this->buildChain();
216
    }
217
218
    /**
219
     * Get the global chain for all values
220
     *
221
     * @return Chain
222
     */
223 4
    protected function getGlobalChain()
224
    {
225 4
        if ($this->globalChain === null) {
226 4
            $this->globalChain = $this->buildChain();
227 4
        }
228 4
        return $this->globalChain;
229
    }
230
231
    /**
232
     * Build a new chain of filters
233
     *
234
     * @return Chain
235
     */
236 163
    protected function buildChain()
237
    {
238 163
        return new Chain();
239
    }
240
}
241