Completed
Push — master ( 1efa22...cfa6a3 )
by Sam
22s
created

ManifestCacheFactory::createCache()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 2
nop 2
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Core\Cache;
4
5
use BadMethodCallException;
6
use Monolog\Handler\ErrorLogHandler;
7
use Monolog\Handler\StreamHandler;
8
use Monolog\Logger;
9
use Psr\Log\LoggerAwareInterface;
10
use Psr\Log\LoggerInterface;
11
use Psr\SimpleCache\CacheInterface;
12
use ReflectionClass;
13
use SilverStripe\Control\Director;
14
15
/**
16
 * Assists with building of manifest cache prior to config being available
17
 */
18
class ManifestCacheFactory extends DefaultCacheFactory
19
{
20
    public function __construct(array $args = [], LoggerInterface $logger = null)
21
    {
22
        // Build default manifest logger
23
        if (!$logger) {
24
            $logger = new Logger("manifestcache-log");
25
            if (Director::isDev()) {
26
                $logger->pushHandler(new StreamHandler('php://output'));
27
            } else {
28
                $logger->pushHandler(new ErrorLogHandler());
29
            }
30
        }
31
32
        parent::__construct($args, $logger);
33
    }
34
35
    /**
36
     * Note: While the returned object is used as a singleton (by the originating Injector->get() call),
37
     * this cache object shouldn't be a singleton itself - it has varying constructor args for the same service name.
38
     *
39
     * @param string $service The class name of the service.
40
     * @param array $params The constructor parameters.
41
     * @return CacheInterface
42
     */
43
    public function create($service, array $params = array())
44
    {
45
        // Override default cache generation with SS_MANIFESTCACHE
46
        $cacheClass = getenv('SS_MANIFESTCACHE');
47
        if (!$cacheClass) {
48
            return parent::create($service, $params);
49
        }
50
51
        // Check if SS_MANIFESTCACHE is a factory
52
        if (is_a($cacheClass, CacheFactory::class, true)) {
53
            /** @var CacheFactory $factory */
54
            $factory = new $cacheClass;
55
            return $factory->create($service, $params);
56
        }
57
58
        // Check if SS_MANIFESTCACHE is a cache subclass
59
        if (is_a($cacheClass, CacheInterface::class, true)) {
60
            $args = array_merge($this->args, $params);
61
            $namespace = isset($args['namespace']) ? $args['namespace'] : '';
62
            return $this->createCache($cacheClass, [$namespace]);
63
        }
64
65
        // Validate type
66
        throw new BadMethodCallException(
67
            'SS_MANIFESTCACHE is not a valid CacheInterface or CacheFactory class name'
68
        );
69
    }
70
71
    /**
72
     * Create cache directly without config / injector
73
     *
74
     * @param string $class
75
     * @param array $args
76
     * @return CacheInterface
77
     */
78
    public function createCache($class, $args)
79
    {
80
        /** @var CacheInterface $cache */
81
        $reflection = new ReflectionClass($class);
82
        $cache = $reflection->newInstanceArgs($args);
83
84
        // Assign cache logger
85
        if ($this->logger && $cache instanceof LoggerAwareInterface) {
86
            $cache->setLogger($this->logger);
87
        }
88
89
        return $cache;
90
    }
91
}
92