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