Passed
Pull Request — master (#2)
by
unknown
09:41
created

PhpCacheFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WShafer\PSR11PhpCache;
6
7
use Cache\Hierarchy\HierarchicalPoolInterface;
8
use Cache\Namespaced\NamespacedCachePool;
9
use Cache\Prefixed\PrefixedCachePool;
10
use Psr\Cache\CacheItemPoolInterface;
11
use Psr\Container\ContainerInterface;
12
use Psr\Log\LoggerAwareInterface;
13
use Psr\Log\LoggerInterface;
14
use WShafer\PSR11PhpCache\Adapter\AdapterMapper;
15
use WShafer\PSR11PhpCache\Adapter\FactoryInterface;
16
use WShafer\PSR11PhpCache\Config\Config;
17
use WShafer\PSR11PhpCache\Config\ConfigCollection;
18
use WShafer\PSR11PhpCache\Exception\InvalidContainerException;
19
use WShafer\PSR11PhpCache\Exception\MissingCacheConfigException;
20
21
class PhpCacheFactory
22
{
23
    protected $configKey = 'default';
24 10
25
    public function __construct(string $configKey = 'default')
26 10
    {
27
        $this->configKey = $configKey;
28 9
    }
29
30 9
    public function __invoke(ContainerInterface $container): CacheItemPoolInterface
31
    {
32 9
        $configCollection = $this->getConfigCollection($container);
33
34
        $config = $configCollection->getCacheConfig($this->configKey);
35 9
36 9
        $pool = $this->getCachePool($container, $config);
37
38
        if (
39 1
            $pool instanceof LoggerAwareInterface
40 1
            && $config->getLoggerServiceName()
41
        ) {
42
            /** @var LoggerInterface $logger */
43
            $logger = $container->get($config->getLoggerServiceName());
44 9
            $pool->setLogger($logger);
45 9
        }
46
47 1
        if (
48
            $pool instanceof HierarchicalPoolInterface
49
            && !empty($config->getNamespace())
50 8
        ) {
51 1
            return new NamespacedCachePool($pool, $config->getNamespace());
52
        }
53
54 7
        if (!empty($config->getPrefix())) {
55
            return new PrefixedCachePool($pool, $config->getPrefix());
56
        }
57
58
        return $pool;
59
    }
60
61
    /**
62
     * Magic method for constructing Cache pools by service name
63
     *
64
     * @param $name
65 2
     * @param $arguments
66
     *
67
     * @return CacheItemPoolInterface
68 2
     */
69 2
    public static function __callStatic($name, $arguments): CacheItemPoolInterface
70
    {
71 1
        if (
72 1
            empty($arguments[0])
73
            || !$arguments[0] instanceof ContainerInterface
74
        ) {
75 1
            throw new InvalidContainerException(
76 1
                'Argument 0 must be an instance of a PSR-11 container'
77 1
            );
78
        }
79
        $factory = new static($name);
80 9
        return $factory($arguments[0]);
81
    }
82 9
83
    protected function getConfigCollection(ContainerInterface $container): ConfigCollection
84
    {
85 1
        return new ConfigCollection(
86
            $this->getConfigArray($container)
87 1
        );
88 1
    }
89
90 10
    protected function getConfigArray(ContainerInterface $container): array
91
    {
92 10
        // Symfony config is parameters. //
93
        if (
94 9
            method_exists($container, 'getParameter')
95
            && method_exists($container, 'hasParameter')
96
            && $container->hasParameter('caches')
97 10
        ) {
98
            return $container->getParameter('caches') ?? [];
99
        }
100
101 10
        // Slim Config comes from "settings"
102 10
        if ($container->has('settings')) {
103 10
            return $container->get('settings')['caches'] ?? [];
104
        }
105 1
106
        // Laminas/Zend uses config key
107
        if ($container->has('config')) {
108
            return $container->get('config')['caches'] ?? [];
109 9
        }
110 1
111
        throw new MissingCacheConfigException(
112
            'Unable to locate the config inside the container'
113
        );
114 8
    }
115 7
116
    protected function getCachePool(ContainerInterface $container, Config $serviceConfig): CacheItemPoolInterface
117
    {
118 1
        $type = $serviceConfig->getType();
119 1
        $factory = $this->getFactory($type);
120
121
        return $factory($container, $serviceConfig->getOptions());
122
    }
123 9
124
    /**
125 9
     * @SuppressWarnings(PHPMD.MissingImport)
126 9
     *
127
     * @param $type
128 9
     * @return callable|FactoryInterface
129
     */
130
    protected function getFactory($type)
131
    {
132
        if (is_callable($type)) {
133
            return $type;
134
        }
135
136
        if (
137 9
            class_exists($type)
138
            && in_array(FactoryInterface::class, class_implements($type), true)
139 9
        ) {
140 1
            return new $type();
141
        }
142
143
        $mapper = new AdapterMapper();
144 8
        return $mapper->map($type);
145 8
    }
146
}
147