Passed
Pull Request — master (#62)
by Sergei
01:55
created

ReplaceValue::withKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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