+++ /dev/null
-<?php
-
-/*
- * This file is part of the Behat.
- * (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\Behat\HelperContainer;
-
-use Behat\Behat\HelperContainer\Exception\ServiceNotFoundException;
-use Behat\Behat\HelperContainer\Exception\WrongServicesConfigurationException;
-use Interop\Container\ContainerInterface;
-use ReflectionClass;
-use ReflectionMethod;
-
-/**
- * Built-in service container.
- *
- * @author Konstantin Kudryashov <ever.zet@gmail.com>
- */
-final class BuiltInServiceContainer implements ContainerInterface
-{
- /**
- * @var array
- */
- private $schema;
- /**
- * @var array
- */
- private $instances;
-
- /**
- * Initialises container using provided service configuration.
- *
- * @param array $schema
- */
- public function __construct(array $schema)
- {
- $this->schema = $schema;
- }
-
- /**
- * {@inheritdoc}
- */
- public function has($id)
- {
- return array_key_exists($id, $this->schema);
- }
-
- /**
- * {@inheritdoc}
- */
- public function get($id)
- {
- if (!$this->has($id)) {
- throw new ServiceNotFoundException(
- sprintf('Service with id `%s` was not defined inside the `services` setting`.', $id),
- $id
- );
- }
-
- return $this->instances[$id] = isset($this->instances[$id]) ? $this->instances[$id] : $this->createInstance($id);
- }
-
- /**
- * Creates an instance of given service.
- *
- * @param string $id
- *
- * @return mixed
- */
- private function createInstance($id)
- {
- $schema = $this->getAndValidateServiceSchema($id);
-
- $reflection = new ReflectionClass($schema['class']);
- $arguments = $schema['arguments'];
-
- if ($factoryMethod = $this->getAndValidateFactoryMethod($reflection, $schema)) {
- return $factoryMethod->invokeArgs(null, $arguments);
- }
-
- return $reflection->newInstanceArgs($arguments);
- }
-
- /**
- * Gets and validates a service configuration for a service with given ID.
- *
- * @param string $id
- *
- * @throws WrongServicesConfigurationException
- *
- * @return array|string
- */
- private function getAndValidateServiceSchema($id)
- {
- $schema = $this->schema[$id];
-
- if (null === $schema) {
- $schema = array('class' => $id);
- }
-
- if (is_string($schema)) {
- $schema = array('class' => $schema);
- }
-
- $schema['class'] = $this->getAndValidateClass($id, $schema);
- $schema['arguments'] = $this->getAndValidateArguments($schema);
-
- return $schema;
- }
-
- /**
- * Gets and validates a class from schema.
- *
- * @param string $id
- * @param string|array $schema
- *
- * @return string
- */
- private function getAndValidateClass($id, array $schema)
- {
- if (!isset($schema['class'])) {
- $schema['class'] = $id;
- }
-
- return $schema['class'];
- }
-
- /**
- * Gets and validates arguments from schema.
- *
- * @param array $schema
- *
- * @return array
- */
- private function getAndValidateArguments(array $schema)
- {
- return isset($schema['arguments']) ? (array)$schema['arguments'] : array();
- }
-
- /**
- * Gets and validates a factory method.
- *
- * @param ReflectionClass $reflection
- * @param array $schema
- *
- * @return null|ReflectionMethod
- */
- private function getAndValidateFactoryMethod(ReflectionClass $reflection, array $schema)
- {
- if (!isset($schema['factory_method'])) {
- return null;
- }
-
- $factoryMethod = $schema['factory_method'];
- $this->assertFactoryMethodExists($reflection, $factoryMethod);
- $method = $reflection->getMethod($factoryMethod);
- $this->assertFactoryMethodIsStatic($method);
-
- return $method;
- }
-
- /**
- * Checks if factory method exists.
- *
- * @param ReflectionClass $class
- * @param string $methodName
- *
- * @throws WrongServicesConfigurationException
- */
- private function assertFactoryMethodExists(ReflectionClass $class, $methodName)
- {
- if (!$class->hasMethod($methodName)) {
- throw new WrongServicesConfigurationException(sprintf(
- 'Factory method `%s::%s` does not exist.',
- $class->getName(),
- $methodName
- ));
- }
- }
-
- /**
- * Checks if factory method is static.
- *
- * @param ReflectionMethod $method
- *
- * @throws WrongServicesConfigurationException
- */
- private function assertFactoryMethodIsStatic(ReflectionMethod $method)
- {
- if (!$method->isStatic()) {
- throw new WrongServicesConfigurationException(sprintf(
- 'Service factory methods must be static, but `%s::%s` is not.',
- $method->getDeclaringClass()->getName(),
- $method->getName()
- ));
- }
- }
-}