[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/php-ai-client/third-party/Http/Discovery/ -> ClassDiscovery.php (source)

   1  <?php
   2  
   3  namespace WordPress\AiClientDependencies\Http\Discovery;
   4  
   5  use WordPress\AiClientDependencies\Http\Discovery\Exception\ClassInstantiationFailedException;
   6  use WordPress\AiClientDependencies\Http\Discovery\Exception\DiscoveryFailedException;
   7  use WordPress\AiClientDependencies\Http\Discovery\Exception\NoCandidateFoundException;
   8  use WordPress\AiClientDependencies\Http\Discovery\Exception\StrategyUnavailableException;
   9  use WordPress\AiClientDependencies\Http\Discovery\Strategy\DiscoveryStrategy;
  10  /**
  11   * Registry that based find results on class existence.
  12   *
  13   * @author David de Boer <david@ddeboer.nl>
  14   * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
  15   * @author Tobias Nyholm <tobias.nyholm@gmail.com>
  16   */
  17  abstract class ClassDiscovery
  18  {
  19      /**
  20       * A list of strategies to find classes.
  21       *
  22       * @var DiscoveryStrategy[]
  23       */
  24      private static $strategies = [Strategy\GeneratedDiscoveryStrategy::class, Strategy\CommonClassesStrategy::class, Strategy\CommonPsr17ClassesStrategy::class, Strategy\PuliBetaStrategy::class];
  25      private static $deprecatedStrategies = [Strategy\PuliBetaStrategy::class => \true];
  26      /**
  27       * Discovery cache to make the second time we use discovery faster.
  28       *
  29       * @var array
  30       */
  31      private static $cache = [];
  32      /**
  33       * Finds a class.
  34       *
  35       * @param string $type
  36       *
  37       * @return string|\Closure
  38       *
  39       * @throws DiscoveryFailedException
  40       */
  41      protected static function findOneByType($type)
  42      {
  43          // Look in the cache
  44          if (null !== $class = self::getFromCache($type)) {
  45              return $class;
  46          }
  47          static $skipStrategy;
  48          $skipStrategy ?? $skipStrategy = self::safeClassExists(Strategy\GeneratedDiscoveryStrategy::class) ? \false : Strategy\GeneratedDiscoveryStrategy::class;
  49          $exceptions = [];
  50          foreach (self::$strategies as $strategy) {
  51              if ($skipStrategy === $strategy) {
  52                  continue;
  53              }
  54              try {
  55                  $candidates = $strategy::getCandidates($type);
  56              } catch (StrategyUnavailableException $e) {
  57                  if (!isset(self::$deprecatedStrategies[$strategy])) {
  58                      $exceptions[] = $e;
  59                  }
  60                  continue;
  61              }
  62              foreach ($candidates as $candidate) {
  63                  if (isset($candidate['condition'])) {
  64                      if (!self::evaluateCondition($candidate['condition'])) {
  65                          continue;
  66                      }
  67                  }
  68                  // save the result for later use
  69                  self::storeInCache($type, $candidate);
  70                  return $candidate['class'];
  71              }
  72              $exceptions[] = new NoCandidateFoundException($strategy, $candidates);
  73          }
  74          throw DiscoveryFailedException::create($exceptions);
  75      }
  76      /**
  77       * Get a value from cache.
  78       *
  79       * @param string $type
  80       *
  81       * @return string|null
  82       */
  83      private static function getFromCache($type)
  84      {
  85          if (!isset(self::$cache[$type])) {
  86              return;
  87          }
  88          $candidate = self::$cache[$type];
  89          if (isset($candidate['condition'])) {
  90              if (!self::evaluateCondition($candidate['condition'])) {
  91                  return;
  92              }
  93          }
  94          return $candidate['class'];
  95      }
  96      /**
  97       * Store a value in cache.
  98       *
  99       * @param string $type
 100       * @param string $class
 101       */
 102      private static function storeInCache($type, $class)
 103      {
 104          self::$cache[$type] = $class;
 105      }
 106      /**
 107       * Set new strategies and clear the cache.
 108       *
 109       * @param string[] $strategies list of fully qualified class names that implement DiscoveryStrategy
 110       */
 111      public static function setStrategies(array $strategies)
 112      {
 113          self::$strategies = $strategies;
 114          self::clearCache();
 115      }
 116      /**
 117       * Returns the currently configured discovery strategies as fully qualified class names.
 118       *
 119       * @return string[]
 120       */
 121      public static function getStrategies(): iterable
 122      {
 123          return self::$strategies;
 124      }
 125      /**
 126       * Append a strategy at the end of the strategy queue.
 127       *
 128       * @param string $strategy Fully qualified class name of a DiscoveryStrategy
 129       */
 130      public static function appendStrategy($strategy)
 131      {
 132          self::$strategies[] = $strategy;
 133          self::clearCache();
 134      }
 135      /**
 136       * Prepend a strategy at the beginning of the strategy queue.
 137       *
 138       * @param string $strategy Fully qualified class name to a DiscoveryStrategy
 139       */
 140      public static function prependStrategy($strategy)
 141      {
 142          array_unshift(self::$strategies, $strategy);
 143          self::clearCache();
 144      }
 145      public static function clearCache()
 146      {
 147          self::$cache = [];
 148      }
 149      /**
 150       * Evaluates conditions to boolean.
 151       *
 152       * @return bool
 153       */
 154      protected static function evaluateCondition($condition)
 155      {
 156          if (is_string($condition)) {
 157              // Should be extended for functions, extensions???
 158              return self::safeClassExists($condition);
 159          }
 160          if (is_callable($condition)) {
 161              return (bool) $condition();
 162          }
 163          if (is_bool($condition)) {
 164              return $condition;
 165          }
 166          if (is_array($condition)) {
 167              foreach ($condition as $c) {
 168                  if (\false === static::evaluateCondition($c)) {
 169                      // Immediately stop execution if the condition is false
 170                      return \false;
 171                  }
 172              }
 173              return \true;
 174          }
 175          return \false;
 176      }
 177      /**
 178       * Get an instance of the $class.
 179       *
 180       * @param string|\Closure $class a FQCN of a class or a closure that instantiate the class
 181       *
 182       * @return object
 183       *
 184       * @throws ClassInstantiationFailedException
 185       */
 186      protected static function instantiateClass($class)
 187      {
 188          try {
 189              if (is_string($class)) {
 190                  return new $class();
 191              }
 192              if (is_callable($class)) {
 193                  return $class();
 194              }
 195          } catch (\Exception $e) {
 196              throw new ClassInstantiationFailedException('Unexpected exception when instantiating class.', 0, $e);
 197          }
 198          throw new ClassInstantiationFailedException('Could not instantiate class because parameter is neither a callable nor a string');
 199      }
 200      /**
 201       * We need a "safe" version of PHP's "class_exists" because Magento has a bug
 202       * (or they call it a "feature"). Magento is throwing an exception if you do class_exists()
 203       * on a class that ends with "Factory" and if that file does not exits.
 204       *
 205       * This function catches all potential exceptions and makes sure to always return a boolean.
 206       *
 207       * @param string $class
 208       *
 209       * @return bool
 210       */
 211      public static function safeClassExists($class)
 212      {
 213          try {
 214              return class_exists($class) || interface_exists($class);
 215          } catch (\Exception $e) {
 216              return \false;
 217          }
 218      }
 219  }


Generated : Sat Jun 13 09:38:55 2026 Cross-referenced by PHPXref