From 2d255736805ccda356f5f4f4bd6b5fb25698aa42 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Fri, 8 Apr 2016 15:51:59 +0200 Subject: [PATCH 1/3] Created a trait to sort tagged services --- .../Compiler/AddCacheWarmerPass.php | 14 ++-- .../Compiler/ConfigCachePass.php | 15 ++--- .../ControllerArgumentValueResolverPass.php | 34 +--------- .../Compiler/PropertyInfoPass.php | 34 +--------- .../Compiler/SerializerPass.php | 43 +++--------- .../Compiler/AddCacheWarmerPassTest.php | 2 +- .../Compiler/ConfigCachePassTest.php | 3 +- .../Compiler/PriorityTaggedServiceTrait.php | 53 +++++++++++++++ .../Compiler/PriorityTaggedServiceTrait.php | 67 +++++++++++++++++++ 9 files changed, 146 insertions(+), 119 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php index 5fe2f6202086e..8f5353121ce8b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php @@ -11,9 +11,9 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\Reference; /** * Registers the cache warmers. @@ -22,6 +22,8 @@ */ class AddCacheWarmerPass implements CompilerPassInterface { + use PriorityTaggedServiceTrait; + /** * {@inheritdoc} */ @@ -31,20 +33,12 @@ public function process(ContainerBuilder $container) return; } - $warmers = array(); - foreach ($container->findTaggedServiceIds('kernel.cache_warmer') as $id => $attributes) { - $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; - $warmers[$priority][] = new Reference($id); - } + $warmers = $this->findAndSortTaggedServices('kernel.cache_warmer', $container); if (empty($warmers)) { return; } - // sort by priority and flatten - krsort($warmers); - $warmers = call_user_func_array('array_merge', $warmers); - $container->getDefinition('cache_warmer')->replaceArgument(0, $warmers); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ConfigCachePass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ConfigCachePass.php index a8e1c549a2d6a..d73e941f427ba 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ConfigCachePass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ConfigCachePass.php @@ -12,8 +12,8 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; /** * Adds services tagged config_cache.resource_checker to the config_cache_factory service, ordering them by priority. @@ -23,23 +23,16 @@ */ class ConfigCachePass implements CompilerPassInterface { + use PriorityTaggedServiceTrait; + public function process(ContainerBuilder $container) { - $resourceCheckers = array(); - - foreach ($container->findTaggedServiceIds('config_cache.resource_checker') as $id => $tags) { - $priority = isset($tags[0]['priority']) ? $tags[0]['priority'] : 0; - $resourceCheckers[$priority][] = new Reference($id); - } + $resourceCheckers = $this->findAndSortTaggedServices('config_cache.resource_checker', $container); if (empty($resourceCheckers)) { return; } - // sort by priority and flatten - krsort($resourceCheckers); - $resourceCheckers = call_user_func_array('array_merge', $resourceCheckers); - $container->getDefinition('config_cache_factory')->replaceArgument(0, $resourceCheckers); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ControllerArgumentValueResolverPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ControllerArgumentValueResolverPass.php index f4b64a347891f..e087e691440f9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ControllerArgumentValueResolverPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ControllerArgumentValueResolverPass.php @@ -12,8 +12,8 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; /** * Gathers and configures the argument value resolvers. @@ -22,6 +22,8 @@ */ class ControllerArgumentValueResolverPass implements CompilerPassInterface { + use PriorityTaggedServiceTrait; + public function process(ContainerBuilder $container) { if (!$container->hasDefinition('argument_resolver')) { @@ -32,34 +34,4 @@ public function process(ContainerBuilder $container) $argumentResolvers = $this->findAndSortTaggedServices('controller.argument_value_resolver', $container); $definition->replaceArgument(1, $argumentResolvers); } - - /** - * Finds all services with the given tag name and order them by their priority. - * - * @param string $tagName - * @param ContainerBuilder $container - * - * @return array - */ - private function findAndSortTaggedServices($tagName, ContainerBuilder $container) - { - $services = $container->findTaggedServiceIds($tagName); - - $sortedServices = array(); - foreach ($services as $serviceId => $tags) { - foreach ($tags as $attributes) { - $priority = isset($attributes['priority']) ? $attributes['priority'] : 0; - $sortedServices[$priority][] = new Reference($serviceId); - } - } - - if (empty($sortedServices)) { - return array(); - } - - krsort($sortedServices); - - // Flatten the array - return call_user_func_array('array_merge', $sortedServices); - } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/PropertyInfoPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/PropertyInfoPass.php index f2a92021e9281..f05445f1a6276 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/PropertyInfoPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/PropertyInfoPass.php @@ -12,8 +12,8 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; /** * Adds extractors to the property_info service. @@ -22,6 +22,8 @@ */ class PropertyInfoPass implements CompilerPassInterface { + use PriorityTaggedServiceTrait; + /** * {@inheritdoc} */ @@ -45,34 +47,4 @@ public function process(ContainerBuilder $container) $accessExtractors = $this->findAndSortTaggedServices('property_info.access_extractor', $container); $definition->replaceArgument(3, $accessExtractors); } - - /** - * Finds all services with the given tag name and order them by their priority. - * - * @param string $tagName - * @param ContainerBuilder $container - * - * @return array - */ - private function findAndSortTaggedServices($tagName, ContainerBuilder $container) - { - $services = $container->findTaggedServiceIds($tagName); - - $sortedServices = array(); - foreach ($services as $serviceId => $tags) { - foreach ($tags as $attributes) { - $priority = isset($attributes['priority']) ? $attributes['priority'] : 0; - $sortedServices[$priority][] = new Reference($serviceId); - } - } - - if (empty($sortedServices)) { - return array(); - } - - krsort($sortedServices); - - // Flatten the array - return call_user_func_array('array_merge', $sortedServices); - } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SerializerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SerializerPass.php index 6188feab553ed..c7d5cb40a59fd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SerializerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SerializerPass.php @@ -11,9 +11,9 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\Reference; /** * Adds all services with the tags "serializer.encoder" and "serializer.normalizer" as @@ -23,6 +23,8 @@ */ class SerializerPass implements CompilerPassInterface { + use PriorityTaggedServiceTrait; + public function process(ContainerBuilder $container) { if (!$container->hasDefinition('serializer')) { @@ -31,42 +33,17 @@ public function process(ContainerBuilder $container) // Looks for all the services tagged "serializer.normalizer" and adds them to the Serializer service $normalizers = $this->findAndSortTaggedServices('serializer.normalizer', $container); + + if (empty($normalizers)) { + throw new \RuntimeException('You must tag at least one service as "serializer.normalizer" to use the Serializer service'); + } $container->getDefinition('serializer')->replaceArgument(0, $normalizers); // Looks for all the services tagged "serializer.encoders" and adds them to the Serializer service $encoders = $this->findAndSortTaggedServices('serializer.encoder', $container); - $container->getDefinition('serializer')->replaceArgument(1, $encoders); - } - - /** - * Finds all services with the given tag name and order them by their priority. - * - * @param string $tagName - * @param ContainerBuilder $container - * - * @return array - * - * @throws \RuntimeException - */ - private function findAndSortTaggedServices($tagName, ContainerBuilder $container) - { - $services = $container->findTaggedServiceIds($tagName); - - if (empty($services)) { - throw new \RuntimeException(sprintf('You must tag at least one service as "%s" to use the Serializer service', $tagName)); - } - - $sortedServices = array(); - foreach ($services as $serviceId => $tags) { - foreach ($tags as $attributes) { - $priority = isset($attributes['priority']) ? $attributes['priority'] : 0; - $sortedServices[$priority][] = new Reference($serviceId); - } + if (empty($encoders)) { + throw new \RuntimeException('You must tag at least one service as "serializer.encoder" to use the Serializer service'); } - - krsort($sortedServices); - - // Flatten the array - return call_user_func_array('array_merge', $sortedServices); + $container->getDefinition('serializer')->replaceArgument(1, $encoders); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php index 61d31cb86b7b6..204fdf09b653e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php @@ -21,7 +21,7 @@ public function testThatCacheWarmersAreProcessedInPriorityOrder() $services = array( 'my_cache_warmer_service1' => array(0 => array('priority' => 100)), 'my_cache_warmer_service2' => array(0 => array('priority' => 200)), - 'my_cache_warmer_service3' => array(), + 'my_cache_warmer_service3' => array(0 => array()), ); $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ConfigCachePassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ConfigCachePassTest.php index c0eef3d627ce7..48c753b6e2d45 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ConfigCachePassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ConfigCachePassTest.php @@ -21,7 +21,7 @@ public function testThatCheckersAreProcessedInPriorityOrder() $services = array( 'checker_2' => array(0 => array('priority' => 100)), 'checker_1' => array(0 => array('priority' => 200)), - 'checker_3' => array(), + 'checker_3' => array(0 => array()), ); $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); @@ -52,7 +52,6 @@ public function testThatCheckersAreProcessedInPriorityOrder() public function testThatCheckersCanBeMissing() { - $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); $container = $this->getMock( 'Symfony\Component\DependencyInjection\ContainerBuilder', array('findTaggedServiceIds') diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php new file mode 100644 index 0000000000000..32ae11039f466 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Trait that allows a generic method to find and sort service by priority option in the tag. + * + * @author Iltar van der Berg + */ +trait PriorityTaggedServiceTrait +{ + /** + * Finds all services with the given tag name and order them by their priority. + * + * @param string $tagName + * @param ContainerBuilder $container + * + * @return Reference[] + */ + private function findAndSortTaggedServices($tagName, ContainerBuilder $container) + { + $services = $container->findTaggedServiceIds($tagName); + + $sortedServices = array(); + foreach ($services as $serviceId => $tags) { + foreach ($tags as $attributes) { + $priority = isset($attributes['priority']) ? $attributes['priority'] : 0; + $sortedServices[$priority][] = new Reference($serviceId); + } + } + + if (empty($sortedServices)) { + return array(); + } + + krsort($sortedServices); + + // Flatten the array + return call_user_func_array('array_merge', $sortedServices); + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php new file mode 100644 index 0000000000000..e61b7e334f1b6 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class PriorityTaggedServiceTraitTest extends \PHPUnit_Framework_TestCase +{ + public function testThatCacheWarmersAreProcessedInPriorityOrder() + { + $services = array( + 'my_service1' => array(0 => array('priority' => 100)), + 'my_service2' => array(0 => array('priority' => 200)), + 'my_service3' => array(0 => array('priority' => -500)), + 'my_service4' => array(0 => array()), + ); + + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $container = $this->getMock( + 'Symfony\Component\DependencyInjection\ContainerBuilder', + array('findTaggedServiceIds', 'getDefinition', 'hasDefinition') + ); + + $container + ->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->returnValue($services)); + $container + ->expects($this->atLeastOnce()) + ->method('getDefinition') + ->with('my_custom_tag') + ->will($this->returnValue($definition)); + + $definition + ->expects($this->once()) + ->method('replaceArgument') + ->with(0, array( + new Reference('my_service2'), + new Reference('my_service1'), + new Reference('my_service4'), + new Reference('my_service3'), + )); + + (new PriorityTaggedServiceTraitImplementation())->test('my_custom_tag', $container); + } +} + +class PriorityTaggedServiceTraitImplementation +{ + use PriorityTaggedServiceTrait; + + public function test($tagName, ContainerBuilder $container) + { + return $this->findAndSortTaggedServices($tagName, $container); + } +} From e5ca7c523879a8da8e81f11b0cebb79cf2a33a58 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Mon, 11 Apr 2016 09:42:46 +0200 Subject: [PATCH 2/3] Implemented the SplPriorityQueue --- .../Compiler/PriorityTaggedServiceTrait.php | 14 ++++---------- .../Compiler/PriorityTaggedServiceTrait.php | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php index 32ae11039f466..74c6d19581860 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php @@ -33,21 +33,15 @@ private function findAndSortTaggedServices($tagName, ContainerBuilder $container { $services = $container->findTaggedServiceIds($tagName); - $sortedServices = array(); + $queue = new \SplPriorityQueue(); + foreach ($services as $serviceId => $tags) { foreach ($tags as $attributes) { $priority = isset($attributes['priority']) ? $attributes['priority'] : 0; - $sortedServices[$priority][] = new Reference($serviceId); + $queue->insert(new Reference($serviceId), $priority * -1); } } - if (empty($sortedServices)) { - return array(); - } - - krsort($sortedServices); - - // Flatten the array - return call_user_func_array('array_merge', $sortedServices); + return iterator_to_array($queue); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php index e61b7e334f1b6..7436433e39519 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php @@ -20,10 +20,14 @@ class PriorityTaggedServiceTraitTest extends \PHPUnit_Framework_TestCase public function testThatCacheWarmersAreProcessedInPriorityOrder() { $services = array( - 'my_service1' => array(0 => array('priority' => 100)), - 'my_service2' => array(0 => array('priority' => 200)), - 'my_service3' => array(0 => array('priority' => -500)), - 'my_service4' => array(0 => array()), + 'my_service1' => array(array('priority' => 100)), + 'my_service2' => array(array('priority' => 200)), + 'my_service3' => array(array('priority' => -500)), + 'my_service4' => array(array()), + 'my_service5' => array(array()), + 'my_service6' => array(array('priority' => -500)), + 'my_service7' => array(array('priority' => -499)), + 'my_service8' => array(array('priority' => 1)), ); $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); @@ -48,8 +52,12 @@ public function testThatCacheWarmersAreProcessedInPriorityOrder() ->with(0, array( new Reference('my_service2'), new Reference('my_service1'), + new Reference('my_service8'), new Reference('my_service4'), + new Reference('my_service5'), + new Reference('my_service7'), new Reference('my_service3'), + new Reference('my_service6'), )); (new PriorityTaggedServiceTraitImplementation())->test('my_custom_tag', $container); From 38d93455ea4bdab20215fe1313d065332bee3f12 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Mon, 11 Apr 2016 10:01:21 +0200 Subject: [PATCH 3/3] Added case to verify insert sequence matters --- .../Tests/Compiler/PriorityTaggedServiceTrait.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php index 7436433e39519..cb877d7a6c448 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTrait.php @@ -28,6 +28,11 @@ public function testThatCacheWarmersAreProcessedInPriorityOrder() 'my_service6' => array(array('priority' => -500)), 'my_service7' => array(array('priority' => -499)), 'my_service8' => array(array('priority' => 1)), + 'my_service9' => array(array()), + 'my_service10' => array(array('priority' => -1000)), + 'my_service11' => array(array('priority' => -1000)), + 'my_service12' => array(array('priority' => -1000)), + 'my_service13' => array(array('priority' => -1000)), ); $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); @@ -55,9 +60,14 @@ public function testThatCacheWarmersAreProcessedInPriorityOrder() new Reference('my_service8'), new Reference('my_service4'), new Reference('my_service5'), + new Reference('my_service9'), new Reference('my_service7'), new Reference('my_service3'), new Reference('my_service6'), + new Reference('my_service10'), + new Reference('my_service11'), + new Reference('my_service12'), + new Reference('my_service13'), )); (new PriorityTaggedServiceTraitImplementation())->test('my_custom_tag', $container); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy