コード例 #1
0
ファイル: ContainerBuilder.php プロジェクト: silktide/syringe
 protected function processExtensions(array $config, Container $container, $alias)
 {
     $extensions = !empty($config["extensions"]) ? $config["extensions"] : [];
     foreach ($extensions as $service => $extension) {
         if (!$container->offsetExists($service)) {
             $aliasedService = $this->referenceResolver->aliasThisKey($service, $alias);
             if (!$container->offsetExists($aliasedService)) {
                 throw new ConfigException(sprintf("Cannot use extension for the service '%s' as it does not exist", $service));
             }
             $service = $aliasedService;
         }
         foreach ($extension as $i => $call) {
             $extension[$i] = $this->processCall($call, $i, $service . " (extension)");
         }
         if (!empty($extension)) {
             $container->extend($service, function ($object) use($extension, $alias) {
                 return $this->serviceFactory->extendService($object, $extension, $alias);
             });
         }
     }
 }
コード例 #2
0
ファイル: ContainerBuilder.php プロジェクト: sojimaxi/syringe
 /**
  * parse service definition and add to the container
  *
  * @param array $config
  * @param Container $container
  * @param string $alias
  * @throws Exception\ConfigException
  */
 protected function processServices(array $config, Container $container, $alias = "")
 {
     if (!isset($config["services"])) {
         return;
     }
     if (!$this->isAssocArray($config["services"])) {
         throw new ConfigException("The 'services' configuration must be an associative array");
     }
     // scan for abstract definitions
     foreach ($config["services"] as $key => $definition) {
         if (!empty($definition["abstract"])) {
             $this->abstractDefinitions[self::SERVICE_CHAR . $this->referenceResolver->aliasThisKey($key, $alias)] = $definition;
             unset($config["services"][$key]);
         }
     }
     // process services
     foreach ($config["services"] as $key => $definition) {
         $key = $this->referenceResolver->aliasThisKey($key, $alias);
         // check for collisions
         if (isset($container[$key])) {
             throw new ConfigException(sprintf("Tried to define a service named '%s', but that name already exists in the container", $key));
         }
         if (!$this->isAssocArray($definition)) {
             throw new ConfigException("A service definition must be an associative array");
         }
         // check if this definition extends an abstract one
         if (!empty($definition["extends"])) {
             $extends = $this->referenceResolver->aliasThisKey($definition["extends"], $alias);
             if (!isset($this->abstractDefinitions[$extends])) {
                 throw new ConfigException(sprintf("The service definition for '%s' extends '%s' but there is no abstract definition of that name", $key, $extends));
             }
             // As calls gets wiped out by the replace_recursive, so we need to store it and merge it separately
             $calls = !empty($definition["calls"]) ? $definition["calls"] : [];
             if (!empty($this->abstractDefinitions[$extends]["calls"])) {
                 $calls = array_merge($calls, $this->abstractDefinitions[$extends]["calls"]);
             }
             $definition = array_replace_recursive($this->abstractDefinitions[$extends], $definition);
             $definition["calls"] = $calls;
         }
         // get class
         if (empty($definition["class"])) {
             throw new ConfigException(sprintf("The service definition for %s does not have a class", $key));
         }
         // get class, resolving parameters if necessary
         $class = $this->referenceResolver->resolveParameter($definition["class"], $container, $alias);
         if (!class_exists($class)) {
             throw new ConfigException(sprintf("The service class '%s' does not exist", $class));
         }
         // factories
         $factory = [];
         if (!empty($definition["factoryMethod"])) {
             $factory["method"] = $definition["factoryMethod"];
         }
         if (!empty($definition["factoryClass"])) {
             // check for malformed definitions ...
             if (empty($factory["method"])) {
                 throw new ConfigException(sprintf("A factory class was specified for '%s', but no method was set", $key));
             }
             //... and non-existent classes
             $factoryClass = $this->referenceResolver->resolveParameter($definition["factoryClass"], $container, $alias);
             if (!class_exists($factoryClass)) {
                 throw new ConfigException(sprintf("The factory class '%s', for '%s', does not exist", $factoryClass, $key));
             }
             // make sure the method actually exists on the class
             if (!method_exists($factoryClass, $factory["method"])) {
                 throw new ConfigException(sprintf("Invalid factory definition. The method '%s' does not exist on the class '%s'", $factory["method"], $factoryClass));
             }
             $factory["class"] = $factoryClass;
         }
         if (!empty($definition["factoryService"])) {
             // check for malformed definitions
             if (empty($factory["method"])) {
                 throw new ConfigException(sprintf("A factory service was specified for '%s', but no method was set", $key));
             }
             if (!empty($factory["class"])) {
                 throw new ConfigException(sprintf("The definition for '%s' cannot have both a factory class and a factory service", $key));
             }
             // remove the service char if it exists
             if ($definition["factoryService"][0] == self::SERVICE_CHAR) {
                 $definition["factoryService"] = substr($definition["factoryService"], 1);
             }
             $factory["service"] = $this->referenceResolver->aliasThisKey($definition["factoryService"], $alias);
         }
         // arguments
         $arguments = !empty($definition["arguments"]) ? $definition["arguments"] : [];
         // calls / setters
         $calls = !empty($definition["calls"]) ? $definition["calls"] : [];
         foreach ($calls as $i => &$call) {
             if (empty($call["method"])) {
                 throw new ConfigException(sprintf("Call '%s' for the service '%s' does not specify a method name", $i, $key));
             }
             if (!method_exists($class, $call["method"])) {
                 throw new ConfigException(sprintf("Error for service '%s': the method call '%s' does not exist for the class '%s'", $key, $call["method"], $class));
             }
             if (empty($call["arguments"])) {
                 // if no arguments have been defined, set arguments to an empty array
                 $call["arguments"] = [];
             } else {
                 if (!is_array($call["arguments"])) {
                     throw new ConfigException(sprintf("Error for service '%s': the method call '%s' has invalid arguments", $key, $call["method"]));
                 }
             }
         }
         // tags
         if (!empty($definition["tags"])) {
             if (!is_array($definition["tags"])) {
                 throw new ConfigException(sprintf("Error for service '%s': the tags definition was not in the expected array format", $key));
             }
             foreach ($definition["tags"] as $tag) {
                 $tag = self::TAG_CHAR . $tag;
                 if (!isset($container[$tag])) {
                     $container[$tag] = function () {
                         return new TagCollection();
                     };
                 }
                 /** @var TagCollection $collection */
                 $collection = $container[$tag];
                 $collection->addService($key);
             }
         }
         // add the definition to the container
         $container[$key] = function () use($class, $factory, $arguments, $calls, $alias) {
             // parse arguments for injected parameters and services
             return $this->serviceFactory->createService($class, $factory, $arguments, $calls, $alias);
         };
     }
 }