Passed
Push — master ( c85748...2fd0ab )
by Petr
08:11
created

TFinder   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 41
c 0
b 0
f 0
dl 0
loc 116
ccs 38
cts 38
cp 1
rs 10
wmc 22

3 Methods

Rating   Name   Duplication   Size   Complexity  
B findMatched() 0 39 10
B getArrayToCompare() 0 19 9
A loadOnDemand() 0 9 3
1
<?php
2
3
namespace kalanis\kw_mapper\Mappers\Shared;
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\Shared
13
 * Abstract for manipulation with file content as table
14
 */
15
trait TFinder
16
{
17
    /** @var array<Records\ARecord<int|string, Records\Entry>>|Records\ARecord[] */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<Records\ARecord<in...try>>|Records\ARecord[] at position 2 could not be parsed: Expected '>' at position 2, but found 'Records\ARecord'.
Loading history...
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
        if (false === $toProcess) {
33
            // @codeCoverageIgnoreStart
34
            // php7-
35
            throw new MapperException('Combine on field went wrong. Call php support.');
36
        }
37
        // @codeCoverageIgnoreEnd
38 27
        $toCompare = $this->getArrayToCompare($record, $usePks, $wantFromStorage);
39
40 27
        if ($usePks) { // nothing to get when any necessary primary key is unknown
41 4
            foreach ($record->getMapper()->getPrimaryKeys() as $primaryKey) {
42 4
                if (!isset($toCompare[$primaryKey])) {
43 1
                    return [];
44
                }
45
            }
46
        }
47
48
        // through relations
49 27
        foreach ($toCompare as $relationKey => $compareValue) {
50 12
            foreach ($this->records as $positionKey => $knownRecord) {
51 12
                if ( !isset($toProcess[$positionKey]) ) { // not twice
52 1
                    continue;
53
                }
54 12
                if ( !$knownRecord->offsetExists($relationKey) ) { // unknown relation key in record is not allowed into compare
55 1
                    unset($toProcess[$positionKey]);
56 1
                    continue;
57
                }
58 11
                if ( strval($knownRecord->offsetGet($relationKey)) != strval($compareValue) ) {
59 11
                    unset($toProcess[$positionKey]);
60 11
                    continue;
61
                }
62
            }
63
        }
64
65 27
        return $toProcess;
66
    }
67
68
    /**
69
     * More records on one mapper - reload with correct one
70
     * @param Records\ARecord $record
71
     * @throws MapperException
72
     */
73 27
    protected function loadOnDemand(Records\ARecord $record): void
74
    {
75 27
        if (empty($this->records)) {
76 8
            $this->records = $this->loadSource($record);
77
        } else {
78 24
            $test = reset($this->records);
79 24
            if (get_class($test) != get_class($record)) { // reload other data - changed record
80
                // @codeCoverageIgnoreStart
81
                $this->records = $this->loadSource($record);
82
            }
83
            // @codeCoverageIgnoreEnd
84
        }
85
    }
86
87
    /**
88
     * @param Records\ARecord $record
89
     * @param bool $usePks
90
     * @param bool $wantFromStorage
91
     * @throws MapperException
92
     * @return array<string|int, mixed>
93
     */
94 35
    protected function getArrayToCompare(Records\ARecord $record, bool $usePks, bool $wantFromStorage): array
95
    {
96 35
        $stored = [];
97 35
        $written = [];
98 35
        foreach ($record as $key => $item) {
99 35
            $entry = $record->getEntry($key);
100 35
            if ($usePks && !in_array($key, $record->getMapper()->getPrimaryKeys())) {
101 8
                continue;
102
            }
103 35
            if (false === $entry->getData() && !$entry->isFromStorage()) {
104 27
                continue;
105
            }
106 20
            if ($entry->isFromStorage()) {
107 6
                $stored[$key] = $entry->getData();
108
            } else {
109 20
                $written[$key] = $entry->getData();
110
            }
111
        }
112 35
        return $wantFromStorage ? (empty($stored) ? $written : $stored) : array_merge($stored, $written);
113
    }
114
115
    /**
116
     * @param Records\ARecord $record
117
     * @throws MapperException
118
     * @return Records\ARecord[]
119
     */
120
    abstract protected function loadSource(Records\ARecord $record): array;
121
122
    /**
123
     * @return string[]
124
     */
125
    abstract public function getPrimaryKeys(): array;
126
127
    /**
128
     * @return array<string|int, string|int>
129
     */
130
    abstract public function getRelations(): array;
131
}
132