Completed
Branch feature/pre-split (60f5c0)
by Anton
03:19
created

CacheManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Spiral\Cache;
10
11
use Spiral\Cache\Configs\CacheConfig;
12
use Spiral\Cache\Exceptions\CacheException;
13
use Spiral\Core\Component;
14
use Spiral\Core\Container\InjectorInterface;
15
use Spiral\Core\Container\SingletonInterface;
16
use Spiral\Core\FactoryInterface;
17
use Spiral\Debug\Traits\BenchmarkTrait;
18
19
/**
20
 * Default implementation of CacheInterface. Better fit for spiral.
21
 *
22
 * @todo implement at top of good psr6 package?
23
 */
24
class CacheManager extends Component implements SingletonInterface, CacheInterface, InjectorInterface
25
{
26
    use BenchmarkTrait;
27
28
    /**
29
     * Already constructed cache adapters.
30
     *
31
     * @var StoreInterface[]
32
     */
33
    private $stores = [];
34
35
    /**
36
     * @var CacheConfig
37
     */
38
    protected $config;
39
40
    /**
41
     * @invisible
42
     *
43
     * @var FactoryInterface
44
     */
45
    protected $factory;
46
47
    /**
48
     * @param CacheConfig      $config
49
     * @param FactoryInterface $factory
50
     */
51
    public function __construct(CacheConfig $config, FactoryInterface $factory)
52
    {
53
        $this->config = $config;
54
        $this->factory = $factory;
55
    }
56
57
    /**
58
     * Set custom implementation of store.
59
     *
60
     * @param string         $name
61
     * @param StoreInterface $store
62
     */
63
    public function setStore(string $name, StoreInterface $store)
64
    {
65
        if (!empty($this->stores[$name])) {
66
            throw new CacheException("Store '{$name}' is already created");
67
        }
68
69
        if (!$store->isAvailable()) {
70
            throw new CacheException("Unable to mount unavailable store '" . get_class($store) . "'");
71
        }
72
73
        $this->stores[$name] = $store;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function getStore(string $store = null): StoreInterface
80
    {
81
        //Default store class
82
        $store = !empty($store) ? $store : $this->config->defaultStore();
83
84
        //We are allowing reference aliases for store names
85
        $store = $this->config->resolveAlias($store);
86
87
        if (isset($this->stores[$store])) {
88
            return $this->stores[$store];
89
        }
90
91
        $benchmark = $this->benchmark('store', $store);
92
        try {
93
            //Constructing cache instance
94
            $this->stores[$store] = $this->factory->make(
95
                $this->config->storeClass($store),
96
                $this->config->storeOptions($store)
97
            );
98
        } finally {
99
            $this->benchmark($benchmark);
100
        }
101
102
        if ($store == $this->config->defaultStore() && !$this->stores[$store]->isAvailable()) {
103
            throw new CacheException(
104
                "Unable to use default store '{$store}', driver is unavailable"
105
            );
106
        }
107
108
        return $this->stores[$store];
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     *
114
     * @throws CacheException
115
     */
116
    public function createInjection(\ReflectionClass $class, string $context = null)
117
    {
118
        if ($class->isAbstract()) {
119
            //Default store
120
            return $this->getStore();
121
        }
122
123
        return $this->getStore(
124
            $this->config->resolveStore($class)
125
        );
126
    }
127
}
128