Skip to content
Snippets Groups Projects
Verified Commit b16df24b authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2896993 by cburschka, andypost, mxr576, jedihe: Decorated services crash on serialization

parent 7f337ca7
No related branches found
No related tags found
No related merge requests found
......@@ -16,12 +16,34 @@ class DependencySerializationTraitPass implements CompilerPassInterface {
* {@inheritdoc}
*/
public function process(ContainerBuilder $container) {
$decorations = new \SplPriorityQueue();
$order = PHP_INT_MAX;
foreach ($container->getDefinitions() as $service_id => $definition) {
// Only add the property to services that are public (as private services
// can not be reloaded through Container::get()) and are objects.
if (!$definition->hasTag('parameter_service') && $definition->isPublic()) {
$definition->setProperty('_serviceId', $service_id);
}
if ($decorated = $definition->getDecoratedService()) {
$decorations->insert([$service_id, $definition], [$decorated[2], --$order]);
}
}
foreach ($decorations as list($service_id, $definition)) {
list($inner, $renamedId) = $definition->getDecoratedService();
if (!$renamedId) {
$renamedId = $service_id . '.inner';
}
$original = $container->getDefinition($inner);
if ($original->isPublic()) {
// The old service is renamed.
$original->setProperty('_serviceId', $renamedId);
// The decorating service takes over the old ID.
$definition->setProperty('_serviceId', $inner);
}
}
}
......
name: 'Decorated Service Test'
type: module
description: 'Support module for decorated service test.'
package: Testing
version: VERSION
services:
test_service:
class: 'Drupal\decorated_service_test\TestService'
test_service_decorator:
class: 'Drupal\decorated_service_test\TestServiceDecorator'
public: false
decorates: test_service
test_service2:
class: 'Drupal\decorated_service_test\TestService'
test_service2_decorator:
class: 'Drupal\decorated_service_test\TestServiceDecorator'
public: false
decorates: test_service2
test_service2_decorator2:
class: 'Drupal\decorated_service_test\TestServiceDecorator'
public: false
decorates: test_service2
<?php
namespace Drupal\decorated_service_test;
class TestService {
}
<?php
namespace Drupal\decorated_service_test;
class TestServiceDecorator extends TestService {
}
<?php
namespace Drupal\Tests\system\Kernel;
use Drupal\decorated_service_test\TestServiceDecorator;
use Drupal\KernelTests\KernelTestBase;
/**
* Test handling of decorated services in DependencySerializationTraitPass.
*
* @group system
*/
class DecoratedServiceTest extends KernelTestBase {
protected static $modules = [
'decorated_service_test',
];
/**
* Check that decorated services keep their original service ID.
*/
public function testDecoratedServiceId() {
// Service decorated once.
$test_service = $this->container->get('test_service');
$this->assertEquals('test_service', $test_service->_serviceId);
$this->assertInstanceOf(TestServiceDecorator::class, $test_service);
// Service decorated twice.
$test_service2 = $this->container->get('test_service2');
$this->assertEquals('test_service2', $test_service2->_serviceId);
$this->assertInstanceOf(TestServiceDecorator::class, $test_service2);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment