Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Testwork / ServiceContainer / ExtensionManager.php
diff --git a/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ExtensionManager.php b/vendor/behat/behat/src/Behat/Testwork/ServiceContainer/ExtensionManager.php
new file mode 100644 (file)
index 0000000..7e2d955
--- /dev/null
@@ -0,0 +1,231 @@
+<?php
+
+/*
+ * This file is part of the Behat Testwork.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Testwork\ServiceContainer;
+
+use Behat\Testwork\ServiceContainer\Exception\ExtensionInitializationException;
+
+/**
+ * Manages both default and 3rd-party extensions.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ExtensionManager
+{
+    /**
+     * @var string
+     */
+    private $extensionsPath;
+    /**
+     * @var Extension[]
+     */
+    private $extensions = array();
+    /**
+     * @var Extension[string]
+     */
+    private $locatedExtensions = array();
+    private $debugInformation = array(
+        'extensions_list' => array()
+    );
+
+    /**
+     * Initializes manager.
+     *
+     * @param Extension[] $extensions     List of default extensions
+     * @param null|string $extensionsPath Base path where to search custom extension files
+     */
+    public function __construct(array $extensions, $extensionsPath = null)
+    {
+        foreach ($extensions as $extension) {
+            $this->extensions[$extension->getConfigKey()] = $extension;
+        }
+
+        $this->extensionsPath = $extensionsPath;
+    }
+
+    /**
+     * Sets path to directory in which manager will try to find extension files.
+     *
+     * @param null|string $path
+     */
+    public function setExtensionsPath($path)
+    {
+        $this->extensionsPath = $path;
+    }
+
+    /**
+     * Activate extension by its locator.
+     *
+     * @param string $locator phar file name, php file name, class name
+     *
+     * @return Extension
+     */
+    public function activateExtension($locator)
+    {
+        $extension = $this->initialize($locator);
+
+        $this->debugInformation['extensions_list'][] = $extension->getConfigKey();
+
+        return $this->extensions[$extension->getConfigKey()] = $extension;
+    }
+
+    /**
+     * Returns specific extension by its name.
+     *
+     * @param string $key
+     *
+     * @return Extension
+     */
+    public function getExtension($key)
+    {
+        return isset($this->extensions[$key]) ? $this->extensions[$key] : null;
+    }
+
+    /**
+     * Returns all available extensions.
+     *
+     * @return Extension[]
+     */
+    public function getExtensions()
+    {
+        return $this->extensions;
+    }
+
+    /**
+     * Returns activated extension names.
+     *
+     * @return array
+     */
+    public function getExtensionClasses()
+    {
+        return array_map('get_class', array_values($this->extensions));
+    }
+
+    /**
+     * Initializes all activated and predefined extensions.
+     */
+    public function initializeExtensions()
+    {
+        foreach ($this->extensions as $extension) {
+            $extension->initialize($this);
+        }
+    }
+
+    /**
+     * Returns array with extensions debug information.
+     *
+     * @return array
+     */
+    public function debugInformation()
+    {
+        return $this->debugInformation;
+    }
+
+    /**
+     * Attempts to guess full extension class from relative.
+     *
+     * @param string $locator
+     *
+     * @return string
+     */
+    private function getFullExtensionClass($locator)
+    {
+        $parts = explode('\\', $locator);
+        $name = preg_replace('/Extension$/', '', end($parts)) . 'Extension';
+
+        return $locator . '\\ServiceContainer\\' . $name;
+    }
+
+    /**
+     * Initializes extension by id.
+     *
+     * @param string $locator
+     *
+     * @return Extension
+     *
+     * @throws ExtensionInitializationException
+     */
+    private function initialize($locator)
+    {
+        if (isset($this->locatedExtensions[$locator])) {
+            return $this->locatedExtensions[$locator];
+        }
+
+        $extension = $this->instantiateExtension($locator);
+        $this->validateExtensionInstance($extension, $locator);
+
+        return $this->locatedExtensions[$locator] = $extension;
+    }
+
+    /**
+     * Instantiates extension from its locator.
+     *
+     * @param string $locator
+     *
+     * @return Extension
+     *
+     * @throws ExtensionInitializationException
+     */
+    private function instantiateExtension($locator)
+    {
+        if (class_exists($class = $locator)) {
+            return new $class;
+        }
+
+        if (class_exists($class = $this->getFullExtensionClass($locator))) {
+            return new $class;
+        }
+
+        if (file_exists($locator)) {
+            return require($locator);
+        }
+
+        if (file_exists($path = $this->extensionsPath . DIRECTORY_SEPARATOR . $locator)) {
+            return require($path);
+        }
+
+        throw new ExtensionInitializationException(sprintf(
+            '`%s` extension file or class could not be located.',
+            $locator
+        ), $locator);
+    }
+
+    /**
+     * Validates extension instance.
+     *
+     * @param Extension $extension
+     * @param string    $locator
+     *
+     * @throws ExtensionInitializationException
+     */
+    private function validateExtensionInstance($extension, $locator)
+    {
+        if (null === $extension) {
+            throw new ExtensionInitializationException(sprintf(
+                '`%s` extension could not be found.',
+                $locator
+            ), $locator);
+        }
+
+        if (!is_object($extension)) {
+            throw new ExtensionInitializationException(sprintf(
+                '`%s` extension could not be initialized.',
+                $locator
+            ), $locator);
+        }
+
+        if (!$extension instanceof Extension) {
+            throw new ExtensionInitializationException(sprintf(
+                '`%s` extension class should implement Testwork Extension interface.',
+                get_class($extension)
+            ), $locator);
+        }
+    }
+}