TaggedProfile   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 28
eloc 64
c 1
b 0
f 0
dl 0
loc 145
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A scanDescriptors() 0 23 4
A scanLinks() 0 16 4
A __construct() 0 6 1
A getDescriptorId() 0 20 5
A validDescriptor() 0 7 3
A filteredDescriptor() 0 17 3
A isFilteredOr() 0 13 4
A isFilteredAnd() 0 13 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Koriym\AppStateDiagram;
6
7
use Koriym\AppStateDiagram\Exception\InvalidDescriptorMissingIdOrHrefException;
8
use stdClass;
9
10
use function array_key_exists;
11
use function assert;
12
use function explode;
13
use function in_array;
14
use function is_string;
15
use function json_encode;
16
use function substr;
17
18
final class TaggedProfile extends AbstractProfile
19
{
20
    /** @var array<string, AbstractDescriptor> */
21
    private $tranceDescriptor;
22
23
    /**
24
     * @param list<string> $orTags
0 ignored issues
show
Bug introduced by
The type Koriym\AppStateDiagram\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
     * @param list<string> $andTags
26
     */
27
    public function __construct(AbstractProfile $alpsFile, array $orTags, array $andTags)
28
    {
29
        $this->title = $alpsFile->title;
30
        $this->doc = $alpsFile->doc;
31
        $this->scanLinks($alpsFile, $andTags, $orTags);
32
        $this->scanDescriptors($alpsFile);
33
    }
34
35
    /**
36
     * @param list<string> $andTags
37
     * @param list<string> $orTags
38
     */
39
    private function scanLinks(AbstractProfile $alpsFile, array $andTags, array $orTags): void
40
    {
41
        $links = new Links();
42
        $transDescriptors = new Descriptors();
43
        foreach ($alpsFile->links as $link) {
44
            if (
45
                $this->isFilteredAnd($link->transDescriptor, $andTags)
46
                || $this->isFilteredOr($link->transDescriptor, $orTags)
47
            ) {
48
                $links->add($link);
49
                $transDescriptors->add($link->transDescriptor);
50
            }
51
        }
52
53
        $this->links = $links->links;
54
        $this->tranceDescriptor = $transDescriptors->descriptors;
55
    }
56
57
    private function scanDescriptors(AbstractProfile $alpsFile): void
58
    {
59
        $descriptors = new Descriptors();
60
        foreach ($this->links as $link) {
61
            $descriptors->add($link->transDescriptor);
62
            $from = $this->filteredDescriptor(
63
                $alpsFile->descriptors[$link->from],
64
                $alpsFile->descriptors
65
            );
66
            foreach ($from->descriptors as $descriptor) {
67
                $descriptors->add($descriptor);
68
            }
69
70
            $to = $this->filteredDescriptor(
71
                $alpsFile->descriptors[$link->to],
72
                $alpsFile->descriptors
73
            );
74
            foreach ($to->descriptors as $descriptor) {
75
                $descriptors->add($descriptor);
76
            }
77
        }
78
79
        $this->descriptors = $descriptors->descriptors;
80
    }
81
82
    /** @param list<string> $andTags */
83
    private function isFilteredAnd(AbstractDescriptor $descriptor, array $andTags): bool
84
    {
85
        if ($andTags === []) {
86
            return false;
87
        }
88
89
        foreach ($andTags as $tag) {
90
            if (! in_array($tag, $descriptor->tags, true)) {
0 ignored issues
show
Bug introduced by
$descriptor->tags of type Koriym\AppStateDiagram\list is incompatible with the type array expected by parameter $haystack of in_array(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

90
            if (! in_array($tag, /** @scrutinizer ignore-type */ $descriptor->tags, true)) {
Loading history...
91
                return false;
92
            }
93
        }
94
95
        return true;
96
    }
97
98
    /** @param list<string> $orTags */
99
    private function isFilteredOr(AbstractDescriptor $descriptor, array $orTags): bool
100
    {
101
        if ($orTags === []) {
102
            return false;
103
        }
104
105
        foreach ($orTags as $tag) {
106
            if (in_array($tag, $descriptor->tags, true)) {
0 ignored issues
show
Bug introduced by
$descriptor->tags of type Koriym\AppStateDiagram\list is incompatible with the type array expected by parameter $haystack of in_array(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

106
            if (in_array($tag, /** @scrutinizer ignore-type */ $descriptor->tags, true)) {
Loading history...
107
                return true;
108
            }
109
        }
110
111
        return false;
112
    }
113
114
    private function getDescriptorId(stdClass $child): string
115
    {
116
        if (isset($child->id) && is_string($child->id)) {
117
            return $child->id;
118
        }
119
120
        $href = $child->href;
121
        if (! isset($href)) {
122
            throw new InvalidDescriptorMissingIdOrHrefException((string) json_encode($child)); // @codeCoverageIgnore
123
        }
124
125
        assert(is_string($href));
126
127
        $isInternal = $href[0] === '#';
128
129
        if ($isInternal) {
130
            return substr($href, 1);
131
        }
132
133
        return explode('#', $href)[1];
134
    }
135
136
    /** @param array<AbstractDescriptor> $allDescriptors */
137
    private function filteredDescriptor(AbstractDescriptor $edge, array $allDescriptors): Descriptors
138
    {
139
        $descriptors = new Descriptors();
140
        $filteredChildren = [];
141
142
        foreach ($edge->descriptor as $child) {
143
            $descriptor = $allDescriptors[$this->getDescriptorId($child)];
144
            if ($this->validDescriptor($descriptor)) {
145
                $filteredChildren[] = $child;
146
                $descriptors->add($descriptor);
147
            }
148
        }
149
150
        $edge->descriptor = $filteredChildren;
0 ignored issues
show
Documentation Bug introduced by
It seems like $filteredChildren of type array or array is incompatible with the declared type Koriym\AppStateDiagram\list of property $descriptor.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
151
        $descriptors->add($edge);
152
153
        return $descriptors;
154
    }
155
156
    private function validDescriptor(AbstractDescriptor $descriptor): bool
157
    {
158
        if ($descriptor instanceof SemanticDescriptor) {
159
            return true;
160
        }
161
162
        return $descriptor instanceof TransDescriptor && array_key_exists($descriptor->id, $this->tranceDescriptor);
163
    }
164
}
165