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.
Completed
Pull Request — master (#100)
by joseph
18:26
created

UsesPHPMetaDataTrait::getSetters()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6.0073

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 26
ccs 16
cts 17
cp 0.9412
rs 9.0777
c 0
b 0
f 0
cc 6
nc 6
nop 0
crap 6.0073
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Entity\Traits;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use Doctrine\Common\Util\Debug;
7
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
8
use Doctrine\ORM\Mapping\ClassMetadata;
9
use Doctrine\ORM\Mapping\ClassMetadata as DoctrineClassMetaData;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
11
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\UsesPHPMetaDataInterface;
12
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
13
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
14
15
trait UsesPHPMetaDataTrait
16
{
17
18
    /**
19
     * @var \ts\Reflection\ReflectionClass
20
     */
21
    private static $reflectionClass;
22
23
    /**
24
     * @var ClassMetadata
25
     */
26
    private static $metaData;
27
28
    /**
29
     * @var string
30
     */
31
    private static $singular;
32
33
    /**
34
     * @var string
35
     */
36
    private static $plural;
37
38
    /**
39
     * @var array
40
     */
41
    private static $setters;
42
43
    /**
44
     * @var array
45
     */
46
    private static $getters;
47
48
    /**
49
     * Loads the class and property meta data in the class
50
     *
51
     * This is the method called by Doctrine to load the meta data
52
     *
53
     * @param DoctrineClassMetaData $metadata
54
     *
55
     * @throws DoctrineStaticMetaException
56
     * @SuppressWarnings(PHPMD.StaticAccess)
57
     */
58 57
    public static function loadMetadata(DoctrineClassMetaData $metadata): void
59
    {
60
        try {
61 57
            static::$metaData        = $metadata;
0 ignored issues
show
Bug introduced by
Since $metaData is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $metaData to at least protected.
Loading history...
62 57
            $builder                 = new ClassMetadataBuilder($metadata);
63 57
            static::$reflectionClass = $metadata->getReflectionClass();
0 ignored issues
show
Documentation Bug introduced by
It seems like $metadata->getReflectionClass() of type ReflectionClass is incompatible with the declared type ts\Reflection\ReflectionClass of property $reflectionClass.

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...
Bug introduced by
Since $reflectionClass is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $reflectionClass to at least protected.
Loading history...
64 57
            static::loadPropertyDoctrineMetaData($builder);
65 57
            static::loadClassDoctrineMetaData($builder);
66 57
            static::setChangeTrackingPolicy($builder);
67
        } catch (\Exception $e) {
68
            throw new DoctrineStaticMetaException(
69
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
70
                $e->getCode(),
71
                $e
72
            );
73
        }
74 57
    }
75
76
    /**
77
     * This method will reflect on the entity class and pull out all the methods that begin with
78
     * UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META
79
     *
80
     * Once it has an array of methods, it calls them all, passing in the $builder
81
     *
82
     * @param ClassMetadataBuilder $builder
83
     *
84
     * @throws DoctrineStaticMetaException
85
     * @throws \ReflectionException
86
     * @SuppressWarnings(PHPMD.StaticAccess)
87
     */
88 57
    protected static function loadPropertyDoctrineMetaData(ClassMetadataBuilder $builder): void
89
    {
90 57
        $methodName = '__no_method__';
91
        try {
92 57
            $staticMethods = static::getStaticMethods();
93
            //now loop through and call them
94 57
            foreach ($staticMethods as $method) {
95 57
                $methodName = $method->getName();
96 57
                if (0 === stripos(
97 57
                    $methodName,
98 57
                    UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META
99
                )
100
                ) {
101 57
                    static::$methodName($builder);
102
                }
103
            }
104
        } catch (\Exception $e) {
105
            $reflectionClass = static::getReflectionClass();
106
            throw new DoctrineStaticMetaException(
107
                'Exception in ' . __METHOD__ . 'for '
108
                . $reflectionClass->getName() . "::$methodName\n\n"
109
                . $e->getMessage()
110
            );
111
        }
112 57
    }
113
114
    /**
115
     * Get an array of all static methods implemented by the current class
116
     *
117
     * Merges trait methods
118
     * Filters out this trait
119
     *
120
     * @return array|\ReflectionMethod[]
121
     * @throws \ReflectionException
122
     */
123 73
    protected static function getStaticMethods(): array
124
    {
125 73
        $reflectionClass = static::getReflectionClass();
126 73
        $staticMethods   = $reflectionClass->getMethods(
127 73
            \ReflectionMethod::IS_STATIC
128
        );
129
        // get static methods from traits
130 73
        $traits = $reflectionClass->getTraits();
131 73
        foreach ($traits as $trait) {
132 73
            if ($trait->getShortName() === 'UsesPHPMetaData') {
133
                continue;
134
            }
135 73
            $traitStaticMethods = $trait->getMethods(
136 73
                \ReflectionMethod::IS_STATIC
137
            );
138 73
            array_merge(
139 73
                $staticMethods,
140 73
                $traitStaticMethods
141
            );
142
        }
143
144 73
        return $staticMethods;
145
    }
146
147
    /**
148
     * Get class level meta data, eg table name, custom repository
149
     *
150
     * @param ClassMetadataBuilder $builder
151
     *
152
     * @SuppressWarnings(PHPMD.StaticAccess)
153
     */
154 57
    protected static function loadClassDoctrineMetaData(ClassMetadataBuilder $builder): void
155
    {
156 57
        $tableName = MappingHelper::getTableNameForEntityFqn(static::class);
157 57
        $builder->setTable($tableName);
158 57
        static::setCustomRepositoryClass($builder);
159 57
    }
160
161
    /**
162
     * Setting the change policy to be Notify - best performance
163
     *
164
     * @see http://doctrine-orm.readthedocs.io/en/latest/reference/change-tracking-policies.html
165
     *
166
     * @param ClassMetadataBuilder $builder
167
     */
168 57
    public static function setChangeTrackingPolicy(ClassMetadataBuilder $builder): void
169
    {
170 57
        $builder->setChangeTrackingPolicyNotify();
171 57
    }
172
173
    /**
174
     * Get the property name the Entity is mapped by when plural
175
     *
176
     * Override it in your entity class if you are using an Entity class name that doesn't pluralize nicely
177
     *
178
     * @return string
179
     * @throws DoctrineStaticMetaException
180
     * @SuppressWarnings(PHPMD.StaticAccess)
181
     */
182 9
    public static function getPlural(): string
183
    {
184
        try {
185 9
            if (null === static::$plural) {
0 ignored issues
show
Bug introduced by
Since $plural is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $plural to at least protected.
Loading history...
introduced by
The condition static::plural is always false. If static::plural can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:34
Loading history...
186 9
                $singular       = static::getSingular();
187 9
                static::$plural = Inflector::pluralize($singular);
188
            }
189
190 9
            return static::$plural;
191
        } catch (\Exception $e) {
192
            throw new DoctrineStaticMetaException(
193
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
194
                $e->getCode(),
195
                $e
196
            );
197
        }
198
    }
199
200
    /**
201
     * Get the property the name the Entity is mapped by when singular
202
     *
203
     * @return string
204
     * @throws DoctrineStaticMetaException
205
     * @SuppressWarnings(PHPMD.StaticAccess)
206
     */
207 10
    public static function getSingular(): string
208
    {
209
        try {
210 10
            if (null === static::$singular) {
0 ignored issues
show
Bug introduced by
Since $singular is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $singular to at least protected.
Loading history...
introduced by
The condition static::singular is always false. If static::singular can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:29
Loading history...
211 9
                $reflectionClass = static::getReflectionClass();
212
213 9
                $shortName         = $reflectionClass->getShortName();
214 9
                $singularShortName = Inflector::singularize($shortName);
215
216 9
                $namespaceName   = $reflectionClass->getNamespaceName();
217 9
                $namespaceParts  = \explode(AbstractGenerator::ENTITIES_FOLDER_NAME, $namespaceName);
218 9
                $entityNamespace = \array_pop($namespaceParts);
219
220 9
                $namespacedShortName = \preg_replace(
221 9
                    '/\\\\/',
222 9
                    '',
223 9
                    $entityNamespace . $singularShortName
224
                );
225
226 9
                static::$singular = \lcfirst($namespacedShortName);
227
            }
228
229 10
            return static::$singular;
230
        } catch (\Exception $e) {
231
            throw new DoctrineStaticMetaException(
232
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
233
                $e->getCode(),
234
                $e
235
            );
236
        }
237
    }
238
239
    /**
240
     * Which field is being used for ID - will normally be `id` as implemented by
241
     * \EdmondsCommerce\DoctrineStaticMeta\Fields\Traits\IdField
242
     *
243
     * @return string
244
     * @SuppressWarnings(PHPMD.StaticAccess)
245
     */
246 2
    public static function getIdField(): string
247
    {
248 2
        return 'id';
249
    }
250
251
    /**
252
     * In the class itself, we need to specify the repository class name
253
     *
254
     * @param ClassMetadataBuilder $builder
255
     *
256
     * @return mixed
257
     */
258
    abstract protected static function setCustomRepositoryClass(ClassMetadataBuilder $builder);
259
260
    /**
261
     * Get an array of setters by name
262
     *
263
     * @return array|string[]
264
     * @throws \ReflectionException
265
     */
266 2
    public function getSetters(): array
267
    {
268 2
        if (null !== static::$setters) {
0 ignored issues
show
introduced by
The condition static::setters is always true. If static::setters can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:39
Loading history...
Bug introduced by
Since $setters is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $setters to at least protected.
Loading history...
269
            return static::$setters;
270
        }
271
        $skip            = [
272 2
            'setChangeTrackingPolicy' => true,
273
        ];
274 2
        static::$setters = [];
275 2
        $reflectionClass = static::getReflectionClass();
276 2
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
277 2
            $methodName = $method->getName();
278 2
            if (isset($skip[$methodName])) {
279 2
                continue;
280
            }
281 2
            if (\ts\stringStartsWith($methodName, 'set')) {
282 2
                static::$setters[] = $methodName;
283 2
                continue;
284
            }
285 2
            if (\ts\stringStartsWith($methodName, 'add')) {
286 1
                static::$setters[] = $methodName;
287 2
                continue;
288
            }
289
        }
290
291 2
        return static::$setters;
292
    }
293
294
    /**
295
     * Get the short name (without fully qualified namespace) of the current Entity
296
     *
297
     * @return string
298
     * @throws \ReflectionException
299
     */
300 2
    public function getShortName(): string
301
    {
302 2
        $reflectionClass = static::getReflectionClass();
303
304 2
        return $reflectionClass->getShortName();
305
    }
306
307
    /**
308
     * @return string
309
     * @throws \ReflectionException
310
     * @SuppressWarnings(PHPMD.StaticAccess)
311
     * @SuppressWarnings(PHPMD.ElseExpression)
312
     */
313 4
    public function __toString(): string
314
    {
315 4
        $dump     = [];
316 4
        $metaData = static::$metaData;
0 ignored issues
show
Bug introduced by
Since $metaData is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $metaData to at least protected.
Loading history...
317 4
        if ($metaData === null) {
318 1
            return 'Could not get metadata for ' . \get_class($this);
319
        }
320 3
        $fieldMappings = static::$metaData->fieldMappings;
321 3
        foreach ($this->getGetters() as $getter) {
322 3
            $got       = $this->$getter();
323 3
            $fieldName = \lcfirst(\substr($getter, 3));
324 3
            if (isset($fieldMappings[$fieldName])
325 3
                && 'decimal' === $fieldMappings[$fieldName]['type']
326
            ) {
327 1
                $value = (float)$got;
328 3
            } elseif ($got instanceof \Doctrine\ORM\Proxy\Proxy) {
329
                $value = 'Proxy class ';
330 3
            } elseif (\is_object($got) && method_exists($got, '__toString')) {
331
                $value = $got->__toString();
332
            } else {
333 3
                $value = Debug::export($got, 2);
334
            }
335 3
            $dump[$getter] = $value;
336
        }
337
338 3
        return (string)print_r($dump, true);
339
    }
340
341
    /**
342
     * Get an array of getters by name
343
     * [];
344
     *
345
     * @return array|string[]
346
     * @throws \ReflectionException
347
     */
348 4
    public function getGetters(): array
349
    {
350 4
        if (null !== static::$getters) {
0 ignored issues
show
introduced by
The condition static::getters is always true. If static::getters can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:44
Loading history...
Bug introduced by
Since $getters is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $getters to at least protected.
Loading history...
351 3
            return static::$getters;
352
        }
353
        $skip = [
354 4
            'getPlural'    => true,
355
            'getSingular'  => true,
356
            'getSetters'   => true,
357
            'getGetters'   => true,
358
            'getIdField'   => true,
359
            'getShortName' => true,
360
        ];
361
362 4
        static::$getters = [];
363 4
        $reflectionClass = static::getReflectionClass();
364 4
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
365 4
            $methodName = $method->getName();
366 4
            if (isset($skip[$methodName])) {
367 4
                continue;
368
            }
369 4
            if (\ts\stringStartsWith($methodName, 'get')) {
370 4
                static::$getters[] = $methodName;
371 4
                continue;
372
            }
373 4
            if (\ts\stringStartsWith($methodName, 'is')) {
374 3
                static::$getters[] = $methodName;
375 3
                continue;
376
            }
377 4
            if (\ts\stringStartsWith($methodName, 'has')) {
378
                static::$getters[] = $methodName;
379 4
                continue;
380
            }
381
        }
382
383 4
        return static::$getters;
384
    }
385
386
    /**
387
     * Find and run all init methods
388
     * - defined in relationship traits and generally to init ArrayCollection properties
389
     *
390
     * @throws \ReflectionException
391
     */
392 75
    protected function runInitMethods(): void
393
    {
394 75
        $reflectionClass = static::getReflectionClass();
395 75
        $methods         = $reflectionClass->getMethods(\ReflectionMethod::IS_PRIVATE);
396 75
        foreach ($methods as $method) {
397 75
            if ($method instanceof \ReflectionMethod) {
398 75
                $method = $method->getName();
399
            }
400 75
            if (\ts\stringContains($method, UsesPHPMetaDataInterface::METHOD_PREFIX_INIT)
401 75
                && \ts\stringStartsWith($method, UsesPHPMetaDataInterface::METHOD_PREFIX_INIT)
402
            ) {
403 75
                $this->$method();
404
            }
405
        }
406 75
    }
407
408
    /**
409
     * @return \ts\Reflection\ReflectionClass
410
     * @throws \ReflectionException
411
     */
412 85
    private static function getReflectionClass(): \ts\Reflection\ReflectionClass
413
    {
414 85
        if (!static::$reflectionClass instanceof \ts\Reflection\ReflectionClass) {
0 ignored issues
show
Bug introduced by
Since $reflectionClass is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $reflectionClass to at least protected.
Loading history...
introduced by
static::reflectionClass is always a sub-type of ts\Reflection\ReflectionClass. If static::reflectionClass can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:19.
Loading history...
415 84
            static::$reflectionClass = new \ts\Reflection\ReflectionClass(static::class);
416
        }
417
418 85
        return static::$reflectionClass;
419
    }
420
}
421