This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

595 lines
21 KiB
PHP
Raw Normal View History

2010-01-04 14:26:20 +00:00
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Loader;
2010-01-04 14:26:20 +00:00
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Util\XmlUtils;
2011-01-26 23:14:31 +00:00
use Symfony\Component\DependencyInjection\DefinitionDecorator;
2011-01-17 22:28:59 +00:00
use Symfony\Component\DependencyInjection\ContainerInterface;
2011-01-07 14:44:29 +00:00
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\ExpressionLanguage\Expression;
2010-01-04 14:26:20 +00:00
/**
* XmlFileLoader loads XML files service definitions.
*
* @author Fabien Potencier <fabien@symfony.com>
2010-01-04 14:26:20 +00:00
*/
class XmlFileLoader extends FileLoader
{
const NS = 'http://symfony.com/schema/dic/services';
/**
* {@inheritdoc}
*/
public function load($resource, $type = null)
{
$path = $this->locator->locate($resource);
$xml = $this->parseFileToDOM($path);
2010-01-04 14:26:20 +00:00
$this->container->addResource(new FileResource($path));
2010-01-04 14:26:20 +00:00
// anonymous services
$this->processAnonymousServices($xml, $path);
2010-01-04 14:26:20 +00:00
// imports
$this->parseImports($xml, $path);
2010-01-04 14:26:20 +00:00
// parameters
$this->parseParameters($xml);
// extensions
$this->loadFromExtensions($xml);
// services
$this->parseDefinitions($xml, $path);
2010-01-04 14:26:20 +00:00
}
/**
* {@inheritdoc}
*/
public function supports($resource, $type = null)
{
return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION);
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Parses parameters.
2011-02-13 18:06:41 +00:00
*
* @param \DOMDocument $xml
2011-02-13 18:06:41 +00:00
*/
private function parseParameters(\DOMDocument $xml)
2010-01-04 14:26:20 +00:00
{
if ($parameters = $this->getChildren($xml->documentElement, 'parameters')) {
$this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter'));
}
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Parses imports.
2011-02-13 18:06:41 +00:00
*
* @param \DOMDocument $xml
* @param string $file
2011-02-13 18:06:41 +00:00
*/
private function parseImports(\DOMDocument $xml, $file)
2010-01-04 14:26:20 +00:00
{
$xpath = new \DOMXPath($xml);
$xpath->registerNamespace('container', self::NS);
if (false === $imports = $xpath->query('//container:imports/container:import')) {
return;
}
$defaultDirectory = dirname($file);
2011-02-15 09:09:58 +00:00
foreach ($imports as $import) {
$this->setCurrentDir($defaultDirectory);
$this->import($import->getAttribute('resource'), null, (bool) XmlUtils::phpize($import->getAttribute('ignore-errors')), $file);
}
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Parses multiple definitions.
2011-02-13 18:06:41 +00:00
*
* @param \DOMDocument $xml
* @param string $file
2011-02-13 18:06:41 +00:00
*/
private function parseDefinitions(\DOMDocument $xml, $file)
2010-01-04 14:26:20 +00:00
{
$xpath = new \DOMXPath($xml);
$xpath->registerNamespace('container', self::NS);
if (false === $services = $xpath->query('//container:services/container:service')) {
return;
}
2011-02-15 09:09:58 +00:00
foreach ($services as $service) {
if (null !== $definition = $this->parseDefinition($service, $file)) {
$this->container->setDefinition((string) $service->getAttribute('id'), $definition);
}
}
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Parses an individual Definition.
2011-02-13 18:06:41 +00:00
*
* @param \DOMElement $service
* @param string $file
*
* @return Definition|null
2011-02-13 18:06:41 +00:00
*/
private function parseDefinition(\DOMElement $service, $file)
2010-01-04 14:26:20 +00:00
{
if ($alias = $service->getAttribute('alias')) {
$this->validateAlias($service, $file);
2011-01-07 14:44:29 +00:00
$public = true;
if ($publicAttr = $service->getAttribute('public')) {
$public = XmlUtils::phpize($publicAttr);
2011-01-07 14:44:29 +00:00
}
$this->container->setAlias((string) $service->getAttribute('id'), new Alias($alias, $public));
2010-01-04 14:26:20 +00:00
return;
}
2010-01-04 14:26:20 +00:00
if ($parent = $service->getAttribute('parent')) {
$definition = new DefinitionDecorator($parent);
2011-01-26 23:14:31 +00:00
} else {
$definition = new Definition();
}
2010-01-04 14:26:20 +00:00
Merge branch '2.8' * 2.8: (65 commits) [VarDumper] Fix tests for HHVM Update DateTimeToArrayTransformer.php Mock microtime() and time() in transient tests Azerbaijani language pluralization rule Move HHVM tests out of the allowed failures Fix merge [2.6] Towards 100% HHVM compat [Security/Http] Fix test [Stopwatch] Fix test Minor fixes [Validator] Added missing error codes and turned codes into UUIDs Towards 100% HHVM compat Warmup twig templates in non-standard paths (closes #12507) [Bridge/PhpUnit] Enforce a consistent locale Fix param order of assertEquals (expected, actual) in test for Finder\Glob Fix choice translation domain for expanded choice widget unify default AccessDeniedExeption message trigger event with right user (add test) [Security] Initialize SwitchUserEvent::targetUser on attemptExitUser fixed CS ... Conflicts: UPGRADE-2.8.md src/Symfony/Bridge/ProxyManager/composer.json src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php src/Symfony/Bundle/FrameworkBundle/Resources/config/old_assets.xml src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.xml src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/config.yml src/Symfony/Bundle/SecurityBundle/composer.json src/Symfony/Component/Debug/ErrorHandler.php src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php src/Symfony/Component/DependencyInjection/Definition.php src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/legacy-container9.php src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/legacy-services9.dot src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/legacy-services6.xml src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/legacy-services9.xml src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy-services6.yml src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy-services9.yml src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php src/Symfony/Component/Form/ResolvedFormType.php src/Symfony/Component/Form/Tests/CompoundFormTest.php src/Symfony/Component/Process/Tests/AbstractProcessTest.php src/Symfony/Component/VarDumper/Tests/CliDumperTest.php src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php
2015-07-01 21:40:29 +01:00
foreach (array('class', 'shared', 'public', 'synthetic', 'lazy', 'abstract') as $key) {
if ($value = $service->getAttribute($key)) {
$method = 'set'.str_replace('-', '', $key);
$definition->$method(XmlUtils::phpize($value));
}
2010-01-04 14:26:20 +00:00
}
if ($value = $service->getAttribute('autowire')) {
$definition->setAutowired(XmlUtils::phpize($value));
}
if ($files = $this->getChildren($service, 'file')) {
$definition->setFile($files[0]->nodeValue);
2010-01-04 14:26:20 +00:00
}
if ($deprecated = $this->getChildren($service, 'deprecated')) {
$definition->setDeprecated(true, $deprecated[0]->nodeValue);
}
$definition->setArguments($this->getArgumentsAsPhp($service, 'argument'));
$definition->setProperties($this->getArgumentsAsPhp($service, 'property'));
2010-01-04 14:26:20 +00:00
if ($factories = $this->getChildren($service, 'factory')) {
$factory = $factories[0];
if ($function = $factory->getAttribute('function')) {
$definition->setFactory($function);
} else {
$factoryService = $this->getChildren($factory, 'service');
if (isset($factoryService[0])) {
$class = $this->parseDefinition($factoryService[0], $file);
} elseif ($childService = $factory->getAttribute('service')) {
$class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
} else {
$class = $factory->getAttribute('class');
}
$definition->setFactory(array($class, $factory->getAttribute('method')));
}
}
if ($configurators = $this->getChildren($service, 'configurator')) {
$configurator = $configurators[0];
if ($function = $configurator->getAttribute('function')) {
$definition->setConfigurator($function);
} else {
$configuratorService = $this->getChildren($configurator, 'service');
if (isset($configuratorService[0])) {
$class = $this->parseDefinition($configuratorService[0], $file);
} elseif ($childService = $configurator->getAttribute('service')) {
$class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
} else {
$class = $configurator->getAttribute('class');
}
$definition->setConfigurator(array($class, $configurator->getAttribute('method')));
}
}
2010-01-04 14:26:20 +00:00
foreach ($this->getChildren($service, 'call') as $call) {
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument'));
}
foreach ($this->getChildren($service, 'tag') as $tag) {
$parameters = array();
foreach ($tag->attributes as $name => $node) {
if ('name' === $name) {
continue;
}
2013-11-10 19:01:46 +00:00
if (false !== strpos($name, '-') && false === strpos($name, '_') && !array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) {
$parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue);
2013-11-10 19:01:46 +00:00
}
2015-10-04 14:03:24 +01:00
// keep not normalized key
$parameters[$name] = XmlUtils::phpize($node->nodeValue);
}
if ('' === $tag->getAttribute('name')) {
throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', (string) $service->getAttribute('id'), $file));
}
$definition->addTag($tag->getAttribute('name'), $parameters);
}
foreach ($this->getChildren($service, 'autowiring-type') as $type) {
$definition->addAutowiringType($type->textContent);
}
if ($value = $service->getAttribute('decorates')) {
$renameId = $service->hasAttribute('decoration-inner-name') ? $service->getAttribute('decoration-inner-name') : null;
$priority = $service->hasAttribute('decoration-priority') ? $service->getAttribute('decoration-priority') : 0;
$definition->setDecoratedService($value, $renameId, $priority);
}
return $definition;
}
/**
* Parses a XML file to a \DOMDocument.
*
* @param string $file Path to a file
*
* @return \DOMDocument
*
* @throws InvalidArgumentException When loading of XML file returns error
*/
private function parseFileToDOM($file)
2010-01-04 14:26:20 +00:00
{
try {
$dom = XmlUtils::loadFile($file, array($this, 'validateSchema'));
} catch (\InvalidArgumentException $e) {
throw new InvalidArgumentException(sprintf('Unable to parse file "%s".', $file), $e->getCode(), $e);
}
$this->validateExtensions($dom, $file);
2010-01-04 14:26:20 +00:00
return $dom;
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Processes anonymous services.
2011-02-13 18:06:41 +00:00
*
* @param \DOMDocument $xml
* @param string $file
2011-02-13 18:06:41 +00:00
*/
private function processAnonymousServices(\DOMDocument $xml, $file)
2010-01-04 14:26:20 +00:00
{
$definitions = array();
$count = 0;
2010-01-04 14:26:20 +00:00
$xpath = new \DOMXPath($xml);
$xpath->registerNamespace('container', self::NS);
// anonymous services as arguments/properties
if (false !== $nodes = $xpath->query('//container:argument[@type="service"][not(@id)]|//container:property[@type="service"][not(@id)]')) {
foreach ($nodes as $node) {
// give it a unique name
$id = sprintf('%s_%d', hash('sha256', $file), ++$count);
$node->setAttribute('id', $id);
if ($services = $this->getChildren($node, 'service')) {
$definitions[$id] = array($services[0], $file, false);
$services[0]->setAttribute('id', $id);
}
}
}
// anonymous services "in the wild"
if (false !== $nodes = $xpath->query('//container:services/container:service[not(@id)]')) {
foreach ($nodes as $node) {
// give it a unique name
$id = sprintf('%s_%d', hash('sha256', $file), ++$count);
$node->setAttribute('id', $id);
if ($services = $this->getChildren($node, 'service')) {
$definitions[$id] = array($node, $file, true);
$services[0]->setAttribute('id', $id);
}
}
}
// resolve definitions
krsort($definitions);
foreach ($definitions as $id => list($domElement, $file, $wild)) {
// anonymous services are always private
// we could not use the constant false here, because of XML parsing
$domElement->setAttribute('public', 'false');
if (null !== $definition = $this->parseDefinition($domElement, $file)) {
$this->container->setDefinition($id, $definition);
}
if (true === $wild) {
$tmpDomElement = new \DOMElement('_services', null, self::NS);
$domElement->parentNode->replaceChild($tmpDomElement, $domElement);
$tmpDomElement->setAttribute('id', $id);
} else {
$domElement->parentNode->removeChild($domElement);
}
}
}
/**
* Returns arguments as valid php types.
*
* @param \DOMElement $node
* @param string $name
* @param bool $lowercase
*
* @return mixed
*/
private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true)
{
$arguments = array();
foreach ($this->getChildren($node, $name) as $arg) {
if ($arg->hasAttribute('name')) {
$arg->setAttribute('key', $arg->getAttribute('name'));
}
if (!$arg->hasAttribute('key')) {
$key = !$arguments ? 0 : max(array_keys($arguments)) + 1;
} else {
$key = $arg->getAttribute('key');
}
// parameter keys are case insensitive
if ('parameter' == $name && $lowercase) {
$key = strtolower($key);
}
// this is used by DefinitionDecorator to overwrite a specific
// argument of the parent definition
if ($arg->hasAttribute('index')) {
$key = 'index_'.$arg->getAttribute('index');
}
switch ($arg->getAttribute('type')) {
case 'service':
$onInvalid = $arg->getAttribute('on-invalid');
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
if ('ignore' == $onInvalid) {
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
} elseif ('null' == $onInvalid) {
$invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
}
if ($strict = $arg->getAttribute('strict')) {
$strict = XmlUtils::phpize($strict);
} else {
$strict = true;
}
$arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior, $strict);
break;
case 'expression':
$arguments[$key] = new Expression($arg->nodeValue);
break;
case 'collection':
$arguments[$key] = $this->getArgumentsAsPhp($arg, $name, false);
break;
case 'string':
$arguments[$key] = $arg->nodeValue;
break;
case 'constant':
$arguments[$key] = constant($arg->nodeValue);
break;
default:
$arguments[$key] = XmlUtils::phpize($arg->nodeValue);
}
}
return $arguments;
}
/**
* Get child elements by name.
*
* @param \DOMNode $node
* @param mixed $name
*
* @return array
*/
private function getChildren(\DOMNode $node, $name)
{
$children = array();
foreach ($node->childNodes as $child) {
if ($child instanceof \DOMElement && $child->localName === $name && $child->namespaceURI === self::NS) {
$children[] = $child;
}
}
return $children;
}
/**
2011-02-13 18:06:41 +00:00
* Validates a documents XML schema.
*
* @param \DOMDocument $dom
*
2014-04-16 11:30:19 +01:00
* @return bool
*
* @throws RuntimeException When extension references a non-existent XSD file
*/
public function validateSchema(\DOMDocument $dom)
{
$schemaLocations = array('http://symfony.com/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd'));
if ($element = $dom->documentElement->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')) {
$items = preg_split('/\s+/', $element);
for ($i = 0, $nb = count($items); $i < $nb; $i += 2) {
if (!$this->container->hasExtension($items[$i])) {
continue;
}
if (($extension = $this->container->getExtension($items[$i])) && false !== $extension->getXsdValidationBasePath()) {
2010-06-27 17:54:03 +01:00
$path = str_replace($extension->getNamespace(), str_replace('\\', '/', $extension->getXsdValidationBasePath()).'/', $items[$i + 1]);
if (!is_file($path)) {
throw new RuntimeException(sprintf('Extension "%s" references a non-existent XSD file "%s"', get_class($extension), $path));
}
$schemaLocations[$items[$i]] = $path;
}
}
}
$tmpfiles = array();
$imports = '';
foreach ($schemaLocations as $namespace => $location) {
2010-05-21 15:18:29 +01:00
$parts = explode('/', $location);
if (0 === stripos($location, 'phar://')) {
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
if ($tmpfile) {
copy($location, $tmpfile);
$tmpfiles[] = $tmpfile;
$parts = explode('/', str_replace('\\', '/', $tmpfile));
}
}
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
2010-05-21 15:18:29 +01:00
$location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
$imports .= sprintf(' <xsd:import namespace="%s" schemaLocation="%s" />'."\n", $namespace, $location);
}
$source = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns="http://symfony.com/schema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://symfony.com/schema"
elementFormDefault="qualified">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
$imports
</xsd:schema>
EOF
;
$valid = @$dom->schemaValidateSource($source);
foreach ($tmpfiles as $tmpfile) {
@unlink($tmpfile);
}
return $valid;
2010-01-04 14:26:20 +00:00
}
/**
* Validates an alias.
*
* @param \DOMElement $alias
* @param string $file
*/
private function validateAlias(\DOMElement $alias, $file)
{
foreach ($alias->attributes as $name => $node) {
if (!in_array($name, array('alias', 'id', 'public'))) {
@trigger_error(sprintf('Using the attribute "%s" is deprecated for alias definition "%s" in "%s". Allowed attributes are "alias", "id" and "public". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $name, $alias->getAttribute('id'), $file), E_USER_DEPRECATED);
}
}
foreach ($alias->childNodes as $child) {
if ($child instanceof \DOMElement && $child->namespaceURI === self::NS) {
@trigger_error(sprintf('Using the element "%s" is deprecated for alias definition "%s" in "%s". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported elements.', $child->localName, $alias->getAttribute('id'), $file), E_USER_DEPRECATED);
}
}
}
/**
2011-02-13 18:06:41 +00:00
* Validates an extension.
*
* @param \DOMDocument $dom
2012-05-18 18:41:48 +01:00
* @param string $file
2011-02-13 18:06:41 +00:00
*
* @throws InvalidArgumentException When no extension is found corresponding to a tag
*/
private function validateExtensions(\DOMDocument $dom, $file)
2010-01-04 14:26:20 +00:00
{
foreach ($dom->documentElement->childNodes as $node) {
if (!$node instanceof \DOMElement || 'http://symfony.com/schema/dic/services' === $node->namespaceURI) {
continue;
}
// can it be handled by an extension?
if (!$this->container->hasExtension($node->namespaceURI)) {
$extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getNamespace(); }, $this->container->getExtensions()));
throw new InvalidArgumentException(sprintf(
'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
$node->tagName,
$file,
$node->namespaceURI,
$extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'
));
}
}
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
* Loads from an extension.
*
* @param \DOMDocument $xml
2011-02-13 18:06:41 +00:00
*/
private function loadFromExtensions(\DOMDocument $xml)
2010-01-04 14:26:20 +00:00
{
foreach ($xml->documentElement->childNodes as $node) {
if (!$node instanceof \DOMElement || $node->namespaceURI === self::NS) {
continue;
}
2010-01-04 14:26:20 +00:00
$values = static::convertDomElementToArray($node);
if (!is_array($values)) {
$values = array();
}
$this->container->loadFromExtension($node->namespaceURI, $values);
}
2010-01-04 14:26:20 +00:00
}
/**
* Converts a \DomElement object to a PHP array.
*
* The following rules applies during the conversion:
*
* * Each tag is converted to a key value or an array
* if there is more than one "value"
*
* * The content of a tag is set under a "value" key (<foo>bar</foo>)
* if the tag also has some nested tags
*
* * The attributes are converted to keys (<foo foo="bar"/>)
*
* * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>)
*
* @param \DomElement $element A \DomElement instance
*
* @return array A PHP array
*/
2012-07-09 13:50:58 +01:00
public static function convertDomElementToArray(\DomElement $element)
2010-01-04 14:26:20 +00:00
{
return XmlUtils::convertDomElementToArray($element);
2010-01-04 14:26:20 +00:00
}
}