| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | namespace W2w\Laravel\Apie\Services; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use Illuminate\Container\Container; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use Illuminate\Http\Request; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use W2w\Laravel\Apie\Exceptions\ApieContextMissingException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use W2w\Laravel\Apie\Plugins\Illuminate\IlluminatePlugin; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use W2w\Lib\Apie\Apie; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use W2w\Lib\Apie\Exceptions\BadConfigurationException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | use W2w\Lib\Apie\Plugins\FakeAnnotations\FakeAnnotationsPlugin; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | final class ApieContext | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |     private $contextKey = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     private $container; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     private $apie; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     private $config; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     private $contexts; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     private $instantiatedContexts; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     public function __construct(Container $container, Apie $apie, array $config, array& $contexts) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |         $this->container = $container; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |         $this->apie = $apie; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |         $this->config = $config; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |         $this->contexts = &$contexts; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 35 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |     public function getApie(): Apie | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |         return $this->apie; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     public function getActiveContext(): ApieContext | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |         if ($this->container->bound(Request::class)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |             /** @var Request $request */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |             $request = $this->container->get(Request::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |             $contexts = $request->route('context'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |             if (is_array($contexts)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |                 $context = $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |                 while ($contexts && $context) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |                     $key = array_shift($contexts); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |                     $context = $context->getContext($key); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |                 if ($context) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |                     return $context; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |     public function getContext(string $context): ApieContext | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         // done for potential file read exploits | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         if (!preg_match('/^[a-z0-9]+$/i', $context)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |             throw new BadConfigurationException('Context "' . $context . '" is not a valid context name!'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |         if (!isset($this->instantiatedContexts[$context])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |             $this->instantiatedContexts[$context] = $this->createContext($context); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         return $this->instantiatedContexts[$context]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |     private function createContext(string $context): ApieContext | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |         if (!isset($this->contexts[$context])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |             throw new ApieContextMissingException($context); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |         $plugins = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |         foreach ($this->contexts[$context]['plugins'] as $plugin) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |             $plugins[] = $this->container->make($plugin); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |         if (!empty($this->contexts[$context]['resource-config'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |             $plugins[] = new FakeAnnotationsPlugin($this->contexts[$context]['resource-config']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         $plugins[] = new IlluminatePlugin($this->container, $this->contexts[$context]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         $apie = $this->apie->createContext($plugins); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         $apieContext = new ApieContext( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |             $this->container, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |             $apie, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |             $this->contexts[$context], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |             $this->contexts[$context]['contexts'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         $key = $this->contextKey; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |         $key[] = $context; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         $apieContext->contextKey = $key; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |         return $apieContext; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |     public function getConfig(string $key) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |         return $this->config[$key]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |     public function getContextKey(): array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |         return $this->contextKey; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |      * @return ApieContext[] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |     public function allContexts(): array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         $res = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |         foreach (array_keys($this->contexts) as $context) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |             $res[$context] = $this->getContext($context); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |         return $res; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 120 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 121 |  |  |  |