Commit df9a8289 authored by catch's avatar catch

Issue #2611816 by dawehner, jibran, catch, hussainweb, Ankit Agrawal: Update to symfony 2.8

parent 49db6446
This diff is collapsed.
......@@ -5,18 +5,18 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"symfony/class-loader": "2.7.*",
"symfony/console": "2.7.*",
"symfony/dependency-injection": "2.7.*",
"symfony/event-dispatcher": "2.7.*",
"symfony/http-foundation": "~2.7.2",
"symfony/http-kernel": "2.7.*",
"symfony/routing": "2.7.*",
"symfony/serializer": "2.7.*",
"symfony/translation": "2.7.*",
"symfony/validator": "2.7.*",
"symfony/process": "2.7.*",
"symfony/yaml": "2.7.*",
"symfony/class-loader": "~2.8",
"symfony/console": "~2.8",
"symfony/dependency-injection": "~2.8",
"symfony/event-dispatcher": "~2.8",
"symfony/http-foundation": "~2.8",
"symfony/http-kernel": "~2.8",
"symfony/routing": "~2.8",
"symfony/serializer": "~2.8",
"symfony/translation": "~2.8",
"symfony/validator": "~2.8",
"symfony/process": "~2.8",
"symfony/yaml": "~2.8",
"twig/twig": "^1.23.1",
"doctrine/common": "2.5.*",
"doctrine/annotations": "1.2.*",
......
......@@ -497,6 +497,7 @@ services:
entity.manager:
class: Drupal\Core\Entity\EntityManager
parent: container.trait
deprecated: %service_id%-no-warning
# @todo Remove this tag in https://www.drupal.org/node/2549143.
tags:
- { name: plugin_manager_cache_clear }
......@@ -1015,7 +1016,7 @@ services:
class: Symfony\Component\HttpKernel\EventListener\RouterListener
tags:
- { name: event_subscriber }
arguments: ['@router', '@router.request_context', NULL, '@request_stack']
arguments: ['@router', '@request_stack', '@router.request_context', NULL]
bare_html_page_renderer:
class: Drupal\Core\Render\BareHtmlPageRenderer
arguments: ['@renderer', '@html_response.attachments_processor']
......@@ -1297,71 +1298,71 @@ services:
calls:
- [setContainer, ['@service_container']]
arguments: ['feed.writer.']
# Zend Feed reader plugins. Plugins should be set as prototype scope.
# Zend Feed reader plugins. Plugin instances should not be shared.
feed.reader.dublincoreentry:
class: Zend\Feed\Reader\Extension\DublinCore\Entry
scope: prototype
shared: false
feed.reader.dublincorefeed:
class: Zend\Feed\Reader\Extension\DublinCore\Feed
scope: prototype
shared: false
feed.reader.contententry:
class: Zend\Feed\Reader\Extension\Content\Entry
scope: prototype
shared: false
feed.reader.atomentry:
class: Zend\Feed\Reader\Extension\Atom\Entry
scope: prototype
shared: false
feed.reader.atomfeed:
class: Zend\Feed\Reader\Extension\Atom\Feed
scope: prototype
shared: false
feed.reader.slashentry:
class: Zend\Feed\Reader\Extension\Slash\Entry
scope: prototype
shared: false
feed.reader.wellformedwebentry:
class: Zend\Feed\Reader\Extension\WellFormedWeb\Entry
scope: prototype
shared: false
feed.reader.threadentry:
class: Zend\Feed\Reader\Extension\Thread\Entry
scope: prototype
shared: false
feed.reader.podcastentry:
class: Zend\Feed\Reader\Extension\Podcast\Entry
scope: prototype
shared: false
feed.reader.podcastfeed:
class: Zend\Feed\Reader\Extension\Podcast\Feed
scope: prototype
shared: false
# Zend Feed writer plugins. Plugins should be set as prototype scope.
feed.writer.atomrendererfeed:
class: Zend\Feed\Writer\Extension\Atom\Renderer\Feed
scope: prototype
shared: false
feed.writer.contentrendererentry:
class: Zend\Feed\Writer\Extension\Content\Renderer\Entry
scope: prototype
shared: false
feed.writer.dublincorerendererentry:
class: Zend\Feed\Writer\Extension\DublinCore\Renderer\Entry
scope: prototype
shared: false
feed.writer.dublincorerendererfeed:
class: Zend\Feed\Writer\Extension\DublinCore\Renderer\Feed
scope: prototype
shared: false
feed.writer.itunesentry:
class: Zend\Feed\Writer\Extension\ITunes\Entry
scope: prototype
shared: false
feed.writer.itunesfeed:
class: Zend\Feed\Writer\Extension\ITunes\Feed
scope: prototype
shared: false
feed.writer.itunesrendererentry:
class: Zend\Feed\Writer\Extension\ITunes\Renderer\Entry
scope: prototype
shared: false
feed.writer.itunesrendererfeed:
class: Zend\Feed\Writer\Extension\ITunes\Renderer\Feed
scope: prototype
shared: false
feed.writer.slashrendererentry:
class: Zend\Feed\Writer\Extension\Slash\Renderer\Entry
scope: prototype
shared: false
feed.writer.threadingrendererentry:
class: Zend\Feed\Writer\Extension\Threading\Renderer\Entry
scope: prototype
shared: false
feed.writer.wellformedwebrendererentry:
class: Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry
scope: prototype
shared: false
theme.manager:
class: Drupal\Core\Theme\ThemeManager
arguments: ['@app.root', '@theme.negotiator', '@theme.initialization', '@module_handler']
......
......@@ -9,6 +9,7 @@
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\IntrospectableContainerInterface;
use Symfony\Component\DependencyInjection\ResettableContainerInterface;
use Symfony\Component\DependencyInjection\ScopeInterface;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
......@@ -54,7 +55,7 @@
*
* @ingroup container
*/
class Container implements IntrospectableContainerInterface {
class Container implements IntrospectableContainerInterface, ResettableContainerInterface {
/**
* The parameters of the container.
......@@ -182,11 +183,7 @@ public function get($id, $invalid_behavior = ContainerInterface::EXCEPTION_ON_IN
}
catch (\Exception $e) {
unset($this->loading[$id]);
// Remove a potentially shared service that was constructed incompletely.
if (array_key_exists($id, $this->services)) {
unset($this->services[$id]);
}
unset($this->services[$id]);
if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalid_behavior) {
return;
......@@ -200,6 +197,17 @@ public function get($id, $invalid_behavior = ContainerInterface::EXCEPTION_ON_IN
return $service;
}
/**
* {@inheritdoc}
*/
public function reset() {
if (!empty($this->scopedServices)) {
throw new LogicException('Resetting the container is not allowed when a scope is active.');
}
$this->services = [];
}
/**
* Creates a service from a service definition.
*
......@@ -359,6 +367,10 @@ protected function createService(array $definition, $id) {
* {@inheritdoc}
*/
public function set($id, $service, $scope = ContainerInterface::SCOPE_CONTAINER) {
if (!in_array($scope, array('container', 'request')) || ('request' === $scope && 'request' !== $id)) {
@trigger_error('The concept of container scopes is deprecated since version 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED);
}
$this->services[$id] = $service;
}
......@@ -585,6 +597,10 @@ protected function getParameterAlternatives($name) {
* {@inheritdoc}
*/
public function enterScope($name) {
if ('request' !== $name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
......@@ -592,6 +608,10 @@ public function enterScope($name) {
* {@inheritdoc}
*/
public function leaveScope($name) {
if ('request' !== $name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
......@@ -599,6 +619,11 @@ public function leaveScope($name) {
* {@inheritdoc}
*/
public function addScope(ScopeInterface $scope) {
$name = $scope->getName();
if ('request' !== $name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
......@@ -606,6 +631,10 @@ public function addScope(ScopeInterface $scope) {
* {@inheritdoc}
*/
public function hasScope($name) {
if ('request' !== $name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
......@@ -613,6 +642,8 @@ public function hasScope($name) {
* {@inheritdoc}
*/
public function isScopeActive($name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
......@@ -626,4 +657,11 @@ public function getServiceIds() {
return array_keys($this->serviceDefinitions + $this->services);
}
/**
* Ensure that cloning doesn't work.
*/
private function __clone()
{
}
}
......@@ -252,6 +252,11 @@ protected function getServiceDefinition(Definition $definition) {
}
}
// By default services are shared, so just provide the flag, when needed.
if ($definition->isShared() === FALSE) {
$service['shared'] = $definition->isShared();
}
if (($decorated = $definition->getDecoratedService()) !== NULL) {
throw new InvalidArgumentException("The 'decorated' definition is not supported by the Drupal 8 run-time container. The Container Builder should have resolved that during the DecoratorServicePass compiler pass.");
}
......
......@@ -9,8 +9,13 @@
use Symfony\Component\DependencyInjection\ContainerBuilder as SymfonyContainerBuilder;
use Symfony\Component\DependencyInjection\Container as SymfonyContainer;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
/**
* Drupal's dependency injection container builder.
......@@ -21,6 +26,11 @@
*/
class ContainerBuilder extends SymfonyContainerBuilder {
/**
* @var \Doctrine\Instantiator\InstantiatorInterface|null
*/
private $proxyInstantiator;
/**
* {@inheritdoc}
*/
......@@ -29,6 +39,161 @@ public function __construct(ParameterBagInterface $parameterBag = NULL) {
parent::__construct($parameterBag);
}
/**
* Creates a service for a service definition.
*
* Overrides the parent implementation, but just changes one line about
* deprecations, see below.
*
* @param \Symfony\Component\DependencyInjection\Definition $definition
* @param string $id
* @param bool|true $tryProxy
*
* @return mixed|object
*/
public function createService(Definition $definition, $id, $tryProxy = true)
{
if ($definition->isSynthetic()) {
throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id));
}
if ($definition->isDeprecated()) {
// Suppress deprecation warnings when a service is marked as
// 'deprecated: %service_id%-no-warning'
if ($definition->getDeprecationMessage($id) != ($id . '-no-warning')) {
@trigger_error($definition->getDeprecationMessage($id), E_USER_DEPRECATED);
}
}
if ($tryProxy && $definition->isLazy()) {
$container = $this;
$proxy = $this
->getProxyInstantiator()
->instantiateProxy(
$container,
$definition,
$id, function () use ($definition, $id, $container) {
return $container->createService($definition, $id, false);
}
);
$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 !== $factory = $definition->getFactory()) {
if (is_array($factory)) {
$factory = array($this->resolveServices($parameterBag->resolveValue($factory[0])), $factory[1]);
} elseif (!is_string($factory)) {
throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
}
$service = call_user_func_array($factory, $arguments);
if (!$definition->isDeprecated() && is_array($factory) && is_string($factory[0])) {
$r = new \ReflectionClass($factory[0]);
if (0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
@trigger_error(sprintf('The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name), E_USER_DEPRECATED);
}
}
} elseif (null !== $definition->getFactoryMethod(false)) {
if (null !== $definition->getFactoryClass(false)) {
$factory = $parameterBag->resolveValue($definition->getFactoryClass(false));
} elseif (null !== $definition->getFactoryService(false)) {
$factory = $this->get($parameterBag->resolveValue($definition->getFactoryService(false)));
} else {
throw new 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(false)), $arguments);
} else {
$r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
// Skip deprecation notices for deprecations which opt out.
@trigger_error(sprintf('The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name), E_USER_DEPRECATED);
}
}
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->unescapeValue($parameterBag->resolveValue($definition->getProperties())));
foreach ($properties as $name => $value) {
$service->$name = $value;
}
if ($callable = $definition->getConfigurator()) {
if (is_array($callable)) {
$callable[0] = $parameterBag->resolveValue($callable[0]);
if ($callable[0] instanceof Reference) {
$callable[0] = $this->get((string) $callable[0], $callable[0]->getInvalidBehavior());
} elseif ($callable[0] instanceof Definition) {
$callable[0] = $this->createService($callable[0], null);
}
}
if (!is_callable($callable)) {
throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_class($service)));
}
call_user_func($callable, $service);
}
return $service;
}
/**
* Retrieves the currently set proxy instantiator or instantiates one.
*
* @return InstantiatorInterface
*/
private function getProxyInstantiator()
{
if (!$this->proxyInstantiator) {
$this->proxyInstantiator = new RealServiceInstantiator();
}
return $this->proxyInstantiator;
}
/**
* Direct copy of the parent function.
*/
protected function shareService(Definition $definition, $service, $id)
{
if ($definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
throw new InactiveScopeException($id, $scope);
}
$this->services[$lowerId = strtolower($id)] = $service;
if (self::SCOPE_CONTAINER !== $scope) {
$this->scopedServices[$scope][$lowerId] = $service;
}
}
}
/**
* Overrides Symfony\Component\DependencyInjection\ContainerBuilder::set().
*
......
......@@ -159,8 +159,15 @@ private function parseDefinition($id, $service, $file)
$definition->setClass($service['class']);
}
if (isset($service['shared'])) {
$definition->setShared($service['shared']);
}
if (isset($service['scope'])) {
$definition->setScope($service['scope']);
if ('request' !== $id) {
@trigger_error(sprintf('The "scope" key of service "%s" in file "%s" is deprecated since version 2.8 and will be removed in 3.0.', $id, $file), E_USER_DEPRECATED);
}
$definition->setScope($service['scope'], false);
}
if (isset($service['synthetic'])) {
......@@ -183,6 +190,10 @@ private function parseDefinition($id, $service, $file)
$definition->setAbstract($service['abstract']);
}
if (array_key_exists('deprecated', $service)) {
$definition->setDeprecated(true, $service['deprecated']);
}
if (isset($service['factory'])) {
if (is_string($service['factory'])) {
if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) {
......@@ -275,7 +286,30 @@ private function parseDefinition($id, $service, $file)
if (isset($service['decorates'])) {
$renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null;
$definition->setDecoratedService($service['decorates'], $renameId);
$priority = isset($service['decoration_priority']) ? $service['decoration_priority'] : 0;
$definition->setDecoratedService($service['decorates'], $renameId, $priority);
}
if (isset($service['autowire'])) {
$definition->setAutowired($service['autowire']);
}
if (isset($service['autowiring_types'])) {
if (is_string($service['autowiring_types'])) {
$definition->addAutowiringType($service['autowiring_types']);
} else {
if (!is_array($service['autowiring_types'])) {
throw new InvalidArgumentException(sprintf('Parameter "autowiring_types" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}
foreach ($service['autowiring_types'] as $autowiringType) {
if (!is_string($autowiringType)) {
throw new InvalidArgumentException(sprintf('A "autowiring_types" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file));
}
$definition->addAutowiringType($autowiringType);
}
}
}
$this->container->setDefinition($id, $definition);
......
......@@ -266,6 +266,10 @@ public function getDefinitionsDataProvider() {
'synthetic' => TRUE,
) + $base_service_definition;
$service_definitions[] = array(
'shared' => FALSE,
) + $base_service_definition;
$service_definitions[] = array(
'lazy' => TRUE,
) + $base_service_definition;
......@@ -358,6 +362,10 @@ public function getDefinitionsDataProvider() {
'shared' => FALSE,
) + $base_service_definition;
$service_definitions[] = array(
'shared' => FALSE,
) + $base_service_definition;
// Test factory.
$service_definitions[] = array(
'factory' => array(new Reference('bar'), 'factoryMethod'),
......@@ -397,6 +405,7 @@ public function getDefinitionsDataProvider() {
$definition->getProperties()->willReturn($service_definition['properties']);
$definition->getMethodCalls()->willReturn