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

DataMutator   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 37
c 1
b 0
f 0
dl 0
loc 84
rs 10
wmc 15

3 Methods

Rating   Name   Duplication   Size   Complexity  
A addNewEntry() 0 13 3
B setIndexed() 0 37 10
A setByPath() 0 14 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Communibase\DataBag;
6
7
final class DataMutator
8
{
9
    /**
10
     * @var array<string,array>
11
     */
12
    private $data;
13
14
    /**
15
     * @param mixed $value
16
     */
17
    public function setByPath(array &$data, string $path, $value): void
18
    {
19
        $this->data = &$data;
20
21
        [$entityType, $path] = explode('.', $path, 2);
22
23
        // Direct property
24
        if (strpos($path, '.') === false) {
25
            $data[$entityType][$path] = $value;
26
            return;
27
        }
28
29
        // Indexed
30
        $this->setIndexed($entityType, $path, $value);
31
    }
32
33
    /**
34
     * @param mixed $value
35
     */
36
    private function setIndexed(string $entityType, string $path, $value): void
37
    {
38
        [$path, $index] = explode('.', $path, 2);
39
40
        $field = null;
41
        if (strpos($index, '.') > 0) {
42
            [$index, $field] = explode('.', $index, 2);
43
        }
44
45
        $target = $index;
46
        if (!is_numeric($index)) {
47
            if (\is_array($value)) {
48
                $value['type'] = $index;
49
            }
50
            $index = null;
51
            if (isset($this->data[$entityType][$path])) {
52
                foreach ((array)$this->data[$entityType][$path] as $nodeIndex => $node) {
53
                    if (isset($node['type']) && $node['type'] === $target) {
54
                        $index = $nodeIndex;
55
                        break;
56
                    }
57
                }
58
            }
59
        }
60
61
        // No index found, new entry
62
        if ($index === null) {
63
            $this->addNewEntry($entityType, $path, $field, $target, $value);
64
            return;
65
        }
66
67
        // Use found index
68
        if ($field === null) {
69
            $this->data[$entityType][$path][$index] = $value;
70
            return;
71
        }
72
        $this->data[$entityType][$path][$index][$field] = $value;
73
    }
74
75
    /**
76
     * @param mixed $value
77
     */
78
    private function addNewEntry(string $entityType, string $path, ?string $field, string $target, $value): void
79
    {
80
        if ($field === null) {
81
            $this->data[$entityType][$path][] = $value;
82
            return;
83
        }
84
        $value = [
85
            $field => $value
86
        ];
87
        if (!is_numeric($target)) {
88
            $value['type'] = $target;
89
        }
90
        $this->data[$entityType][$path][] = $value;
91
    }
92
}
93