Augmentation vers version 3.3.0

This commit is contained in:
Gauvain Boiché
2020-03-31 15:31:03 +02:00
parent d926806907
commit a1864c0414
2618 changed files with 406015 additions and 31377 deletions

View File

@@ -11,12 +11,15 @@
namespace Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;
@@ -40,22 +43,28 @@ class XmlFileLoader extends FileLoader
$xml = $this->parseFileToDOM($path);
$this->container->addResource(new FileResource($path));
$this->container->fileExists($path);
$defaults = $this->getServiceDefaults($xml, $path);
// anonymous services
$this->processAnonymousServices($xml, $path);
$this->processAnonymousServices($xml, $path, $defaults);
// imports
$this->parseImports($xml, $path);
// parameters
$this->parseParameters($xml);
$this->parseParameters($xml, $path);
// extensions
$this->loadFromExtensions($xml);
// services
$this->parseDefinitions($xml, $path);
try {
$this->parseDefinitions($xml, $path, $defaults);
} finally {
$this->instanceof = [];
}
}
/**
@@ -63,26 +72,33 @@ class XmlFileLoader extends FileLoader
*/
public function supports($resource, $type = null)
{
return \is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION);
if (!\is_string($resource)) {
return false;
}
if (null === $type && 'xml' === pathinfo($resource, PATHINFO_EXTENSION)) {
return true;
}
return 'xml' === $type;
}
/**
* Parses parameters.
*
* @param \DOMDocument $xml
* @param string $file
*/
private function parseParameters(\DOMDocument $xml)
private function parseParameters(\DOMDocument $xml, $file)
{
if ($parameters = $this->getChildren($xml->documentElement, 'parameters')) {
$this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter'));
$this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter', $file));
}
}
/**
* Parses imports.
*
* @param \DOMDocument $xml
* @param string $file
* @param string $file
*/
private function parseImports(\DOMDocument $xml, $file)
{
@@ -96,64 +112,148 @@ class XmlFileLoader extends FileLoader
$defaultDirectory = \dirname($file);
foreach ($imports as $import) {
$this->setCurrentDir($defaultDirectory);
$this->import($import->getAttribute('resource'), null, (bool) XmlUtils::phpize($import->getAttribute('ignore-errors')), $file);
$this->import($import->getAttribute('resource'), XmlUtils::phpize($import->getAttribute('type')) ?: null, (bool) XmlUtils::phpize($import->getAttribute('ignore-errors')), $file);
}
}
/**
* Parses multiple definitions.
*
* @param \DOMDocument $xml
* @param string $file
* @param string $file
*/
private function parseDefinitions(\DOMDocument $xml, $file)
private function parseDefinitions(\DOMDocument $xml, $file, $defaults)
{
$xpath = new \DOMXPath($xml);
$xpath->registerNamespace('container', self::NS);
if (false === $services = $xpath->query('//container:services/container:service')) {
if (false === $services = $xpath->query('//container:services/container:service|//container:services/container:prototype')) {
return;
}
$this->setCurrentDir(\dirname($file));
$this->instanceof = [];
$this->isLoadingInstanceof = true;
$instanceof = $xpath->query('//container:services/container:instanceof');
foreach ($instanceof as $service) {
$this->setDefinition((string) $service->getAttribute('id'), $this->parseDefinition($service, $file, []));
}
$this->isLoadingInstanceof = false;
foreach ($services as $service) {
if (null !== $definition = $this->parseDefinition($service, $file)) {
$this->container->setDefinition((string) $service->getAttribute('id'), $definition);
if (null !== $definition = $this->parseDefinition($service, $file, $defaults)) {
if ('prototype' === $service->tagName) {
$this->registerClasses($definition, (string) $service->getAttribute('namespace'), (string) $service->getAttribute('resource'), (string) $service->getAttribute('exclude'));
} else {
$this->setDefinition((string) $service->getAttribute('id'), $definition);
}
}
}
}
/**
* Get service defaults.
*
* @return array
*/
private function getServiceDefaults(\DOMDocument $xml, $file)
{
$xpath = new \DOMXPath($xml);
$xpath->registerNamespace('container', self::NS);
if (null === $defaultsNode = $xpath->query('//container:services/container:defaults')->item(0)) {
return [];
}
$defaults = [
'tags' => $this->getChildren($defaultsNode, 'tag'),
'bind' => array_map(function ($v) { return new BoundArgument($v); }, $this->getArgumentsAsPhp($defaultsNode, 'bind', $file)),
];
foreach ($defaults['tags'] as $tag) {
if ('' === $tag->getAttribute('name')) {
throw new InvalidArgumentException(sprintf('The tag name for tag "<defaults>" in %s must be a non-empty string.', $file));
}
}
if ($defaultsNode->hasAttribute('autowire')) {
$defaults['autowire'] = XmlUtils::phpize($defaultsNode->getAttribute('autowire'));
}
if ($defaultsNode->hasAttribute('public')) {
$defaults['public'] = XmlUtils::phpize($defaultsNode->getAttribute('public'));
}
if ($defaultsNode->hasAttribute('autoconfigure')) {
$defaults['autoconfigure'] = XmlUtils::phpize($defaultsNode->getAttribute('autoconfigure'));
}
return $defaults;
}
/**
* Parses an individual Definition.
*
* @param \DOMElement $service
* @param string $file
* @param string $file
*
* @return Definition|null
*/
private function parseDefinition(\DOMElement $service, $file)
private function parseDefinition(\DOMElement $service, $file, array $defaults)
{
if ($alias = $service->getAttribute('alias')) {
$public = true;
if ($publicAttr = $service->getAttribute('public')) {
$public = XmlUtils::phpize($publicAttr);
}
$this->container->setAlias((string) $service->getAttribute('id'), new Alias($alias, $public));
$this->validateAlias($service, $file);
return;
$this->container->setAlias((string) $service->getAttribute('id'), $alias = new Alias($alias));
if ($publicAttr = $service->getAttribute('public')) {
$alias->setPublic(XmlUtils::phpize($publicAttr));
} elseif (isset($defaults['public'])) {
$alias->setPublic($defaults['public']);
}
return null;
}
if ($parent = $service->getAttribute('parent')) {
$definition = new DefinitionDecorator($parent);
if ($this->isLoadingInstanceof) {
$definition = new ChildDefinition('');
} elseif ($parent = $service->getAttribute('parent')) {
if (!empty($this->instanceof)) {
throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "instanceof" configuration is defined as using both is not supported. Move your child definitions to a separate file.', $service->getAttribute('id')));
}
foreach ($defaults as $k => $v) {
if ('tags' === $k) {
// since tags are never inherited from parents, there is no confusion
// thus we can safely add them as defaults to ChildDefinition
continue;
}
if ('bind' === $k) {
if ($defaults['bind']) {
throw new InvalidArgumentException(sprintf('Bound values on service "%s" cannot be inherited from "defaults" when a "parent" is set. Move your child definitions to a separate file.', $service->getAttribute('id')));
}
continue;
}
if (!$service->hasAttribute($k)) {
throw new InvalidArgumentException(sprintf('Attribute "%s" on service "%s" cannot be inherited from "defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly.', $k, $service->getAttribute('id')));
}
}
$definition = new ChildDefinition($parent);
} else {
$definition = new Definition();
if (isset($defaults['public'])) {
$definition->setPublic($defaults['public']);
}
if (isset($defaults['autowire'])) {
$definition->setAutowired($defaults['autowire']);
}
if (isset($defaults['autoconfigure'])) {
$definition->setAutoconfigured($defaults['autoconfigure']);
}
$definition->setChanges([]);
}
foreach (array('class', 'shared', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'lazy', 'abstract') as $key) {
foreach (['class', 'public', 'shared', 'synthetic', 'lazy', 'abstract'] as $key) {
if ($value = $service->getAttribute($key)) {
if (\in_array($key, array('factory-class', 'factory-method', 'factory-service'))) {
@trigger_error(sprintf('The "%s" attribute of service "%s" in file "%s" is deprecated since Symfony 2.6 and will be removed in 3.0. Use the "factory" element instead.', $key, (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED);
}
$method = 'set'.str_replace('-', '', $key);
$method = 'set'.$key;
$definition->$method(XmlUtils::phpize($value));
}
}
@@ -162,24 +262,12 @@ class XmlFileLoader extends FileLoader
$definition->setAutowired(XmlUtils::phpize($value));
}
if ($value = $service->getAttribute('scope')) {
$triggerDeprecation = 'request' !== (string) $service->getAttribute('id');
if ($triggerDeprecation) {
@trigger_error(sprintf('The "scope" attribute of service "%s" in file "%s" is deprecated since Symfony 2.8 and will be removed in 3.0.', (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED);
if ($value = $service->getAttribute('autoconfigure')) {
if (!$definition instanceof ChildDefinition) {
$definition->setAutoconfigured(XmlUtils::phpize($value));
} elseif ($value = XmlUtils::phpize($value)) {
throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try setting autoconfigure="false" for the service.', $service->getAttribute('id')));
}
$definition->setScope(XmlUtils::phpize($value), false);
}
if ($value = $service->getAttribute('synchronized')) {
$triggerDeprecation = 'request' !== (string) $service->getAttribute('id');
if ($triggerDeprecation) {
@trigger_error(sprintf('The "synchronized" attribute of service "%s" in file "%s" is deprecated since Symfony 2.7 and will be removed in 3.0.', (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED);
}
$definition->setSynchronized(XmlUtils::phpize($value), $triggerDeprecation);
}
if ($files = $this->getChildren($service, 'file')) {
@@ -190,25 +278,21 @@ class XmlFileLoader extends FileLoader
$definition->setDeprecated(true, $deprecated[0]->nodeValue ?: null);
}
$definition->setArguments($this->getArgumentsAsPhp($service, 'argument'));
$definition->setProperties($this->getArgumentsAsPhp($service, 'property'));
$definition->setArguments($this->getArgumentsAsPhp($service, 'argument', $file, $definition instanceof ChildDefinition));
$definition->setProperties($this->getArgumentsAsPhp($service, 'property', $file));
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);
if ($childService = $factory->getAttribute('service')) {
$class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
} else {
$class = $factory->getAttribute('class');
$class = $factory->hasAttribute('class') ? $factory->getAttribute('class') : null;
}
$definition->setFactory(array($class, $factory->getAttribute('method')));
$definition->setFactory([$class, $factory->getAttribute('method')]);
}
}
@@ -217,35 +301,37 @@ class XmlFileLoader extends FileLoader
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);
if ($childService = $configurator->getAttribute('service')) {
$class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
} else {
$class = $configurator->getAttribute('class');
}
$definition->setConfigurator(array($class, $configurator->getAttribute('method')));
$definition->setConfigurator([$class, $configurator->getAttribute('method')]);
}
}
foreach ($this->getChildren($service, 'call') as $call) {
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument'));
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument', $file));
}
foreach ($this->getChildren($service, 'tag') as $tag) {
$parameters = array();
$tags = $this->getChildren($service, 'tag');
if (!empty($defaults['tags'])) {
$tags = array_merge($tags, $defaults['tags']);
}
foreach ($tags as $tag) {
$parameters = [];
foreach ($tag->attributes as $name => $node) {
if ('name' === $name) {
continue;
}
if (false !== strpos($name, '-') && false === strpos($name, '_') && !array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) {
if (false !== strpos($name, '-') && false === strpos($name, '_') && !\array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) {
$parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue);
}
// keep not normalized key for BC too
// keep not normalized key
$parameters[$name] = XmlUtils::phpize($node->nodeValue);
}
@@ -260,6 +346,15 @@ class XmlFileLoader extends FileLoader
$definition->addAutowiringType($type->textContent);
}
$bindings = $this->getArgumentsAsPhp($service, 'bind', $file);
if (isset($defaults['bind'])) {
// deep clone, to avoid multiple process of the same instance in the passes
$bindings = array_merge(unserialize(serialize($defaults['bind'])), $bindings);
}
if ($bindings) {
$definition->setBindings($bindings);
}
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;
@@ -281,9 +376,9 @@ class XmlFileLoader extends FileLoader
private function parseFileToDOM($file)
{
try {
$dom = XmlUtils::loadFile($file, array($this, 'validateSchema'));
$dom = XmlUtils::loadFile($file, [$this, 'validateSchema']);
} catch (\InvalidArgumentException $e) {
throw new InvalidArgumentException(sprintf('Unable to parse file "%s".', $file), $e->getCode(), $e);
throw new InvalidArgumentException(sprintf('Unable to parse file "%s": %s', $file, $e->getMessage()), $e->getCode(), $e);
}
$this->validateExtensions($dom, $file);
@@ -294,26 +389,28 @@ class XmlFileLoader extends FileLoader
/**
* Processes anonymous services.
*
* @param \DOMDocument $xml
* @param string $file
* @param string $file
* @param array $defaults
*/
private function processAnonymousServices(\DOMDocument $xml, $file)
private function processAnonymousServices(\DOMDocument $xml, $file, $defaults)
{
$definitions = array();
$definitions = [];
$count = 0;
$suffix = '~'.ContainerBuilder::hash($file);
$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)]')) {
if (false !== $nodes = $xpath->query('//container:argument[@type="service"][not(@id)]|//container:property[@type="service"][not(@id)]|//container:bind[not(@id)]|//container:factory[not(@service)]|//container:configurator[not(@service)]')) {
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);
// give it a unique name
$id = sprintf('%d_%s', ++$count, preg_replace('/^.*\\\\/', '', $services[0]->getAttribute('class')).$suffix);
$node->setAttribute('id', $id);
$node->setAttribute('service', $id);
$definitions[$id] = [$services[0], $file, false];
$services[0]->setAttribute('id', $id);
// anonymous services are always private
@@ -326,30 +423,26 @@ class XmlFileLoader extends FileLoader
// anonymous services "in the wild"
if (false !== $nodes = $xpath->query('//container:services/container:service[not(@id)]')) {
foreach ($nodes as $node) {
@trigger_error(sprintf('Top-level anonymous services are deprecated since Symfony 3.4, the "id" attribute will be required in version 4.0 in %s at line %d.', $file, $node->getLineNo()), E_USER_DEPRECATED);
// give it a unique name
$id = sprintf('%s_%d', hash('sha256', $file), ++$count);
$id = sprintf('%d_%s', ++$count, preg_replace('/^.*\\\\/', '', $node->getAttribute('class')).$suffix);
$node->setAttribute('id', $id);
$definitions[$id] = array($node, $file, true);
$definitions[$id] = [$node, $file, true];
}
}
// resolve definitions
krsort($definitions);
foreach ($definitions as $id => $def) {
list($domElement, $file, $wild) = $def;
if (null !== $definition = $this->parseDefinition($domElement, $file)) {
$this->container->setDefinition($id, $definition);
uksort($definitions, 'strnatcmp');
foreach (array_reverse($definitions) as $id => list($domElement, $file, $wild)) {
if (null !== $definition = $this->parseDefinition($domElement, $file, $wild ? $defaults : [])) {
$this->setDefinition($id, $definition);
}
if (true === $wild) {
$tmpDomElement = new \DOMElement('_services', null, self::NS);
$domElement->parentNode->replaceChild($tmpDomElement, $domElement);
$tmpDomElement->setAttribute('id', $id);
} else {
if (null !== $domElement->parentNode) {
$domElement->parentNode->removeChild($domElement);
}
}
}
}
@@ -357,24 +450,23 @@ class XmlFileLoader extends FileLoader
/**
* Returns arguments as valid php types.
*
* @param \DOMElement $node
* @param string $name
* @param bool $lowercase
* @param string $name
* @param string $file
*
* @return mixed
*/
private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true)
private function getArgumentsAsPhp(\DOMElement $node, $name, $file, $isChildDefinition = false)
{
$arguments = array();
$arguments = [];
foreach ($this->getChildren($node, $name) as $arg) {
if ($arg->hasAttribute('name')) {
$arg->setAttribute('key', $arg->getAttribute('name'));
}
// this is used by DefinitionDecorator to overwrite a specific
// this is used by ChildDefinition to overwrite a specific
// argument of the parent definition
if ($arg->hasAttribute('index')) {
$key = 'index_'.$arg->getAttribute('index');
$key = ($isChildDefinition ? 'index_' : '').$arg->getAttribute('index');
} elseif (!$arg->hasAttribute('key')) {
// Append an empty argument, then fetch its key to overwrite it later
$arguments[] = null;
@@ -382,36 +474,52 @@ class XmlFileLoader extends FileLoader
$key = array_pop($keys);
} else {
$key = $arg->getAttribute('key');
}
// parameter keys are case insensitive
if ('parameter' == $name && $lowercase) {
$key = strtolower($key);
}
$onInvalid = $arg->getAttribute('on-invalid');
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
if ('ignore' == $onInvalid) {
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
} elseif ('ignore_uninitialized' == $onInvalid) {
$invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
} elseif ('null' == $onInvalid) {
$invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
}
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 ('' === $arg->getAttribute('id')) {
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="service" has no or empty "id" attribute in "%s".', $name, $file));
}
if ($arg->hasAttribute('strict')) {
@trigger_error(sprintf('The "strict" attribute used when referencing the "%s" service is deprecated since Symfony 3.3 and will be removed in 4.0.', $arg->getAttribute('id')), E_USER_DEPRECATED);
}
if ($strict = $arg->getAttribute('strict')) {
$strict = XmlUtils::phpize($strict);
} else {
$strict = true;
}
$arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior, $strict);
$arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior);
break;
case 'expression':
if (!class_exists(Expression::class)) {
throw new \LogicException(sprintf('The type="expression" attribute cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'));
}
$arguments[$key] = new Expression($arg->nodeValue);
break;
case 'collection':
$arguments[$key] = $this->getArgumentsAsPhp($arg, $name, false);
$arguments[$key] = $this->getArgumentsAsPhp($arg, $name, $file);
break;
case 'iterator':
$arg = $this->getArgumentsAsPhp($arg, $name, $file);
try {
$arguments[$key] = new IteratorArgument($arg);
} catch (InvalidArgumentException $e) {
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="iterator" only accepts collections of type="service" references in "%s".', $name, $file));
}
break;
case 'tagged':
if (!$arg->getAttribute('tag')) {
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="tagged" has no or empty "tag" attribute in "%s".', $name, $file));
}
$arguments[$key] = new TaggedIteratorArgument($arg->getAttribute('tag'));
break;
case 'string':
$arguments[$key] = $arg->nodeValue;
@@ -430,14 +538,13 @@ class XmlFileLoader extends FileLoader
/**
* Get child elements by name.
*
* @param \DOMNode $node
* @param mixed $name
* @param mixed $name
*
* @return array
* @return \DOMElement[]
*/
private function getChildren(\DOMNode $node, $name)
{
$children = array();
$children = [];
foreach ($node->childNodes as $child) {
if ($child instanceof \DOMElement && $child->localName === $name && self::NS === $child->namespaceURI) {
$children[] = $child;
@@ -450,15 +557,13 @@ class XmlFileLoader extends FileLoader
/**
* Validates a documents XML schema.
*
* @param \DOMDocument $dom
*
* @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'));
$schemaLocations = ['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);
@@ -468,7 +573,8 @@ class XmlFileLoader extends FileLoader
}
if (($extension = $this->container->getExtension($items[$i])) && false !== $extension->getXsdValidationBasePath()) {
$path = str_replace($extension->getNamespace(), str_replace('\\', '/', $extension->getXsdValidationBasePath()).'/', $items[$i + 1]);
$ns = $extension->getNamespace();
$path = str_replace([$ns, str_replace('http://', 'https://', $ns)], 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));
@@ -479,13 +585,13 @@ class XmlFileLoader extends FileLoader
}
}
$tmpfiles = array();
$tmpfiles = [];
$imports = '';
foreach ($schemaLocations as $namespace => $location) {
$parts = explode('/', $location);
$locationstart = 'file:///';
if (0 === stripos($location, 'phar://')) {
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
$tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
if ($tmpfile) {
copy($location, $tmpfile);
$tmpfiles[] = $tmpfile;
@@ -525,11 +631,30 @@ EOF
return $valid;
}
/**
* Validates an alias.
*
* @param string $file
*/
private function validateAlias(\DOMElement $alias, $file)
{
foreach ($alias->attributes as $name => $node) {
if (!\in_array($name, ['alias', 'id', 'public'])) {
@trigger_error(sprintf('Using the attribute "%s" is deprecated for the service "%s" which is defined as an alias in "%s". Allowed attributes for service aliases 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 && self::NS === $child->namespaceURI) {
@trigger_error(sprintf('Using the element "%s" is deprecated for the service "%s" which is defined as an alias 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);
}
}
}
/**
* Validates an extension.
*
* @param \DOMDocument $dom
* @param string $file
* @param string $file
*
* @throws InvalidArgumentException When no extension is found corresponding to a tag
*/
@@ -550,8 +675,6 @@ EOF
/**
* Loads from an extension.
*
* @param \DOMDocument $xml
*/
private function loadFromExtensions(\DOMDocument $xml)
{
@@ -562,7 +685,7 @@ EOF
$values = static::convertDomElementToArray($node);
if (!\is_array($values)) {
$values = array();
$values = [];
}
$this->container->loadFromExtension($node->namespaceURI, $values);
@@ -586,7 +709,7 @@ EOF
*
* @param \DOMElement $element A \DOMElement instance
*
* @return array A PHP array
* @return mixed
*/
public static function convertDomElementToArray(\DOMElement $element)
{