ConfigurationOption   B
last analyzed

Complexity

Total Complexity 45

Size/Duplication

Total Lines 342
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 95
dl 0
loc 342
rs 8.8
c 2
b 0
f 0
wmc 45

25 Methods

Rating   Name   Duplication   Size   Complexity  
A toArray() 0 3 1
A setDefaultKeyHashFunction() 0 8 5
A setItemDetailedDate() 0 5 1
A setDefaultTtl() 0 5 1
A isValidOption() 0 3 1
A getDefaultKeyHashFunction() 0 3 1
A getPath() 0 3 1
A isAutoTmpFallback() 0 3 1
A isItemDetailedDate() 0 3 1
A getDefaultTtl() 0 3 1
A getDefaultFileNameHashFunction() 0 3 1
A setPath() 0 5 1
A setAutoTmpFallback() 0 5 1
A isValueSerializable() 0 3 3
A __construct() 0 21 4
A setDefaultFileNameHashFunction() 0 8 4
A getSuperGlobalAccessor() 0 7 2
A setCacheSlamsTimeout() 0 11 2
A isPreventCacheSlams() 0 3 1
A getCacheSlamsTimeout() 0 3 1
A getDefaultSuperGlobalAccessor() 0 8 4
A isUseStaticItemCaching() 0 3 1
A setUseStaticItemCaching() 0 5 1
A setSuperGlobalAccessor() 0 23 3
A setPreventCacheSlams() 0 12 2

How to fix   Complexity   

Complex Class

Complex classes like ConfigurationOption often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ConfigurationOption, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 *
5
 * This file is part of Phpfastcache.
6
 *
7
 * @license MIT License (MIT)
8
 *
9
 * For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
10
 *
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 * @author Contributors  https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
13
 */
14
15
declare(strict_types=1);
16
17
namespace Phpfastcache\Config;
18
19
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
20
use Phpfastcache\Exceptions\PhpfastcacheInvalidConfigurationException;
21
use Phpfastcache\Exceptions\PhpfastcacheInvalidTypeException;
22
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
23
24
class ConfigurationOption extends AbstractConfigurationOption implements ConfigurationOptionInterface
25
{
26
    protected bool $itemDetailedDate = false;
27
28
    protected bool $autoTmpFallback = false;
29
30
    protected int $defaultTtl = 900;
31
32
    /**
33
     * @var string|callable
34
     */
35
    protected mixed $defaultKeyHashFunction = 'md5';
36
37
    /**
38
     * @var string|callable
39
     */
40
    protected mixed $defaultFileNameHashFunction = 'md5';
41
42
    protected string $path = '';
43
44
    protected bool $preventCacheSlams = false;
45
46
    protected int $cacheSlamsTimeout = 15;
47
48
    protected bool $useStaticItemCaching = true;
49
50
    protected ?object $superGlobalAccessor = null;
51
52
    /**
53
     * @inheritDoc
54
     * @throws PhpfastcacheInvalidConfigurationException
55
     * @throws PhpfastcacheInvalidTypeException
56
     */
57
    public function __construct(array $parameters = [])
58
    {
59
        foreach ($parameters as $configKey => $configVal) {
60
            try {
61
                if (\property_exists($this, $configKey)) {
62
                    $this->{'set' . \ucfirst($configKey)}($configVal);
63
                } else {
64
                    throw new PhpfastcacheInvalidConfigurationException(
65
                        sprintf(
66
                            'Unknown configuration option name "%s" for the config class "%s". Allowed configurations options are "%s"',
67
                            $configKey,
68
                            $this::class,
69
                            \implode('", "', \array_keys($this->toArray())),
70
                        )
71
                    );
72
                }
73
            } catch (\TypeError $e) {
74
                throw new PhpfastcacheInvalidTypeException(
75
                    \sprintf(
76
                        'TypeError exception thrown while trying to set your configuration: %s',
77
                        $e->getMessage()
78
                    )
79
                );
80
            }
81
        }
82
    }
83
84
    public function toArray(): array
85
    {
86
        return \get_object_vars($this);
87
    }
88
89
    /**
90
     * @throws \ReflectionException
91
     */
92
    public function isValueSerializable(mixed $val): bool
93
    {
94
        return !\is_callable($val) && !(is_object($val) && (new \ReflectionClass($val))->isAnonymous());
95
    }
96
97
    /**
98
     * @param string $optionName
99
     * @return bool
100
     */
101
    public function isValidOption(string $optionName): bool
102
    {
103
        return \property_exists($this, $optionName);
104
    }
105
106
    /**
107
     * @return bool
108
     */
109
    public function isItemDetailedDate(): bool
110
    {
111
        return $this->itemDetailedDate;
112
    }
113
114
    /**
115
     * @param bool $itemDetailedDate
116
     * @return ConfigurationOption
117
     * @throws PhpfastcacheLogicException
118
     */
119
    public function setItemDetailedDate(bool $itemDetailedDate): static
120
    {
121
        $this->enforceLockedProperty(__FUNCTION__);
122
        $this->itemDetailedDate = $itemDetailedDate;
123
        return $this;
124
    }
125
126
    /**
127
     * @return bool
128
     */
129
    public function isAutoTmpFallback(): bool
130
    {
131
        return $this->autoTmpFallback;
132
    }
133
134
    /**
135
     * @param bool $autoTmpFallback
136
     * @return ConfigurationOption
137
     * @throws PhpfastcacheLogicException
138
     */
139
    public function setAutoTmpFallback(bool $autoTmpFallback): static
140
    {
141
        $this->enforceLockedProperty(__FUNCTION__);
142
        $this->autoTmpFallback = $autoTmpFallback;
143
        return $this;
144
    }
145
146
    /**
147
     * @return int
148
     */
149
    public function getDefaultTtl(): int
150
    {
151
        return $this->defaultTtl;
152
    }
153
154
    /**
155
     * @param int $defaultTtl
156
     * @return ConfigurationOption
157
     * @throws PhpfastcacheLogicException
158
     */
159
    public function setDefaultTtl(int $defaultTtl): static
160
    {
161
        $this->enforceLockedProperty(__FUNCTION__);
162
        $this->defaultTtl = $defaultTtl;
163
        return $this;
164
    }
165
166
    /**
167
     * @return callable|string
168
     */
169
    public function getDefaultKeyHashFunction(): callable|string
170
    {
171
        return $this->defaultKeyHashFunction;
172
    }
173
174
    /**
175
     * @param callable|string $defaultKeyHashFunction
176
     * @return ConfigurationOption
177
     * @throws  PhpfastcacheInvalidConfigurationException
178
     * @throws PhpfastcacheLogicException
179
     */
180
    public function setDefaultKeyHashFunction(callable|string $defaultKeyHashFunction): static
181
    {
182
        $this->enforceLockedProperty(__FUNCTION__);
183
        if ($defaultKeyHashFunction && !\is_callable($defaultKeyHashFunction) && (\is_string($defaultKeyHashFunction) && !\function_exists($defaultKeyHashFunction))) {
184
            throw new PhpfastcacheInvalidConfigurationException('defaultKeyHashFunction must be a valid function name string');
185
        }
186
        $this->defaultKeyHashFunction = $defaultKeyHashFunction;
187
        return $this;
188
    }
189
190
    /**
191
     * @return callable|string
192
     */
193
    public function getDefaultFileNameHashFunction(): callable|string
194
    {
195
        return $this->defaultFileNameHashFunction;
196
    }
197
198
    /**
199
     * @param callable|string $defaultFileNameHashFunction
200
     * @return ConfigurationOption
201
     * @throws  PhpfastcacheInvalidConfigurationException
202
     * @throws PhpfastcacheLogicException
203
     */
204
    public function setDefaultFileNameHashFunction(callable|string $defaultFileNameHashFunction): static
205
    {
206
        $this->enforceLockedProperty(__FUNCTION__);
207
        if (!\is_callable($defaultFileNameHashFunction) && (\is_string($defaultFileNameHashFunction) && !\function_exists($defaultFileNameHashFunction))) {
208
            throw new PhpfastcacheInvalidConfigurationException('defaultFileNameHashFunction must be a valid function name string');
209
        }
210
        $this->defaultFileNameHashFunction = $defaultFileNameHashFunction;
211
        return $this;
212
    }
213
214
    /**
215
     * @return string
216
     */
217
    public function getPath(): string
218
    {
219
        return $this->path;
220
    }
221
222
    /**
223
     * @param string $path
224
     * @return ConfigurationOption
225
     * @throws PhpfastcacheLogicException
226
     */
227
    public function setPath(string $path): static
228
    {
229
        $this->enforceLockedProperty(__FUNCTION__);
230
        $this->path = $path;
231
        return $this;
232
    }
233
234
    /**
235
     * @deprecated This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.
236
     * @return bool
237
     */
238
    public function isPreventCacheSlams(): bool
239
    {
240
        return $this->preventCacheSlams;
241
    }
242
243
    /**
244
     * @deprecated This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.
245
     * @param bool $preventCacheSlams
246
     * @return ConfigurationOption
247
     * @throws PhpfastcacheLogicException
248
     */
249
    public function setPreventCacheSlams(bool $preventCacheSlams): static
250
    {
251
        if ($preventCacheSlams !== $this->preventCacheSlams) {
252
            trigger_error(
253
                'This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.',
254
                E_USER_DEPRECATED
255
            );
256
        }
257
258
        $this->enforceLockedProperty(__FUNCTION__);
259
        $this->preventCacheSlams = $preventCacheSlams;
260
        return $this;
261
    }
262
263
    /**
264
     * @deprecated This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.
265
     * @return int
266
     */
267
    public function getCacheSlamsTimeout(): int
268
    {
269
        return $this->cacheSlamsTimeout;
270
    }
271
272
    /**
273
     * @deprecated This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.
274
     * @param int $cacheSlamsTimeout
275
     * @return ConfigurationOption
276
     * @throws PhpfastcacheLogicException
277
     */
278
    public function setCacheSlamsTimeout(int $cacheSlamsTimeout): static
279
    {
280
        if ($cacheSlamsTimeout !== $this->cacheSlamsTimeout) {
281
            trigger_error(
282
                'This method is deprecated and will be soon moved to IOConfigurationOption class, which means they will only be available for `IO` drivers.',
283
                E_USER_DEPRECATED
284
            );
285
        }
286
        $this->enforceLockedProperty(__FUNCTION__);
287
        $this->cacheSlamsTimeout = $cacheSlamsTimeout;
288
        return $this;
289
    }
290
291
    /**
292
     * @return bool
293
     */
294
    public function isUseStaticItemCaching(): bool
295
    {
296
        return $this->useStaticItemCaching;
297
    }
298
299
    /**
300
     * @param bool $useStaticItemCaching
301
     * @return ConfigurationOption
302
     * @throws PhpfastcacheLogicException
303
     */
304
    public function setUseStaticItemCaching(bool $useStaticItemCaching): static
305
    {
306
        $this->enforceLockedProperty(__FUNCTION__);
307
        $this->useStaticItemCaching = $useStaticItemCaching;
308
        return $this;
309
    }
310
311
    /**
312
     * @return object
313
     */
314
    public function getSuperGlobalAccessor(): object
315
    {
316
        if (!isset($this->superGlobalAccessor)) {
317
            $this->superGlobalAccessor = $this->getDefaultSuperGlobalAccessor();
318
        }
319
320
        return $this->superGlobalAccessor;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->superGlobalAccessor could return the type null which is incompatible with the type-hinted return object. Consider adding an additional type-check to rule them out.
Loading history...
321
    }
322
323
    /**
324
     * @param ?object $superGlobalAccessor
325
     * @return static
326
     * @throws PhpfastcacheInvalidArgumentException
327
     * @throws PhpfastcacheLogicException
328
     */
329
    public function setSuperGlobalAccessor(?object $superGlobalAccessor): static
330
    {
331
        $this->enforceLockedProperty(__FUNCTION__);
332
        /**
333
         *  Symfony's implementation for users that want a good control of their code:
334
         *
335
         *  $config['superGlobalAccessor'] = \Closure::fromCallable(static function(string $superGlobalName, string $keyName) use ($request) {
336
         *      return match ($superGlobalName) {
337
         *          'SERVER' => $request->server->get($keyName),
338
         *          'REQUEST' => $request->request->get($keyName),
339
         *      };
340
         *  });
341
         */
342
343
        if ($superGlobalAccessor === null) {
344
            $this->superGlobalAccessor = $this->getDefaultSuperGlobalAccessor();
345
        } elseif (!\is_callable($superGlobalAccessor)) {
346
            throw new PhpfastcacheInvalidArgumentException('The "superGlobalAccessor" callback must be callable using "__invoke" or \Closure implementation');
347
        } else {
348
            $this->superGlobalAccessor = $superGlobalAccessor;
349
        }
350
351
        return $this;
352
    }
353
354
    /**
355
     * @return \Closure
356
     * @SuppressWarnings(PHPMD.Superglobals)
357
     */
358
    protected function getDefaultSuperGlobalAccessor(): \Closure
359
    {
360
        return \Closure::fromCallable(static function (string $superGlobalName, ?string $keyName = null): string|int|float|array|bool|null {
361
            return match ($superGlobalName) {
362
                'SERVER' => $keyName !== null ? $_SERVER[$keyName] ?? null : $_SERVER,
363
                'REQUEST' => $keyName !== null ? $_REQUEST[$keyName] ?? null : $_REQUEST,
364
                'COOKIE' => $keyName !== null ? $_COOKIE[$keyName] ?? null : $_COOKIE,
365
                default => null,
366
            };
367
        });
368
    }
369
}
370