RegisterSerializationClassesCompilerPass.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace Drupal\serialization;
  3. use Drupal\Core\Config\BootstrapConfigStorageFactory;
  4. use Symfony\Component\DependencyInjection\Reference;
  5. use Symfony\Component\DependencyInjection\ContainerBuilder;
  6. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  7. /**
  8. * Adds services tagged 'normalizer' and 'encoder' to the Serializer.
  9. */
  10. class RegisterSerializationClassesCompilerPass implements CompilerPassInterface {
  11. /**
  12. * Adds services to the Serializer.
  13. *
  14. * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
  15. * The container to process.
  16. */
  17. public function process(ContainerBuilder $container) {
  18. $definition = $container->getDefinition('serializer');
  19. // Retrieve registered Normalizers and Encoders from the container.
  20. foreach ($container->findTaggedServiceIds('normalizer') as $id => $attributes) {
  21. // The 'serializer' service is the public API: mark normalizers private.
  22. $container->getDefinition($id)->setPublic(FALSE);
  23. // If there is a BC key present, pass this to determine if the normalizer
  24. // should be skipped.
  25. if (isset($attributes[0]['bc']) && $this->normalizerBcSettingIsEnabled($attributes[0]['bc'], $attributes[0]['bc_config_name'])) {
  26. continue;
  27. }
  28. $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
  29. $normalizers[$priority][] = new Reference($id);
  30. }
  31. foreach ($container->findTaggedServiceIds('encoder') as $id => $attributes) {
  32. // The 'serializer' service is the public API: mark encoders private.
  33. $container->getDefinition($id)->setPublic(FALSE);
  34. $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
  35. $encoders[$priority][] = new Reference($id);
  36. }
  37. // Add the registered Normalizers and Encoders to the Serializer.
  38. if (!empty($normalizers)) {
  39. $definition->replaceArgument(0, $this->sort($normalizers));
  40. }
  41. if (!empty($encoders)) {
  42. $definition->replaceArgument(1, $this->sort($encoders));
  43. }
  44. // Find all serialization formats known.
  45. $formats = [];
  46. $format_providers = [];
  47. foreach ($container->findTaggedServiceIds('encoder') as $service_id => $attributes) {
  48. $format = $attributes[0]['format'];
  49. $formats[] = $format;
  50. if ($provider_tag = $container->getDefinition($service_id)->getTag('_provider')) {
  51. $format_providers[$format] = $provider_tag[0]['provider'];
  52. }
  53. }
  54. $container->setParameter('serializer.formats', $formats);
  55. $container->setParameter('serializer.format_providers', $format_providers);
  56. }
  57. /**
  58. * Returns whether a normalizer BC setting is disabled or not.
  59. *
  60. * @param string $key
  61. *
  62. * @return bool
  63. */
  64. protected function normalizerBcSettingIsEnabled($key, $config_name) {
  65. $settings = BootstrapConfigStorageFactory::get()->read($config_name);
  66. return !empty($settings[$key]);
  67. }
  68. /**
  69. * Sorts by priority.
  70. *
  71. * Order services from highest priority number to lowest (reverse sorting).
  72. *
  73. * @param array $services
  74. * A nested array keyed on priority number. For each priority number, the
  75. * value is an array of Symfony\Component\DependencyInjection\Reference
  76. * objects, each a reference to a normalizer or encoder service.
  77. *
  78. * @return array
  79. * A flattened array of Reference objects from $services, ordered from high
  80. * to low priority.
  81. */
  82. protected function sort($services) {
  83. $sorted = [];
  84. krsort($services);
  85. // Flatten the array.
  86. foreach ($services as $a) {
  87. $sorted = array_merge($sorted, $a);
  88. }
  89. return $sorted;
  90. }
  91. }