Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
72.97% covered (warning)
72.97%
27 / 37
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
FilterFromArray
72.97% covered (warning)
72.97%
27 / 37
60.00% covered (warning)
60.00%
3 / 5
19.44
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
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 createFromArray
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 isFiltered
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 followField
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
5.01
1<?php
2namespace Apie\Serializer\FieldFilters;
3
4use Apie\Core\Lists\StringList;
5use Apie\Core\Lists\StringSet;
6
7final class FilterFromArray implements FieldFilterInterface
8{
9    private function __construct(private array $fieldMap)
10    {
11    }
12
13    public static function createFromMixed(mixed $fieldNames): FieldFilterInterface
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 NoFiltering();
28    }
29
30    public static function createFromArray(StringList|StringSet $fieldNames): FieldFilterInterface
31    {
32        if ($fieldNames->count() === 0) {
33            return new NoFiltering();
34        }
35        $map = [];
36        foreach ($fieldNames as $fieldName) {
37            if (strpos($fieldName, '.') === false) {
38                $map[$fieldName] = [];
39            } else {
40                $prefix = strstr($fieldName, '.', true);
41                $map[$prefix] ??= [];
42                $map[$prefix][] = substr(strstr($fieldName, '.'), 1);
43            }
44        }
45        return new self($map);
46    }
47
48    public function isFiltered(string $fieldName): bool
49    {
50        return isset($this->fieldMap[$fieldName]) || isset($this->fieldMap['*']);
51    }
52
53    public function followField(string $fieldName): FieldFilterInterface
54    {
55        $list = [];
56        if (isset($this->fieldMap[$fieldName])) {
57            $list[] = self::createFromArray(new StringList($this->fieldMap[$fieldName]));
58        }
59        if (isset($this->fieldMap['*'])) {
60            $list[] = self::createFromArray(new StringList($this->fieldMap['*']));
61        }
62        $list = array_filter(
63            $list,
64            function (FieldFilterInterface $filter) {
65                return !($filter instanceof NoFiltering);
66            }
67        );
68        if (empty($list)) {
69            return new NoFiltering();
70        }
71        if (count($list) === 1) {
72            return reset($list);
73        }
74        return new ChainedFilter(...$list);
75    }
76}