Commit f0337421 authored by Dries's avatar Dries

Issue #2208115 by Xano, damiankloip, Crell: Add DependencySerializationTrait.

parent 505a062e
......@@ -9,7 +9,7 @@
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\String;
use \Drupal\Core\DependencyInjection\DependencySerialization;
use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
/**
* Provides a base class for configuration objects with get/set support.
......@@ -26,7 +26,8 @@
* @see \Drupal\Core\Config\Config
* @see \Drupal\Core\Theme\ThemeSettings
*/
abstract class ConfigBase extends DependencySerialization {
abstract class ConfigBase {
use DependencySerializationTrait;
/**
* The name of the configuration object.
......
......@@ -11,7 +11,7 @@
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Component\Utility\String;
use Drupal\Core\Config\Entity\ImportableEntityStorageInterface;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
......@@ -37,8 +37,9 @@
*
* @see \Drupal\Core\Config\ConfigImporterEvent
*/
class ConfigImporter extends DependencySerialization {
class ConfigImporter {
use StringTranslationTrait;
use DependencySerializationTrait;
/**
* The name used to identify the lock.
......
......@@ -9,12 +9,13 @@
use Drupal\Component\Utility\String;
use Drupal\Core\Config\Entity\ConfigDependencyManager;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
/**
* Defines a config storage comparer.
*/
class StorageComparer extends DependencySerialization implements StorageComparerInterface {
class StorageComparer implements StorageComparerInterface {
use DependencySerializationTrait;
/**
* The source storage used to discover configuration changes.
......
......@@ -7,8 +7,7 @@
namespace Drupal\Core\Controller;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\Controller\ControllerResolverInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Form\FormBuilderInterface;
use Symfony\Component\HttpFoundation\Request;
......@@ -17,8 +16,8 @@
*
* @todo Make this a trait in PHP 5.4.
*/
abstract class FormController extends DependencySerialization {
abstract class FormController {
use DependencySerializationTrait;
/**
* The form definition. The format may vary depending on the child class.
*
......
......@@ -2,16 +2,17 @@
/**
* @file
* Contains \Drupal\Core\DependencyInjection\DependencySerialization.
* Contains \Drupal\Core\DependencyInjection\DependencySerializationTrait.
*/
namespace Drupal\Core\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a dependency injection friendly methods for serialization.
* Provides dependency injection friendly methods for serialization.
*/
abstract class DependencySerialization {
trait DependencySerializationTrait {
/**
* An array of service IDs keyed by property name used for serialization.
......@@ -52,7 +53,7 @@ public function __wakeup() {
foreach ($this->_serviceIds as $key => $service_id) {
$this->$key = $container->get($service_id);
}
unset($this->_serviceIds);
$this->_serviceIds = array();
}
}
......@@ -8,7 +8,7 @@
namespace Drupal\Core\Entity;
use Drupal\Core\Cache\Cache;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode;
......@@ -24,7 +24,8 @@
/**
* Defines a base entity class.
*/
abstract class Entity extends DependencySerialization implements EntityInterface {
abstract class Entity implements EntityInterface {
use DependencySerializationTrait;
/**
* The entity type.
......
......@@ -7,7 +7,7 @@
namespace Drupal\Core\Entity;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
......@@ -17,8 +17,9 @@
*
* @todo Convert this to a trait.
*/
abstract class EntityControllerBase extends DependencySerialization {
abstract class EntityControllerBase {
use StringTranslationTrait;
use DependencySerializationTrait;
/**
* The module handler to invoke hooks on.
......
......@@ -9,7 +9,7 @@
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -18,8 +18,9 @@
/**
* Provides a base class for forms.
*/
abstract class FormBase extends DependencySerialization implements FormInterface, ContainerInjectionInterface {
abstract class FormBase implements FormInterface, ContainerInjectionInterface {
use StringTranslationTrait;
use DependencySerializationTrait;
/**
* The current request.
......@@ -38,14 +39,14 @@ abstract class FormBase extends DependencySerialization implements FormInterface
/**
* The config factory.
*
* This is marked private in order to force subclasses to use the
* self::config() method, which may be overridden to address specific needs
* when loading config. See \Drupal\Core\Form\ConfigFormBase::config() for an
* example of this.
* Subclasses should use the self::config() method, which may be overridden to
* address specific needs when loading config, rather than this property
* directly. See \Drupal\Core\Form\ConfigFormBase::config() for an example of
* this.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
private $configFactory;
protected $configFactory;
/**
* The form error handler.
......
......@@ -8,13 +8,14 @@
namespace Drupal\Core\Language;
use Drupal\Component\Utility\String;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
/**
* Class responsible for providing language support on language-unaware sites.
*/
class LanguageManager extends DependencySerialization implements LanguageManagerInterface {
class LanguageManager implements LanguageManagerInterface {
use DependencySerializationTrait;
/**
* The string translation service.
......
......@@ -8,10 +8,10 @@
namespace Drupal\Core\Plugin;
use Drupal\Component\Plugin\ContextAwarePluginBase as ComponentContextAwarePluginBase;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Drupal specific class for plugins that use context.
......@@ -22,16 +22,7 @@
*/
abstract class ContextAwarePluginBase extends ComponentContextAwarePluginBase {
use StringTranslationTrait;
/**
* An array of service IDs keyed by property name used for serialization.
*
* @todo Remove when Drupal\Core\DependencyInjection\DependencySerialization
* is converted to a trait in https://drupal.org/node/2208115.
*
* @var array
*/
protected $_serviceIds = array();
use DependencySerializationTrait;
/**
* Override of \Drupal\Component\Plugin\ContextAwarePluginBase::__construct().
......@@ -61,45 +52,4 @@ public function setContextValue($name, $value) {
return $this;
}
/**
* {@inheritdoc}
*
* @todo Remove when Drupal\Core\DependencyInjection\DependencySerialization
* is converted to a trait in https://drupal.org/node/2208115.
*/
public function __sleep() {
$this->_serviceIds = array();
$vars = get_object_vars($this);
foreach ($vars as $key => $value) {
if (is_object($value) && isset($value->_serviceId)) {
// If a class member was instantiated by the dependency injection
// container, only store its ID so it can be used to get a fresh object
// on unserialization.
$this->_serviceIds[$key] = $value->_serviceId;
unset($vars[$key]);
}
// Special case the container, which might not have a service ID.
elseif ($value instanceof ContainerInterface) {
$this->_serviceIds[$key] = 'service_container';
unset($vars[$key]);
}
}
return array_keys($vars);
}
/**
* {@inheritdoc}
*
* @todo Remove when Drupal\Core\DependencyInjection\DependencySerialization
* is converted to a trait in https://drupal.org/node/2208115.
*/
public function __wakeup() {
$container = \Drupal::getContainer();
foreach ($this->_serviceIds as $key => $service_id) {
$this->$key = $container->get($service_id);
}
unset($this->_serviceIds);
}
}
......@@ -9,63 +9,13 @@
use Drupal\Component\Plugin\PluginBase as ComponentPluginBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
/**
* Base class for plugins supporting metadata inspection and translation.
*/
abstract class PluginBase extends ComponentPluginBase {
use StringTranslationTrait;
/**
* An array of service IDs keyed by property name used for serialization.
*
* @todo Remove when Drupal\Core\DependencyInjection\DependencySerialization
* is converted to a trait.
*
* @var array
*/
protected $_serviceIds = array();
/**
* {@inheritdoc}
*
* @todo Remove when Drupal\Core\DependencyInjection\DependencySerialization
* is converted to a trait.
*/
public function __sleep() {
$this->_serviceIds = array();
$vars = get_object_vars($this);
foreach ($vars as $key => $value) {
if (is_object($value) && isset($value->_serviceId)) {
// If a class member was instantiated by the dependency injection
// container, only store its ID so it can be used to get a fresh object
// on unserialization.
$this->_serviceIds[$key] = $value->_serviceId;
unset($vars[$key]);
}
// Special case the container, which might not have a service ID.
elseif ($value instanceof ContainerInterface) {
$this->_serviceIds[$key] = 'service_container';
unset($vars[$key]);
}
}
return array_keys($vars);
}
/**
* {@inheritdoc}
*
* @todo Remove when Drupal\Core\DependencyInjection\DependencySerialization
* is converted to a trait.
*/
public function __wakeup() {
$container = \Drupal::getContainer();
foreach ($this->_serviceIds as $key => $service_id) {
$this->$key = $container->get($service_id);
}
unset($this->_serviceIds);
}
use DependencySerializationTrait;
}
......@@ -8,7 +8,7 @@
namespace Drupal\Core;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Routing\MatchingRouteNotFoundException;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
......@@ -18,7 +18,8 @@
/**
* Defines an object that holds information about a URL.
*/
class Url extends DependencySerialization {
class Url {
use DependencySerializationTrait;
/**
* The URL generator.
......
......@@ -9,7 +9,7 @@
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
......@@ -19,8 +19,12 @@
/**
* Provides forum manager service.
*/
class ForumManager extends DependencySerialization implements ForumManagerInterface {
class ForumManager implements ForumManagerInterface {
use StringTranslationTrait;
use DependencySerializationTrait {
__wakeup as defaultWakeup;
__sleep as defaultSleep;
}
/**
* Forum sort order, newest first.
......@@ -499,7 +503,7 @@ public function unreadTopics($term, $uid) {
* {@inheritdoc}
*/
public function __sleep() {
$vars = parent::__sleep();
$vars = $this->defaultSleep();
// Do not serialize static cache.
unset($vars['history'], $vars['index'], $vars['lastPostData'], $vars['forumChildren'], $vars['forumStatistics']);
return $vars;
......@@ -509,7 +513,7 @@ public function __sleep() {
* {@inheritdoc}
*/
public function __wakeup() {
parent::__wakeup();
$this->defaultWakeup();
// Initialize static cache.
$this->history = array();
$this->lastPostData = array();
......
......@@ -11,7 +11,7 @@
use Drupal\Core\Controller\ControllerResolverInterface;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\views\ViewExecutable;
......@@ -26,7 +26,8 @@
* default is \Drupal\views\Form\ViewsFormMainForm). That way it is actually
* possible for modules to have a multistep form if they need to.
*/
class ViewsForm extends DependencySerialization implements FormInterface, ContainerInjectionInterface {
class ViewsForm implements FormInterface, ContainerInjectionInterface {
use DependencySerializationTrait;
/**
* The class resolver to get the subform form objects.
......
......@@ -7,7 +7,7 @@
namespace Drupal\views;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Session\AccountInterface;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewStorageInterface;
......@@ -26,7 +26,8 @@
* An object to contain all of the data to generate a view, plus the member
* functions to build the view query, execute the query and render the output.
*/
class ViewExecutable extends DependencySerialization {
class ViewExecutable {
use DependencySerializationTrait;
/**
* The config entity in which the view is stored.
......
......@@ -8,15 +8,15 @@
namespace Drupal\Tests\Core\DependencyInjection;
use Drupal\Core\DependencyInjection\Container;
use Drupal\Core\DependencyInjection\DependencySerialization;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Tests the dependency serialization base class.
* Tests the dependency serialization trait.
*
* @see \Drupal\Core\DependencyInjection\DependencySerialization
* @coversDefaultClass \Drupal\Core\DependencyInjection\DependencySerializationTrait
*/
class DependencySerializationTest extends UnitTestCase {
......@@ -25,14 +25,15 @@ class DependencySerializationTest extends UnitTestCase {
*/
public static function getInfo() {
return array(
'name' => 'Service dependency serialization',
'description' => 'Tests the dependency serialization base class.',
'name' => '\Drupal\Core\DependencyInjection\DependencySerializationTrait unit test',
'description' => '',
'group' => 'System'
);
}
/**
* Tests serialization and unserialization.
* @covers ::__sleep
* @covers ::__wakeup
*/
public function testSerialization() {
// Create a pseudo service and dependency injected object.
......@@ -43,26 +44,19 @@ public function testSerialization() {
$container->set('service_container', $container);
\Drupal::setContainer($container);
$dependencySerialization = new TestClass($service);
$dependencySerialization = new DependencySerializationTestDummy($service);
$dependencySerialization->setContainer($container);
$string = serialize($dependencySerialization);
$object = unserialize($string);
// The original object got _serviceIds added so removing it to check
// equality.
unset($dependencySerialization->_serviceIds);
// Ensure dependency injected object remains the same after serialization.
$this->assertEquals($dependencySerialization, $object);
// Ensure that _serviceIds does not exist on the object anymore.
$this->assertFalse(isset($object->_serviceIds));
$string = serialize($dependencySerialization);
/** @var \Drupal\Tests\Core\DependencyInjection\DependencySerializationTestDummy $object */
$dependencySerialization = unserialize($string);
// Ensure that both the service and the variable are in the unserialized
// object.
$this->assertSame($service, $object->service);
$this->assertSame($container, $object->container);
$this->assertSame($service, $dependencySerialization->service);
$this->assertSame($container, $dependencySerialization->container);
$this->assertEmpty($dependencySerialization->getServiceIds());
}
}
......@@ -70,7 +64,9 @@ public function testSerialization() {
/**
* Defines a test class which has a single service as dependency.
*/
class TestClass extends DependencySerialization implements ContainerAwareInterface {
class DependencySerializationTestDummy implements ContainerAwareInterface {
use DependencySerializationTrait;
/**
* A test service.
......@@ -86,13 +82,6 @@ class TestClass extends DependencySerialization implements ContainerAwareInterfa
*/
public $container;
/**
* {@inheritdoc}
*
* Make the property accessible for the test.
*/
public $_serviceIds;
/**
* Constructs a new TestClass object.
*
......@@ -109,4 +98,11 @@ public function __construct(\stdClass $service) {
public function setContainer(ContainerInterface $container = NULL) {
$this->container = $container;
}
/**
* Gets the stored service IDs.
*/
public function getServiceIds() {
return $this->_serviceIds;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment