AbstractSortStrategy::getSortOrder()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace PHPExtra\Sorter\Strategy;
4
5
use PHPExtra\Sorter\Comparator\ComparatorInterface;
6
use PHPExtra\Sorter\Comparator\UnicodeCIComparator;
7
8
/**
9
 * The AbstractSortStrategy class
10
 *
11
 * @author Jacek Kobus <[email protected]>
12
 */
13
abstract class AbstractSortStrategy implements StrategyInterface
14
{
15
    /**
16
     * @var int
17
     */
18
    private $sortOrder = null;
19
20
    /**
21
     * @var bool
22
     */
23
    private $maintainKeyAssociation = false;
24
25
    /**
26
     * @var ComparatorInterface
27
     */
28
    private $comparator;
29
30
    /**
31
     * @param int                 $sortOrder  Default sort order
32
     * @param ComparatorInterface $comparator Default comparator
33
     */
34 7
    function __construct(ComparatorInterface $comparator = null, $sortOrder = self::ASC)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
35
    {
36 7
        if($sortOrder === null){
37
            $sortOrder = self::ASC;
38
        }
39
40 7
        $this->setSortOrder($sortOrder);
41
42 7
        if (!$comparator) {
43 5
            $comparator = new UnicodeCIComparator();
44 5
        }
45
46 7
        $this->setComparator($comparator);
47 7
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52 7
    public function setComparator(ComparatorInterface $comparator)
53
    {
54 7
        $this->comparator = $comparator;
55
56 7
        return $this;
57
    }
58
59
    /**
60
     * @return ComparatorInterface
61
     */
62 4
    protected function getComparator()
63
    {
64 4
        return $this->comparator;
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70 7
    public function setSortOrder($order)
71
    {
72 7
        $this->sortOrder = $order;
73
74 7
        return $this;
75
    }
76
77
    /**
78
     * @return int
79
     */
80 1
    protected function getSortOrder()
81
    {
82 1
        return $this->sortOrder;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 1
    public function setMaintainKeyAssociation($maintainKeyAssociation)
89
    {
90 1
        $this->maintainKeyAssociation = (bool)$maintainKeyAssociation;
91 1
    }
92
93
    /**
94
     * @return \Closure
95
     */
96 3
    protected function createSortTransformFunction()
97
    {
98 3
        $comparator = $this->getComparator();
99 3
        $checker = $this->getValueChecker();
100 3
        $sortOrder = $this->sortOrder;
101
102
        return function ($a, $b) use ($comparator, $checker, $sortOrder) {
103
            /** @var ComparatorInterface $comparator */
104 3
            $checker($a, $b, $comparator);
105
106 3
            return $comparator->compare($a, $b) * $sortOrder;
107 3
        };
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113 4
    public function sort(array $collection)
114
    {
115 4
        $function = $this->maintainKeyAssociation ? 'uasort' : 'usort';
116 4
        $function($collection, $this->createSortTransformFunction());
117
118 4
        return $collection;
119
    }
120
121
    /**
122
     * Returns a closure that validates values before passing them to the ComparatorInterface
123
     *
124
     * @return \Closure
125
     */
126
    protected function getValueChecker()
127
    {
128 4
        return function ($a, $b, ComparatorInterface $comparator) {
129
130 4
            $exceptionMessage = 'Comparator (%s) does not support "%s"';
131
132 4
            $error = null;
133 4
            if (!$comparator->supports($a)) {
134
                $error = sprintf($exceptionMessage, get_class($comparator), gettype($a));
135 4
            } elseif (!$comparator->supports($b)) {
136
                $error = sprintf($exceptionMessage, get_class($comparator), gettype($a));
137
            }
138
139 4
            if ($error !== null) {
140
                throw new \RuntimeException($error);
141
            }
142 4
        };
143
    }
144
}