Completed
Push — final ( d26b7a...86b86f )
by Georges
13s
created

CacheManager::validateConfig()   C

Complexity

Conditions 29
Paths 28

Size

Total Lines 75
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 75
rs 5.1914
cc 29
eloc 56
nc 28
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
namespace phpFastCache;
15
16
use phpFastCache\Core\Pool\ExtendedCacheItemPoolInterface;
17
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
18
use phpFastCache\Exceptions\phpFastCacheInvalidArgumentException;
19
use phpFastCache\Exceptions\phpFastCacheInvalidConfigurationException;
20
21
/**
22
 * Class CacheManager
23
 * @package phpFastCache
24
 *
25
 * @method static ExtendedCacheItemPoolInterface Apc() Apc($config = []) Return a driver "Apc" instance
26
 * @method static ExtendedCacheItemPoolInterface Apcu() Apcu($config = []) Return a driver "Apcu" instance
27
 * @method static ExtendedCacheItemPoolInterface Cassandra() Cassandra($config = []) Return a driver "Cassandra" instance
28
 * @method static ExtendedCacheItemPoolInterface Cookie() Cookie($config = []) Return a driver "Cookie" instance
29
 * @method static ExtendedCacheItemPoolInterface Couchbase() Couchbase($config = []) Return a driver "Couchbase" instance
30
 * @method static ExtendedCacheItemPoolInterface Couchdb() Couchdb($config = []) Return a driver "Couchdb" instance
31
 * @method static ExtendedCacheItemPoolInterface Devnull() Devnull($config = []) Return a driver "Devnull" instance
32
 * @method static ExtendedCacheItemPoolInterface Files() Files($config = []) Return a driver "files" instance
33
 * @method static ExtendedCacheItemPoolInterface Leveldb() Leveldb($config = []) Return a driver "Leveldb" instance
34
 * @method static ExtendedCacheItemPoolInterface Memcache() Memcache($config = []) Return a driver "Memcache" instance
35
 * @method static ExtendedCacheItemPoolInterface Memcached() Memcached($config = []) Return a driver "Memcached" instance
36
 * @method static ExtendedCacheItemPoolInterface Memstatic() Memstatic($config = []) Return a driver "Memstatic" instance
37
 * @method static ExtendedCacheItemPoolInterface Mongodb() Mongodb($config = []) Return a driver "Mongodb" instance
38
 * @method static ExtendedCacheItemPoolInterface Predis() Predis($config = []) Return a driver "Predis" instance
39
 * @method static ExtendedCacheItemPoolInterface Redis() Redis($config = []) Return a driver "Pedis" instance
40
 * @method static ExtendedCacheItemPoolInterface Sqlite() Sqlite($config = []) Return a driver "Sqlite" instance
41
 * @method static ExtendedCacheItemPoolInterface Ssdb() Ssdb($config = []) Return a driver "Ssdb" instance
42
 * @method static ExtendedCacheItemPoolInterface Wincache() Wincache($config = []) Return a driver "Wincache" instance
43
 * @method static ExtendedCacheItemPoolInterface Xcache() Xcache($config = []) Return a driver "Xcache" instance
44
 * @method static ExtendedCacheItemPoolInterface Zenddisk() Zenddisk($config = []) Return a driver "Zend disk cache" instance
45
 * @method static ExtendedCacheItemPoolInterface Zendshm() Zendshm($config = []) Return a driver "Zend memory cache" instance
46
 *
47
 */
48
class CacheManager
49
{
50
    /**
51
     * @var int
52
     */
53
    public static $ReadHits = 0;
54
55
    /**
56
     * @var int
57
     */
58
    public static $WriteHits = 0;
59
60
    /**
61
     * @var ExtendedCacheItemPoolInterface[]
62
     */
63
    protected static $config = [
64
        /**
65
         * Specify if the item must provide detailed creation/modification dates
66
         */
67
      'itemDetailedDate' => false,
68
69
        /**
70
         * Automatically attempt to fallback to temporary directory
71
         * if the cache fails to write on the specified directory
72
         */
73
      'autoTmpFallback' => false,
74
75
        /**
76
         * Provide a secure file manipulation mechanism,
77
         * on intensive usage the performance can be affected.
78
         */
79
      'secureFileManipulation' => false,
80
81
        /**
82
         * Ignore Symfony notice for Symfony project which
83
         * do not makes use of PhpFastCache's Symfony Bundle
84
         */
85
      'ignoreSymfonyNotice' => false,
86
87
        /**
88
         * Default time-to-live in second
89
         */
90
      'defaultTtl' => 900,
91
92
        /**
93
         * Default key hash function
94
         * (md5 by default)
95
         */
96
      'defaultKeyHashFunction' => '',
97
98
        /**
99
         * The securityKey that will be used
100
         * to create sub-directory
101
         * (Files-based drivers only)
102
         */
103
      'securityKey' => 'auto',
104
105
        /**
106
         * Auto-generate .htaccess if it's missing
107
         * (Files-based drivers only)
108
         */
109
      'htaccess' => true,
110
111
        /**
112
         * Default files chmod
113
         * 0777 recommended
114
         * (Files-based drivers only)
115
         */
116
      'default_chmod' => 0777,
117
118
        /**
119
         * The path where we will writecache files
120
         * default value if empty: sys_get_temp_dir()
121
         * (Files-based drivers only)
122
         */
123
      'path' => '',
124
125
        /**
126
         * Driver fallback in case of failure.
127
         * Caution, in case of failure an E_WARNING
128
         * error will always be raised
129
         */
130
      'fallback' => false,
131
132
        /**
133
         * Maximum size (bytes) of object store in memory
134
         * (Memcache(d) drivers only)
135
         */
136
      'limited_memory_each_object' => 4096,
137
138
        /**
139
         * Compress stored data, if the backend supports it
140
         * (Memcache(d) drivers only)
141
         */
142
      'compress_data' => false,
143
144
        /**
145
         * Prevent cache slams when
146
         * making use of heavy cache
147
         * items
148
         */
149
      'preventCacheSlams' => false,
150
151
        /**
152
         * Cache slams timeout
153
         * in seconds
154
         */
155
      'cacheSlamsTimeout' => 15,
156
157
    ];
158
159
    /**
160
     * @var string
161
     */
162
    protected static $namespacePath;
163
164
    /**
165
     * @var ExtendedCacheItemPoolInterface[]
166
     */
167
    protected static $instances = [];
168
169
    /**
170
     * @param string $driver
171
     * @param array $config
172
     * @return ExtendedCacheItemPoolInterface
173
     * @throws phpFastCacheDriverCheckException
174
     * @throws phpFastCacheInvalidConfigurationException
175
     */
176
    public static function getInstance($driver = 'auto', array $config = [])
177
    {
178
        static $badPracticeOmeter = [];
179
180
        /**
181
         * @todo: Standardize a method for driver name
182
         */
183
        $driver = self::standardizeDriverName($driver);
184
        $config = array_merge(self::$config, $config);
185
        self::validateConfig($config);
186
        if (!$driver || $driver === 'Auto') {
187
            $driver = self::getAutoClass($config);
188
        }
189
190
        $instance = crc32($driver . serialize($config));
191
        if (!isset(self::$instances[ $instance ])) {
192
            $badPracticeOmeter[$driver] = 1;
193
            if(!$config['ignoreSymfonyNotice'] && interface_exists('Symfony\Component\HttpKernel\KernelInterface') && !class_exists('phpFastCache\Bundle\phpFastCacheBundle')){
194
                trigger_error('A Symfony Bundle to make the PhpFastCache integration more easier is now available here: https://github.com/PHPSocialNetwork/phpfastcache-bundle', E_USER_NOTICE);
195
            }
196
            $class = self::getNamespacePath() . $driver . '\Driver';
197
            try{
198
                self::$instances[ $instance ] = new $class($config);
199
                self::$instances[ $instance ]->setEventManager(EventManager::getInstance());
200
            }catch(phpFastCacheDriverCheckException $e){
201
                if($config['fallback']){
202
                    try{
203
                        $fallback = self::standardizeDriverName($config['fallback']);
204
                        if($fallback !== $driver){
205
                            $class = self::getNamespacePath() . $fallback . '\Driver';
206
                            self::$instances[ $instance ] = new $class($config);
207
                            self::$instances[ $instance ]->setEventManager(EventManager::getInstance());
208
                            trigger_error(sprintf('The "%s" driver is unavailable at the moment, the fallback driver "%s" has been used instead.', $driver, $fallback), E_USER_WARNING);
209
                        }else{
210
                            throw new phpFastCacheInvalidConfigurationException('The fallback driver cannot be the same than the default driver', 0, $e);
211
                        }
212
                    }catch (phpFastCacheInvalidArgumentException $e){
213
                        throw new phpFastCacheInvalidConfigurationException('Invalid fallback driver configuration', 0, $e);
214
                    }
215
                }else{
216
                    throw new phpFastCacheDriverCheckException($e->getMessage(), $e->getCode(), $e);
217
                }
218
            }
219
        } else if($badPracticeOmeter[$driver] >= 5){
220
            trigger_error('[' . $driver . '] Calling many times CacheManager::getInstance() for already instanced drivers is a bad practice and have a significant impact on performances.
221
           See https://github.com/PHPSocialNetwork/phpfastcache/wiki/[V5]-Why-calling-getInstance%28%29-each-time-is-a-bad-practice-%3F');
222
        }
223
224
        $badPracticeOmeter[$driver]++;
225
226
        return self::$instances[ $instance ];
227
    }
228
229
    /**
230
     * This method is intended for internal
231
     * use only and should not be used for
232
     * any external development use the
233
     * getInstances() method instead
234
     *
235
     * @internal
236
     * @return ExtendedCacheItemPoolInterface[]
237
     */
238
    public static function getInstances()
239
    {
240
        return self::$instances;
241
    }
242
243
    /**
244
     * This method is intended for internal
245
     * use only and should not be used for
246
     * any external development use the
247
     * getInstances() method instead
248
     *
249
     * @internal
250
     * @return ExtendedCacheItemPoolInterface[]
251
     */
252
    public static function &getInternalInstances()
253
    {
254
        return self::$instances;
255
    }
256
257
    /**
258
     * @param $config
259
     * @return string
260
     * @throws phpFastCacheDriverCheckException
261
     */
262
    public static function getAutoClass(array $config = [])
263
    {
264
        static $autoDriver;
265
266
        if ($autoDriver === null) {
267
            foreach (self::getStaticSystemDrivers() as $driver) {
268
                try {
269
                    self::getInstance($driver, $config);
270
                    $autoDriver = $driver;
271
                } catch (phpFastCacheDriverCheckException $e) {
272
                    continue;
273
                }
274
            }
275
        }
276
277
        return $autoDriver;
278
    }
279
280
    /**
281
     * @param string $name
282
     * @param array $arguments
283
     * @return \Psr\Cache\CacheItemPoolInterface
284
     */
285
    public static function __callStatic($name, $arguments)
286
    {
287
        $options = (array_key_exists(0, $arguments) && is_array($arguments) ? $arguments[ 0 ] : []);
288
289
        return self::getInstance($name, $options);
290
    }
291
292
    /**
293
     * @return bool
294
     */
295
    public static function clearInstances()
296
    {
297
        self::$instances = [];
298
299
        gc_collect_cycles();
300
        return !count(self::$instances);
301
    }
302
303
    /**
304
     * @return string
305
     */
306
    public static function getNamespacePath()
307
    {
308
        return self::$namespacePath ?: __NAMESPACE__ . '\Drivers\\';
309
    }
310
311
    /**
312
     * @param string $path
313
     */
314
    public static function setNamespacePath($path)
315
    {
316
        self::$namespacePath = $path;
317
    }
318
319
    /**
320
     * @param $name string|array
321
     * @param mixed $value
322
     * @throws phpFastCacheInvalidArgumentException
323
     */
324
    public static function setDefaultConfig($name, $value = null)
325
    {
326
        if (is_array($name)) {
327
            self::$config = array_merge(self::$config, $name);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge(self::$config, $name) of type array is incompatible with the declared type array<integer,object<php...acheItemPoolInterface>> of property $config.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
328
        } else if (is_string($name)){
329
            self::$config[ $name ] = $value;
330
        }else{
331
            throw new phpFastCacheInvalidArgumentException('Invalid variable type: $name');
332
        }
333
    }
334
335
    /**
336
     * @param $name string|array
337
     * @param mixed $value
338
     * @throws phpFastCacheInvalidConfigurationException
339
     * @deprecated Method "setup" is deprecated, please use "setDefaultConfig" method instead
340
     */
341
    public static function setup($name, $value = null)
342
    {
343
        throw new phpFastCacheInvalidConfigurationException(sprintf('Method "%s" is deprecated, please use "setDefaultConfig" method instead.', __FUNCTION__));
344
    }
345
346
347
    /**
348
     * @return array
349
     */
350
    public static function getDefaultConfig()
351
    {
352
        return self::$config;
353
    }
354
355
    /**
356
     * @return array
357
     */
358
    public static function getStaticSystemDrivers()
359
    {
360
        return [
361
          'Apc',
362
          'Apcu',
363
          'Cassandra',
364
          'Couchbase',
365
          'Couchdb',
366
          'Devnull',
367
          'Files',
368
          'Leveldb',
369
          'Memcache',
370
          'Memcached',
371
          'Memstatic',
372
          'Mongodb',
373
          'Predis',
374
          'Redis',
375
          'Ssdb',
376
          'Sqlite',
377
          'Wincache',
378
          'Xcache',
379
        ];
380
    }
381
382
    /**
383
     * @return array
384
     */
385
    public static function getStaticAllDrivers()
386
    {
387
        return array_merge(self::getStaticSystemDrivers(), [
388
          'Devtrue',
389
          'Devfalse',
390
          'Cookie',
391
        ]);
392
    }
393
394
    /**
395
     * @param $driverName
396
     * @return string
397
     * @throws \phpFastCache\Exceptions\phpFastCacheInvalidArgumentException
398
     */
399
    public static function standardizeDriverName($driverName)
400
    {
401
        if(!is_string($driverName)){
402
            throw new phpFastCacheInvalidArgumentException(sprintf('Expected $driverName to be a string got "%s" instead', gettype($driverName)));
403
        }
404
        return ucfirst(strtolower(trim($driverName)));
405
    }
406
407
    /**
408
     * @param array $config
409
     * @todo Move this to a config file
410
     * @throws phpFastCacheInvalidConfigurationException
411
     * @return bool
412
     */
413
    protected static function validateConfig(array $config)
414
    {
415
        foreach ($config as $configName => $configValue) {
416
            switch($configName)
417
            {
418
                case 'itemDetailedDate':
419
                    if(!is_bool($configValue)){
420
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
421
                    }
422
                    break;
423
                case 'autoTmpFallback':
424
                    if(!is_bool($configValue)){
425
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
426
                    }
427
                    break;
428
                case 'secureFileManipulation':
429
                    if(!is_bool($configValue)){
430
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
431
                    }
432
                    break;
433
                case 'ignoreSymfonyNotice':
434
                    if(!is_bool($configValue)){
435
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
436
                    }
437
                    break;
438
                case 'defaultTtl':
439
                    if(!is_numeric($configValue)){
440
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be numeric");
441
                    }
442
                    break;
443
                case 'defaultKeyHashFunction':
444
                    if(!is_string($configValue) && !function_exists($configValue)){
445
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a valid function name string");
446
                    }
447
                    break;
448
                case 'securityKey':
449
                    if(!is_string($configValue)){
450
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a string");
451
                    }
452
                    break;
453
                case 'htaccess':
454
                    if(!is_bool($configValue)){
455
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
456
                    }
457
                    break;
458
                case 'default_chmod':
459
                    if(!is_int($configValue)){
460
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be an integer");
461
                    }
462
                    break;
463
                case 'path':
464
                    if(!is_string($configValue)){
465
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a string");
466
                    }
467
                    break;
468
                case 'fallback':
469
                    if(!is_bool($configValue)){
470
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
471
                    }
472
                    break;
473
                case 'limited_memory_each_object':
474
                    if(!is_int($configValue)){
475
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be an integer");
476
                    }
477
                    break;
478
                case 'compress_data':
479
                    if(!is_bool($configValue)){
480
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
481
                    }
482
                    break;
483
            }
484
        }
485
486
        return true;
487
    }
488
}
489