/** * Processes the ContainerBuilder to validate the ehough_iconic_Definition. * * @param ehough_iconic_ContainerBuilder $container * * @throws ehough_iconic_exception_RuntimeException When the ehough_iconic_Definition is invalid */ public function process(ehough_iconic_ContainerBuilder $container) { foreach ($container->getDefinitions() as $id => $definition) { // synthetic service is public if ($definition->isSynthetic() && !$definition->isPublic()) { throw new ehough_iconic_exception_RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id)); } // synthetic service has non-prototype scope if ($definition->isSynthetic() && ehough_iconic_ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) { throw new ehough_iconic_exception_RuntimeException(sprintf('A synthetic service ("%s") cannot be of scope "prototype".', $id)); } // non-synthetic, non-abstract service has class if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) { if ($definition->getFactoryClass() || $definition->getFactoryService()) { throw new ehough_iconic_exception_RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory ' . 'since we might need to add method calls based on compile-time checks.', $id)); } throw new ehough_iconic_exception_RuntimeException(sprintf('The definition for "%s" has no class. If you intend to inject ' . 'this service dynamically at runtime, please mark it as synthetic=true. ' . 'If this is an abstract definition solely used by child definitions, ' . 'please add abstract=true, otherwise specify a class to get rid of this error.', $id)); } // tag attribute values must be scalars foreach ($definition->getTags() as $name => $tags) { foreach ($tags as $attributes) { foreach ($attributes as $attribute => $value) { if (!is_scalar($value) && null !== $value) { throw new ehough_iconic_exception_RuntimeException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $id, $name, $attribute)); } } } } } }
/** * Processes the ContainerBuilder to validate ehough_iconic_References. * * @param ehough_iconic_ContainerBuilder $container */ public function process(ehough_iconic_ContainerBuilder $container) { $this->container = $container; $children = $this->container->getScopeChildren(); $ancestors = array(); $scopes = $this->container->getScopes(); foreach ($scopes as $name => $parent) { $ancestors[$name] = array($parent); while (isset($scopes[$parent])) { $ancestors[$name][] = $parent = $scopes[$parent]; } } foreach ($container->getDefinitions() as $id => $definition) { if ($definition->isSynthetic() || $definition->isAbstract()) { continue; } $this->currentId = $id; $this->currentDefinition = $definition; $this->currentScope = $scope = $definition->getScope(); if (ehough_iconic_ContainerInterface::SCOPE_CONTAINER === $scope) { $this->currentScopeChildren = array_keys($scopes); $this->currentScopeAncestors = array(); } elseif (ehough_iconic_ContainerInterface::SCOPE_PROTOTYPE !== $scope) { $this->currentScopeChildren = isset($children[$scope]) ? $children[$scope] : array(); $this->currentScopeAncestors = isset($ancestors[$scope]) ? $ancestors[$scope] : array(); } $this->validateReferences($definition->getArguments()); $this->validateReferences($definition->getMethodCalls()); $this->validateReferences($definition->getProperties()); } }
/** * Processes the ContainerBuilder to resolve parameter placeholders. * * @param ehough_iconic_ContainerBuilder $container * * @throws ehough_iconic_exception_ParameterNotFoundException */ public function process(ehough_iconic_ContainerBuilder $container) { $parameterBag = $container->getParameterBag(); foreach ($container->getDefinitions() as $id => $definition) { try { $definition->setClass($parameterBag->resolveValue($definition->getClass())); $definition->setFile($parameterBag->resolveValue($definition->getFile())); $definition->setArguments($parameterBag->resolveValue($definition->getArguments())); $calls = array(); foreach ($definition->getMethodCalls() as $name => $arguments) { $calls[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($arguments); } $definition->setMethodCalls($calls); $definition->setProperties($parameterBag->resolveValue($definition->getProperties())); } catch (ehough_iconic_exception_ParameterNotFoundException $e) { $e->setSourceId($id); throw $e; } } $aliases = array(); foreach ($container->getAliases() as $name => $target) { $aliases[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($target); } $container->setAliases($aliases); $parameterBag->resolve(); }
/** * Process the ContainerBuilder to resolve invalid references. * * @param ehough_iconic_ContainerBuilder $container */ public function process(ehough_iconic_ContainerBuilder $container) { $this->container = $container; foreach ($container->getDefinitions() as $definition) { if ($definition->isSynthetic() || $definition->isAbstract()) { continue; } $definition->setArguments($this->processArguments($definition->getArguments())); $calls = array(); foreach ($definition->getMethodCalls() as $call) { try { $calls[] = array($call[0], $this->processArguments($call[1], true)); } catch (ehough_iconic_exception_RuntimeException $ignore) { // this call is simply removed } } $definition->setMethodCalls($calls); $properties = array(); foreach ($definition->getProperties() as $name => $value) { try { $value = $this->processArguments(array($value), true); $properties[$name] = reset($value); } catch (ehough_iconic_exception_RuntimeException $ignore) { // ignore property } } $definition->setProperties($properties); } }
/** * {@inheritdoc} */ public function process(ehough_iconic_ContainerBuilder $container) { $parameters = $container->getParameterBag()->all(); $definitions = $container->getDefinitions(); $aliases = $container->getAliases(); foreach ($container->getExtensions() as $extension) { if ($extension instanceof ehough_iconic_extension_PrependExtensionInterface) { $extension->prepend($container); } } foreach ($container->getExtensions() as $name => $extension) { if (!($config = $container->getExtensionConfig($name))) { // this extension was not called continue; } $config = $container->getParameterBag()->resolveValue($config); $tmpContainer = new ehough_iconic_ContainerBuilder($container->getParameterBag()); $tmpContainer->setResourceTracking($container->isTrackingResources()); if (class_exists('\\Symfony\\Component\\Config\\Resource\\FileResource')) { $tmpContainer->addObjectResource($extension); } $extension->load($config, $tmpContainer); $container->merge($tmpContainer); } $container->addDefinitions($definitions); $container->addAliases($aliases); $container->getParameterBag()->add($parameters); }
/** * Processes a ContainerBuilder object to populate the service reference graph. * * @param ehough_iconic_ContainerBuilder $container */ public function process(ehough_iconic_ContainerBuilder $container) { $this->container = $container; $this->graph = $container->getCompiler()->getServiceReferenceGraph(); $this->graph->clear(); foreach ($container->getDefinitions() as $id => $definition) { if ($definition->isSynthetic() || $definition->isAbstract()) { continue; } $this->currentId = $id; $this->currentDefinition = $definition; $this->processArguments($definition->getArguments()); if ($definition->getFactoryService()) { $this->processArguments(array(new ehough_iconic_Reference($definition->getFactoryService()))); } if (!$this->onlyConstructorArguments) { $this->processArguments($definition->getMethodCalls()); $this->processArguments($definition->getProperties()); if ($definition->getConfigurator()) { $this->processArguments(array($definition->getConfigurator())); } } } foreach ($container->getAliases() as $id => $alias) { $this->graph->connect($id, $alias, (string) $alias, $this->getDefinition((string) $alias), null); } }
public function process(ehough_iconic_ContainerBuilder $container) { $this->container = $container; foreach ($container->getDefinitions() as $id => $definition) { $this->sourceId = $id; $this->processDefinition($definition); } }
/** * Checks the ContainerBuilder object for circular references. * * @param ehough_iconic_ContainerBuilder $container The ContainerBuilder instances */ public function process(ehough_iconic_ContainerBuilder $container) { $graph = $container->getCompiler()->getServiceReferenceGraph(); $this->checkedNodes = array(); foreach ($graph->getNodes() as $id => $node) { $this->currentId = $id; $this->currentPath = array($id); $this->checkOutEdges($node->getOutEdges()); } }
/** * Removes abstract definitions from the ContainerBuilder * * @param ehough_iconic_ContainerBuilder $container */ public function process(ehough_iconic_ContainerBuilder $container) { $compiler = $container->getCompiler(); $formatter = $compiler->getLoggingFormatter(); foreach ($container->getDefinitions() as $id => $definition) { if ($definition->isAbstract()) { $container->removeDefinition($id); $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'abstract')); } } }
/** * Removes private aliases from the ContainerBuilder * * @param ehough_iconic_ContainerBuilder $container */ public function process(ehough_iconic_ContainerBuilder $container) { $compiler = $container->getCompiler(); $formatter = $compiler->getLoggingFormatter(); foreach ($container->getAliases() as $id => $alias) { if ($alias->isPublic()) { continue; } $container->removeAlias($id); $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'private alias')); } }
/** * Updates references to remove aliases. * * @param ehough_iconic_ContainerBuilder $container The container * @param string $currentId The alias identifier being replaced * @param string $newId The id of the service the alias points to */ private function updateReferences($container, $currentId, $newId) { foreach ($container->getAliases() as $id => $alias) { if ($currentId === (string) $alias) { $container->setAlias($id, $newId); } } foreach ($container->getDefinitions() as $id => $definition) { $this->sourceId = $id; $definition->setArguments($this->updateArgumentReferences($definition->getArguments(), $currentId, $newId)); $definition->setMethodCalls($this->updateArgumentReferences($definition->getMethodCalls(), $currentId, $newId)); $definition->setProperties($this->updateArgumentReferences($definition->getProperties(), $currentId, $newId)); } }
public function process(ehough_iconic_ContainerBuilder $container) { foreach ($container->getDefinitions() as $id => $definition) { if (!($decorated = $definition->getDecoratedService())) { continue; } $definition->setDecoratedService(null); list($inner, $renamedId) = $decorated; if (!$renamedId) { $renamedId = $id . '.inner'; } // we create a new alias/service for the service we are replacing // to be able to reference it in the new one if ($container->hasAlias($inner)) { $alias = $container->getAlias($inner); $public = $alias->isPublic(); $container->setAlias($renamedId, new ehough_iconic_Alias((string) $alias, false)); } else { $definition = $container->getDefinition($inner); $public = $definition->isPublic(); $definition->setPublic(false); $container->setDefinition($renamedId, $definition); } $container->setAlias($inner, new ehough_iconic_Alias($id, $public)); } }
/** * Process the ContainerBuilder to replace ehough_iconic_DefinitionDecorator instances with their real ehough_iconic_Definition instances. * * @param ehough_iconic_ContainerBuilder $container */ public function process(ehough_iconic_ContainerBuilder $container) { $this->container = $container; $this->compiler = $container->getCompiler(); $this->formatter = $this->compiler->getLoggingFormatter(); foreach (array_keys($container->getDefinitions()) as $id) { // yes, we are specifically fetching the definition from the // container to ensure we are not operating on stale data $definition = $container->getDefinition($id); if (!$definition instanceof ehough_iconic_DefinitionDecorator || $definition->isAbstract()) { continue; } $this->resolveDefinition($id, $definition); } }
/** * Processes the ContainerBuilder to replace references to aliases with actual service references. * * @param ehough_iconic_ContainerBuilder $container */ public function process(ehough_iconic_ContainerBuilder $container) { $this->container = $container; foreach ($container->getDefinitions() as $definition) { if ($definition->isSynthetic() || $definition->isAbstract()) { continue; } $definition->setArguments($this->processArguments($definition->getArguments())); $definition->setMethodCalls($this->processArguments($definition->getMethodCalls())); $definition->setProperties($this->processArguments($definition->getProperties())); } foreach ($container->getAliases() as $id => $alias) { $aliasId = (string) $alias; if ($aliasId !== ($defId = $this->getDefinitionId($aliasId))) { $container->setAlias($id, new ehough_iconic_Alias($defId, $alias->isPublic())); } } }
public function process(ehough_iconic_ContainerBuilder $container) { if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) { return; } $definition = $container->findDefinition($this->dispatcherService); foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) { $def = $container->getDefinition($id); if (!$def->isPublic()) { throw new InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id)); } if ($def->isAbstract()) { throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id)); } foreach ($events as $event) { $priority = isset($event['priority']) ? $event['priority'] : 0; if (!isset($event['event'])) { throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag)); } if (!isset($event['method'])) { $event['method'] = 'on' . preg_replace_callback(array('/(?<=\\b)[a-z]/i', '/[^a-z0-9]/i'), array($this, '_upperMatches'), $event['event']); $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); } $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); } } foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) { $def = $container->getDefinition($id); if (!$def->isPublic()) { throw new InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id)); } // We must assume that the class value has been correctly filled, even if the service is created by a factory $class = $def->getClass(); $refClass = new ReflectionClass($class); $interface = 'ehough_tickertape_EventSubscriberInterface'; if (!$refClass->implementsInterface($interface)) { throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); } $definition->addMethodCall('addSubscriberService', array($id, $class)); } }
/** * Processes the ContainerBuilder to remove unused definitions. * * @param ehough_iconic_ContainerBuilder $container */ public function process(ehough_iconic_ContainerBuilder $container) { $compiler = $container->getCompiler(); $formatter = $compiler->getLoggingFormatter(); $graph = $compiler->getServiceReferenceGraph(); $hasChanged = false; foreach ($container->getDefinitions() as $id => $definition) { if ($definition->isPublic()) { continue; } if ($graph->hasNode($id)) { $edges = $graph->getNode($id)->getInEdges(); $referencingAliases = array(); $sourceIds = array(); foreach ($edges as $edge) { $node = $edge->getSourceNode(); $sourceIds[] = $node->getId(); if ($node->isAlias()) { $referencingAliases[] = $node->getValue(); } } $isReferenced = count(array_unique($sourceIds)) - count($referencingAliases) > 0; } else { $referencingAliases = array(); $isReferenced = false; } if (1 === count($referencingAliases) && false === $isReferenced) { $container->setDefinition((string) reset($referencingAliases), $definition); $definition->setPublic(true); $container->removeDefinition($id); $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'replaces alias ' . reset($referencingAliases))); } elseif (0 === count($referencingAliases) && false === $isReferenced) { $container->removeDefinition($id); $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'unused')); $hasChanged = true; } } if ($hasChanged) { $this->repeatedPass->setRepeat(); } }
/** * Wraps the service conditionals. * * @param string $value * @param string $code * * @return string */ private function wrapServiceConditionals($value, $code) { if (!($services = ehough_iconic_ContainerBuilder::getServiceConditionals($value))) { return $code; } $conditions = array(); foreach ($services as $service) { $conditions[] = sprintf("\$this->has('%s')", $service); } // re-indent the wrapped code $code = implode("\n", array_map(array($this, '_callbackWrapServiceConditionals'), explode("\n", $code))); return sprintf(" if (%s) {\n%s }\n", implode(' && ', $conditions), $code); }
private function cloneContainer() { $parameterBag = new ehough_iconic_parameterbag_ParameterBag($this->container->getParameterBag()->all()); $container = new ehough_iconic_ContainerBuilder($parameterBag); $container->setDefinitions($this->container->getDefinitions()); $container->setAliases($this->container->getAliases()); $container->setResources($this->container->getResources()); foreach ($this->container->getScopes() as $scope => $parentScope) { $container->addScope(new ehough_iconic_Scope($scope, $parentScope)); } foreach ($this->container->getExtensions() as $extension) { $container->registerExtension($extension); } return $container; }
/** * 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(); }
public function create() { return $this->_container->createService($this->_definition, $this->_id, false); }
/** * @param ehough_iconic_ContainerBuilder $container * @param array $config * * @return Boolean Whether the configuration is enabled * * @throws ehough_iconic_exception_InvalidArgumentException When the config is not enableable */ protected function isConfigEnabled(ehough_iconic_ContainerBuilder $container, array $config) { if (!array_key_exists('enabled', $config)) { throw new ehough_iconic_exception_InvalidArgumentException("The config array has no 'enabled' key."); } return (bool) $container->getParameterBag()->resolveValue($config['enabled']); }
/** * Merges a ContainerBuilder with the current ContainerBuilder configuration. * * Service definitions overrides the current defined ones. * * But for parameters, they are overridden by the current ones. It allows * the parameters passed to the container constructor to have precedence * over the loaded ones. * * $container = new ContainerBuilder(array('foo' => 'bar')); * $loader = new LoaderXXX($container); * $loader->load('resource_name'); * $container->register('foo', new stdClass()); * * In the above example, even if the loaded resource defines a foo * parameter, the value will still be 'bar' as defined in the ContainerBuilder * constructor. * * @param ehough_iconic_ContainerBuilder $container The ContainerBuilder instance to merge. * * * @throws ehough_iconic_exception_BadMethodCallException When this ContainerBuilder is frozen * * @api */ public function merge(ehough_iconic_ContainerBuilder $container) { if ($this->isFrozen()) { throw new ehough_iconic_exception_BadMethodCallException('Cannot merge on a frozen container.'); } $this->addDefinitions($container->getDefinitions()); $this->addAliases($container->getAliases()); $this->getParameterBag()->add($container->getParameterBag()->all()); if ($this->trackResources) { foreach ($container->getResources() as $resource) { $this->addResource($resource); } } foreach ($this->extensions as $name => $extension) { if (!isset($this->extensionConfigs[$name])) { $this->extensionConfigs[$name] = array(); } $this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name)); } }