Passed
Pull Request — master (#62)
by Sergei
10:53
created

ReplaceValue::afterMerge()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
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\Collection\Modifier\ModifierInterface\AfterMergeModifierInterface;
8
use Yiisoft\Arrays\Collection\Modifier\ModifierInterface\BeforeMergeModifierInterface;
9
10
/**
11
 * The modifier allows to mark an array element from the collection it is applied to,
12
 * as the element to be processed in a special way on merge.
13
 *
14
 * - In case there are elements with the same keys in previous arrays, they will be replaced
15
 *   with a value from the current array.
16
 *
17
 * - If there are elements with the same keys in next arrays, they will replace current array value.
18
 *
19
 * If there is no element with the given key in the array, modifier won't change anything.
20
 *
21
 * Note that this modifier is applied on merge.
22
 */
23
final class ReplaceValue implements BeforeMergeModifierInterface, AfterMergeModifierInterface
24
{
25
    /**
26
     * @var int|string
27
     */
28
    private $key;
29
30
    /**
31
     * @var mixed
32
     */
33
    private $value;
34
35
    private bool $setValueAfterMerge = false;
36
37
    /**
38
     * @param int|string $key
39
     */
40
    public function __construct($key)
41
    {
42
        $this->key = $key;
43
    }
44
45
    /**
46
     * @param int|string $key
47
     * @return self
48
     */
49
    public function withKey($key): self
50
    {
51
        $new = clone $this;
52
        $new->key = $key;
53
        return $new;
54
    }
55
56
    public function beforeMerge(array $arrays, int $index): array
57
    {
58
        $currentArray = $arrays[$index];
59
60
        if (!array_key_exists($this->key, $currentArray)) {
61
            return $arrays[$index];
62
        }
63
64
        foreach (array_slice($arrays, $index + 1) as $array) {
65
            if (array_key_exists($this->key, $array)) {
66
                $currentArray[$this->key] = null;
67
                return $currentArray;
68
            }
69
        }
70
71
        foreach (array_slice($arrays, 0, $index) as $array) {
72
            if (array_key_exists($this->key, $array)) {
73
                $this->value = $currentArray[$this->key];
74
                $this->setValueAfterMerge = true;
75
                return $currentArray;
76
            }
77
        }
78
79
        return $currentArray;
80
    }
81
82
    public function afterMerge(array $data): array
83
    {
84
        if ($this->setValueAfterMerge) {
85
            $data[$this->key] = $this->value;
86
            $this->setValueAfterMerge = false;
87
        }
88
        return $data;
89
    }
90
}
91