Merger::mergeClass()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5.0061

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 15
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 26
ccs 15
cts 16
cp 0.9375
crap 5.0061
rs 9.4555
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 *  This file is part of the Micro framework package.
7
 *
8
 *  (c) Stanislau Komar <[email protected]>
9
 *
10
 *  For the full copyright and license information, please view the LICENSE
11
 *  file that was distributed with this source code.
12
 */
13
14
namespace Micro\Library\DTO\Merger;
15
16
class Merger implements MergerInterface
17
{
18
    /**
19
     * @param array<mixed, mixed> $classCollection
20
     */
21 4
    public function __construct(private array $classCollection)
22
    {
23 4
    }
24
25 4
    public function merge(): \Generator
26
    {
27 4
        $preparedClassCollection = $this->sortClassCollectionByName($this->classCollection);
28
29 4
        foreach ($preparedClassCollection as $className => $classData) {
30 4
            if (1 === \count($classData)) {
31 3
                yield $classData[0];
32
33 3
                continue;
34
            }
35
36 2
            yield $this->mergeClass($className, $classData);
37
        }
38
    }
39
40
    /**
41
     * @param string               $className
42
     * @param array<string, mixed> $classData
43
     *
44
     * @return array<string, mixed>
45
     */
46 2
    protected function mergeClass(string $className, array $classData): array
47
    {
48 2
        $properties = [];
49 2
        $propertiesExisted = [];
50
51 2
        foreach ($classData as $declaration) {
52 2
            if (!\array_key_exists('property', $declaration)) {
53
                continue;
54
            }
55
56 2
            foreach ($declaration['property'] as $propertyDef) {
57 2
                $propName = $propertyDef['name'];
58 2
                if (!\in_array($propName, $propertiesExisted)) {
59 2
                    $propertiesExisted[] = $propName;
60 2
                    $properties[] = $propertyDef;
61
62 2
                    continue;
63
                }
64
65 1
                throw new \RuntimeException(sprintf('Property "%s" already declared in %s', $propName, $className));
66
            }
67
        }
68
69 1
        return [
70 1
            'name' => $className,
71 1
            'property' => $properties,
72 1
        ];
73
    }
74
75
    /**
76
     * @param iterable<mixed, mixed> $classCollection
77
     *
78
     * @return array<string, mixed>
79
     */
80 4
    protected function sortClassCollectionByName(iterable $classCollection): array
81
    {
82 4
        $collectionPrepared = [];
83
84 4
        foreach ($classCollection as $item) {
85 4
            $className = $item['name'];
86
87 4
            if (!\array_key_exists($className, $collectionPrepared)) {
88 4
                $collectionPrepared[$className] = [];
89
            }
90
91 4
            $collectionPrepared[$className][] = $item;
92
        }
93
94 4
        return $collectionPrepared; // @phpstan-ignore-line
95
    }
96
}
97