Elgg  Version 4.3
CacheManager.php
Go to the documentation of this file.
1 <?php
2 
17 declare(strict_types=1);
18 
19 namespace Phpfastcache;
20 
33 };
35 
36 
63 {
64  public const CORE_DRIVER_NAMESPACE = 'Phpfastcache\Drivers\\';
65 
67 
71  protected static $config;
75  protected static $namespacePath;
76 
80  protected static $instances = [];
81 
85  protected static $driverOverrides = [];
86 
90  protected static $driverCustoms = [];
91 
95  final protected function __construct()
96  {
97  // The cache manager is not meant to be instantiated
98  }
99 
105  public static function getInstanceById(string $instanceId): ExtendedCacheItemPoolInterface
106  {
107  if (isset(self::$instances[$instanceId])) {
108  return self::$instances[$instanceId];
109  }
110 
111  throw new PhpfastcacheInstanceNotFoundException(sprintf('Instance ID %s not found', $instanceId));
112  }
113 
119  public static function getInstances(): array
120  {
121  return self::$instances;
122  }
123 
134  public static function &getInternalInstances(): array
135  {
136  return self::$instances;
137  }
138 
151  public static function __callStatic(string $name, array $arguments): ExtendedCacheItemPoolInterface
152  {
153  $options = (\array_key_exists(0, $arguments) && \is_array($arguments) ? $arguments[0] : []);
154 
155  return self::getInstance($name, $options);
156  }
157 
171  public static function getInstance(string $driver, ?ConfigurationOptionInterface $config = null, ?string $instanceId = null): ExtendedCacheItemPoolInterface
172  {
173  $config = self::validateConfig($config);
174  $driver = self::standardizeDriverName($driver);
175 
176  $instanceId = $instanceId ?: md5($driver . \serialize(\array_filter($config->toArray(), static function ($val){
177  return !\is_callable($val);
178  })));
179 
180  if (!isset(self::$instances[$instanceId])) {
181  $driverClass = self::validateDriverClass(self::getDriverClass($driver));
182 
183  if (\class_exists($driverClass)) {
184  $configClass = $driverClass::getConfigClass();
185  self::$instances[$instanceId] = new $driverClass(new $configClass($config->toArray()), $instanceId);
186  self::$instances[$instanceId]->setEventManager(EventManager::getInstance());
187  } else {
188  throw new PhpfastcacheDriverNotFoundException(sprintf('The driver "%s" does not exists', $driver));
189  }
190  }
191 
192  return self::$instances[$instanceId];
193  }
194 
202  protected static function validateConfig(?ConfigurationOptionInterface $config): ConfigurationOption
203  {
204  if ($config === null) {
205  $config = self::getDefaultConfig();
206  } else {
207  if (!($config instanceof ConfigurationOption)) {
208  throw new PhpfastcacheInvalidArgumentException(\sprintf('Unsupported config type: %s', \gettype($config)));
209  }
210  }
211 
212  return $config;
213  }
214 
220  public static function getDefaultConfig(): ConfigurationOptionInterface
221  {
222  return self::$config ?: self::$config = new ConfigurationOption();
223  }
224 
229  public static function standardizeDriverName(string $driverName): string
230  {
231  return \ucfirst(\strtolower(\trim($driverName)));
232  }
233 
239  protected static function validateDriverClass(string $driverClass): string
240  {
241  if (!\is_a($driverClass, ExtendedCacheItemPoolInterface::class, true)) {
242  throw new PhpfastcacheDriverException(
243  \sprintf(
244  'Class "%s" does not implement "%s"',
245  $driverClass,
246  ExtendedCacheItemPoolInterface::class
247  )
248  );
249  }
250  return $driverClass;
251  }
252 
257  public static function getDriverClass(string $driverName): string
258  {
259  if (!empty(self::$driverCustoms[$driverName])) {
260  $driverClass = self::$driverCustoms[$driverName];
261  } else {
262  if (!empty(self::$driverOverrides[$driverName])) {
263  $driverClass = self::$driverOverrides[$driverName];
264  } else {
265  $driverClass = self::getNamespacePath() . $driverName . '\Driver';
266  }
267  }
268 
269  return $driverClass;
270  }
271 
275  public static function getNamespacePath(): string
276  {
277  return self::$namespacePath ?: self::getDefaultNamespacePath();
278  }
279 
283  public static function getDefaultNamespacePath(): string
284  {
285  return self::CORE_DRIVER_NAMESPACE;
286  }
287 
291  public static function clearInstances(): bool
292  {
293  self::$instances = [];
294 
295  \gc_collect_cycles();
296  return !\count(self::$instances);
297  }
298 
304  public static function clearInstance(ExtendedCacheItemPoolInterface $cachePoolInstance): bool
305  {
306  $found = false;
307  self::$instances = \array_filter(
308  \array_map(
309  static function (ExtendedCacheItemPoolInterface $cachePool) use ($cachePoolInstance, &$found) {
310  if (\spl_object_hash($cachePool) === \spl_object_hash($cachePoolInstance)) {
311  $found = true;
312  return null;
313  }
314  return $cachePool;
315  },
316  self::$instances
317  )
318  );
319 
320  return $found;
321  }
322 
326  public static function setDefaultConfig(ConfigurationOption $config): void
327  {
329  }
330 
339  public static function addCustomDriver(string $driverName, string $className): void
340  {
341  $driverName = self::standardizeDriverName($driverName);
342 
343  if (empty($driverName)) {
344  throw new PhpfastcacheInvalidArgumentException("Can't add a custom driver because its name is empty");
345  }
346 
347  if (!\class_exists($className)) {
349  \sprintf("Can't add '%s' because the class '%s' does not exists", $driverName, $className)
350  );
351  }
352 
353  if (!empty(self::$driverCustoms[$driverName])) {
354  throw new PhpfastcacheLogicException(\sprintf("Driver '%s' has been already added", $driverName));
355  }
356 
357  if (\in_array($driverName, self::getDriverList(), true)) {
358  throw new PhpfastcacheLogicException(\sprintf("Driver '%s' is already a part of the PhpFastCache core", $driverName));
359  }
360 
361  self::$driverCustoms[$driverName] = $className;
362  }
363 
372  public static function getDriverList(bool $FQCNAsKey = false): array
373  {
374  static $driverList;
375 
376  if (self::getDefaultNamespacePath() === self::getNamespacePath()) {
377  if ($driverList === null) {
378  $prefix = self::CORE_DRIVER_NAMESPACE;
379  $classMap = self::createClassMap(__DIR__ . '/Drivers');
380  $driverList = [];
381 
382  foreach ($classMap as $class => $file) {
383  $driverList[] = \str_replace($prefix, '', \substr($class, 0, \strrpos($class, '\\')));
384  }
385 
386  $driverList = \array_values(\array_unique($driverList));
387  }
388 
389  $driverList = \array_merge($driverList, \array_keys(self::$driverCustoms));
390 
391  if ($FQCNAsKey) {
392  $realDriverList = [];
393  foreach ($driverList as $driverName) {
394  $realDriverList[self::getDriverClass($driverName)] = $driverName;
395  }
396  $driverList = $realDriverList;
397  }
398 
399  \asort($driverList);
400 
401  return $driverList;
402  }
403 
404  throw new PhpfastcacheUnsupportedOperationException('Cannot get the driver list if the default namespace path has changed.');
405  }
406 
413  public static function removeCustomDriver(string $driverName): void
414  {
415  $driverName = self::standardizeDriverName($driverName);
416 
417  if (empty($driverName)) {
418  throw new PhpfastcacheInvalidArgumentException("Can't remove a custom driver because its name is empty");
419  }
420 
421  if (!isset(self::$driverCustoms[$driverName])) {
422  throw new PhpfastcacheLogicException(\sprintf("Driver '%s' does not exists", $driverName));
423  }
424 
425  unset(self::$driverCustoms[$driverName]);
426  }
427 
436  public static function addCoreDriverOverride(string $driverName, string $className): void
437  {
438  $driverName = self::standardizeDriverName($driverName);
439 
440  if (empty($driverName)) {
441  throw new PhpfastcacheInvalidArgumentException("Can't add a core driver override because its name is empty");
442  }
443 
444  if (!\class_exists($className)) {
446  \sprintf("Can't override '%s' because the class '%s' does not exists", $driverName, $className)
447  );
448  }
449 
450  if (!empty(self::$driverOverrides[$driverName])) {
451  throw new PhpfastcacheLogicException(\sprintf("Driver '%s' has been already overridden", $driverName));
452  }
453 
454  if (!\in_array($driverName, self::getDriverList(), true)) {
455  throw new PhpfastcacheLogicException(\sprintf("Driver '%s' can't be overridden since its not a part of the PhpFastCache core", $driverName));
456  }
457 
458  if (!\is_subclass_of($className, self::CORE_DRIVER_NAMESPACE . $driverName . '\\Driver', true)) {
459  throw new PhpfastcacheLogicException(
460  \sprintf(
461  "Can't override '%s' because the class '%s' MUST extend '%s'",
462  $driverName,
463  $className,
464  self::CORE_DRIVER_NAMESPACE . $driverName . '\\Driver'
465  )
466  );
467  }
468 
469  self::$driverOverrides[$driverName] = $className;
470  }
471 
478  public static function removeCoreDriverOverride(string $driverName): void
479  {
480  $driverName = self::standardizeDriverName($driverName);
481 
482  if (empty($driverName)) {
483  throw new PhpfastcacheInvalidArgumentException("Can't remove a core driver override because its name is empty");
484  }
485 
486  if (!isset(self::$driverOverrides[$driverName])) {
487  throw new PhpfastcacheLogicException(\sprintf("Driver '%s' were not overridden", $driverName));
488  }
489 
490  unset(self::$driverOverrides[$driverName]);
491  }
492 }
static addCoreDriverOverride(string $driverName, string $className)
static __callStatic(string $name, array $arguments)
static removeCustomDriver(string $driverName)
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
static getInstanceById(string $instanceId)
__construct()
CacheManager constructor.
static setDefaultConfig(ConfigurationOption $config)
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is void
Definition: LICENSE.txt:215
static removeCoreDriverOverride(string $driverName)
$options
Elgg admin footer.
Definition: footer.php:6
static clearInstance(ExtendedCacheItemPoolInterface $cachePoolInstance)
$class
Definition: summary.php:44
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
static getInstances()
Return the list of instances.
static & getInternalInstances()
This method is intended for internal use only and should not be used for any external development use...
static addCustomDriver(string $driverName, string $className)
static getInstance(string $driver,?ConfigurationOptionInterface $config=null,?string $instanceId=null)
static validateDriverClass(string $driverClass)
static standardizeDriverName(string $driverName)
static getDriverClass(string $driverName)
static getDriverList(bool $FQCNAsKey=false)
Return the list of available drivers Capitalized with optional FQCN as key.
static validateConfig(?ConfigurationOptionInterface $config)