Passed
Branch 3.0.0 (0ebb76)
by Pieter
02:27
created

FallbackFactory::getApiResourceRetrieverInstance()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 13
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 18
rs 9.5222
1
<?php
2
3
namespace W2w\Lib\Apie\Plugins\Core\ResourceFactories;
4
5
use ReflectionClass;
6
use Symfony\Component\PropertyAccess\PropertyAccessor;
7
use W2w\Lib\Apie\Core\IdentifierExtractor;
8
use W2w\Lib\Apie\Exceptions\CouldNotConstructApiResourceClassException;
9
use W2w\Lib\Apie\Exceptions\InvalidClassTypeException;
10
use W2w\Lib\Apie\Interfaces\ApiResourceFactoryInterface;
11
use W2w\Lib\Apie\Interfaces\ApiResourcePersisterInterface;
12
use W2w\Lib\Apie\Interfaces\ApiResourceRetrieverInterface;
13
use W2w\Lib\Apie\Plugins\Core\DataLayers\ApplicationInfoRetriever;
14
use W2w\Lib\Apie\Plugins\Core\DataLayers\MemoryDataLayer;
15
use W2w\Lib\Apie\Plugins\Core\DataLayers\StatusCheckRetriever;
16
17
class FallbackFactory implements ApiResourceFactoryInterface
18
{
19
    private $propertyAccessor;
20
21
    private $identifierExtractor;
22
23
    private $debug;
24
25
    public function __construct(
26
        PropertyAccessor $propertyAccessor,
27
        IdentifierExtractor $identifierExtractor,
28
        bool $debug
29
    ) {
30
        $this->propertyAccessor = $propertyAccessor;
31
        $this->identifierExtractor = $identifierExtractor;
32
        $this->debug = $debug;
33
    }
34
35
    /**
36
     * Returns true if this factory can create this identifier.
37
     *
38
     * @param string $identifier
39
     * @return bool
40
     */
41
    public function hasApiResourceRetrieverInstance(string $identifier): bool
42
    {
43
        $defaultRetriever = in_array(
44
            $identifier,
45
            [
46
                ApplicationInfoRetriever::class,
47
                StatusCheckRetriever::class,
48
                MemoryDataLayer::class,
49
            ]
50
        );
51
        return $defaultRetriever || $this->isClassWithoutConstructorArguments($identifier);
52
    }
53
54
    /**
55
     * Gets an instance of ApiResourceRetrieverInstance
56
     * @param string $identifier
57
     * @return ApiResourceRetrieverInterface
58
     */
59
    public function getApiResourceRetrieverInstance(string $identifier): ApiResourceRetrieverInterface
60
    {
61
        switch ($identifier) {
62
            case ApplicationInfoRetriever::class:
63
                return new ApplicationInfoRetriever('undefined', 'unknown', '-', $this->debug);
64
            case StatusCheckRetriever::class:
65
                return new StatusCheckRetriever([]);
66
            case MemoryDataLayer::class:
67
                return new MemoryDataLayer(
68
                    $this->propertyAccessor,
69
                    $this->identifierExtractor
70
                );
71
        }
72
        $retriever = $this->createClassWithoutConstructorArguments($identifier);
73
        if (!$retriever instanceof ApiResourceRetrieverInterface) {
74
            throw new InvalidClassTypeException($identifier, 'ApiResourceRetrieverInterface');
75
        }
76
        return $retriever;
77
    }
78
79
    /**
80
     * Returns true if this factory can create this identifier.
81
     *
82
     * @param string $identifier
83
     * @return bool
84
     */
85
    public function hasApiResourcePersisterInstance(string $identifier): bool
86
    {
87
        return $identifier === MemoryDataLayer::class || $this->isClassWithoutConstructorArguments($identifier);
88
    }
89
90
    /**
91
     * Gets an instance of ApiResourceRetrieverInstance
92
     * @param string $identifier
93
     * @return ApiResourcePersisterInterface
94
     */
95
    public function getApiResourcePersisterInstance(string $identifier): ApiResourcePersisterInterface
96
    {
97
        if ($identifier === MemoryDataLayer::class) {
98
            return new MemoryDataLayer(
99
                $this->propertyAccessor,
100
                $this->identifierExtractor
101
            );
102
        }
103
        $retriever = $this->createClassWithoutConstructorArguments($identifier);
104
        if (!$retriever instanceof ApiResourcePersisterInterface) {
105
            throw new InvalidClassTypeException($identifier, 'ApiResourcePersisterInterface');
106
        }
107
        return $retriever;
108
    }
109
110
    private function isClassWithoutConstructorArguments(string $identifier): bool
111
    {
112
        try {
113
            $reflClass = new ReflectionClass($identifier);
114
        } catch (ReflectionException $reflectionException) {
0 ignored issues
show
Bug introduced by
The type W2w\Lib\Apie\Plugins\Cor...ies\ReflectionException was not found. Did you mean ReflectionException? If so, make sure to prefix the type with \.
Loading history...
115
            return false;
116
        }
117
        return !$reflClass->getConstructor() || $reflClass->getConstructor()->getNumberOfRequiredParameters() === 0;
118
    }
119
120
    private function createClassWithoutConstructorArguments(string $identifier): object
121
    {
122
        try {
123
            $reflClass = new ReflectionClass($identifier);
124
        } catch (ReflectionException $reflectionException) {
125
            throw new CouldNotConstructApiResourceClassException($identifier, $reflectionException);
126
        }
127
        if ($reflClass->getConstructor() && $reflClass->getConstructor()->getNumberOfRequiredParameters() > 0) {
128
            throw new CouldNotConstructApiResourceClassException($identifier);
129
        }
130
        return new $identifier();
131
    }
132
}
133