Passed
Push — master ( 82a58b...d35cf8 )
by Tomasz
02:32
created

EmbedWalker::embed()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 8
cts 8
cp 1
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 13
nc 4
nop 2
crap 3
1
<?php
2
declare(strict_types=1);
3
4
namespace ReadModel\Walker;
5
6
class EmbedWalker implements ResultWalker
7
{
8
    /** @var array */
9
    private $prefixes;
10
11
    /**
12
     * @param string[] $prefixes Prefixes to embed, eg: for 'address' prefix:
13
     *      [id => 5, address_street = 'Sesame', 'address_number' = 4]
14
     *      will be turned into:
15
     *      [id => 5, address => [street = 'Sesame', 'number' = 4]]
16
     */
17 3
    public function __construct(string ...$prefixes)
18
    {
19 3
        $this->prefixes = $prefixes;
20 3
    }
21
22 1
    public function walk(array $result): array
23
    {
24 1
        foreach ($this->prefixes as $prefix) {
25 1
            $result = $this->embed($prefix, $result);
26
        }
27
28 1
        return $result;
29
    }
30
31
    private function embed(string $prefix, array $result): array
32
    {
33
        // filter out prefixed fields
34 1
        $prefixed = array_filter($result, function ($key) use ($prefix) {
35 1
            return strpos($key, $prefix) === 0;
36 1
        }, ARRAY_FILTER_USE_KEY);
37
38
        // remove filtered out fields from result
39 1
        foreach (array_keys($prefixed) as $key) {
40 1
            unset($result[$key]);
41
        }
42
43
        // remove prefix from field's name
44 1
        $keys = array_map(function ($key) use ($prefix) {
45 1
            return substr($key, strlen($prefix.'_'));
46 1
        }, array_keys($prefixed));
47
48
        // add new field to the result
49
        if (empty(array_filter($prefixed))) {
50
            $result[$prefix] = null;
51
        } else {
52
            $result[$prefix] = array_combine($keys, $prefixed);
53
        }
54
55
        return $result;
56
    }
57
}
58