Chain   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 1
dl 0
loc 114
ccs 25
cts 25
cp 1
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __invoke() 0 8 2
A isEmpty() 0 4 1
A isRequired() 0 4 1
A count() 0 4 1
A getIterator() 0 4 1
A then() 0 5 1
A each() 0 8 2
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Caridea
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
 * use this file except in compliance with the License. You may obtain a copy of
8
 * the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 * License for the specific language governing permissions and limitations under
16
 * the License.
17
 *
18
 * @copyright 2015-2018 LibreWorks contributors
19
 * @license   Apache-2.0
20
 */
21
namespace Caridea\Filter;
22
23
/**
24
 * Unchained, yeah you hit the ground running.
25
 *
26
 * This class holds several callable objects and invokes them in insert order.
27
 */
28
class Chain implements \IteratorAggregate, \Countable
29
{
30
    /**
31
     * @var Registry - The builder containing definitions
32
     */
33
    protected $registry;
34
    /**
35
     * @var callable[] - The filters to apply
36
     */
37
    protected $filters = [];
38
    /**
39
     * @var bool - Whether to run this filter regardless of value existence
40
     */
41
    protected $required;
42
43
    /**
44
     * Creates a new Chain
45
     *
46
     * @param \Caridea\Filter\Registry $registry The builder
47
     * @param bool $required Whether these filters run even if value is missing
48
     */
49 1
    public function __construct(Registry $registry, bool $required = false)
50
    {
51 1
        $this->registry = $registry;
52 1
        $this->required = $required;
53 1
    }
54
55
    /**
56
     * Run all of the filters.
57
     *
58
     * @param mixed $value The value to filter
59
     * @return mixed The sanitized value
60
     */
61 2
    public function __invoke($value)
62
    {
63 2
        $result = $value;
64 2
        foreach ($this->filters as $f) {
65 1
            $result = $f($result);
66
        }
67 2
        return $result;
68
    }
69
70
    /**
71
     * Whether this set is empty.
72
     *
73
     * @return bool `true` if this set is empty
74
     */
75 1
    public function isEmpty(): bool
76
    {
77 1
        return !$this->filters;
78
    }
79
80
    /**
81
     * Whether this set is required to run.
82
     *
83
     * @return bool `true` if this set is required
84
     */
85 1
    public function isRequired(): bool
86
    {
87 1
        return $this->required;
88
    }
89
90
    /**
91
     * Gets the count.
92
     *
93
     * @return int The count
94
     */
95 1
    public function count(): int
96
    {
97 1
        return count($this->filters);
98
    }
99
100
    /**
101
     * Gets the iterator.
102
     *
103
     * @return \Traversable The iterator
104
     */
105 1
    public function getIterator(): \Traversable
106
    {
107 1
        return new \ArrayIterator($this->filters);
108
    }
109
110
    /**
111
     * Returns this chain with the defined filter appended.
112
     *
113
     * @param string $name The filter name
114
     * @param mixed $args Any remaining arguments for the filter
115
     * @return self provides a fluent interface
116
     */
117 1
    public function then(string $name, ...$args): self
118
    {
119 1
        $this->filters[] = $this->registry->factory($name, $args);
120 1
        return $this;
121
    }
122
123
    /**
124
     * Returns this chain with the defined *each* filter appended.
125
     *
126
     * If the filter receives an array, it will run for every entry, and if it
127
     * receives anything else, it will be run once.
128
     *
129
     * @param string $name The filter name
130
     * @param mixed $args Any remaining arguments for the filter
131
     * @return self provides a fluent interface
132
     */
133 1
    public function each(string $name, ...$args): self
134
    {
135 1
        $f = $this->registry->factory($name, $args);
136 1
        $this->filters[] = function ($input) use ($f) {
137 1
            return is_array($input) ? array_map($f, $input) : $f($input);
138
        };
139 1
        return $this;
140
    }
141
}
142