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 (#138)
by joseph
96:08 queued 65:06
created

buildEntityInjectMethodsForEntity()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 5
nop 1
dl 0
loc 20
ccs 0
cts 15
cp 0
crap 30
rs 9.4888
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Entity\Factory;
4
5
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
6
use Psr\Container\ContainerInterface;
7
use ReflectionMethod;
8
9
class EntityDependencyInjector
10
{
11
    public const INJECT_DEPENDENCY_METHOD_PREFIX = 'inject';
12
13
    private const TYPE_KEY_STATIC   = 'static';
14
    private const TYPE_KEY_INSTANCE = 'instance';
15
    /**
16
     * @var ContainerInterface
17
     */
18
    protected $container;
19
20
21
    /**
22
     * This array is keyed by Entity FQN and the values are the inject*** method names that are used for injecting
23
     * dependencies
24
     *
25
     * @var array|ReflectionMethod
26
     */
27
    private $entityInjectMethods = [];
28
29
    public function __construct(ContainerInterface $container)
30
    {
31
        $this->container = $container;
32
    }
33
34
    /**
35
     * This method loops over the inject methods for an Entity and then injects the relevant dependencies
36
     *
37
     * We match the method argument type with the dependency to be injected.
38
     *
39
     * @param EntityInterface $entity
40
     */
41
    public function injectEntityDependencies(EntityInterface $entity): void
42
    {
43
        $this->buildEntityInjectMethodsForEntity($entity);
44
        $entityFqn = $this->leadingSlash($entity::getDoctrineStaticMeta()->getReflectionClass()->getName());
45
        $this->injectStatic($entity, $this->entityInjectMethods[$entityFqn][self::TYPE_KEY_STATIC]);
46
        $this->inject($entity, $this->entityInjectMethods[$entityFqn][self::TYPE_KEY_INSTANCE]);
47
    }
48
49
    /**
50
     * Build the array of entity methods to dependencies ready to be used for injection
51
     *
52
     * @param EntityInterface $entity
53
     */
54
    private function buildEntityInjectMethodsForEntity(EntityInterface $entity): void
55
    {
56
        $reflection = $entity::getDoctrineStaticMeta()->getReflectionClass();
57
        $entityFqn  = $this->leadingSlash($reflection->getName());
58
        if (array_key_exists($entityFqn, $this->entityInjectMethods)) {
0 ignored issues
show
Bug introduced by
It seems like $this->entityInjectMethods can also be of type ReflectionMethod; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

58
        if (array_key_exists($entityFqn, /** @scrutinizer ignore-type */ $this->entityInjectMethods)) {
Loading history...
59
            return;
60
        }
61
        $this->entityInjectMethods[$entityFqn] = [
62
            self::TYPE_KEY_INSTANCE => [],
63
            self::TYPE_KEY_STATIC   => [],
64
        ];
65
        $methods                               = $reflection->getMethods(ReflectionMethod::IS_PUBLIC);
66
        foreach ($methods as $method) {
67
            if (!\ts\stringStartsWith($method->getName(), self::INJECT_DEPENDENCY_METHOD_PREFIX)) {
68
                continue;
69
            }
70
            $typeKey = $method->isStatic() ? self::TYPE_KEY_STATIC : self::TYPE_KEY_INSTANCE;
71
72
            $this->entityInjectMethods[$entityFqn][$typeKey][$method->getName()] =
73
                $this->getDependencyForInjectMethod($method);
74
        }
75
    }
76
77
    private function leadingSlash(string $fqn): string
78
    {
79
        return '\\' . ltrim($fqn, '\\');
80
    }
81
82
    private function getDependencyForInjectMethod(ReflectionMethod $method): string
83
    {
84
        $params = $method->getParameters();
85
        if (1 !== count($params)) {
86
            throw new \RuntimeException(
87
                'Invalid method signature for ' .
88
                $method->getName() .
89
                ', should only take one argument which is the dependency to be injected'
90
            );
91
        }
92
        $type = current($params)->getType();
93
        if (null === $type) {
94
            throw new \RuntimeException(
95
                'Invalid method signature for ' .
96
                $method->getName() .
97
                ', the object being set must be type hinted'
98
            );
99
        }
100
101
        return $type->getName();
102
    }
103
104
    private function injectStatic(EntityInterface $entity, array $methods)
105
    {
106
        foreach ($methods as $methodName => $dependencyFqn) {
107
            $entity::$methodName($this->container->get($dependencyFqn));
108
        }
109
    }
110
111
    private function inject(EntityInterface $entity, array $methods)
112
    {
113
        foreach ($methods as $methodName => $dependencyFqn) {
114
            $entity->$methodName($this->container->get($dependencyFqn));
115
        }
116
    }
117
}
118