| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 |   | 
        
           |  |  | 3 | declare(strict_types=1);
 | 
        
           |  |  | 4 |   | 
        
           |  |  | 5 | namespace DI\Definition\Source;
 | 
        
           |  |  | 6 |   | 
        
           |  |  | 7 | use DI\Definition\Definition;
 | 
        
           |  |  | 8 |   | 
        
           |  |  | 9 | /**
 | 
        
           |  |  | 10 |  * Reads DI definitions from a PHP array.
 | 
        
           |  |  | 11 |  *
 | 
        
           |  |  | 12 |  * @author Matthieu Napoli <matthieu@mnapoli.fr>
 | 
        
           |  |  | 13 |  */
 | 
        
           |  |  | 14 | class DefinitionArray implements DefinitionSource, MutableDefinitionSource
 | 
        
           |  |  | 15 | {
 | 
        
           |  |  | 16 |     public const WILDCARD = '*';
 | 
        
           |  |  | 17 |     /**
 | 
        
           |  |  | 18 |      * Matches anything except "\".
 | 
        
           |  |  | 19 |      */
 | 
        
           |  |  | 20 |     private const WILDCARD_PATTERN = '([^\\\\]+)';
 | 
        
           |  |  | 21 |   | 
        
           |  |  | 22 |     /** DI definitions in a PHP array. */
 | 
        
           |  |  | 23 |     private array $definitions;
 | 
        
           |  |  | 24 |   | 
        
           |  |  | 25 |     /** Cache of wildcard definitions. */
 | 
        
           |  |  | 26 |     private ?array $wildcardDefinitions = null;
 | 
        
           |  |  | 27 |   | 
        
           |  |  | 28 |     private DefinitionNormalizer $normalizer;
 | 
        
           |  |  | 29 |   | 
        
           | 1441 | ariadna | 30 |     public function __construct(array $definitions = [], ?Autowiring $autowiring = null)
 | 
        
           | 1 | efrain | 31 |     {
 | 
        
           |  |  | 32 |         if (isset($definitions[0])) {
 | 
        
           |  |  | 33 |             throw new \Exception('The PHP-DI definition is not indexed by an entry name in the definition array');
 | 
        
           |  |  | 34 |         }
 | 
        
           |  |  | 35 |   | 
        
           |  |  | 36 |         $this->definitions = $definitions;
 | 
        
           |  |  | 37 |   | 
        
           |  |  | 38 |         $this->normalizer = new DefinitionNormalizer($autowiring ?: new NoAutowiring);
 | 
        
           |  |  | 39 |     }
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 |     /**
 | 
        
           |  |  | 42 |      * @param array $definitions DI definitions in a PHP array indexed by the definition name.
 | 
        
           |  |  | 43 |      */
 | 
        
           |  |  | 44 |     public function addDefinitions(array $definitions) : void
 | 
        
           |  |  | 45 |     {
 | 
        
           |  |  | 46 |         if (isset($definitions[0])) {
 | 
        
           |  |  | 47 |             throw new \Exception('The PHP-DI definition is not indexed by an entry name in the definition array');
 | 
        
           |  |  | 48 |         }
 | 
        
           |  |  | 49 |   | 
        
           |  |  | 50 |         // The newly added data prevails
 | 
        
           |  |  | 51 |         // "for keys that exist in both arrays, the elements from the left-hand array will be used"
 | 
        
           |  |  | 52 |         $this->definitions = $definitions + $this->definitions;
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 |         // Clear cache
 | 
        
           |  |  | 55 |         $this->wildcardDefinitions = null;
 | 
        
           |  |  | 56 |     }
 | 
        
           |  |  | 57 |   | 
        
           |  |  | 58 |     public function addDefinition(Definition $definition) : void
 | 
        
           |  |  | 59 |     {
 | 
        
           |  |  | 60 |         $this->definitions[$definition->getName()] = $definition;
 | 
        
           |  |  | 61 |   | 
        
           |  |  | 62 |         // Clear cache
 | 
        
           |  |  | 63 |         $this->wildcardDefinitions = null;
 | 
        
           |  |  | 64 |     }
 | 
        
           |  |  | 65 |   | 
        
           |  |  | 66 |     public function getDefinition(string $name) : Definition|null
 | 
        
           |  |  | 67 |     {
 | 
        
           |  |  | 68 |         // Look for the definition by name
 | 
        
           |  |  | 69 |         if (array_key_exists($name, $this->definitions)) {
 | 
        
           |  |  | 70 |             $definition = $this->definitions[$name];
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 |             return $this->normalizer->normalizeRootDefinition($definition, $name);
 | 
        
           |  |  | 73 |         }
 | 
        
           |  |  | 74 |   | 
        
           |  |  | 75 |         // Build the cache of wildcard definitions
 | 
        
           |  |  | 76 |         if ($this->wildcardDefinitions === null) {
 | 
        
           |  |  | 77 |             $this->wildcardDefinitions = [];
 | 
        
           |  |  | 78 |             foreach ($this->definitions as $key => $definition) {
 | 
        
           |  |  | 79 |                 if (str_contains($key, self::WILDCARD)) {
 | 
        
           |  |  | 80 |                     $this->wildcardDefinitions[$key] = $definition;
 | 
        
           |  |  | 81 |                 }
 | 
        
           |  |  | 82 |             }
 | 
        
           |  |  | 83 |         }
 | 
        
           |  |  | 84 |   | 
        
           |  |  | 85 |         // Look in wildcards definitions
 | 
        
           |  |  | 86 |         foreach ($this->wildcardDefinitions as $key => $definition) {
 | 
        
           |  |  | 87 |             // Turn the pattern into a regex
 | 
        
           |  |  | 88 |             $key = preg_quote($key, '#');
 | 
        
           |  |  | 89 |             $key = '#^' . str_replace('\\' . self::WILDCARD, self::WILDCARD_PATTERN, $key) . '#';
 | 
        
           |  |  | 90 |             if (preg_match($key, $name, $matches) === 1) {
 | 
        
           |  |  | 91 |                 array_shift($matches);
 | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 |                 return $this->normalizer->normalizeRootDefinition($definition, $name, $matches);
 | 
        
           |  |  | 94 |             }
 | 
        
           |  |  | 95 |         }
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 |         return null;
 | 
        
           |  |  | 98 |     }
 | 
        
           |  |  | 99 |   | 
        
           |  |  | 100 |     public function getDefinitions() : array
 | 
        
           |  |  | 101 |     {
 | 
        
           |  |  | 102 |         // Return all definitions except wildcard definitions
 | 
        
           |  |  | 103 |         $definitions = [];
 | 
        
           |  |  | 104 |         foreach ($this->definitions as $key => $definition) {
 | 
        
           |  |  | 105 |             if (! str_contains($key, self::WILDCARD)) {
 | 
        
           |  |  | 106 |                 $definitions[$key] = $definition;
 | 
        
           |  |  | 107 |             }
 | 
        
           |  |  | 108 |         }
 | 
        
           |  |  | 109 |   | 
        
           |  |  | 110 |         return $definitions;
 | 
        
           |  |  | 111 |     }
 | 
        
           |  |  | 112 | }
 |