ApplyFilters::__invoke()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 19
ccs 0
cts 11
cp 0
rs 9.9332
c 0
b 0
f 0
cc 4
nc 6
nop 2
crap 20
1
<?php
2
declare(strict_types=1);
3
4
namespace ReadModel\Bridge\Doctrine;
5
6
use Doctrine\DBAL\Query\QueryBuilder;
7
use ReadModel\Filters\Filters;
8
9
final class ApplyFilters
10
{
11
    /** @var array */
12
    private $columnMapping;
13
14
    /**
15
     * @param array $columnMapping to provide columnMapping from filters to db, eg: city => address_city
16
     */
17
    public function __construct(array $columnMapping = [])
18
    {
19
        $this->columnMapping = $columnMapping;
20
    }
21
22
    /**
23
     * Applies unused filters and unused orders by to the query.
24
     */
25
    public function __invoke(QueryBuilder $qb, Filters $filters)
26
    {
27
        // add filters to a query
28
        foreach ($filters->unusedFilters() as $filter) {
29
            $value = $filter->simplifiedValue();
30
31
            if ($value === null) {
32
                continue;
33
            }
34
35
            $columnName = $this->getColumnName($filter->name());
36
            $qb->andWhere(sprintf('%s = :%s', $columnName, $filter->name()))
37
               ->setParameter($filter->name(), $value);
38
        }
39
40
        // add orders by to a query
41
        foreach ($filters->unusedOrdersBy() as $orderBy) {
42
            $columnName = $this->getColumnName($orderBy->field());
43
            $qb->addOrderBy($columnName, $orderBy->order());
44
        }
45
    }
46
47
    private function getColumnName(string $name): string
48
    {
49
        $name = $this->columnMapping[$name] ?? $name;
50
        return $this->toUnderscore($name);
51
    }
52
53
    private function toUnderscore(string $value): string
54
    {
55
        return strtolower(preg_replace('/[A-Z]/', '_\\0', lcfirst($value)));
56
    }
57
}
58