FilterSet::remove()   A
last analyzed

Complexity

Conditions 5
Paths 7

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.246

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 11
cts 14
cp 0.7856
rs 9.2568
c 0
b 0
f 0
cc 5
nc 7
nop 1
crap 5.246
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Filtration;
5
6
use Sirius\Filtration\Filter\AbstractFilter as AbstractFilterAlias;
7
8
class FilterSet extends \SplPriorityQueue
9
{
10
    /**
11
     * Cache of priorities that were already taken
12
     *
13
     * @var array
14
     */
15
    protected $allocatedPriorities = [];
16
17 17
    public function __construct()
18
    {
19 17
        $this->setExtractFlags(static::EXTR_BOTH);
20 17
    }
21
22 5
    public function compare($priority1, $priority2)
23
    {
24 5
        if ($priority1 === $priority2) {
25 3
            return 0;
26
        }
27 3
        return $priority1 < $priority2 ? 1 : -1;
28
    }
29
30 17
    public function insert($filter, $priority)
31
    {
32 17
        if (!$filter instanceof Filter\AbstractFilter) {
33
            throw new \InvalidArgumentException('Only filter instances can be added to the filter set');
34
        }
35 17
        $this->allocatedPriorities[] =  $this->getValidPriority($priority);
36 17
        return parent::insert($filter, $priority);
37
    }
38
39 2
    public function remove($filter)
40
    {
41
        /* @var $filter AbstractFilterAlias */
42 2
        if (!$filter instanceof Filter\AbstractFilter) {
43
            throw new \InvalidArgumentException('Only filter instances can be removed from the filter set');
44
        }
45 2
        $filters = [];
46 2
        $this->top();
47 2
        while ($this->valid()) {
48 2
            $item = $this->current();
49
            /* @var $itemFilter AbstractFilterAlias */
50 2
            $itemFilter = $item['data'];
51 2
            if ($itemFilter->getUniqueId() !== $filter->getUniqueId()) {
52
                $filters[$item['priority']] = $item['data'];
53
            }
54 2
            $this->next();
55
        }
56 2
        foreach ($filters as $priority => $filter) {
57
            $this->insert($filter, $priority);
58
        }
59 2
        return $this;
60
    }
61
62
    /**
63
     * Get a valid priority number to attach to a filter
64
     *
65
     * @param int $desiredPriority
66
     * @return number
67
     */
68 17
    protected function getValidPriority($desiredPriority)
69
    {
70
        // make sure the priority is an integer so we don't screw up the math
71
        // also multiply everything by 10000 because the priority must be an integer
72
        // as it will be used as the $filters[$selector] array key
73 17
        $desiredPriority = (int) $desiredPriority * 10000;
74 17
        if (! in_array($desiredPriority, $this->allocatedPriorities)) {
75 17
            return $desiredPriority;
76
        }
77
        // the increment will be used to determine when we find an available spot
78
        // obviously if you have 10000 filters with priority 0,
79
        // the 10000th will get to priority one but that's a chance we are willing to take
80 3
        $increment = 1;
81 3
        while (in_array($desiredPriority, $this->allocatedPriorities)) {
82 3
            $desiredPriority += $increment;
83
        }
84 3
        return $desiredPriority;
85
    }
86
87 15
    public function applyFilters($value, $valueIdentifier = null, $context = null)
88
    {
89 15
        foreach (clone $this as $filter) {
90 13
            if (is_array($filter)) {
91
                $filter = $filter['data'];
92
            }
93
            /* @var $filter AbstractFilterAlias */
94 13
            $filter->setContext($context);
95 13
            $value = $filter->filter($value, (string) $valueIdentifier);
96
        }
97 15
        return $value;
98
    }
99
}
100