Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.11% covered (success)
91.11%
41 / 45
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
EmbedRelationFromArray
91.11% covered (success)
91.11%
41 / 45
60.00% covered (warning)
60.00%
3 / 5
17.20
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createFromMixed
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
3.01
 createFromArray
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
4
 hasEmbeddedRelation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 followField
86.36% covered (warning)
86.36%
19 / 22
0.00% covered (danger)
0.00%
0 / 1
8.16
1<?php
2namespace Apie\Serializer\Relations;
3
4use Apie\Core\Lists\StringList;
5use Apie\Core\Lists\StringSet;
6
7class EmbedRelationFromArray implements EmbedRelationInterface
8{
9    private function __construct(private array $fieldMap, private bool $embedded, private array $embeddedMap)
10    {
11    }
12
13    public static function createFromMixed(mixed $fieldNames): EmbedRelationInterface
14    {
15        if (is_string($fieldNames)) {
16            return self::createFromArray(
17                new StringList(explode(',', $fieldNames))
18            );
19        }
20
21        if (is_array($fieldNames)) {
22            return self::createFromArray(
23                new StringList($fieldNames)
24            );
25        }
26
27        return new NoRelationEmbedded();
28    }
29
30    public static function createFromArray(StringList|StringSet $fieldNames, bool $embedded = false): EmbedRelationInterface
31    {
32        if ($fieldNames->count() === 0) {
33            return new NoRelationEmbedded();
34        }
35        $map = [];
36        $embeddedMap = [];
37        foreach ($fieldNames as $fieldName) {
38            if (strpos($fieldName, '.') === false) {
39                $map[$fieldName] = [];
40                $embeddedMap[$fieldName] = true;
41            } else {
42                $prefix = strstr($fieldName, '.', true);
43                $map[$prefix] ??= [];
44                $map[$prefix][] = substr(strstr($fieldName, '.'), 1);
45            }
46        }
47        return new self($map, $embedded, $embeddedMap);
48    }
49
50    public function hasEmbeddedRelation(): bool
51    {
52        return $this->embedded;
53    }
54
55    public function followField(string $fieldName): EmbedRelationInterface
56    {
57        if ($fieldName === 'id') {
58            return new NoRelationEmbedded();
59        }
60        $list = [];
61        if (isset($this->fieldMap[$fieldName])) {
62            if (count($this->fieldMap[$fieldName]) === 0) {
63                return new HasRelationEmbedded();
64            }
65            $list[] = self::createFromArray(new StringList($this->fieldMap[$fieldName]), $this->embeddedMap[$fieldName] ?? false);
66        }
67        if (isset($this->fieldMap['*'])) {
68            if (count($this->fieldMap['*']) === 0) {
69                return new HasRelationEmbedded();
70            }
71            $list[] = self::createFromArray(new StringList($this->fieldMap['*']), $this->embeddedMap['*'] ?? false);
72        }
73        $list = array_filter(
74            $list,
75            function (EmbedRelationInterface $filter) {
76                return !($filter instanceof NoRelationEmbedded);
77            }
78        );
79        if (empty($list)) {
80            return new NoRelationEmbedded();
81        }
82        if (count($list) === 1) {
83            return reset($list);
84        }
85        return new ChainedRelation(...$list);
86    }
87}