Passed
Push — master ( 6070fb...9c7c6d )
by Petr
03:01
created

Connector::fetchData()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
namespace kalanis\kw_connect\eloquent;
4
5
6
use ArrayIterator;
7
use Illuminate\Database\Eloquent\Builder;
8
use Illuminate\Database\Eloquent\Collection;
9
use kalanis\kw_connect\core\AConnector;
10
use kalanis\kw_connect\core\Interfaces\IFilterFactory;
11
use kalanis\kw_connect\core\Interfaces\IFilterSubs;
12
use kalanis\kw_connect\core\Interfaces\IIterableConnector;
13
use kalanis\kw_connect\core\Interfaces\IOrder;
14
use kalanis\kw_connect\core\Interfaces\IRow;
15
16
17
/**
18
 * Class Connector
19
 * @package kalanis\kw_connect\eloquent
20
 * Data source is Laravel\Eloquent
21
 */
22
class Connector extends AConnector implements IIterableConnector
23
{
24
    protected Builder $queryBuilder;
25
    protected string $primaryKey;
26
    /** @var array<int, array<string>> */
27
    protected array $sorters = [];
28
    protected ?int $limit = null;
29
    protected ?int $offset = null;
30
    /** @var Collection */
31
    protected $rawData = null;
32
    protected bool $dataFetched = false;
33
34
    public function __construct(Builder $queryBuilder, string $primaryKey)
35
    {
36
        $this->queryBuilder = $queryBuilder;
37
        $this->primaryKey = $primaryKey;
38
    }
39
40
    public function setFiltering(string $colName, string $filterType, $value): void
41
    {
42
        $type = $this->getFilterFactory()->getFilter($filterType);
43
        if ($type instanceof IFilterSubs) {
44
            $type->addFilterFactory($this->getFilterFactory());
45
        }
46
        $type->setDataSource($this->queryBuilder);
47
        $type->setFiltering($colName, $value);
48
    }
49
50
    public function setOrdering(string $colName, string $direction): void
51
    {
52
        $this->sorters[] = [$colName, $direction];
53
    }
54
55
    public function setPagination(?int $offset, ?int $limit): void
56
    {
57
        $this->offset = $offset;
58
        $this->limit = $limit;
59
    }
60
61
    public function getTotalCount(): int
62
    {
63
        // count needs only filtered content
64
        $dataSource = clone $this->queryBuilder;
65
        return $dataSource->count();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $dataSource->count() could return the type Illuminate\Database\Eloquent\Builder which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
66
    }
67
68
    public function fetchData(): void
69
    {
70
        foreach (array_reverse($this->sorters) as list($colName, $direction)) {
71
            $dir = IOrder::ORDER_ASC == $direction ? 'asc' : 'desc' ;
72
            $this->queryBuilder->orderBy($colName, $dir);
73
        }
74
        $this->rawData = $this->queryBuilder->offset($this->offset)->limit($this->limit)->get();
75
        $this->parseData();
76
    }
77
78
    protected function parseData(): void
79
    {
80
        foreach ($this->rawData->getIterator() as $iterate) {
81
            $this->translatedData[$this->getPrimaryKey($iterate)] = $this->getTranslated($iterate);
82
        }
83
    }
84
85
    protected function getTranslated(ArrayIterator $data): IRow
86
    {
87
        return new Row($data);
88
    }
89
90
    protected function getPrimaryKey(ArrayIterator $record): string
91
    {
92
        return strval($record->offsetGet($this->primaryKey));
93
    }
94
95
    public function getFilterFactory(): IFilterFactory
96
    {
97
        return Filters\Factory::getInstance();
98
    }
99
}
100