Passed
Push — v7 ( f08608...4c8ab7 )
by Georges
01:47
created

CacheManager::getDefaultConfig()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * This file is part of phpFastCache.
5
 *
6
 * @license MIT License (MIT)
7
 *
8
 * For full copyright and license information, please see the docs/CREDITS.txt file.
9
 *
10
 * @author Khoa Bui (khoaofgod)  <[email protected]> http://www.phpfastcache.com
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 *
13
 */
14
declare(strict_types=1);
15
16
namespace Phpfastcache;
17
18
use Phpfastcache\Config\ConfigurationOption;
19
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
20
use Phpfastcache\Exceptions\{
21
  PhpfastcacheDeprecatedException, PhpfastcacheDriverCheckException, PhpfastcacheDriverNotFoundException, PhpfastcacheInstanceNotFoundException, PhpfastcacheInvalidArgumentException, PhpfastcacheInvalidConfigurationException, PhpfastcacheLogicException, PhpfastcacheUnsupportedOperationException
22
};
23
use Phpfastcache\Util\ClassNamespaceResolverTrait;
24
25
/**
26
 * Class CacheManager
27
 * @package phpFastCache
28
 *
29
 * @method static ExtendedCacheItemPoolInterface Apc() Apc($config = []) Return a driver "Apc" instance
30
 * @method static ExtendedCacheItemPoolInterface Apcu() Apcu($config = []) Return a driver "Apcu" instance
31
 * @method static ExtendedCacheItemPoolInterface Cassandra() Cassandra($config = []) Return a driver "Cassandra" instance
32
 * @method static ExtendedCacheItemPoolInterface Cookie() Cookie($config = []) Return a driver "Cookie" instance
33
 * @method static ExtendedCacheItemPoolInterface Couchbase() Couchbase($config = []) Return a driver "Couchbase" instance
34
 * @method static ExtendedCacheItemPoolInterface Couchdb() Couchdb($config = []) Return a driver "Couchdb" instance
35
 * @method static ExtendedCacheItemPoolInterface Devnull() Devnull($config = []) Return a driver "Devnull" instance
36
 * @method static ExtendedCacheItemPoolInterface Files() Files($config = []) Return a driver "files" instance
37
 * @method static ExtendedCacheItemPoolInterface Leveldb() Leveldb($config = []) Return a driver "Leveldb" instance
38
 * @method static ExtendedCacheItemPoolInterface Memcache() Memcache($config = []) Return a driver "Memcache" instance
39
 * @method static ExtendedCacheItemPoolInterface Memcached() Memcached($config = []) Return a driver "Memcached" instance
40
 * @method static ExtendedCacheItemPoolInterface Memstatic() Memstatic($config = []) Return a driver "Memstatic" instance
41
 * @method static ExtendedCacheItemPoolInterface Mongodb() Mongodb($config = []) Return a driver "Mongodb" instance
42
 * @method static ExtendedCacheItemPoolInterface Predis() Predis($config = []) Return a driver "Predis" instance
43
 * @method static ExtendedCacheItemPoolInterface Redis() Redis($config = []) Return a driver "Pedis" instance
44
 * @method static ExtendedCacheItemPoolInterface Riak() Riak($config = []) Return a driver "Riak" instance
45
 * @method static ExtendedCacheItemPoolInterface Sqlite() Sqlite($config = []) Return a driver "Sqlite" instance
46
 * @method static ExtendedCacheItemPoolInterface Ssdb() Ssdb($config = []) Return a driver "Ssdb" instance
47
 * @method static ExtendedCacheItemPoolInterface Wincache() Wincache($config = []) Return a driver "Wincache" instance
48
 * @method static ExtendedCacheItemPoolInterface Xcache() Xcache($config = []) Return a driver "Xcache" instance
49
 * @method static ExtendedCacheItemPoolInterface Zenddisk() Zenddisk($config = []) Return a driver "Zend disk cache" instance
50
 * @method static ExtendedCacheItemPoolInterface Zendshm() Zendshm($config = []) Return a driver "Zend memory cache" instance
51
 *
52
 */
53
class CacheManager
54
{
55
    use ClassNamespaceResolverTrait;
56
57
    /**
58
     * @var ConfigurationOption
59
     */
60
    protected static $config;
61
62
    /**
63
     * @var int
64
     */
65
    public static $ReadHits = 0;
66
67
    /**
68
     * @var int
69
     */
70
    public static $WriteHits = 0;
71
72
    /**
73
     * @var string
74
     */
75
    protected static $namespacePath;
76
77
    /**
78
     * @var ExtendedCacheItemPoolInterface[]
79
     */
80
    protected static $instances = [];
81
82
    /**
83
     * @param string $driver
84
     * @param array|ConfigurationOption $config
85
     * @param string $instanceId
86
     *
87
     * @return ExtendedCacheItemPoolInterface
88
     *
89
     * @throws PhpfastcacheDriverCheckException
90
     * @throws PhpfastcacheInvalidConfigurationException
91
     * @throws PhpfastcacheDriverNotFoundException
92
     * @throws PhpfastcacheInvalidArgumentException
93
     */
94
    public static function getInstance($driver = 'auto', $config = null, $instanceId = null): ExtendedCacheItemPoolInterface
95
    {
96
        static $badPracticeOmeter = [];
97
98
        if ($instanceId !== null && !\is_string($instanceId)) {
0 ignored issues
show
introduced by
The condition is_string($instanceId) is always true.
Loading history...
99
            throw new PhpfastcacheInvalidArgumentException('The Instance ID must be a string');
100
        }
101
102
        if (is_array($config)) {
103
            $config = new ConfigurationOption($config);
104
            trigger_error(
105
              'The CacheManager will drops the support of primitive configuration arrays, use a "\Phpfastcache\Config\ConfigurationOption" object instead',
106
              E_USER_DEPRECATED
107
            );
108
        }elseif ($config === null){
109
            $config = self::getDefaultConfig();
110
        }else if(!($config instanceof ConfigurationOption)){
0 ignored issues
show
introduced by
$config is always a sub-type of Phpfastcache\Config\ConfigurationOption.
Loading history...
111
            throw new PhpfastcacheInvalidArgumentException(sprintf('Unsupported config type: %s', gettype($config)));
112
        }
113
114
        $driver = self::standardizeDriverName($driver);
115
116
        if (!$driver || $driver === 'Auto') {
117
            $driver = self::getAutoClass($config);
118
        }
119
120
        $instance = $instanceId ?: md5($driver . \serialize($config->toArray()));
121
122
        if (!isset(self::$instances[ $instance ])) {
123
            $badPracticeOmeter[ $driver ] = 1;
124
            $driverClass = self::getNamespacePath() . $driver . '\Driver';
125
            try {
126
                if (\class_exists($driverClass)) {
127
                    $configClass = $driverClass::getConfigClass();
128
                    self::$instances[ $instance ] = new $driverClass(new $configClass($config->toArray()), $instance);
129
                    self::$instances[ $instance ]->setEventManager(EventManager::getInstance());
130
                } else {
131
                    throw new PhpfastcacheDriverNotFoundException(sprintf('The driver "%s" does not exists', $driver));
132
                }
133
            } catch (PhpfastcacheDriverCheckException $e) {
134
                if ($config->getFallback()) {
135
                    try {
136
                        $fallback = $config->getFallback();
137
                        $config->setFallback('');
138
                        trigger_error(sprintf('The "%s" driver is unavailable at the moment, the fallback driver "%s" has been used instead.', $driver, $fallback), E_USER_WARNING);
139
                        return self::getInstance($fallback, $config->getFallbackConfig());
140
                    } catch (PhpfastcacheInvalidArgumentException $e) {
141
                        throw new PhpfastcacheInvalidConfigurationException('Invalid fallback driver configuration', 0, $e);
142
                    }
143
                } else {
144
                    throw new PhpfastcacheDriverCheckException($e->getMessage(), $e->getCode(), $e);
145
                }
146
            }
147
        } else if ($badPracticeOmeter[ $driver ] >= 2) {
148
            trigger_error('[' . $driver . '] Calling many times CacheManager::getInstance() for already instanced drivers is a bad practice and have a significant impact on performances.
149
           See https://github.com/PHPSocialNetwork/phpfastcache/wiki/[V5]-Why-calling-getInstance%28%29-each-time-is-a-bad-practice-%3F');
150
        }
151
152
        $badPracticeOmeter[ $driver ]++;
153
154
        return self::$instances[ $instance ];
155
    }
156
157
    /**
158
     * @param string $instanceId
159
     *
160
     * @return ExtendedCacheItemPoolInterface
161
     *
162
     * @throws PhpfastcacheInvalidArgumentException
163
     * @throws PhpfastcacheInstanceNotFoundException
164
     */
165
    public static function getInstanceById($instanceId): ExtendedCacheItemPoolInterface
166
    {
167
        if ($instanceId !== null && !\is_string($instanceId)) {
0 ignored issues
show
introduced by
The condition is_string($instanceId) is always true.
Loading history...
168
            throw new PhpfastcacheInvalidArgumentException('The Instance ID must be a string');
169
        }
170
171
        if (isset(self::$instances[ $instanceId ])) {
172
            return self::$instances[ $instanceId ];
173
        }
174
175
        throw new PhpfastcacheInstanceNotFoundException(sprintf('Instance ID %s not found', $instanceId));
176
    }
177
178
    /**
179
     * This method is intended for internal
180
     * use only and should not be used for
181
     * any external development use the
182
     * getInstances() method instead
183
     *
184
     * @internal
185
     * @return ExtendedCacheItemPoolInterface[]
186
     */
187
    public static function getInstances(): array
188
    {
189
        return self::$instances;
190
    }
191
192
    /**
193
     * This method is intended for internal
194
     * use only and should not be used for
195
     * any external development use the
196
     * getInstances() method instead
197
     *
198
     * @todo Use a proper way to passe them as a reference ?
199
     * @internal
200
     * @return ExtendedCacheItemPoolInterface[]
201
     */
202
    public static function &getInternalInstances(): array
203
    {
204
        return self::$instances;
205
    }
206
207
    /**
208
     * @param ConfigurationOption $config
209
     * @return string
210
     * @throws PhpfastcacheDriverCheckException
211
     * @throws \Phpfastcache\Exceptions\PhpfastcacheLogicException
212
     */
213
    public static function getAutoClass(ConfigurationOption $config): string
214
    {
215
        static $autoDriver;
216
217
        if ($autoDriver === null) {
218
            foreach (self::getDriverList() as $driver) {
219
                try {
220
                    self::getInstance($driver, $config);
221
                    $autoDriver = $driver;
222
                    break;
223
                } catch (PhpfastcacheDriverCheckException $e) {
224
                    continue;
225
                }
226
            }
227
        }
228
229
        if(!$autoDriver || !\is_string($autoDriver)){
230
            throw new PhpfastcacheLogicException('Unable to find out a valid driver automatically');
231
        }
232
233
        return $autoDriver;
234
    }
235
236
    /**
237
     * @param string $name
238
     * @param array $arguments
239
     * @return \Psr\Cache\ExtendedCacheItemPoolInterface
0 ignored issues
show
Bug introduced by
The type Psr\Cache\ExtendedCacheItemPoolInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
240
     */
241
    public static function __callStatic(string $name, array $arguments): ExtendedCacheItemPoolInterface
242
    {
243
        $options = (\array_key_exists(0, $arguments) && \is_array($arguments) ? $arguments[ 0 ] : []);
244
245
        return self::getInstance($name, $options);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::getInstance($name, $options) returns the type Phpfastcache\Core\Pool\E...dCacheItemPoolInterface which is incompatible with the documented return type Psr\Cache\ExtendedCacheItemPoolInterface.
Loading history...
246
    }
247
248
    /**
249
     * @return bool
250
     */
251
    public static function clearInstances(): bool
252
    {
253
        self::$instances = [];
254
255
        gc_collect_cycles();
256
        return !\count(self::$instances);
257
    }
258
259
    /**
260
     * @return string
261
     */
262
    public static function getNamespacePath(): string
263
    {
264
        return self::$namespacePath ?: self::getDefaultNamespacePath();
265
    }
266
267
    /**
268
     * @return string
269
     */
270
    public static function getDefaultNamespacePath(): string
271
    {
272
        return  __NAMESPACE__ . '\Drivers\\';
273
    }
274
275
    /**
276
     * @param string $path
277
     */
278
    public static function setNamespacePath($path)
279
    {
280
        self::$namespacePath = \trim($path, "\\") . '\\';
281
    }
282
283
    /**
284
     * @param ConfigurationOption $config
285
     */
286
    public static function setDefaultConfig(ConfigurationOption $config)
287
    {
288
        self::$config = $config;
289
    }
290
291
    /**
292
     * @return ConfigurationOption
293
     */
294
    public static function getDefaultConfig(): ConfigurationOption
295
    {
296
        return self::$config ?: self::$config = new ConfigurationOption();
297
    }
298
299
    /**
300
     * @return array
301
     * @deprecated As of V7 will be removed soon or later, use CacheManager::getDriverList() instead
302
     */
303
    public static function getStaticSystemDrivers(): array
304
    {
305
        trigger_error(sprintf('Method "%s" is deprecated as of the V7 and will be removed soon or later, use CacheManager::getDriverList() instead.', __METHOD__), E_USER_DEPRECATED);
306
        return [
307
          'Apc',
308
          'Apcu',
309
          'Cassandra',
310
          'Couchbase',
311
          'Couchdb',
312
          'Devnull',
313
          'Files',
314
          'Leveldb',
315
          'Memcache',
316
          'Memcached',
317
          'Memstatic',
318
          'Mongodb',
319
          'Predis',
320
          'Redis',
321
          'Riak',
322
          'Ssdb',
323
          'Sqlite',
324
          'Wincache',
325
          'Xcache',
326
          'Zenddisk',
327
          'Zendshm',
328
        ];
329
    }
330
331
    /**
332
     * @return array
333
     * @deprecated As of V7 will be removed soon or later, use CacheManager::getDriverList() instead
334
     */
335
    public static function getStaticAllDrivers(): array
336
    {
337
        trigger_error(sprintf('Method "%s" is deprecated as of the V7 and will be removed soon or later, use CacheManager::getDriverList() instead.', __METHOD__), E_USER_DEPRECATED);
338
        return \array_merge(self::getStaticSystemDrivers(), [
1 ignored issue
show
Deprecated Code introduced by
The function Phpfastcache\CacheManage...etStaticSystemDrivers() has been deprecated: As of V7 will be removed soon or later, use CacheManager::getDriverList() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

338
        return \array_merge(/** @scrutinizer ignore-deprecated */ self::getStaticSystemDrivers(), [

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
339
          'Devtrue',
340
          'Devfalse',
341
          'Cookie',
342
        ]);
343
    }
344
345
    /**
346
     * @return string[]
347
     * @throws PhpfastcacheUnsupportedOperationException
348
     */
349
    public static function getDriverList(): array
350
    {
351
        static $driverList;
352
353
        if(self::getDefaultNamespacePath() === self::getNamespacePath()){
354
            if($driverList === null){
355
                $prefix = 'Phpfastcache\Drivers\\';
356
                $classMap = self::createClassMap(__DIR__ . '/Drivers');
357
                $driverList = [];
358
359
                foreach ($classMap as $class => $file) {
360
                    $driverList[] = str_replace($prefix, '', substr($class, 0, strrpos($class, '\\') ));
361
                }
362
363
                $driverList = array_values(array_unique($driverList));
364
            }
365
366
            return $driverList;
367
        }
368
369
        throw new PhpfastcacheUnsupportedOperationException('Cannot get the driver list if the default namespace path has changed.');
370
    }
371
372
    /**
373
     * @param string $driverName
374
     * @return string
375
     */
376
    public static function standardizeDriverName(string $driverName): string
377
    {
378
        return \ucfirst(\strtolower(\trim($driverName)));
379
    }
380
}
381