Processor::writeBuffered()   C
last analyzed

Complexity

Conditions 12
Paths 15

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 12.0022

Importance

Changes 0
Metric Value
dl 0
loc 48
c 0
b 0
f 0
ccs 39
cts 40
cp 0.975
rs 6.9666
cc 12
nc 15
nop 1
crap 12.0022

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 Maketok\DataMigration\Input\Shaper;
4
5
use Maketok\DataMigration\Action\Exception\ConflictException;
6
use Maketok\DataMigration\ArrayUtilsTrait;
7
use Maketok\DataMigration\Expression\LanguageInterface;
8
use Maketok\DataMigration\Input\ShaperInterface;
9
use Maketok\DataMigration\MapInterface;
10
use Maketok\DataMigration\Unit\ImportFileUnitInterface;
11
use Maketok\DataMigration\Unit\UnitBagInterface;
12
13
abstract class Processor implements ShaperInterface
14
{
15
    use ArrayUtilsTrait;
16
17
    /**
18
     * @var array
19
     */
20
    protected $buffer = [];
21
    /**
22
     * @var UnitBagInterface|ImportFileUnitInterface[]
23
     */
24
    protected $bag;
25
    /**
26
     * @var MapInterface
27
     */
28
    private $map;
29
    /**
30
     * @var MapInterface
31
     */
32
    private $oldmap;
33
    /**
34
     * @var LanguageInterface
35
     */
36
    protected $language;
37
38
    /**
39
     * @param UnitBagInterface $bag
40
     * @param MapInterface $map
41
     * @param LanguageInterface $language
42
     */
43 19
    public function __construct(
44
        UnitBagInterface $bag,
45
        MapInterface $map,
46
        LanguageInterface $language
47
    ) {
48 19
        $this->bag = $bag;
49 19
        $this->map = $map;
50 19
        $this->language = $language;
51 19
        $this->bag->compileTree();
52 19
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 7
    public function feed(array $row)
58
    {
59 7
        if ($this->bag->getLowestLevel() == 1) {
60
            // no parent-child relationship
61 1
            if (!empty($row)) {
62 1
                return $row;
63
            }
64 1
            return false;
65
        }
66 6
        if ($this->map->isFresh($row)) {
67 6
            $this->map->feed($row);
68 6
        }
69
        // forcing dump if empty row is coming
70 6
        $res = $this->dumpBuffer(empty($row));
71 6
        $this->writeBuffered($row);
72 6
        if ($res) {
73 6
            $this->map->clear();
74 6
        }
75 6
        return $res;
76
    }
77
78
    /**
79
     * @param bool $force
80
     * @return array|bool
81
     * @throws ConflictException
82
     */
83 6
    private function dumpBuffer($force = false)
84
    {
85 6
        $globalShouldDump = true;
86 6
        if (!$force) {
87 6
            foreach ($this->bag->getUnitsFromLevel(1) as $code) {
88
                /** @var ImportFileUnitInterface $unit */
89 6
                $unit = $this->bag->getUnitByCode($code);
90 6
                $shouldDump = $this->resolveIsEntity($unit);
91 6
                $globalShouldDump &= $shouldDump;
92 6
            }
93 6
        }
94 6
        if ($globalShouldDump) {
95 6
            if (!empty($this->buffer)) {
96 6
                $res = $this->assemble($this->buffer);
97 6
            } else {
98 6
                $res = false;
99
            }
100 6
            $this->clear();
101 6
            return $res;
102
        }
103 4
        return false;
104
    }
105
106
    /**
107
     * @param ImportFileUnitInterface $unit
108
     * @return bool|mixed
109
     */
110 6
    private function resolveIsEntity(ImportFileUnitInterface $unit)
111
    {
112 6
        $isEntity = $unit->getIsEntityCondition();
113 6
        if (!isset($this->oldmap) || empty($isEntity)) {
114 6
            return true;
115 6
        } elseif (is_callable($isEntity) || is_string($isEntity)) {
116 6
            return $this->language->evaluate($isEntity, [
117 6
                'map' => $this->map,
118 6
                'oldmap' => $this->oldmap,
119 6
            ]);
120
        } else {
121
            throw new \LogicException(
122
                sprintf("Can not understand is Entity Condition for %s unit.", $unit->getCode())
123
            );
124
        }
125
    }
126
127
    /**
128
     * @param $row
129
     * @throws ConflictException
130
     */
131 6
    private function writeBuffered($row)
132
    {
133 6
        if (empty($row)) {
134 6
            return;
135
        }
136 6
        $level = 1;
137 6
        $remembered = [];
138 6
        while ($level <= $this->bag->getLowestLevel()) {
139 6
            $codes = $this->bag->getUnitsFromLevel($level);
140 6
            foreach ($codes as $code) {
141 6
                if (isset($this->buffer[$code])) {
142 4
                    $remembered[$level][$code] = array_replace_recursive($this->buffer[$code], $row);
143 4
                } else {
144 6
                    $remembered[$level][$code] = $row;
145
                }
146
                /** @var ImportFileUnitInterface $unit */
147 6
                $unit = $this->bag->getUnitByCode($code);
148 6
                $parent = $unit->getParent();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $parent is correct as $unit->getParent() (which targets Maketok\DataMigration\Un...tInterface::getParent()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
149 6
                if ($parent) {
150 6
                    $parentCode = $parent->getCode();
151 6
                    if (isset($remembered[$level-1][$parentCode])) {
152 6
                        if (isset($row[$code]) && !is_array($row[$code])) {
153
                            throw new ConflictException("Key to assign children to already exists.");
154
                        }
155
                        if (
156 6
                            isset($remembered[$level-1][$parentCode][$code]) &&
157 4
                            is_array($remembered[$level-1][$parentCode][$code])
158 6
                        ) {
159 4
                            if ($this->resolveIsEntity($unit)) {
160 4
                                $remembered[$level-1][$parentCode][$code][] = &$remembered[$level][$code];
161 4
                            } else {
162 1
                                $remembered[$level][$code] = array_replace_recursive(
163 1
                                    $remembered[$level-1][$parentCode][$code][0],
164 1
                                    $remembered[$level][$code]
165 1
                                );
166 1
                                $remembered[$level-1][$parentCode][$code] = [&$remembered[$level][$code]];
167
                            }
168 4
                        } else {
169 6
                            $remembered[$level-1][$parentCode][$code] = [&$remembered[$level][$code]];
170
                        }
171 6
                    }
172 6
                }
173 6
            }
174 6
            $level++;
175 6
        }
176 6
        $this->buffer = array_replace_recursive($remembered[1], $this->buffer);
177 6
        $this->oldmap = clone $this->map;
178 6
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183 6
    public function clear()
184
    {
185 6
        $this->buffer = [];
186 6
    }
187
}
188