| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace Magium\Configuration\Config; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use Interop\Container\ContainerInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use Magium\Configuration\Config\Storage\CallbackInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use Magium\Configuration\Config\Storage\StorageInterface as ConfigurationStorageInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use Magium\Configuration\Container\GenericContainer; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use Magium\Configuration\File\AdapterInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use Magium\Configuration\File\Configuration\ConfigurationFileRepository; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use Magium\Configuration\File\Configuration\UnsupportedFileTypeException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | use Magium\Configuration\File\InvalidFileException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | use Magium\Configuration\InvalidConfigurationException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | use Zend\Cache\Storage\StorageInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | class Builder implements BuilderInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |     protected $repository; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     protected $cache; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |     protected $container; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     protected $hashAlgo; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |     protected $storage; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 | 20 |  |     public function __construct( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |         StorageInterface $cache, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |         ConfigurationStorageInterface $storage, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |         ConfigurationFileRepository $repository, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |         ContainerInterface $container = null, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |         $hashAlgo = 'sha1' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 | 20 |  |         $this->cache = $cache; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 | 20 |  |         $this->storage = $storage; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 | 20 |  |         $this->hashAlgo = $hashAlgo; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 | 20 |  |         $this->repository = $repository; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 | 20 |  |         $this->container = $container; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 | 20 |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 39 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 40 | 3 |  |     public function getConfigurationRepository() | 
            
                                                                        
                            
            
                                    
            
            
                | 41 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 42 | 3 |  |         return $this->repository; | 
            
                                                                        
                            
            
                                    
            
            
                | 43 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |     public function getStorage() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |         return $this->storage; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 | 6 |  |     public function setValue($path, $value, $requestedContext = ConfigurationRepository::CONTEXT_DEFAULT) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 | 6 |  |         $parts = explode('/', $path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 | 6 |  |         if (count($parts) != 3) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 | 3 |  |             throw new InvalidArgumentException('Path must be in the structure of section/group/element'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 | 3 |  |         $merged = $this->getMergedStructure(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 | 3 |  |         $merged->registerXPathNamespace('s', 'http://www.magiumlib.com/Configuration'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 | 3 |  |         $xpath = sprintf('//s:section[@identifier="%s"]/s:group[@identifier="%s"]/s:element[@identifier="%s"]/s:permittedValues/s:value', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 | 3 |  |             $parts[0], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 | 3 |  |             $parts[1], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 | 3 |  |             $parts[2] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 | 3 |  |         $elements = $merged->xpath($xpath); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 | 3 |  |         if ($elements) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 | 3 |  |             $check = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 | 3 |  |             foreach ($elements as $element) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 | 3 |  |                 $check[] = (string)$element; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 | 3 |  |             if (!in_array($value, $check)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 | 1 |  |                 throw new InvalidArgumentException('The value must be one of: ' . implode(', ', $check)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 | 2 |  |         return $this->getStorage()->setValue($path, $value, $requestedContext); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 | 8 |  |     public function getContainer() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 | 8 |  |         if (!$this->container instanceof ContainerInterface) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 | 8 |  |             $this->container = new GenericContainer(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 | 8 |  |             $this->container->set($this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 | 8 |  |             $this->container->set($this->cache); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 | 8 |  |             $this->container->set($this->repository); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 | 8 |  |             $this->container->set($this->storage); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 | 8 |  |         return $this->container; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |      * Retrieves a list of files that have been registered | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |      * @return ConfigurationFileRepository | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 | 5 |  |     public function getRegisteredConfigurationFiles() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 | 5 |  |         return $this->repository; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |      * @param ConfigurationRepository|null $config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |      * @return ConfigurationRepository | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |      * @throws InvalidConfigurationLocationException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |      * @throws InvalidFileException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |      * @throws | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 | 6 |  |     public function build($context = ConfigurationRepository::CONTEXT_DEFAULT, ConfigInterface $config = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 | 6 |  |         if (!$config instanceof ConfigurationRepository) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 | 6 |  |             $config = new ConfigurationRepository('<config />'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 | 6 |  |         $structure = $this->getMergedStructure(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 | 4 |  |         if (!$structure instanceof MergedStructure) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 | 1 |  |             throw new InvalidConfigurationException('No configuration files provided'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 | 3 |  |         $this->getContainer()->set($config); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 | 3 |  |         $this->getContainer()->set($structure); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 | 3 |  |         $this->buildConfigurationObject($structure, $config, $context); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 | 3 |  |         return $config; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |      * @return \SimpleXMLElement | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |      * @throws InvalidFileException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |      * @throws MissingConfigurationException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 | 6 |  |     public function getMergedStructure() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 | 6 |  |         $files = $this->getRegisteredConfigurationFiles(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 | 6 |  |         if (!count($files)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 | 1 |  |             throw new MissingConfigurationException('No configuration files have been provided.  Please add via registerConfigurationFile()'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 | 5 |  |         $structure = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 | 5 |  |         foreach ($files as $file) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 | 4 |  |             if (!$file instanceof AdapterInterface) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |                 throw new InvalidFileException('Configuration file object must implement ' . AdapterInterface::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 | 4 |  |             $simpleXml = $file->toXml(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 | 4 |  |             if (!$structure instanceof MergedStructure) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 | 4 |  |                 $structure = $simpleXml; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 | 4 |  |                 $this->mergeStructure($structure, $simpleXml); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 | 4 |  |         return $structure; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 | 6 |  |     protected function executeCallback($callbackString, $value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 | 6 |  |         if (function_exists($callbackString)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 | 1 |  |             $execute = $callbackString; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 | 5 |  |             $container = $this->getContainer(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |             try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 | 5 |  |                 $callbackObject = $this->getContainer()->get($callbackString); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 | 3 |  |                 if (!$callbackObject instanceof CallbackInterface) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 | 1 |  |                     throw new UncallableCallbackException('Callback must implement ' . CallbackInterface::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |                 $execute = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 | 2 |  |                     $callbackObject, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 | 2 |  |                     'filter' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |                 ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 | 2 |  |                 if (!is_callable($execute)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 | 2 |  |                     throw new UncallableCallbackException('Unable to execute callback: ' . $callbackString); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 | 3 |  |             } catch (\Exception $e) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |                 /* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |                  * This is slightly a hack but the purpose is to throw the insufficient exception if it's an actual | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |                  * problem with the generic container we provide. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |                  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 | 3 |  |                 if ($container instanceof GenericContainer && !$e instanceof UncallableCallbackException) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 | 2 |  |                     throw new InsufficientContainerException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |                         'You are using functionality that requires either a fully functional DI Container or Service Locator.  ' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 | 2 |  |                         . 'The container, or container adapter, must implement Interop\Container\ContainerInterface.' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 | 1 |  |                 throw $e; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 | 3 |  |         return call_user_func($execute, $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |      * @param \SimpleXMLElement $structure The object representing the merged configuration structure | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |      * @param \SimpleXmlElement $config An empty config object to be populated | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |      * @return ConfigurationRepository The resulting configuration object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 | 14 |  |     public function buildConfigurationObject( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |         MergedStructure $structure, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |         ConfigInterface $config, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |         $context = ConfigurationRepository::CONTEXT_DEFAULT | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 | 14 |  |         $structure->registerXPathNamespace('s', 'http://www.magiumlib.com/Configuration'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 | 14 |  |         $elements = $structure->xpath('/*/s:section/s:group/s:element'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 | 14 |  |         foreach ($elements as $element) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 | 14 |  |             if ($element instanceof MergedStructure) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 | 14 |  |                 $elementId = $element['identifier']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 | 14 |  |                 $group = $element->xpath('..')[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 | 14 |  |                 $groupId = $group['identifier']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 | 14 |  |                 $section = $group->xpath('..')[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 | 14 |  |                 $sectionId = $section['identifier']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 | 14 |  |                 $configPath = sprintf('%s/%s/%s', $sectionId, $groupId, $elementId); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 | 14 |  |                 $value = $this->storage->getValue($configPath, $context); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 | 14 |  |                 if (!$value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 | 7 |  |                     $xpath = sprintf('/*/s:section[@identifier="%s"]/s:group[@identifier="%s"]/s:element[@identifier="%s"]/s:value', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |                         $sectionId, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |                         $groupId, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |                         $elementId | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 | 7 |  |                     $result = $structure->xpath($xpath); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 | 7 |  |                     if (!empty($result)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 | 7 |  |                         $value = trim((string)$result[0]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 | 14 |  |                 if (isset($element['callbackFromStorage'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 | 6 |  |                     $callbackString = (string)$element['callbackFromStorage']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 | 6 |  |                     $value = $this->executeCallback($callbackString, $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 | 11 |  |                 if ($value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 | 11 |  |                     $config->$sectionId->$groupId->$elementId = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 | 11 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |  | 
            
                                                                                                            
                            
            
                                                                    
                                                                                                        
            
            
                | 246 | 4 | View Code Duplication |     public function mergeStructure(MergedStructure $base, \SimpleXMLElement $new) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 | 4 |  |         $base->registerXPathNamespace('s', 'http://www.magiumlib.com/Configuration'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 | 4 |  |         foreach ($new as $item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 | 4 |  |             if ($item instanceof \SimpleXMLElement) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 | 4 |  |                 $xpath = sprintf('/*/s:section[@identifier="%s"]', $item['identifier']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 | 4 |  |                 $sectionExists = $base->xpath($xpath); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 | 4 |  |                 if (!empty($sectionExists) && $sectionExists[0] instanceof \SimpleXMLElement) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 | 3 |  |                     $section = $sectionExists[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 | 1 |  |                     $section = $base->addChild('section'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 | 4 |  |                 foreach ($item->attributes() as $name => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 | 4 |  |                     $section[$name] = (string)$value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 | 4 |  |                 if ($item->group) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 | 4 |  |                     $this->mergeGroup($section, $item->group); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 | 4 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |  | 
            
                                                                                                            
                            
            
                                                                    
                                                                                                        
            
            
                | 270 | 4 | View Code Duplication |     protected function mergeGroup(\SimpleXMLElement $section, \SimpleXMLElement $newGroups) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 | 4 |  |         $section->registerXPathNamespace('s', 'http://www.magiumlib.com/Configuration'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 | 4 |  |         foreach ($newGroups as $newGroup) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 | 4 |  |             if ($newGroup instanceof \SimpleXMLElement) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 | 4 |  |                 $xpath = sprintf('./s:group[@identifier="%s"]', $newGroup['identifier']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 | 4 |  |                 $groupExists = $section->xpath($xpath); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 | 4 |  |                 if (!empty($groupExists) && $groupExists[0] instanceof \SimpleXMLElement) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 | 3 |  |                     $group = $groupExists[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 | 2 |  |                     $group = $section->addChild('group'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 | 4 |  |                 foreach ($newGroup->attributes() as $name => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 | 4 |  |                     $group[$name] = (string)$value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 | 4 |  |                 $this->mergeElements($group, $newGroup->element); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 | 4 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 | 4 |  |     protected function mergeElements(\SimpleXMLElement $group, \SimpleXMLElement $newElements) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 | 4 |  |         $group->registerXPathNamespace('s', 'http://www.magiumlib.com/Configuration'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 | 4 |  |         foreach ($newElements as $newElement) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 | 4 |  |             if ($newElement instanceof \SimpleXMLElement) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 | 4 |  |                 $xpath = sprintf('./s:element[@identifier="%s"]', $newElement['identifier']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 | 4 |  |                 $elementExists = $group->xpath($xpath); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 | 4 |  |                 if (!empty($elementExists) && $elementExists[0] instanceof \SimpleXMLElement) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 | 1 |  |                     $element = $elementExists[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 | 4 |  |                     $element = $group->addChild('element'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 | 4 |  |                 foreach ($newElement->attributes() as $name => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 | 4 |  |                     $element[$name] = (string)$value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 | 4 |  |                 foreach ($newElement->children() as $key => $item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 | 4 |  |                     $element->$key = (string)$item; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 | 4 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 314 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 315 |  |  |  | 
            
                        
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: