Passed
Push — master ( 18a4d8...e0d339 )
by Marcin
02:40 queued 11s
created

Sort::__construct()   A

Complexity

Conditions 6
Paths 10

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 19
c 0
b 0
f 0
ccs 11
cts 11
cp 1
rs 9.2222
cc 6
nc 10
nop 1
crap 6
1
<?php
2
/**
3
 * Created by Marcin.
4
 * Date: 16.06.2018
5
 * Time: 13:58
6
 */
7
8
namespace Mrcnpdlk\Lib\UrlSearchParser\Criteria;
9
10
use ArrayIterator;
11
use IteratorAggregate;
12
use Mrcnpdlk\Lib\UrlSearchParser\Exception\DuplicateParamException;
13
use Mrcnpdlk\Lib\UrlSearchParser\Exception\EmptyParamException;
14
use Traversable;
15
16
/**
17
 * Class Sort
18
 */
19
class Sort implements IteratorAggregate
20
{
21
    public const DIRECTION_ASC   = 'ASC';
22
    public const DIRECTION_DESC  = 'DESC';
23
    public const DELIMITER       = ',';
24
    public const DESC_IDENTIFIER = '-';
25
26
    /**
27
     * @var \Mrcnpdlk\Lib\UrlSearchParser\Criteria\SortParam[]
28
     */
29
    private $sortParams = [];
30
31
    /**
32
     * Sort constructor.
33
     *
34
     * @param string|null $sortString
35
     *
36
     * @throws \Mrcnpdlk\Lib\UrlSearchParser\Exception\DuplicateParamException
37
     * @throws \Mrcnpdlk\Lib\UrlSearchParser\Exception\EmptyParamException
38
     * @throws \Mrcnpdlk\Lib\UrlSearchParser\Exception\InvalidParamException
39
     */
40 22
    public function __construct(string $sortString = null)
41
    {
42
        /**
43
         * @var string[]
44
         * @var string   $param
45
         */
46 22
        $tParams = $sortString ? explode(self::DELIMITER, $sortString) : [];
47 22
        foreach ($tParams as $param) {
48 5
            if (empty($param)) {
49 1
                throw new EmptyParamException(sprintf('Empty SORT param'));
50
            }
51 4
            if (self::DESC_IDENTIFIER === $param[0]) {
52 4
                $param = substr($param, 1);
53 4
                if (empty($param)) {
54 1
                    throw new EmptyParamException(sprintf('Empty SORT param'));
55
                }
56 3
                $this->appendParam(new SortParam($param, self::DIRECTION_DESC));
57
            } else {
58 3
                $this->appendParam(new SortParam($param, self::DIRECTION_ASC));
59
            }
60
        }
61 19
    }
62
63
    /**
64
     * @param \Mrcnpdlk\Lib\UrlSearchParser\Criteria\SortParam $sortParam
65
     *
66
     * @throws \Mrcnpdlk\Lib\UrlSearchParser\Exception\DuplicateParamException
67
     *
68
     * @return \Mrcnpdlk\Lib\UrlSearchParser\Criteria\Sort
69
     */
70 3
    public function appendParam(SortParam $sortParam): Sort
71
    {
72 3
        if ($this->isExists($sortParam->param)) {
73 1
            throw new DuplicateParamException(sprintf('Duplicate Sort param `%s`', $sortParam->param));
74
        }
75 3
        $this->sortParams[] = $sortParam;
76
77 3
        return $this;
78
    }
79
80
    /**
81
     * @param string $paramName
82
     *
83
     * @return \Mrcnpdlk\Lib\UrlSearchParser\Criteria\SortParam[]
84
     */
85 1
    public function getByParamName(string $paramName): array
86
    {
87 1
        $params = [];
88 1
        foreach ($this->sortParams as $param) {
89 1
            if ($param->param === $paramName) {
90 1
                $params[] = $param;
91
            }
92
        }
93
94 1
        return $params;
95
    }
96
97
    /**
98
     * Retrieve an external iterator
99
     *
100
     * @see   http://php.net/manual/en/iteratoraggregate.getiterator.php
101
     *
102
     * @return Traversable An instance of an object implementing <b>Iterator</b> or
103
     *                     <b>Traversable</b>
104
     *
105
     * @since 5.0.0
106
     */
107 1
    public function getIterator(): Traversable
108
    {
109 1
        return new ArrayIterator($this->sortParams);
110
    }
111
112
    /**
113
     * @param string $paramName
114
     *
115
     * @return bool
116
     */
117 3
    public function isExists(string $paramName): bool
118
    {
119 3
        foreach ($this->sortParams as $param) {
120 3
            if ($param->param === $paramName) {
121 3
                return true;
122
            }
123
        }
124
125 3
        return false;
126
    }
127
128
    /**
129
     * @param \Mrcnpdlk\Lib\UrlSearchParser\Criteria\SortParam $sortParam
130
     *
131
     * @throws \Mrcnpdlk\Lib\UrlSearchParser\Exception\DuplicateParamException
132
     *
133
     * @return \Mrcnpdlk\Lib\UrlSearchParser\Criteria\Sort
134
     */
135 1
    public function replaceParam(SortParam $sortParam): Sort
136
    {
137 1
        $isChanged = false;
138 1
        foreach ($this->sortParams as &$param) {
139 1
            if ($param->param === $sortParam->param) {
140 1
                $param->direction = $sortParam->direction;
141 1
                $isChanged        = true;
142
            }
143
        }
144 1
        unset($param);
145 1
        if (!$isChanged) {
146
            $this->appendParam($sortParam);
147
        }
148
149 1
        return $this;
150
    }
151
152
    /**
153
     * @return \Mrcnpdlk\Lib\UrlSearchParser\Criteria\SortParam[]
154
     */
155 2
    public function toArray(): array
156
    {
157 2
        return $this->sortParams;
158
    }
159
}
160