| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | declare(strict_types=1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | namespace Northwoods\Container\Zend; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use ArrayObject; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use Auryn\Injector; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use Northwoods\Container\ContainerException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use Northwoods\Container\InjectorConfig; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use Psr\Container\ContainerInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | class Config implements InjectorConfig | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |     /** @var array */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |     private $config; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 | 235 |  |     public function __construct(array $config) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 | 235 |  |         $this->config = $config; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 | 235 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |      * Configure the injector using Zend Service Manager format | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 | 235 |  |     public function apply(Injector $injector): void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 | 235 |  |         $dependencies = $this->config['dependencies'] ?? []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |         // Define the "config" service, accounting for the fact that Auryn | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |         // requires all returns are objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 | 235 |  |         $dependencies['services']['config'] = new ArrayObject($this->config, ArrayObject::ARRAY_AS_PROPS); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 | 235 |  |         $this->injectServices($injector, $dependencies); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 | 235 |  |         $this->injectFactories($injector, $dependencies); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 | 235 |  |         $this->injectInvokables($injector, $dependencies); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 | 235 |  |         $this->injectAliases($injector, $dependencies); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 | 235 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                                                    
                                                                                                        
            
            
                | 39 | 235 | View Code Duplication |     private function injectAliases(Injector $injector, array $dependencies): void | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 | 235 |  |         $aliases = $dependencies['aliases'] ?? []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 | 235 |  |         foreach ($aliases as $alias => $target) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |             // Standard Auryn aliases do not work when chained. Work around by | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |             // lazily fetching the shared target from the container. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 | 132 |  |             $injector->share($alias)->share($target)->delegate($alias, $this->makeContainerGet($target)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 | 235 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 | 235 |  |     private function injectFactories(Injector $injector, array $dependencies): void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 | 235 |  |         $factories = $dependencies['factories'] ?? []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 | 235 |  |         foreach ($factories as $name => $factory) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 | 150 |  |             $delegate = $this->makeFactory($injector, $name, $factory); | 
            
                                                                                                            
                            
            
                                                                    
                                                                                                        
            
            
                | 54 | 150 | View Code Duplication |             if (isset($dependencies['delegators'][$name])) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 | 96 |  |                 $delegate = $this->makeDelegator( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 | 96 |  |                     $injector, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 | 96 |  |                     $name, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 | 96 |  |                     $delegate, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 | 96 |  |                     $dependencies['delegators'][$name] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 | 150 |  |             $injector->share($name)->delegate($name, $delegate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 | 235 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 | 235 |  |     private function injectInvokables(Injector $injector, array $dependencies): void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 | 235 |  |         $invokables = $dependencies['invokables'] ?? []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 | 235 |  |         foreach ($invokables as $alias => $invokable) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 | 77 |  |             if (is_string($alias) && $alias !== $invokable) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 | 29 |  |                 $injector->alias($alias, $invokable); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 | 77 |  |             $delegate = $this->makeLazyInvokable($invokable, $invokable); | 
            
                                                                                                            
                            
            
                                                                    
                                                                                                        
            
            
                | 74 | 77 | View Code Duplication |             if (isset($dependencies['delegators'][$invokable])) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 | 49 |  |                 $delegate = $this->makeDelegator( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 | 49 |  |                     $injector, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 | 49 |  |                     $invokable, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 | 49 |  |                     $delegate, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 | 49 |  |                     $dependencies['delegators'][$invokable] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 | 77 |  |             $injector->share($invokable)->delegate($invokable, $delegate); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 | 235 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |  | 
            
                                                                                                            
                            
            
                                                                    
                                                                                                        
            
            
                | 86 | 235 | View Code Duplication |     private function injectServices(Injector $injector, array $dependencies): void | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 | 235 |  |         $services = $dependencies['services'] ?? []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 | 235 |  |         foreach ($services as $name => $service) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 | 235 |  |             $injector->share($name)->delegate($name, $this->makeIdentity($service)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 | 235 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     private function makeDelegator(Injector $injector, string $name, callable $callback, array $delegators): callable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 | 145 |  |         return /** @return object */ function () use ($injector, $name, $callback, $delegators) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 | 145 |  |             foreach ($delegators as $delegator) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 | 127 |  |                 $container = $injector->make(ContainerInterface::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 | 127 |  |                 $delegator = $this->makeInvokable($name, $delegator); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 | 73 |  |                 $instance = $delegator($container, $name, $callback); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 | 53 |  |                 $callback = $this->makeIdentity($instance); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 | 71 |  |             return $instance ?? $callback(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 | 145 |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |     private function makeContainerGet(string $name): callable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 | 132 |  |         return /** @return object */ static function (ContainerInterface $container) use ($name) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 | 132 |  |             return $container->get($name); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 | 132 |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |      * @param string|callable $factory | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |     private function makeFactory(Injector $injector, string $name, $factory): callable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 | 150 |  |         return /** @return object */ function () use ($injector, $name, $factory) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 | 102 |  |             $container = $injector->make(ContainerInterface::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 | 102 |  |             $factory = $this->makeInvokable($name, $factory); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 | 78 |  |             return $factory($container, $name); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 | 150 |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |      * @param object $object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |     private function makeIdentity($object): callable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 | 235 |  |         return /** @return object */ static function () use ($object) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 | 27 |  |             return $object; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 | 235 |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |      * @param string|callable $factory | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |      * @throws ContainerException if the factory cannot be made invokable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 | 223 |  |     private function makeInvokable(string $name, $factory): callable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 | 223 |  |         if (is_callable($factory)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 | 78 |  |             return $factory; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 | 169 |  |         if ($this->isValidClass($factory)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 | 141 |  |             $factory = new $factory(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 | 147 |  |         if (is_callable($factory) === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 | 62 |  |             throw ContainerException::expectedInvokable($name); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 | 99 |  |         return $factory; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |      * @param string|callable $factory | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |     private function makeLazyInvokable(string $name, $factory): callable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 | 77 |  |         return /** @return callable */ function () use ($name, $factory) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 | 47 |  |             return $this->makeInvokable($name, $factory); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 | 77 |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |      * @param mixed $factory | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 169 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 170 | 169 |  |     private function isValidClass($factory): bool | 
            
                                                        
            
                                    
            
            
                | 171 |  |  |     { | 
            
                                                        
            
                                    
            
            
                | 172 | 169 |  |         return is_string($factory) && class_exists($factory); | 
            
                                                        
            
                                    
            
            
                | 173 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 174 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 175 |  |  |  | 
            
                        
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.