Passed
Push — master ( ae1a26...486cfe )
by Petr
03:11
created

TFinder::findMatched()   B

Complexity

Conditions 9
Paths 13

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 18
c 1
b 0
f 0
dl 0
loc 33
ccs 19
cts 19
cp 1
rs 8.0555
cc 9
nc 13
nop 3
crap 9
1
<?php
2
3
namespace kalanis\kw_mapper\Mappers;
4
5
6
use kalanis\kw_mapper\MapperException;
7
use kalanis\kw_mapper\Records;
8
9
10
/**
11
 * Trait TFinder
12
 * @package kalanis\kw_mapper\Mappers
13
 * Abstract for manipulation with file content as table
14
 */
15
trait TFinder
16
{
17
    /** @var Records\ARecord[] */
18
    protected $records = [];
19
20
    /**
21
     * @param Records\ARecord $record
22
     * @param bool $usePks
23
     * @param bool $wantFromStorage
24
     * @throws MapperException
25
     * @return Records\ARecord[]
26
     */
27 27
    protected function findMatched(Records\ARecord $record, bool $usePks = false, bool $wantFromStorage = false): array
28
    {
29 27
        $this->loadOnDemand($record);
30
31 27
        $toProcess = array_combine(array_keys($this->records), array_values($this->records)); // copy array - records will be removed when don't match
32 27
        $toCompare = $this->getArrayToCompare($record, $usePks, $wantFromStorage);
33
34 27
        if ($usePks) { // nothing to get when any necessary primary key is unknown
35 4
            foreach ($record->getMapper()->getPrimaryKeys() as $primaryKey) {
36 4
                if (!isset($toCompare[$primaryKey])) {
37 1
                    return [];
38
                }
39
            }
40
        }
41
42
        // through relations
43 27
        foreach ($toCompare as $relationKey => $compareValue) {
44 12
            foreach ($this->records as $positionKey => $knownRecord) {
45 12
                if ( !isset($toProcess[$positionKey]) ) { // not twice
46 1
                    continue;
47
                }
48 12
                if ( !$knownRecord->offsetExists($relationKey) ) { // unknown relation key in record is not allowed into compare
49 1
                    unset($toProcess[$positionKey]);
50 1
                    continue;
51
                }
52 11
                if ( strval($knownRecord->offsetGet($relationKey)) != strval($compareValue) ) {
53 11
                    unset($toProcess[$positionKey]);
54 11
                    continue;
55
                }
56
            }
57
        }
58
59 27
        return $toProcess;
60
    }
61
62
    /**
63
     * More records on one mapper - reload with correct one
64
     * @param Records\ARecord $record
65
     * @throws MapperException
66
     */
67 27
    protected function loadOnDemand(Records\ARecord $record): void
68
    {
69 27
        if (empty($this->records)) {
70 8
            $this->records = $this->loadSource($record);
71
        } else {
72 24
            $test = reset($this->records);
73 24
            if (get_class($test) != get_class($record)) { // reload other data - changed record
74
                // @codeCoverageIgnoreStart
75
                $this->records = $this->loadSource($record);
76
            }
77
            // @codeCoverageIgnoreEnd
78
        }
79
    }
80
81
    /**
82
     * @param Records\ARecord $record
83
     * @param bool $usePks
84
     * @param bool $wantFromStorage
85
     * @throws MapperException
86
     * @return array<string|int, mixed>
87
     */
88 35
    protected function getArrayToCompare(Records\ARecord $record, bool $usePks, bool $wantFromStorage): array
89
    {
90 35
        $stored = [];
91 35
        $written = [];
92 35
        foreach ($record as $key => $item) {
93 35
            $entry = $record->getEntry($key);
94 35
            if ($usePks && !in_array($key, $record->getMapper()->getPrimaryKeys())) {
95 8
                continue;
96
            }
97 35
            if (false === $entry->getData() && !$entry->isFromStorage()) {
98 27
                continue;
99
            }
100 20
            if ($entry->isFromStorage()) {
101 6
                $stored[$key] = $entry->getData();
102
            } else {
103 20
                $written[$key] = $entry->getData();
104
            }
105
        }
106 35
        return $wantFromStorage ? (empty($stored) ? $written : $stored) : array_merge($stored, $written);
107
    }
108
109
    /**
110
     * @param Records\ARecord $record
111
     * @throws MapperException
112
     * @return Records\ARecord[]
113
     */
114
    abstract protected function loadSource(Records\ARecord $record): array;
115
116
    /**
117
     * @return string[]
118
     */
119
    abstract public function getPrimaryKeys(): array;
120
121
    /**
122
     * @return array<string|int, string|int>
123
     */
124
    abstract public function getRelations(): array;
125
}
126