Order::process()   B
last analyzed

Complexity

Conditions 8
Paths 17

Size

Total Lines 34
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 8

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 34
ccs 20
cts 20
cp 1
rs 8.4444
cc 8
nc 17
nop 0
crap 8
1
<?php
2
3
namespace kalanis\kw_table\core\Table;
4
5
6
use kalanis\kw_address_handler\Handler;
7
use kalanis\kw_address_handler\SingleVariable;
8
use kalanis\kw_connect\core\Interfaces\IOrder;
9
use kalanis\kw_table\core\Interfaces\Table\IColumn;
10
use kalanis\kw_table\core\Table\Internal\Attributes;
11
12
13
/**
14
 * Class Order
15
 * @package kalanis\kw_table\core\Table
16
 * It works two ways - check if desired column is used for ordering and fill header link for use it with another column
17
 *
18
 * The implementation is simple
19
 * First array is from system defined by programmer ($this->ordering)
20
 * If there is none, then get array of columns ($this->>columns)
21
 * Then prepend params from handler ($this->>currentDirection, $this->currentColumnName) if they contains anything usable
22
 *
23
 * First from this list is an active one ($this->primaryOrdering / $this->>activeOrdering) and will be used for compare
24
 */
25
class Order implements IOrder
26
{
27
    public const PARAM_COLUMN = 'column';
28
    public const PARAM_DIRECTION = 'direction';
29
30
    /** @var IColumn[] */
31
    protected array $columns = [];
32
    protected Handler $urlHandler;
33
    protected SingleVariable $urlVariable;
34
    /** @var string|int */
35
    protected $masterColumnName = '';
36
    protected string $masterDirection = '';
37
    /** @var string|int */
38
    protected $addressColumnName = '';
39
    protected string $addressDirection = '';
40
    /** @var array<int, Attributes> */
41
    protected array $ordering = [];
42
43 16
    public function __construct(Handler $urlHandler)
44
    {
45 16
        $this->urlHandler = $urlHandler;
46 16
        $this->urlVariable = new SingleVariable($this->urlHandler->getParams());
47 16
    }
48
49 16
    public function process(): self
50
    {
51 16
        if (empty($this->columns)) {
52 3
            return $this;
53
        }
54
55 13
        $defaultDirection = static::ORDER_ASC; // info about default direction - can be passed from address handler
56 13
        $addrDirection = $this->urlVariable->setVariableName(static::PARAM_DIRECTION)->getVariableValue();
57 13
        $addrColumnName = $this->urlVariable->setVariableName(static::PARAM_COLUMN)->getVariableValue();
58 13
        if ($this->isValidDirection($addrDirection)) {
59 6
            $this->addressDirection = $defaultDirection = $addrDirection;
60 6
            $this->addressColumnName = $addrColumnName;
61
        }
62
63 13
        $this->ordering = array_filter($this->ordering, [$this, 'checkOrder']);
64
65 13
        if (empty($this->ordering)) {
66 4
            foreach ($this->columns as $item) {
67 4
                $this->addOrdering($item->getSourceName(), $defaultDirection);
68
            }
69
        }
70
71 13
        if (!empty($this->addressColumnName) && $this->checkColumn($this->addressColumnName)) {
72 6
            $this->addPrependOrdering(strval($this->addressColumnName), $this->addressDirection);
73
        }
74
75 13
        $first = reset($this->ordering);
76 13
        if (false !== $first) {
77
            /** @var Attributes $first */
78 13
            $this->masterColumnName = $first->getColumnName();
79 13
            $this->masterDirection = $first->getProperty();
80
        }
81
82 13
        return $this;
83
    }
84
85 13
    protected function isValidDirection(string $direction): bool
86
    {
87 13
        return in_array($direction, [static::ORDER_ASC, static::ORDER_DESC]);
88
    }
89
90
    /**
91
     * @param Attributes $ordering
92
     * @return bool
93
     */
94 9
    public function checkOrder(Attributes $ordering): bool
95
    {
96 9
        return $this->checkColumn($ordering->getColumnName());
97
    }
98
99
    /**
100
     * @param string|int $columnName
101
     * @return bool
102
     */
103 16
    public function checkColumn($columnName): bool
104
    {
105 16
        return array_key_exists($columnName, $this->columns);
106
    }
107
108
    /**
109
     * @return array<int, Attributes>
110
     */
111 16
    public function getOrdering(): array
112
    {
113 16
        return $this->ordering;
114
    }
115
116
    /**
117
     * Basic ordering
118
     * @param string|int $columnName
119
     * @param string $direction
120
     */
121 15
    public function addOrdering($columnName, string $direction = self::ORDER_ASC): void
122
    {
123 15
        $this->ordering[] = new Attributes($columnName, $direction);
124 15
    }
125
126
    /**
127
     * Add more important ordering
128
     * @param string|int $columnName
129
     * @param string $direction
130
     */
131 8
    public function addPrependOrdering($columnName, string $direction = self::ORDER_ASC): void
132
    {
133 8
        array_unshift($this->ordering, new Attributes($columnName, $direction));
134 8
    }
135
136 13
    public function addColumn(IColumn $column): self
137
    {
138 13
        $this->columns[$column->getSourceName()] = $column;
139 13
        return $this;
140
    }
141
142 5
    public function getHref(IColumn $column): ?string
143
    {
144 5
        if (!$this->isInOrder($column)) {
145 1
            return null;
146
        }
147
148 4
        $this->urlVariable->setVariableName(static::PARAM_COLUMN)->setVariableValue(strval($column->getSourceName()));
149 4
        $this->urlVariable->setVariableName(static::PARAM_DIRECTION)->setVariableValue($this->getActiveDirection($column));
150 4
        return $this->urlHandler->getAddress();
151
    }
152
153 15
    public function isInOrder(IColumn $column): bool
154
    {
155 15
        return $this->checkColumn($column->getSourceName());
156
    }
157
158 12
    public function getActiveDirection(IColumn $column): string
159
    {
160 12
        if ($this->isActive($column)) {
161 12
            if (static::ORDER_ASC == $this->masterDirection) {
162 5
                return static::ORDER_DESC;
163
            }
164
        }
165
166 12
        return static::ORDER_ASC;
167
    }
168
169 5
    public function getHeaderText(IColumn $header, string $leftSign = '*', string $rightSign = ''): string
170
    {
171 5
        return $this->isActive($header)
172 4
            ? $leftSign . $header->getHeaderText() . $rightSign
173 5
            : $header->getHeaderText()
174
        ;
175
    }
176
177 13
    public function isActive(IColumn $column): bool
178
    {
179 13
        return $column->getSourceName() == $this->masterColumnName;
180
    }
181
182
    /**
183
     * @return int|string
184
     */
185 5
    public function getMasterColumnName()
186
    {
187 5
        return $this->masterColumnName;
188
    }
189
190 5
    public function getMasterDirection(): string
191
    {
192 5
        return $this->masterDirection;
193
    }
194
195
    /**
196
     * @return int|string
197
     */
198 5
    public function getAddressColumnName()
199
    {
200 5
        return $this->addressColumnName;
201
    }
202
203 5
    public function getAddressDirection(): string
204
    {
205 5
        return $this->addressDirection;
206
    }
207
}
208