PhpCacheFactory::__construct()   A
last analyzed

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