Metro::search()   B
last analyzed

Complexity

Conditions 8
Paths 24

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 8

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 17
c 1
b 0
f 0
nc 24
nop 4
dl 0
loc 25
ccs 16
cts 16
cp 1
crap 8
rs 8.4444
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Controllers\Api\V1;
6
7
use Nymfonya\Component\Container;
8
use Nymfonya\Component\Http\Response;
9
use App\Interfaces\Controllers\IApi;
10
use App\Reuse\Controllers\AbstractApi;
11
use App\Model\Repository\Metro\Lines;
12
use App\Model\Repository\Metro\Stations;
13
use App\Component\Db\Core;
14
use App\Component\Model\Orm\Orm;
15
use App\Component\Filter;
16
use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
17
18
final class Metro extends AbstractApi implements IApi
19
{
20
21
    const _LIMIT = 'limit';
22
    const _PAGE = 'page';
23
    const _DATAS = 'datas';
24
25
    /**
26
     * Lines model
27
     *
28
     * @var Lines
29
     */
30
    protected $modelLines;
31
32
33
    /**
34
     * Stations model
35
     *
36
     * @var Stations
37
     */
38
    protected $modelStations;
39
40
    /**
41
     * db core
42
     *
43
     * @var Core
44
     */
45
    protected $dbCore;
46
47
    /**
48
     * instanciate
49
     *
50
     * @param Container $container
51
     */
52 6
    public function __construct(Container $container)
53
    {
54 6
        parent::__construct($container);
55 6
        $this->modelLines = new Lines($container);
56 6
        $this->modelStations = new Stations($container);
57 6
        $this->dbCore = new Core($container);
58
    }
59
60
    /**
61
     * search lines
62
     *
63
     * @return Metro
64
     */
65 1
    final public function lines(): Metro
66
    {
67 1
        $query = $this->search(
68 1
            $this->getFilteredInput(),
69 1
            Lines::_HSRC,
70 1
            '',
71 1
            $this->modelLines
72
        );
73 1
        $this->response->setCode(Response::HTTP_OK)->setContent([
74 1
            Response::_ERROR => false,
75 1
            Response::_ERROR_MSG => '',
76 1
            self::_DATAS => $this->getQueryResults($query)
77
        ]);
78 1
        unset($query);
79 1
        return $this;
80
    }
81
82
    /**
83
     * search stations
84
     *
85
     * @return Metro
86
     */
87 1
    final public function stations(): Metro
88
    {
89 1
        $query = $this->search(
90 1
            $this->getFilteredInput(),
91 1
            Stations::_NAME,
92 1
            Orm::OP_LIKE,
93 1
            $this->modelStations
94
        );
95 1
        $this->response->setCode(Response::HTTP_OK)->setContent([
96 1
            Response::_ERROR => false,
97 1
            Response::_ERROR_MSG => '',
98 1
            self::_DATAS => $this->getQueryResults($query)
99
        ]);
100 1
        unset($query);
101 1
        return $this;
102
    }
103
104
    /**
105
     * get results as array
106
     *
107
     * @param Orm $query
108
     * @return array
109
     */
110 1
    protected function getQueryResults(Orm $query): array
111
    {
112 1
        return $this->dbCore
113 1
            ->fromOrm($query)
114 1
            ->run($query->getSql(), $query->getBuilderValues())
115 1
            ->hydrate()
116 1
            ->getRowset();
117
    }
118
119
    /**
120
     * search items by search key and value limiting results amount
121
     *
122
     * @param array $inputs
123
     * @param string $searchKey
124
     * @param string $operator
125
     * @param Orm $model
126
     * @return Orm
127
     */
128 1
    protected function search(array $inputs, string $searchKey, string $operator, Orm &$model): Orm
129
    {
130 1
        $where = [];
131 1
        if (isset($inputs[$searchKey])) {
132 1
            $searchValue = $inputs[$searchKey];
133 1
            if ($operator === Orm::OP_LIKE) {
134
                $where = [
135 1
                    $searchKey . $operator => Orm::SQL_WILD . $searchValue . Orm::SQL_WILD
136
                ];
137
            } else {
138 1
                $where = [$searchKey => $searchValue];
139
            }
140
        }
141 1
        $model->find([Orm::SQL_ALL], $where);
142 1
        if ([] === $where && !isset($inputs[self::_LIMIT])) {
143 1
            $inputs[self::_LIMIT] = 10;
144
        }
145 1
        if (isset($inputs[self::_LIMIT])) {
146 1
            if ($model->getQuery() instanceof Select) {
147 1
                $page = isset($inputs[self::_PAGE]) ? (int) $inputs[self::_PAGE] : 0;
148 1
                $offset = $page * (int) $inputs[self::_LIMIT];
149 1
                $model->getQuery()->limit($offset, (int) $inputs[self::_LIMIT]);
150
            }
151
        }
152 1
        return $model;
153
    }
154
155
    /**
156
     * return filtered request params
157
     *
158
     * @return array
159
     */
160 1
    protected function getFilteredInput(): array
161
    {
162 1
        return (new Filter($this->getParams(), [
163 1
            Lines::_HSRC => FILTER_SANITIZE_STRING,
164 1
            Stations::_NAME => FILTER_SANITIZE_STRING,
165 1
            self::_LIMIT => FILTER_SANITIZE_NUMBER_INT,
166 1
            self::_PAGE => FILTER_SANITIZE_NUMBER_INT,
167 1
        ]))->process()->toArray();
168
    }
169
}
170