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 (#80)
by joseph
17:47
created

UsesPHPMetaDataTrait::__toString()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 7.0957

Importance

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