Completed
Push — V6 ( 3b9b20...143ccf )
by Georges
02:21
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 Cookie() Cookie($config = []) Return a driver "cookie" instance
28
 * @method static ExtendedCacheItemPoolInterface Couchbase() Couchbase($config = []) Return a driver "couchbase" instance
29
 * @method static ExtendedCacheItemPoolInterface Files() Files($config = []) Return a driver "files" instance
30
 * @method static ExtendedCacheItemPoolInterface Leveldb() Leveldb($config = []) Return a driver "leveldb" instance
31
 * @method static ExtendedCacheItemPoolInterface Memcache() Memcache($config = []) Return a driver "memcache" instance
32
 * @method static ExtendedCacheItemPoolInterface Memcached() Memcached($config = []) Return a driver "memcached" instance
33
 * @method static ExtendedCacheItemPoolInterface Mongodb() Mongodb($config = []) Return a driver "mongodb" instance
34
 * @method static ExtendedCacheItemPoolInterface Predis() Predis($config = []) Return a driver "predis" instance
35
 * @method static ExtendedCacheItemPoolInterface Redis() Redis($config = []) Return a driver "redis" instance
36
 * @method static ExtendedCacheItemPoolInterface Sqlite() Sqlite($config = []) Return a driver "sqlite" instance
37
 * @method static ExtendedCacheItemPoolInterface Ssdb() Ssdb($config = []) Return a driver "ssdb" instance
38
 * @method static ExtendedCacheItemPoolInterface Wincache() Wincache($config = []) Return a driver "wincache" instance
39
 * @method static ExtendedCacheItemPoolInterface Xcache() Xcache($config = []) Return a driver "xcache" instance
40
 * @method static ExtendedCacheItemPoolInterface Zenddisk() Zenddisk($config = []) Return a driver "zend disk cache" instance
41
 * @method static ExtendedCacheItemPoolInterface Zendshm() Zendshm($config = []) Return a driver "zend memory cache" instance
42
 *
43
 */
44
class CacheManager
45
{
46
    /**
47
     * @var int
48
     */
49
    public static $ReadHits = 0;
50
51
    /**
52
     * @var int
53
     */
54
    public static $WriteHits = 0;
55
56
    /**
57
     * @var ExtendedCacheItemPoolInterface[]
58
     */
59
    protected static $config = [
60
        /**
61
         * Specify if the item must provide detailed creation/modification dates
62
         */
63
      'itemDetailedDate' => false,
64
65
        /**
66
         * Automatically attempt to fallback to temporary directory
67
         * if the cache fails to write on the specified directory
68
         */
69
      'autoTmpFallback' => false,
70
71
        /**
72
         * Provide a secure file manipulation mechanism
73
         * on intensive usage the performance can be affected.
74
         */
75
      'secureFileManipulation' => false,
76
77
        /**
78
         * Ignore Symfony notice for Symfony project which
79
         * do not makes use of PhpFastCache's Symfony Bundle
80
         */
81
      'ignoreSymfonyNotice' => false,
82
83
        /**
84
         * Default time-to-live in second
85
         */
86
      'defaultTtl' => 900,
87
88
        /**
89
         * Default key hash function
90
         * (md5 by default)
91
         */
92
      'defaultKeyHashFunction' => '',
93
94
        /**
95
         * The securityKey that will be used
96
         * to create sub-directory
97
         * (Files-based drivers only)
98
         */
99
      'securityKey' => 'auto',
100
101
        /**
102
         * Auto-generate .htaccess if it's missing
103
         * (Files-based drivers only)
104
         */
105
      'htaccess' => true,
106
107
        /**
108
         * Default files chmod
109
         * 0777 recommended
110
         * (Files-based drivers only)
111
         */
112
      'default_chmod' => 0777,
113
114
        /**
115
         * The path where we will writecache files
116
         * default value if empty: sys_get_temp_dir()
117
         * (Files-based drivers only)
118
         */
119
      'path' => '',
120
121
        /**
122
         * Driver fallback in case of failure.
123
         * Caution, in case of failure an E_WARNING
124
         * error will always be raised
125
         */
126
      'fallback' => false,
127
128
        /**
129
         * Maximum size (bytes) of object store in memory
130
         * (Memcache(d) drivers only)
131
         */
132
      'limited_memory_each_object' => 4096,
133
134
        /**
135
         * Compress stored data, if the backend supports it
136
         * (Memcache(d) drivers only)
137
         */
138
      'compress_data' => false,
139
    ];
140
141
    /**
142
     * @var string
143
     */
144
    protected static $namespacePath;
145
146
    /**
147
     * @var ExtendedCacheItemPoolInterface[]
148
     */
149
    protected static $instances = [];
150
151
    /**
152
     * @param string $driver
153
     * @param array $config
154
     * @return ExtendedCacheItemPoolInterface
155
     * @throws phpFastCacheDriverCheckException
156
     */
157
    public static function getInstance($driver = 'auto', array $config = [])
158
    {
159
        static $badPracticeOmeter = [];
160
161
        /**
162
         * @todo: Standardize a method for driver name
163
         */
164
        $driver = self::standardizeDriverName($driver);
165
        $config = array_merge(self::$config, $config);
166
        self::validateConfig($config);
167
        if (!$driver || $driver === 'Auto') {
168
            $driver = self::getAutoClass($config);
169
        }
170
171
        $instance = crc32($driver . serialize($config));
172
        if (!isset(self::$instances[ $instance ])) {
173
            $badPracticeOmeter[$driver] = 1;
174
            if(!$config['ignoreSymfonyNotice'] && interface_exists('Symfony\Component\HttpKernel\KernelInterface') && !class_exists('phpFastCache\Bundle\phpFastCacheBundle')){
175
                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);
176
            }
177
            $class = self::getNamespacePath() . $driver . '\Driver';
178
            try{
179
                self::$instances[ $instance ] = new $class($config);
180
                self::$instances[ $instance ]->setEventManager(EventManager::getInstance());
181
            }catch(phpFastCacheDriverCheckException $e){
182
                $fallback = self::standardizeDriverName($config['fallback']);
183
                if($fallback && $fallback !== $driver){
184
                    $class = self::getNamespacePath() . $fallback . '\Driver';
185
                    self::$instances[ $instance ] = new $class($config);
186
                    self::$instances[ $instance ]->setEventManager(EventManager::getInstance());
187
                    trigger_error(sprintf('The "%s" driver is unavailable at the moment, the fallback driver "%s" has been used instead.', $driver, $fallback), E_USER_WARNING);
188
                }else{
189
                    throw new phpFastCacheDriverCheckException($e->getMessage(), $e->getCode(), $e);
190
                }
191
            }
192
        } else if(++$badPracticeOmeter[$driver] >= 5){
193
            trigger_error('[' . $driver . '] Calling many times CacheManager::getInstance() for already instanced drivers is a bad practice and have a significant impact on performances.
194
           See https://github.com/PHPSocialNetwork/phpfastcache/wiki/[V5]-Why-calling-getInstance%28%29-each-time-is-a-bad-practice-%3F');
195
        }
196
197
        return self::$instances[ $instance ];
198
    }
199
200
    /**
201
     * This method is intended for internal
202
     * use only and should not be used for
203
     * any external development use the
204
     * getInstances() method instead
205
     *
206
     * @internal
207
     * @return ExtendedCacheItemPoolInterface[]
208
     */
209
    public static function getInstances()
210
    {
211
        return self::$instances;
212
    }
213
214
    /**
215
     * This method is intended for internal
216
     * use only and should not be used for
217
     * any external development use the
218
     * getInstances() method instead
219
     *
220
     * @internal
221
     * @return ExtendedCacheItemPoolInterface[]
222
     */
223
    public static function &getInternalInstances()
224
    {
225
        return self::$instances;
226
    }
227
228
    /**
229
     * @param $config
230
     * @return string
231
     * @throws phpFastCacheDriverCheckException
232
     */
233
    public static function getAutoClass(array $config = [])
234
    {
235
        static $autoDriver;
236
237
        if ($autoDriver === null) {
238
            foreach (self::getStaticSystemDrivers() as $driver) {
239
                try {
240
                    self::getInstance($driver, $config);
241
                    $autoDriver = $driver;
242
                } catch (phpFastCacheDriverCheckException $e) {
243
                    continue;
244
                }
245
            }
246
        }
247
248
        return $autoDriver;
249
    }
250
251
    /**
252
     * @param string $name
253
     * @param array $arguments
254
     * @return \Psr\Cache\CacheItemPoolInterface
255
     */
256
    public static function __callStatic($name, $arguments)
257
    {
258
        $options = (array_key_exists(0, $arguments) && is_array($arguments) ? $arguments[ 0 ] : []);
259
260
        return self::getInstance($name, $options);
261
    }
262
263
    /**
264
     * @return bool
265
     */
266
    public static function clearInstances()
267
    {
268
        self::$instances = [];
269
270
        gc_collect_cycles();
271
        return !count(self::$instances);
272
    }
273
274
    /**
275
     * @return string
276
     */
277
    public static function getNamespacePath()
278
    {
279
        return self::$namespacePath ?: __NAMESPACE__ . '\Drivers\\';
280
    }
281
282
    /**
283
     * @param string $path
284
     */
285
    public static function setNamespacePath($path)
286
    {
287
        self::$namespacePath = $path;
288
    }
289
290
    /**
291
     * @param $name string|array
292
     * @param mixed $value
293
     * @throws phpFastCacheInvalidArgumentException
294
     */
295
    public static function setDefaultConfig($name, $value = null)
296
    {
297
        if (is_array($name)) {
298
            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...
299
        } else if (is_string($name)){
300
            self::$config[ $name ] = $value;
301
        }else{
302
            throw new phpFastCacheInvalidArgumentException('Invalid variable type: $name');
303
        }
304
    }
305
306
    /**
307
     * @return array
308
     */
309
    public static function getDefaultConfig()
310
    {
311
        return self::$config;
312
    }
313
314
    /**
315
     * @return array
316
     */
317
    public static function getStaticSystemDrivers()
318
    {
319
        return [
320
          'Apc',
321
          'Apcu',
322
          'Cassandra',
323
          'Couchbase',
324
          'Devnull',
325
          'Files',
326
          'Leveldb',
327
          'Memcache',
328
          'Memcached',
329
          'Memstatic',
330
          'Mongodb',
331
          'Predis',
332
          'Redis',
333
          'Ssdb',
334
          'Sqlite',
335
          'Wincache',
336
          'Xcache',
337
        ];
338
    }
339
340
    /**
341
     * @return array
342
     */
343
    public static function getStaticAllDrivers()
344
    {
345
        return array_merge(self::getStaticSystemDrivers(), [
346
          'Devtrue',
347
          'Devfalse',
348
          'Cookie',
349
        ]);
350
    }
351
352
    /**
353
     * @param string $driverName
354
     * @return string
355
     */
356
    public static function standardizeDriverName($driverName)
357
    {
358
        return ucfirst(strtolower(trim($driverName)));
359
    }
360
361
    /**
362
     * @param array $config
363
     * @todo Move this to a config file
364
     * @throws phpFastCacheInvalidConfigurationException
365
     * @return bool
366
     */
367
    protected static function validateConfig(array $config)
368
    {
369
        foreach ($config as $configName => $configValue) {
370
            switch($configName)
371
            {
372
                case 'itemDetailedDate':
373
                    if(!is_bool($configValue)){
374
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
375
                    }
376
                    break;
377
                case 'autoTmpFallback':
378
                    if(!is_bool($configValue)){
379
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
380
                    }
381
                    break;
382
                case 'secureFileManipulation':
383
                    if(!is_bool($configValue)){
384
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
385
                    }
386
                    break;
387
                case 'ignoreSymfonyNotice':
388
                    if(!is_bool($configValue)){
389
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
390
                    }
391
                    break;
392
                case 'defaultTtl':
393
                    if(!is_numeric($configValue)){
394
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be numeric");
395
                    }
396
                    break;
397
                case 'defaultKeyHashFunction':
398
                    if(!is_string($configValue) && !is_callable($configValue)){
399
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a valid function name/closure");
400
                    }
401
                    break;
402
                case 'securityKey':
403
                    if(!is_string($configValue)){
404
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a string");
405
                    }
406
                    break;
407
                case 'htaccess':
408
                    if(!is_bool($configValue)){
409
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
410
                    }
411
                    break;
412
                case 'default_chmod':
413
                    if(!is_int($configValue)){
414
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be an integer");
415
                    }
416
                    break;
417
                case 'path':
418
                    if(!is_string($configValue)){
419
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a string");
420
                    }
421
                    break;
422
                case 'fallback':
423
                    if(!is_bool($configValue)){
424
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
425
                    }
426
                    break;
427
                case 'limited_memory_each_object':
428
                    if(!is_int($configValue)){
429
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be an integer");
430
                    }
431
                    break;
432
                case 'compress_data':
433
                    if(!is_bool($configValue)){
434
                        throw new phpFastCacheInvalidConfigurationException("{$configName} must be a boolean");
435
                    }
436
                    break;
437
            }
438
        }
439
440
        return true;
441
    }
442
}
443