Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Testwork / ServiceContainer / ExtensionManager.php
1 <?php
2
3 /*
4  * This file is part of the Behat Testwork.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Testwork\ServiceContainer;
12
13 use Behat\Testwork\ServiceContainer\Exception\ExtensionInitializationException;
14
15 /**
16  * Manages both default and 3rd-party extensions.
17  *
18  * @author Konstantin Kudryashov <ever.zet@gmail.com>
19  */
20 final class ExtensionManager
21 {
22     /**
23      * @var string
24      */
25     private $extensionsPath;
26     /**
27      * @var Extension[]
28      */
29     private $extensions = array();
30     /**
31      * @var Extension[string]
32      */
33     private $locatedExtensions = array();
34     private $debugInformation = array(
35         'extensions_list' => array()
36     );
37
38     /**
39      * Initializes manager.
40      *
41      * @param Extension[] $extensions     List of default extensions
42      * @param null|string $extensionsPath Base path where to search custom extension files
43      */
44     public function __construct(array $extensions, $extensionsPath = null)
45     {
46         foreach ($extensions as $extension) {
47             $this->extensions[$extension->getConfigKey()] = $extension;
48         }
49
50         $this->extensionsPath = $extensionsPath;
51     }
52
53     /**
54      * Sets path to directory in which manager will try to find extension files.
55      *
56      * @param null|string $path
57      */
58     public function setExtensionsPath($path)
59     {
60         $this->extensionsPath = $path;
61     }
62
63     /**
64      * Activate extension by its locator.
65      *
66      * @param string $locator phar file name, php file name, class name
67      *
68      * @return Extension
69      */
70     public function activateExtension($locator)
71     {
72         $extension = $this->initialize($locator);
73
74         $this->debugInformation['extensions_list'][] = $extension->getConfigKey();
75
76         return $this->extensions[$extension->getConfigKey()] = $extension;
77     }
78
79     /**
80      * Returns specific extension by its name.
81      *
82      * @param string $key
83      *
84      * @return Extension
85      */
86     public function getExtension($key)
87     {
88         return isset($this->extensions[$key]) ? $this->extensions[$key] : null;
89     }
90
91     /**
92      * Returns all available extensions.
93      *
94      * @return Extension[]
95      */
96     public function getExtensions()
97     {
98         return $this->extensions;
99     }
100
101     /**
102      * Returns activated extension names.
103      *
104      * @return array
105      */
106     public function getExtensionClasses()
107     {
108         return array_map('get_class', array_values($this->extensions));
109     }
110
111     /**
112      * Initializes all activated and predefined extensions.
113      */
114     public function initializeExtensions()
115     {
116         foreach ($this->extensions as $extension) {
117             $extension->initialize($this);
118         }
119     }
120
121     /**
122      * Returns array with extensions debug information.
123      *
124      * @return array
125      */
126     public function debugInformation()
127     {
128         return $this->debugInformation;
129     }
130
131     /**
132      * Attempts to guess full extension class from relative.
133      *
134      * @param string $locator
135      *
136      * @return string
137      */
138     private function getFullExtensionClass($locator)
139     {
140         $parts = explode('\\', $locator);
141         $name = preg_replace('/Extension$/', '', end($parts)) . 'Extension';
142
143         return $locator . '\\ServiceContainer\\' . $name;
144     }
145
146     /**
147      * Initializes extension by id.
148      *
149      * @param string $locator
150      *
151      * @return Extension
152      *
153      * @throws ExtensionInitializationException
154      */
155     private function initialize($locator)
156     {
157         if (isset($this->locatedExtensions[$locator])) {
158             return $this->locatedExtensions[$locator];
159         }
160
161         $extension = $this->instantiateExtension($locator);
162         $this->validateExtensionInstance($extension, $locator);
163
164         return $this->locatedExtensions[$locator] = $extension;
165     }
166
167     /**
168      * Instantiates extension from its locator.
169      *
170      * @param string $locator
171      *
172      * @return Extension
173      *
174      * @throws ExtensionInitializationException
175      */
176     private function instantiateExtension($locator)
177     {
178         if (class_exists($class = $locator)) {
179             return new $class;
180         }
181
182         if (class_exists($class = $this->getFullExtensionClass($locator))) {
183             return new $class;
184         }
185
186         if (file_exists($locator)) {
187             return require($locator);
188         }
189
190         if (file_exists($path = $this->extensionsPath . DIRECTORY_SEPARATOR . $locator)) {
191             return require($path);
192         }
193
194         throw new ExtensionInitializationException(sprintf(
195             '`%s` extension file or class could not be located.',
196             $locator
197         ), $locator);
198     }
199
200     /**
201      * Validates extension instance.
202      *
203      * @param Extension $extension
204      * @param string    $locator
205      *
206      * @throws ExtensionInitializationException
207      */
208     private function validateExtensionInstance($extension, $locator)
209     {
210         if (null === $extension) {
211             throw new ExtensionInitializationException(sprintf(
212                 '`%s` extension could not be found.',
213                 $locator
214             ), $locator);
215         }
216
217         if (!is_object($extension)) {
218             throw new ExtensionInitializationException(sprintf(
219                 '`%s` extension could not be initialized.',
220                 $locator
221             ), $locator);
222         }
223
224         if (!$extension instanceof Extension) {
225             throw new ExtensionInitializationException(sprintf(
226                 '`%s` extension class should implement Testwork Extension interface.',
227                 get_class($extension)
228             ), $locator);
229         }
230     }
231 }