GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — master (#62)
by Simone
02:16
created

JsonPathFinder::numberOfRelationsToEntity()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 6
rs 9.4285
1
<?php
2
3
namespace Mado\QueryBundle\Component\Meta;
4
5
use Psr\Log\LoggerInterface;
6
7
/**
8
 * @since Class available since Release 2.1.0
9
 */
10
class JsonPathFinder
11
{
12
    const INDEX_ENTITY_PARENT = 0;
13
14
    const INDEX_FK_RELATION_NAME = 1;
15
16
    const INDEX_ENTITY_FIRST_CHILD = 2;
17
18
    private $map;
19
20
    private $entity;
21
22
    private $entitiesPath = [];
23
24
    private $wrongPath = [];
25
26
    private $mapper;
27
28
    private $appendRootEntityToSubject;
29
30
    private $incrementSubject;
31
32
    private static $indeToDescriptionMap = [
33
        self::INDEX_ENTITY_PARENT      => 'parent',
34
        self::INDEX_FK_RELATION_NAME   => 'relation',
35
        self::INDEX_ENTITY_FIRST_CHILD => 'first child',
36
    ];
37
38
    private $logger;
39
40
    public function __construct(
41
        DataMapper $mapper,
42
        LoggerInterface $logger = null
43
    ) {
44
        $this->mapper = $mapper;
45
        $this->logger = $logger;
46
47
        $this->appendRootEntityToSubject =  function($subject, $rootEntity) {
48
            $subject[] = $rootEntity;
49
            return $subject;
50
        };
51
52
        $this->incrementSubject = function($subject) {
53
            return ++$subject;
54
        };
55
    }
56
57
    public function setEntity(string $entity)
58
    {
59
        $this->entity = $entity;
60
    }
61
62
    public function getFirstParentOf(string $innerEntity)
63
    {
64
        $this->getMap();
65
66
        return $this->keep(
67
            self::INDEX_ENTITY_PARENT,
68
            $innerEntity
69
        );
70
    }
71
72
    public function getFirstChildOf(string $innerEntity)
73
    {
74
        return $this->keep(
75
            self::INDEX_ENTITY_FIRST_CHILD,
76
            $innerEntity
77
        );
78
    }
79
80
    public function getSourceRelation(string $innerEntity)
81
    {
82
        return $this->keep(
83
            self::INDEX_FK_RELATION_NAME,
84
            $innerEntity
85
        );
86
    }
87
88
    public function clearMap(string $innerEntity)
89
    {
90
        if (in_array($this->entity, $this->listOfParentsOf($innerEntity))) {
91
            foreach ($this->map as $rootEntity => $meta) {
92
                if ($this->entity != $rootEntity) {
93
                    unset($this->map[$rootEntity]);
94
                }
95
            }
96
        }
97
    }
98
99
    public function getPathTo(string $innerEntity = '', $nest = 0)
100
    {
101
        $this->entitiesPath[] = $innerEntity;
102
103
        $path = $this->getSourceRelation($innerEntity);
104
105
        if ($this->numberOfRelationsToEntity($innerEntity) != 1) {
106
            $this->clearMap($innerEntity);
107
        }
108
109
        if ($this->entity != $this->getFirstParentOf($innerEntity)) {
110
            if (!($relation = $this->getFirstParentOf($innerEntity))) {
111
                throw new Exceptions\UnreachablePathException(var_export([
112
                    'innerEntity' => $innerEntity,
113
                    'relation' => $relation,
114
                ], true));
115
            }
116
117
            if ($nest > 10) {
118
                // @codeCoverageIgnoreStart
119
                if ($this->logger) {
120
                    $this->logger->critical(json_encode([
121
                        'nest'         => $nest,
122
                        'entitiesPath' => $this->getEntitiesPath(),
123
                    ], true));
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type integer expected by parameter $options of json_encode(). ( Ignorable by Annotation )

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

123
                    ], /** @scrutinizer ignore-type */ true));
Loading history...
124
                }
125
                // @codeCoverageIgnoreEnd
126
127
                throw new Exceptions\NestingException('loop found');
128
            }
129
130
            return $this->getPathTo($relation, ++$nest) . '.' . $path;
131
        }
132
133
        return $path;
134
    }
135
136
    public function setQueryStartEntity(string $startEntity)
137
    {
138
        $this->setEntity($startEntity);
139
    }
140
141
    public function getPathToEntity(string $entityToReach)
142
    {
143
        foreach ($this->getMap() as $rootEntity => $meta) {
144
            if (in_array($rootEntity, $this->wrongPath)) {
145
                unset($this->map[$rootEntity]);
146
            }
147
        }
148
149
        return '_embedded.' . $this->getPathTo($entityToReach);
150
    }
151
152
    public function keep($val, $innerEntity)
153
    {
154
        foreach ($this->getMap() as $rootEntity => $meta) {
155
            foreach ($meta['relations'] as $name => $entity) {
156
                if (self::INDEX_ENTITY_FIRST_CHILD == $val) {
157
                    return $entity;
158
                }
159
160
                if ($entity == $innerEntity) {
161
                    $return = [
162
                        self::INDEX_ENTITY_PARENT      => $rootEntity,
163
                        self::INDEX_FK_RELATION_NAME   => $name,
164
                    ][$val];
165
166
                    return $return;
167
                }
168
            }
169
        }
170
171
        throw new Exceptions\UnespectedValueException(var_export([
172
            'val'         => self::$indeToDescriptionMap[$val],
173
            'innerEntity' => $innerEntity,
174
            'map'         => $this->getMap(),
175
        ], true));
176
    }
177
178
    public function numberOfRelationsToEntity(string $entityToReach)
179
    {
180
        return $this->mapTargetRelations(
181
            $this->incrementSubject,
182
            $subject = 0,
183
            $entityToReach
184
        );
185
    }
186
187
    public function listOfParentsOf(string $entityToReach)
188
    {
189
        return $this->mapTargetRelations(
190
            $this->appendRootEntityToSubject,
191
            $subject = [],
192
            $entityToReach
193
        );
194
    }
195
196
    public function getEntitiesPath()
197
    {
198
        if (!$this->entitiesPath) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->entitiesPath of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
199
            throw new Exceptions\UndefinedPathException(
200
                'Any path was requested'
201
            );
202
        }
203
204
        return $this->entitiesPath;
205
    }
206
207
    public function removeStep($parentToSkip)
208
    {
209
        $this->wrongPath[] = $parentToSkip;
210
    }
211
212
    public function getHashKeyForDestination(string $destination)
213
    {
214
        return md5($this->entity . $destination);
215
    }
216
217
    private function getMap()
218
    {
219
        if (!$this->map) {
220
            $this->map = $this->mapper->getMap();
221
        }
222
223
        return $this->map;
224
    }
225
226
    public function addEntity(array $parents, $rootEntity) : array
227
    {
228
        $parents[] = $rootEntity;
229
230
        return $parents;
231
    }
232
233
    public function mapTargetRelations(
234
        callable $action,
235
        $subject,
236
        string $entityToReach
237
    ) {
238
        foreach ($this->getMap() as $rootEntity => $meta) {
239
            foreach ($meta['relations'] as $name => $relationEntity) {
240
                if ($relationEntity == $entityToReach) {
241
                    $subject = $action($subject, $rootEntity);
242
                }
243
            }
244
        }
245
246
        return $subject;
247
    }
248
}
249