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

ReplaceValue::beforeMerge()   A

Complexity

Conditions 6
Paths 8

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 13
nc 8
nop 2
dl 0
loc 24
ccs 14
cts 14
cp 1
crap 6
rs 9.2222
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 7
    public function __construct($key)
41
    {
42 7
        $this->key = $key;
43 7
    }
44
45
    /**
46
     * @param int|string $key
47
     * @return self
48
     */
49 1
    public function withKey($key): self
50
    {
51 1
        $new = clone $this;
52 1
        $new->key = $key;
53 1
        return $new;
54
    }
55
56 7
    public function beforeMerge(array $arrays, int $index): array
57
    {
58 7
        $currentArray = $arrays[$index];
59
60 7
        if (!array_key_exists($this->key, $currentArray)) {
61 2
            return $arrays[$index];
62
        }
63
64 6
        foreach (array_slice($arrays, $index + 1) as $array) {
65 4
            if (array_key_exists($this->key, $array)) {
66 2
                $currentArray[$this->key] = null;
67 2
                return $currentArray;
68
            }
69
        }
70
71 4
        foreach (array_slice($arrays, 0, $index) as $array) {
72 4
            if (array_key_exists($this->key, $array)) {
73 3
                $this->value = $currentArray[$this->key];
74 3
                $this->setValueAfterMerge = true;
75 3
                return $currentArray;
76
            }
77
        }
78
79 1
        return $currentArray;
80
    }
81
82 7
    public function afterMerge(array $data): array
83
    {
84 7
        if ($this->setValueAfterMerge) {
85 3
            $data[$this->key] = $this->value;
86 3
            $this->setValueAfterMerge = false;
87
        }
88 7
        return $data;
89
    }
90
}
91