Completed
Pull Request — master (#43)
by Rick
27:38 queued 27:38
created

Filter::getGlobalChain()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
crap 2
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 152
    public function value($key)
47
    {
48 152
        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 162
    public function getFilterResource($keys = null)
77
    {
78 162
        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 161
    public function addFilterRule(FilterRule $rule, $key = null)
100
    {
101 161
        $this->getChain($key)->addRule($rule, $this->encodingFormat);
102 161
    }
103
104
    /**
105
     * Filter the provided data
106
     *
107
     * @param array $data
108
     * @return array
109
     */
110 163
    public function filter(array $data)
111
    {
112 163
        $data = $this->filterGlobals($data);
113
114 163
        $this->data = new Container($data);
115
116 163
        $this->filterChains();
117
118 163
        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 163
    protected function filterGlobals(array $data)
128
    {
129 163
        if ($this->globalChain === null) {
130 159
            return $data;
131
        }
132
133 4
        foreach ($data as $key => $value) {
134 4
            if (is_array($value)) {
135 2
                $data[$key] = $this->filterGlobals($value);
136 2
            } else {
137 4
                $filterResult = $this->globalChain->filter(true, $value, $data);
138 4
                if ($filterResult->isNotEmpty()) {
139 4
                    $data[$key] = $filterResult->getFilteredValue();
140 4
                } else {
141 2
                    unset($data[$key]);
142
                }
143
            }
144 4
        }
145
146 4
        return array_filter($data);
147
    }
148
149
    /**
150
     * Get the filter result from a chain
151
     *
152
     * @param string $key
153
     * @param Chain $chain
154
     * @return FilterResult
155
     */
156 157
    protected function getFilterResult($key, Chain $chain)
157
    {
158 157
        if ($this->data->has($key)) {
159 146
            return $chain->filter(true, $this->data->get($key), $this->data->getArrayCopy());
160
        }
161
162 12
        return $chain->filter(false, null, $this->data->getArrayCopy());
163
    }
164
165
    /**
166
     * Filter all chains set
167
     */
168 163
    protected function filterChains()
169
    {
170 163
        foreach ($this->chains as $key => $chain) {
171 157
            $filterResult = $this->getFilterResult($key, $chain);
172 157
            if ($filterResult->isNotEmpty()) {
173 150
                $this->data->set(
174 150
                    $key,
175 150
                    $filterResult->getFilteredValue()
176 150
                );
177 150
            } else {
178 8
                $this->data->remove($key);
179
            }
180 163
        }
181 163
    }
182
183
    /**
184
     * Get a filter rule chain for a key
185
     *
186
     * @param null|string $key
187
     * @return Chain
188
     */
189 161
    protected function getChain($key)
190
    {
191
        // If no key, set global chain
192 161
        if ($key === null) {
193 4
            return $this->getGlobalChain();
194
        }
195
196
        // Return chain for key
197 157
        if (isset($this->chains[$key])) {
198 8
            return $this->chains[$key];
199
        }
200 157
        return $this->chains[$key] = $this->buildChain();
201
    }
202
203
    /**
204
     * Get the global chain for all values
205
     *
206
     * @return Chain
207
     */
208 4
    protected function getGlobalChain()
209
    {
210 4
        if ($this->globalChain === null) {
211 4
            $this->globalChain = $this->buildChain();
212 4
        }
213 4
        return $this->globalChain;
214
    }
215
216
    /**
217
     * Build a new chain of filters
218
     *
219
     * @return Chain
220
     */
221 161
    protected function buildChain()
222
    {
223 161
        return new Chain();
224
    }
225
}
226