示例#1
0
 /**
  * Adds a service
  *
  * @param string     $id
  * @param ehough_iconic_Definition $definition
  *
  * @return string
  */
 private function addService($id, $definition)
 {
     $code = "    {$id}:\n";
     if ($definition->getClass()) {
         $code .= sprintf("        class: %s\n", $definition->getClass());
     }
     if (!$definition->isPublic()) {
         $code .= "        public: false\n";
     }
     $tagsCode = '';
     foreach ($definition->getTags() as $name => $tags) {
         foreach ($tags as $attributes) {
             $att = array();
             foreach ($attributes as $key => $value) {
                 $att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value));
             }
             $att = $att ? ', ' . implode(' ', $att) : '';
             $tagsCode .= sprintf("            - { name: %s%s }\n", $this->dumper->dump($name), $att);
         }
     }
     if ($tagsCode) {
         $code .= "        tags:\n" . $tagsCode;
     }
     if ($definition->getFile()) {
         $code .= sprintf("        file: %s\n", $definition->getFile());
     }
     if ($definition->isSynthetic()) {
         $code .= sprintf("        synthetic: true\n");
     }
     if ($definition->isSynchronized()) {
         $code .= sprintf("        synchronized: true\n");
     }
     if ($definition->getFactoryClass()) {
         $code .= sprintf("        factory_class: %s\n", $definition->getFactoryClass());
     }
     if ($definition->isLazy()) {
         $code .= sprintf("        lazy: true\n");
     }
     if ($definition->getFactoryMethod()) {
         $code .= sprintf("        factory_method: %s\n", $definition->getFactoryMethod());
     }
     if ($definition->getFactoryService()) {
         $code .= sprintf("        factory_service: %s\n", $definition->getFactoryService());
     }
     if ($definition->getArguments()) {
         $code .= sprintf("        arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0));
     }
     if ($definition->getProperties()) {
         $code .= sprintf("        properties: %s\n", $this->dumper->dump($this->dumpValue($definition->getProperties()), 0));
     }
     if ($definition->getMethodCalls()) {
         $code .= sprintf("        calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12));
     }
     if (ehough_iconic_ContainerInterface::SCOPE_CONTAINER !== ($scope = $definition->getScope())) {
         $code .= sprintf("        scope: %s\n", $scope);
     }
     if ($callable = $definition->getConfigurator()) {
         if (is_array($callable)) {
             if ($callable[0] instanceof ehough_iconic_Reference) {
                 $callable = array($this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]);
             } else {
                 $callable = array($callable[0], $callable[1]);
             }
         }
         $code .= sprintf("        configurator: %s\n", $this->dumper->dump($callable, 0));
     }
     return $code;
 }
示例#2
0
    /**
     * Adds a service
     *
     * @param string     $id
     * @param ehough_iconic_Definition $definition
     *
     * @return string
     */
    private function addService($id, $definition)
    {
        $this->definitionVariables = array();
        $this->referenceVariables = array();
        $this->variableCount = 0;
        $return = array();
        if ($definition->isSynthetic()) {
            $return[] = '@throws ehough_iconic_exception_RuntimeException always since this service is expected to be injected dynamically';
        } elseif ($class = $definition->getClass()) {
            $return[] = sprintf("@return %s A %s instance.", 0 === strpos($class, '%') ? 'object' : $class, $class);
        } elseif ($definition->getFactoryClass()) {
            $return[] = sprintf('@return object An instance returned by %s::%s().', $definition->getFactoryClass(), $definition->getFactoryMethod());
        } elseif ($definition->getFactoryService()) {
            $return[] = sprintf('@return object An instance returned by %s::%s().', $definition->getFactoryService(), $definition->getFactoryMethod());
        }
        $scope = $definition->getScope();
        if (!in_array($scope, array(ehough_iconic_ContainerInterface::SCOPE_CONTAINER, ehough_iconic_ContainerInterface::SCOPE_PROTOTYPE))) {
            if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
                $return[] = '';
            }
            $return[] = sprintf("@throws ehough_iconic_exception_InactiveScopeException when the '%s' service is requested while the '%s' scope is not active", $id, $scope);
        }
        $return = implode("\n     * ", $return);
        $doc = '';
        if (ehough_iconic_ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
            $doc .= <<<EOF

     *
     * This service is shared.
     * This method always returns the same instance of the service.
EOF;
        }
        if (!$definition->isPublic()) {
            $doc .= <<<EOF

     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
EOF;
        }
        if ($definition->isLazy()) {
            $lazyInitialization = '$lazyLoad = true';
            $lazyInitializationDoc = "\n     * @param boolean \$lazyLoad whether to try lazy-loading the service with a proxy\n     *";
        } else {
            $lazyInitialization = '';
            $lazyInitializationDoc = '';
        }
        // with proxies, for 5.3.3 compatibility, the getter must be public to be accessible to the initializer
        $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
        $visibility = $isProxyCandidate ? 'public' : 'protected';
        $code = <<<EOF

    /**
     * Gets the '{$id}' service.{$doc}
     *{$lazyInitializationDoc}
     * {$return}
     */
    {$visibility} function get{$this->camelize($id)}Service({$lazyInitialization})
    {

EOF;
        $code .= $isProxyCandidate ? $this->getProxyDumper()->getProxyFactoryCode($definition, $id) : '';
        if (!in_array($scope, array(ehough_iconic_ContainerInterface::SCOPE_CONTAINER, ehough_iconic_ContainerInterface::SCOPE_PROTOTYPE))) {
            $code .= <<<EOF
        if (!isset(\$this->scopedServices['{$scope}'])) {
            throw new ehough_iconic_exception_InactiveScopeException('{$id}', '{$scope}');
        }


EOF;
        }
        if ($definition->isSynthetic()) {
            $code .= sprintf("        throw new ehough_iconic_exception_RuntimeException('You have requested a synthetic service (\"%s\"). The DIC does not know how to construct this service.');\n    }\n", $id);
        } else {
            $code .= $this->addServiceInclude($id, $definition) . $this->addServiceLocalTempVariables($id, $definition) . $this->addServiceInlinedDefinitions($id, $definition) . $this->addServiceInstance($id, $definition) . $this->addServiceInlinedDefinitionsSetup($id, $definition) . $this->addServiceMethodCalls($id, $definition) . $this->addServiceProperties($id, $definition) . $this->addServiceConfigurator($id, $definition) . $this->addServiceReturn($id, $definition);
        }
        $this->definitionVariables = null;
        $this->referenceVariables = null;
        return $code;
    }
示例#3
0
 /**
  * Creates a service for a service definition.
  *
  * @param ehough_iconic_Definition $definition A service definition instance
  * @param string     $id         The service identifier
  * @param bool       $tryProxy   Whether to try proxying the service with a lazy proxy
  *
  * @return object The service described by the service definition
  *
  * @throws ehough_iconic_exception_RuntimeException When the scope is inactive
  * @throws ehough_iconic_exception_RuntimeException When the factory definition is incomplete
  * @throws ehough_iconic_exception_RuntimeException When the service is a synthetic service
  * @throws ehough_iconic_exception_InvalidArgumentException When configure callable is not callable
  *
  * @internal this method is public because of PHP 5.3 limitations, do not use it explicitly in your code
  */
 public function createService(ehough_iconic_Definition $definition, $id, $tryProxy = true)
 {
     if ($definition->isSynthetic()) {
         throw new ehough_iconic_exception_RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id));
     }
     if ($tryProxy && $definition->isLazy()) {
         $container = $this;
         $inst = new ehough_iconic_lazyproxy_instantiator_IconicInstantiator($definition, $id, $container);
         $proxy = $this->getProxyInstantiator()->instantiateProxy($container, $definition, $id, array($inst, 'create'));
         $this->shareService($definition, $proxy, $id);
         return $proxy;
     }
     $parameterBag = $this->getParameterBag();
     if (null !== $definition->getFile()) {
         require_once $parameterBag->resolveValue($definition->getFile());
     }
     $arguments = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())));
     if (null !== $definition->getFactoryMethod()) {
         if (null !== $definition->getFactoryClass()) {
             $factory = $parameterBag->resolveValue($definition->getFactoryClass());
         } elseif (null !== $definition->getFactoryService()) {
             $factory = $this->get($parameterBag->resolveValue($definition->getFactoryService()));
         } else {
             throw new ehough_iconic_exception_RuntimeException(sprintf('Cannot create service "%s" from factory method without a factory service or factory class.', $id));
         }
         $service = call_user_func_array(array($factory, $definition->getFactoryMethod()), $arguments);
     } else {
         $r = new ReflectionClass($parameterBag->resolveValue($definition->getClass()));
         $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
     }
     if ($tryProxy || !$definition->isLazy()) {
         // share only if proxying failed, or if not a proxy
         $this->shareService($definition, $service, $id);
     }
     foreach ($definition->getMethodCalls() as $call) {
         $this->callMethod($service, $call);
     }
     $properties = $this->resolveServices($parameterBag->resolveValue($definition->getProperties()));
     foreach ($properties as $name => $value) {
         $service->{$name} = $value;
     }
     if ($callable = $definition->getConfigurator()) {
         if (is_array($callable)) {
             $callable[0] = $callable[0] instanceof ehough_iconic_Reference ? $this->get((string) $callable[0]) : $parameterBag->resolveValue($callable[0]);
         }
         if (!is_callable($callable)) {
             throw new ehough_iconic_exception_InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_class($service)));
         }
         call_user_func($callable, $service);
     }
     return $service;
 }
示例#4
0
 /**
  * Adds a service.
  *
  * @param ehough_iconic_Definition  $definition
  * @param string      $id
  * @param \DOMElement $parent
  */
 private function addService($definition, $id, DOMElement $parent)
 {
     $service = $this->document->createElement('service');
     if (null !== $id) {
         $service->setAttribute('id', $id);
     }
     if ($definition->getClass()) {
         $service->setAttribute('class', $definition->getClass());
     }
     if ($definition->getFactoryMethod()) {
         $service->setAttribute('factory-method', $definition->getFactoryMethod());
     }
     if ($definition->getFactoryClass()) {
         $service->setAttribute('factory-class', $definition->getFactoryClass());
     }
     if ($definition->getFactoryService()) {
         $service->setAttribute('factory-service', $definition->getFactoryService());
     }
     if (ehough_iconic_ContainerInterface::SCOPE_CONTAINER !== ($scope = $definition->getScope())) {
         $service->setAttribute('scope', $scope);
     }
     if (!$definition->isPublic()) {
         $service->setAttribute('public', 'false');
     }
     if ($definition->isSynthetic()) {
         $service->setAttribute('synthetic', 'true');
     }
     if ($definition->isSynchronized()) {
         $service->setAttribute('synchronized', 'true');
     }
     if ($definition->isLazy()) {
         $service->setAttribute('lazy', 'true');
     }
     if (null !== ($decorated = $definition->getDecoratedService())) {
         list($decorated, $renamedId) = $decorated;
         $service->setAttribute('decorates', $decorated);
         if (null !== $renamedId) {
             $service->setAttribute('decoration-inner-name', $renamedId);
         }
     }
     foreach ($definition->getTags() as $name => $tags) {
         foreach ($tags as $attributes) {
             $tag = $this->document->createElement('tag');
             $tag->setAttribute('name', $name);
             foreach ($attributes as $key => $value) {
                 $tag->setAttribute($key, $value);
             }
             $service->appendChild($tag);
         }
     }
     if ($definition->getFile()) {
         $file = $this->document->createElement('file');
         $file->appendChild($this->document->createTextNode($definition->getFile()));
         $service->appendChild($file);
     }
     if ($parameters = $definition->getArguments()) {
         $this->convertParameters($parameters, 'argument', $service);
     }
     if ($parameters = $definition->getProperties()) {
         $this->convertParameters($parameters, 'property', $service, 'name');
     }
     $this->addMethodCalls($definition->getMethodCalls(), $service);
     if ($callable = $definition->getConfigurator()) {
         $configurator = $this->document->createElement('configurator');
         if (is_array($callable)) {
             $configurator->setAttribute($callable[0] instanceof ehough_iconic_Reference ? 'service' : 'class', $callable[0]);
             $configurator->setAttribute('method', $callable[1]);
         } else {
             $configurator->setAttribute('function', $callable);
         }
         $service->appendChild($configurator);
     }
     $parent->appendChild($service);
 }
 /**
  * Checks if the definition is inlineable.
  *
  * @param ehough_iconic_ContainerBuilder $container
  * @param string           $id
  * @param ehough_iconic_Definition       $definition
  *
  * @return bool    If the definition is inlineable
  */
 private function isInlineableDefinition(ehough_iconic_ContainerBuilder $container, $id, ehough_iconic_Definition $definition)
 {
     if (ehough_iconic_ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
         return true;
     }
     if ($definition->isPublic() || $definition->isLazy()) {
         return false;
     }
     if (!$this->graph->hasNode($id)) {
         return true;
     }
     if ($this->currentId == $id) {
         return false;
     }
     $ids = array();
     foreach ($this->graph->getNode($id)->getInEdges() as $edge) {
         $ids[] = $edge->getSourceNode()->getId();
     }
     if (count(array_unique($ids)) > 1) {
         return false;
     }
     return $container->getDefinition(reset($ids))->getScope() === $definition->getScope();
 }