Completed
Push — master ( aa77c9...15a70d )
by Alejandro
27s
created

CacheFactory::resolveCacheAdapter()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 9.081

Importance

Changes 0
Metric Value
cc 9
eloc 20
nc 9
nop 1
dl 0
loc 27
rs 8.0555
c 0
b 0
f 0
ccs 18
cts 20
cp 0.9
crap 9.081
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\Common\Factory;
5
6
use Doctrine\Common\Cache;
7
use Interop\Container\ContainerInterface;
8
use Interop\Container\Exception\ContainerException;
9
use Memcached;
10
use Shlinkio\Shlink\Core\Options\AppOptions;
11
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
12
use Zend\ServiceManager\Exception\ServiceNotFoundException;
13
use Zend\ServiceManager\Factory\FactoryInterface;
14
use function Functional\contains;
15
use function Shlinkio\Shlink\Common\env;
16
17
class CacheFactory implements FactoryInterface
18
{
19
    private const VALID_CACHE_ADAPTERS = [
20
        Cache\ApcuCache::class,
21
        Cache\ArrayCache::class,
22
        Cache\FilesystemCache::class,
23
        Cache\PhpFileCache::class,
24
        Cache\MemcachedCache::class,
25
    ];
26
27
    /**
28
     * Create an object
29
     *
30
     * @param  ContainerInterface $container
31
     * @param  string $requestedName
32
     * @param  null|array $options
33
     * @return object
34
     * @throws ServiceNotFoundException if unable to resolve the service.
35
     * @throws ServiceNotCreatedException if an exception is raised when
36
     *     creating a service.
37
     * @throws ContainerException if any other error occurs
38
     */
39 6
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
40
    {
41 6
        $appOptions = $container->get(AppOptions::class);
42 6
        $adapter = $this->getAdapter($container);
43 6
        $adapter->setNamespace($appOptions->__toString());
44
45 6
        return $adapter;
46
    }
47
48 6
    private function getAdapter(ContainerInterface $container): Cache\CacheProvider
49
    {
50
        // Try to get the adapter from config
51 6
        $config = $container->get('config');
52 6
        if (isset($config['cache']['adapter']) && contains(self::VALID_CACHE_ADAPTERS, $config['cache']['adapter'])) {
53 3
            return $this->resolveCacheAdapter($config['cache']);
54
        }
55
56
        // If the adapter has not been set in config, create one based on environment
57 3
        return env('APP_ENV', 'pro') === 'pro' ? new Cache\ApcuCache() : new Cache\ArrayCache();
58
    }
59
60 3
    private function resolveCacheAdapter(array $cacheConfig): Cache\CacheProvider
61
    {
62 3
        switch ($cacheConfig['adapter']) {
63 3
            case Cache\ArrayCache::class:
64 2
            case Cache\ApcuCache::class:
65 1
                return new $cacheConfig['adapter']();
66 2
            case Cache\FilesystemCache::class:
67 1
            case Cache\PhpFileCache::class:
68 1
                return new $cacheConfig['adapter']($cacheConfig['options']['dir']);
69 1
            case Cache\MemcachedCache::class:
70 1
                $memcached = new Memcached();
71 1
                $servers = $cacheConfig['options']['servers'] ?? [];
72
73 1
                foreach ($servers as $server) {
74 1
                    if (! isset($server['host'])) {
75
                        continue;
76
                    }
77 1
                    $port = isset($server['port']) ? (int) $server['port'] : 11211;
78
79 1
                    $memcached->addServer($server['host'], $port);
80
                }
81
82 1
                $cache = new Cache\MemcachedCache();
83 1
                $cache->setMemcached($memcached);
84 1
                return $cache;
85
            default:
86
                return new Cache\ArrayCache();
87
        }
88
    }
89
}
90