Passed
Push — master ( 7ef18e...f705ba )
by Misha
45s
created

DataRemover::removeIndexed()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 36
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 18
c 1
b 0
f 0
nc 5
nop 2
dl 0
loc 36
rs 9.0444
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Communibase\DataBag;
6
7
final class DataRemover
8
{
9
    /**
10
     * @var array<string,array>
11
     */
12
    private $data;
13
14
    /**
15
     * Remove a property from the bag.
16
     *
17
     * @param string $path path to the target (see get() for examples)
18
     *
19
     * @throws InvalidDataBagPathException
20
     */
21
    public function removeByPath(array &$data, string $path): void
22
    {
23
        $this->data = &$data;
24
25
        [$entityType, $path] = explode('.', $path, 2);
26
27
        // Direct property
28
        if (strpos($path, '.') === false) {
29
            if (!isset($this->data[$entityType][$path])) {
30
                return;
31
            }
32
            $data[$entityType][$path] = null;
33
            return;
34
        }
35
36
        $this->removeIndexed($path, $entityType);
37
    }
38
39
    private function removeIndexed(string $path, string $entityType): void
40
    {
41
        [$path, $index] = explode('.', $path);
42
43
        // Target doesn't exist, nothing to remove
44
        if (empty($this->data[$entityType][$path])) {
45
            return;
46
        }
47
48
        if (is_numeric($index)) {
49
            $index = (int)$index;
50
            // Remove all (higher) values to prevent a new value after re-indexing
51
            if ($index === 0) {
52
                $this->data[$entityType][$path] = null;
53
                return;
54
            }
55
            $this->data[$entityType][$path] = \array_slice($this->data[$entityType][$path], 0, $index);
56
            return;
57
        }
58
59
        // Filter out all nodes of the specified type
60
        $this->data[$entityType][$path] = array_filter(
61
            $this->data[$entityType][$path],
62
            static function ($node) use ($index) {
63
                return empty($node['type']) || $node['type'] !== $index;
64
            }
65
        );
66
67
        // If we end up with an empty array make it NULL
68
        if (empty($this->data[$entityType][$path])) {
69
            $this->data[$entityType][$path] = null;
70
            return;
71
        }
72
73
        // Re-index
74
        $this->data[$entityType][$path] = array_values($this->data[$entityType][$path]);
75
    }
76
}
77