Passed
Pull Request — master (#62)
by Sergei
14:50
created

SaveOrder::notNested()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Arrays\Collection\Modifier;
6
7
use Yiisoft\Arrays\ArrayHelper;
8
use Yiisoft\Arrays\Collection\Modifier\ModifierInterface\AfterMergeModifierInterface;
9
use Yiisoft\Arrays\Collection\Modifier\ModifierInterface\BeforeMergeModifierInterface;
10
11
/**
12
 * Modifier "Save Order"
13
 *
14
 * Модификатор запоминает порядок элементов в текущей коллекции и пытается его сохранить
15
 * при объединении массивов.
16
 */
17
final class SaveOrder implements BeforeMergeModifierInterface, AfterMergeModifierInterface
18
{
19
    private array $array = [];
20
21
    private bool $nested = false;
22
23
    public function nested(): self
24
    {
25
        $new = clone $this;
26
        $new->nested = true;
27
        return $new;
28
    }
29
30
    public function notNested(): self
31
    {
32
        $new = clone $this;
33
        $new->nested = false;
34
        return $new;
35
    }
36
37
    public function beforeMerge(array $arrays, int $index): array
38
    {
39
        $this->array = $arrays[$index];
40
        return $this->array;
41
    }
42
43
    public function afterMerge(array $data): array
44
    {
45
        return $this->applyOrder($data, $this->array);
46
    }
47
48
    private function applyOrder(array $data, array $array): array
49
    {
50
        $result = [];
51
52
        foreach ($array as $key => $value) {
53
            if (is_string($key)) {
54
                if (array_key_exists($key, $data)) {
55
                    $result[$key] = ArrayHelper::remove($data, $key);
56
                }
57
            } else {
58
                foreach ($data as $dataKey => $dataValue) {
59
                    if (is_int($dataKey) && $dataValue === $value) {
60
                        $result[] = $dataValue;
61
                        unset($data[$dataKey]);
62
                        break;
63
                    }
64
                }
65
            }
66
67
            if ($this->nested && is_array($value) && is_array($result[$key])) {
68
                $result[$key] = $this->applyOrder($result[$key], $value);
69
            }
70
        }
71
72
        return array_merge($result, $data);
73
    }
74
}
75