Passed
Push — master ( 6139d1...678a4c )
by Petr
13:22 queued 10:27
created

TFinder::findMatched()   B

Complexity

Conditions 10
Paths 14

Size

Total Lines 39
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 10.0107

Importance

Changes 0
Metric Value
cc 10
eloc 20
c 0
b 0
f 0
nc 14
nop 3
dl 0
loc 39
ccs 20
cts 21
cp 0.9524
crap 10.0107
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 11
            $this->records = $this->loadSource($record);
77
        } else {
78 18
            $test = reset($this->records);
79 18
            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 27
    }
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 9
    protected function clearSource(): void
116
    {
117 9
        $this->records = [];
118 9
    }
119
120
    /**
121
     * @param Records\ARecord $record
122
     * @throws MapperException
123
     * @return Records\ARecord[]
124
     */
125
    abstract protected function loadSource(Records\ARecord $record): array;
126
127
    /**
128
     * @return string[]
129
     */
130
    abstract public function getPrimaryKeys(): array;
131
132
    /**
133
     * @return array<string|int, string|int>
134
     */
135
    abstract public function getRelations(): array;
136
}
137