Completed
Push — 1.x ( 8c31f4...5f4811 )
by Samuel
7s
created

CacheTool::getFunction()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 22
rs 8.6737
nc 4
cc 5
eloc 11
nop 1
1
<?php
2
3
/*
4
 * This file is part of CacheTool.
5
 *
6
 * (c) Samuel Gordalina <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace CacheTool;
13
14
use CacheTool\Adapter\AbstractAdapter;
15
use CacheTool\Proxy\ProxyInterface;
16
use Psr\Log\LoggerInterface;
17
use Monolog\Logger;
18
19
class CacheTool
20
{
21
    /**
22
     * @var AbstractAdapter
23
     */
24
    protected $adapter;
25
26
    /**
27
     * @var array
28
     */
29
    protected $proxies = array();
30
31
    /**
32
     * @var array
33
     */
34
    protected $functions = array();
35
36
    /**
37
     * @var string
38
     */
39
    protected $tempDir;
40
41
    /**
42
     * @var LoggerInterface
43
     */
44
    protected $logger;
45
46
    /**
47
     * @param string          $tempDir
48
     * @param LoggerInterface $logger
49
     */
50
    public function __construct($tempDir = null, LoggerInterface $logger = null)
51
    {
52
        $this->logger = $logger ?: new Logger('cachetool');
53
54
        $tempDirs = array($tempDir, '/dev/shm', '/var/run', sys_get_temp_dir());
55
56
        foreach ($tempDirs as $tempDir) {
57
            if (is_dir($tempDir) && is_writable($tempDir)) {
58
                $this->tempDir = $tempDir;
59
                break;
60
            }
61
        }
62
    }
63
64
    /**
65
     * @param  AbstractAdapter $adapter
66
     * @param  string          $tempDir
67
     * @param  LoggerInterface $logger
68
     * @return CacheTool
69
     */
70
    public static function factory(AbstractAdapter $adapter = null, $tempDir = null, LoggerInterface $logger = null)
71
    {
72
        $cacheTool = new static($tempDir, $logger);
73
        $cacheTool->addProxy(new Proxy\ApcProxy());
74
        $cacheTool->addProxy(new Proxy\PhpProxy());
75
        $cacheTool->addProxy(new Proxy\OpcacheProxy());
76
77
        if ($adapter instanceof AbstractAdapter) {
78
            $cacheTool->setAdapter($adapter);
79
        }
80
81
        return $cacheTool;
82
    }
83
84
    /**
85
     * @param  AbstractAdapter $adapter
86
     * @return CacheTool
87
     */
88
    public function setAdapter(AbstractAdapter $adapter)
89
    {
90
        $this->logger->info(sprintf('Setting adapter: %s', get_class($adapter)));
91
92
        $this->adapter = $adapter;
93
        $this->adapter->setLogger($this->logger);
94
        $this->adapter->setTempDir($this->tempDir);
95
96
        return $this;
97
    }
98
99
    /**
100
     * @return AbstractAdapter
101
     */
102
    public function getAdapter()
103
    {
104
        return $this->adapter;
105
    }
106
107
    /**
108
     * @param ProxyInterface $proxy
109
     * @return CacheTool
110
     */
111
    public function addProxy(ProxyInterface $proxy)
112
    {
113
        $this->logger->info(sprintf('Adding Proxy: %s', get_class($proxy)));
114
115
        $this->proxies[] = $proxy;
116
117
        // reset functions (to be built when needed)
118
        $this->functions = array();
119
120
        return $this;
121
    }
122
123
    /**
124
     * @return array
125
     */
126
    public function getProxies()
127
    {
128
        return $this->proxies;
129
    }
130
131
    /**
132
     * @param  LoggerInterface $logger
133
     * @return CacheTool
134
     */
135
    public function setLogger(LoggerInterface $logger)
136
    {
137
        $this->logger = $logger;
138
139
        if ($this->adapter instanceof AbstractAdapter) {
140
            $this->adapter->setLogger($logger);
141
        }
142
143
        return $this;
144
    }
145
146
    /**
147
     * @return LoggerInterface
148
     */
149
    public function getLogger()
150
    {
151
        return $this->logger;
152
    }
153
154
    /**
155
     * Calls proxy functions
156
     *
157
     * @param  string $name
158
     * @param  array $arguments
159
     * @return mixed
160
     */
161
    public function __call($name, $arguments)
162
    {
163
        $this->logger->notice(sprintf('Executing: %s(%s)', $name, implode(', ', array_map('json_encode', $arguments))));
164
165
        if ($this->getFunction($name)) {
166
            return call_user_func_array($this->getFunction($name), $arguments);
167
        }
168
    }
169
170
    /**
171
     * Initializes functions and return callable
172
     *
173
     * @param  string $name
174
     * @return callable
175
     */
176
    protected function getFunction($name)
177
    {
178
        if (empty($this->functions)) {
179
            foreach ($this->proxies as $proxy) {
180
                $this->logger->info(sprintf('Loading Proxy: %s', get_class($proxy)));
181
182
                // lazily set adapter
183
                $proxy->setAdapter($this->adapter);
184
185
                foreach ($proxy->getFunctions() as $fn) {
186
                    $this->logger->debug(sprintf('Loading Function: %s', $fn));
187
                    $this->functions[$fn] = array($proxy, $fn);
188
                }
189
            }
190
        }
191
192
        if (isset($this->functions[$name])) {
193
            return $this->functions[$name];
194
        }
195
196
        throw new \InvalidArgumentException("Function with name: {$name} is not provided by any Proxy.");
197
    }
198
}
199