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 (#75)
by joseph
14:44
created

UsesPHPMetaDataTrait::setChangeTrackingPolicy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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