DependencySerializationTrait.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. <?php
  2. namespace Drupal\Core\DependencyInjection;
  3. use Symfony\Component\DependencyInjection\ContainerInterface;
  4. /**
  5. * Provides dependency injection friendly methods for serialization.
  6. */
  7. trait DependencySerializationTrait {
  8. /**
  9. * An array of service IDs keyed by property name used for serialization.
  10. *
  11. * @var array
  12. */
  13. protected $_serviceIds = [];
  14. /**
  15. * {@inheritdoc}
  16. */
  17. public function __sleep() {
  18. $this->_serviceIds = [];
  19. $vars = get_object_vars($this);
  20. foreach ($vars as $key => $value) {
  21. if (is_object($value) && isset($value->_serviceId)) {
  22. // If a class member was instantiated by the dependency injection
  23. // container, only store its ID so it can be used to get a fresh object
  24. // on unserialization.
  25. $this->_serviceIds[$key] = $value->_serviceId;
  26. unset($vars[$key]);
  27. }
  28. // Special case the container, which might not have a service ID.
  29. elseif ($value instanceof ContainerInterface) {
  30. $this->_serviceIds[$key] = 'service_container';
  31. unset($vars[$key]);
  32. }
  33. }
  34. return array_keys($vars);
  35. }
  36. /**
  37. * {@inheritdoc}
  38. */
  39. public function __wakeup() {
  40. // Tests in isolation potentially unserialize in the parent process.
  41. $phpunit_bootstrap = isset($GLOBALS['__PHPUNIT_BOOTSTRAP']);
  42. if ($phpunit_bootstrap && !\Drupal::hasContainer()) {
  43. return;
  44. }
  45. $container = \Drupal::getContainer();
  46. foreach ($this->_serviceIds as $key => $service_id) {
  47. // In rare cases, when test data is serialized in the parent process,
  48. // there is a service container but it doesn't contain all expected
  49. // services. To avoid fatal errors during the wrap-up of failing tests, we
  50. // check for this case, too.
  51. if ($phpunit_bootstrap && !$container->has($service_id)) {
  52. continue;
  53. }
  54. $this->$key = $container->get($service_id);
  55. }
  56. $this->_serviceIds = [];
  57. }
  58. }