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
04:08
created

JsonPathFinder::clearMap()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 4
nc 4
nop 1
dl 0
loc 6
rs 9.2
c 0
b 0
f 0
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 $allPaths = [];
33
34
    private static $indeToDescriptionMap = [
35
        self::INDEX_ENTITY_PARENT      => 'parent',
36
        self::INDEX_FK_RELATION_NAME   => 'relation',
37
        self::INDEX_ENTITY_FIRST_CHILD => 'first child',
38
    ];
39
40
    private $logger;
41
42
    public function __construct(
43
        DataMapper $mapper,
44
        LoggerInterface $logger = null
45
    ) {
46
        $this->mapper = $mapper;
47
        $this->logger = $logger;
48
49
        $this->appendRootEntityToSubject =  function($subject, $rootEntity) {
50
            $subject[] = $rootEntity;
51
            return $subject;
52
        };
53
54
        $this->incrementSubject = function($subject) {
55
            return ++$subject;
56
        };
57
    }
58
59
    public function setEntity(string $entity)
60
    {
61
        $this->entity = $entity;
62
    }
63
64
    public function getFirstParentOf(string $innerEntity)
65
    {
66
        $this->getMap();
67
68
        return $this->keep(
69
            self::INDEX_ENTITY_PARENT,
70
            $innerEntity
71
        );
72
    }
73
74
    public function getFirstChildOf(string $innerEntity)
75
    {
76
        return $this->keep(
77
            self::INDEX_ENTITY_FIRST_CHILD,
78
            $innerEntity
79
        );
80
    }
81
82
    public function getSourceRelation(string $innerEntity)
83
    {
84
        return $this->keep(
85
            self::INDEX_FK_RELATION_NAME,
86
            $innerEntity
87
        );
88
    }
89
90
    public function clearMap(string $innerEntity)
91
    {
92
        if (in_array($this->entity, $this->listOfParentsOf($innerEntity))) {
93
            foreach ($this->map as $rootEntity => $meta) {
94
                if ($this->entity != $rootEntity) {
95
                    unset($this->map[$rootEntity]);
96
                }
97
            }
98
        }
99
    }
100
101
    public function getPathTo(string $innerEntity = '', $nest = 0)
102
    {
103
        $this->entitiesPath[] = $innerEntity;
104
105
        $path = $this->getSourceRelation($innerEntity);
106
107
        if ($this->numberOfRelationsToEntity($innerEntity) != 1) {
108
            $this->clearMap($innerEntity);
109
        }
110
111
        if ($this->entity != $this->getFirstParentOf($innerEntity)) {
112
            if (!($relation = $this->getFirstParentOf($innerEntity))) {
113
                throw new Exceptions\UnreachablePathException(var_export([
114
                    'innerEntity' => $innerEntity,
115
                    'relation' => $relation,
116
                ], true));
117
            }
118
119
            if ($nest > 10) {
120
                // @codeCoverageIgnoreStart
121
                if ($this->logger) {
122
                    $this->logger->critical(json_encode([
123
                        'nest'         => $nest,
124
                        'entitiesPath' => $this->getEntitiesPath(),
125
                    ], 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

125
                    ], /** @scrutinizer ignore-type */ true));
Loading history...
126
                }
127
                // @codeCoverageIgnoreEnd
128
129
                throw new Exceptions\NestingException('loop found');
130
            }
131
132
            return $this->getPathTo($relation, ++$nest) . '.' . $path;
133
        }
134
135
        return $path;
136
    }
137
138
    public function setQueryStartEntity(string $startEntity)
139
    {
140
        $this->setEntity($startEntity);
141
    }
142
143
    public function getPathToEntity(string $entityToReach)
144
    {
145
        $this->entitiesPath = [];
146
147
        foreach ($this->getMap() as $rootEntity => $meta) {
148
            if (in_array($rootEntity, $this->wrongPath)) {
149
                unset($this->map[$rootEntity]);
150
            }
151
        }
152
153
        $return = '_embedded.' . $this->getPathTo($entityToReach);
154
155
        $this->allPaths[] = $this->entitiesPath;
156
157
        return $return;
158
    }
159
160
    public function keep($val, $innerEntity)
161
    {
162
        foreach ($this->getMap() as $rootEntity => $meta) {
163
            foreach ($meta['relations'] as $name => $entity) {
164
                if (self::INDEX_ENTITY_FIRST_CHILD == $val) {
165
                    return $entity;
166
                }
167
168
                if ($entity == $innerEntity) {
169
                    $return = [
170
                        self::INDEX_ENTITY_PARENT      => $rootEntity,
171
                        self::INDEX_FK_RELATION_NAME   => $name,
172
                    ][$val];
173
174
                    return $return;
175
                }
176
            }
177
        }
178
179
        throw new Exceptions\UnespectedValueException(var_export([
180
            'val'         => self::$indeToDescriptionMap[$val],
181
            'innerEntity' => $innerEntity,
182
            'map'         => $this->getMap(),
183
        ], true));
184
    }
185
186
    public function numberOfRelationsToEntity(string $entityToReach)
187
    {
188
        return $this->mapTargetRelations(
189
            $this->incrementSubject,
190
            $subject = 0,
191
            $entityToReach
192
        );
193
    }
194
195
    public function listOfParentsOf(string $entityToReach)
196
    {
197
        return $this->mapTargetRelations(
198
            $this->appendRootEntityToSubject,
199
            $subject = [],
200
            $entityToReach
201
        );
202
    }
203
204
    public function getEntitiesPath()
205
    {
206
        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...
207
            throw new Exceptions\UndefinedPathException(
208
                'Any path was requested'
209
            );
210
        }
211
212
        return $this->entitiesPath;
213
    }
214
215
    public function removeStep($parentToSkip)
216
    {
217
        $this->wrongPath[] = $parentToSkip;
218
    }
219
220
    public function getHashKeyForDestination(string $destination)
221
    {
222
        return md5($this->entity . $destination);
223
    }
224
225
    private function getMap()
226
    {
227
        if (!$this->map) {
228
            $this->map = $this->mapper->getMap();
229
        }
230
231
        return $this->map;
232
    }
233
234
    public function addEntity(array $parents, $rootEntity) : array
235
    {
236
        $parents[] = $rootEntity;
237
238
        return $parents;
239
    }
240
241
    public function mapTargetRelations(
242
        callable $action,
243
        $subject,
244
        string $entityToReach
245
    ) {
246
        foreach ($this->getMap() as $rootEntity => $meta) {
247
            foreach ($meta['relations'] as $name => $relationEntity) {
248
                if ($relationEntity == $entityToReach) {
249
                    $subject = $action($subject, $rootEntity);
250
                }
251
            }
252
        }
253
254
        return $subject;
255
    }
256
257
    public function getAllPaths() : array
258
    {
259
        array_multisort($this->allPaths);
260
        return $this->allPaths;
261
    }
262
263
    public function findAllPathsTo(string $dest)
264
    {
265
        for ($stay = true;;) {
266
            try {
267
                $this->getPathToEntity($dest);
268
                $entities = $this->getEntitiesPath();
269
                $lastEntityFound = end($entities);
270
                $this->removeStep($lastEntityFound);
271
            } catch(\Mado\QueryBundle\Component\Meta\Exceptions\UnespectedValueException $e) {
272
                $stay = false;
273
            }
274
275
            if (!$stay) {
276
                return;
277
            }
278
        }
279
    }
280
}
281