diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/PropertyInfoPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/PropertyInfoPass.php new file mode 100644 index 0000000000000..819827ac8c388 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/PropertyInfoPass.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Adds extractors to the property_info service. + * + * @author Kévin Dunglas + */ +class PropertyInfoPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('property_info')) { + return; + } + + $listExtractors = $this->findAndSortTaggedServices('property_info.list_extractor', $container); + $container->getDefinition('property_info')->replaceArgument(0, $listExtractors); + + $typeExtractors = $this->findAndSortTaggedServices('property_info.type_extractor', $container); + $container->getDefinition('property_info')->replaceArgument(1, $typeExtractors); + + $descriptionExtractors = $this->findAndSortTaggedServices('property_info.description_extractor', $container); + $container->getDefinition('property_info')->replaceArgument(2, $descriptionExtractors); + + $accessExtractors = $this->findAndSortTaggedServices('property_info.access_extractor', $container); + $container->getDefinition('property_info')->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 aa449dd4c83ee..6188feab553ed 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SerializerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SerializerPass.php @@ -38,6 +38,16 @@ public function process(ContainerBuilder $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); @@ -48,8 +58,8 @@ private function findAndSortTaggedServices($tagName, ContainerBuilder $container $sortedServices = array(); foreach ($services as $serviceId => $tags) { - foreach ($tags as $tag) { - $priority = isset($tag['priority']) ? $tag['priority'] : 0; + foreach ($tags as $attributes) { + $priority = isset($attributes['priority']) ? $attributes['priority'] : 0; $sortedServices[$priority][] = new Reference($serviceId); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index aa8ecfcfc01c2..309cc6c48ccb7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -178,6 +178,7 @@ public function getConfigTreeBuilder() $this->addAnnotationsSection($rootNode); $this->addSerializerSection($rootNode); $this->addPropertyAccessSection($rootNode); + $this->addPropertyInfoSection($rootNode); return $treeBuilder; } @@ -723,4 +724,16 @@ private function addPropertyAccessSection(ArrayNodeDefinition $rootNode) ->end() ; } + + private function addPropertyInfoSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('property_info') + ->info('Property info configuration') + ->canBeEnabled() + ->end() + ->end() + ; + } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index ce16580f2a456..6d9c5f892134b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -131,6 +131,10 @@ public function load(array $configs, ContainerBuilder $container) $this->registerSerializerConfiguration($config['serializer'], $container, $loader); } + if (isset($config['property_info'])) { + $this->registerPropertyInfoConfiguration($config['property_info'], $container, $loader); + } + $loader->load('debug_prod.xml'); $definition = $container->findDefinition('debug.debug_handlers_listener'); @@ -986,6 +990,28 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder } } + /** + * Loads property info configuration. + * + * @param array $config + * @param ContainerBuilder $container + * @param XmlFileLoader $loader + */ + private function registerPropertyInfoConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + { + if (!$config['enabled']) { + return; + } + + $loader->load('property_info.xml'); + + if (class_exists('phpDocumentor\Reflection\ClassReflector')) { + $definition = $container->register('property_info.php_doc_extractor', 'Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor'); + $definition->addTag('property_info.description_extractor', array('priority' => -1000)); + $definition->addTag('property_info.type_extractor', array('priority' => -1001)); + } + } + /** * Returns the base path for the XSD files. * diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 3a96f71e1176d..7d26d00f583ad 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -15,6 +15,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RoutingResolverPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass; @@ -90,6 +91,7 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new TranslationDumperPass()); $container->addCompilerPass(new FragmentRendererPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new SerializerPass()); + $container->addCompilerPass(new PropertyInfoPass()); if ($container->getParameter('kernel.debug')) { $container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml new file mode 100644 index 0000000000000..d4ce4f5d246f6 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 4190dad7cb787..4e382f677f71b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -33,6 +33,7 @@ + @@ -220,4 +221,8 @@ + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/PropertyInfoPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/PropertyInfoPassTest.php new file mode 100644 index 0000000000000..3d41fb12b09e5 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/PropertyInfoPassTest.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass; +use Symfony\Component\DependencyInjection\Reference; + +class PropertyInfoPassTest extends \PHPUnit_Framework_TestCase +{ + public function testServicesAreOrderedAccordingToPriority() + { + $services = array( + 'n3' => array('tag' => array()), + 'n1' => array('tag' => array('priority' => 200)), + 'n2' => array('tag' => array('priority' => 100)), + ); + + $expected = array( + new Reference('n1'), + new Reference('n2'), + new Reference('n3'), + ); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder', array('findTaggedServiceIds')); + + $container->expects($this->any()) + ->method('findTaggedServiceIds') + ->will($this->returnValue($services)); + + $propertyInfoPass = new PropertyInfoPass(); + + $method = new \ReflectionMethod( + 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass', + 'findAndSortTaggedServices' + ); + $method->setAccessible(true); + + $actual = $method->invoke($propertyInfoPass, 'tag', $container); + + $this->assertEquals($expected, $actual); + } + + public function testReturningEmptyArrayWhenNoService() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder', array('findTaggedServiceIds')); + + $container->expects($this->any()) + ->method('findTaggedServiceIds') + ->will($this->returnValue(array())); + + $propertyInfoPass = new PropertyInfoPass(); + + $method = new \ReflectionMethod( + 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass', + 'findAndSortTaggedServices' + ); + $method->setAccessible(true); + + $actual = $method->invoke($propertyInfoPass, 'tag', $container); + + $this->assertEquals(array(), $actual); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php index a098c4fd626ac..27f1636e8ce9d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php @@ -87,7 +87,7 @@ public function testServicesAreOrderedAccordingToPriority() $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder', array('findTaggedServiceIds')); - $container->expects($this->atLeastOnce()) + $container->expects($this->any()) ->method('findTaggedServiceIds') ->will($this->returnValue($services)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 04b6c95b46dae..48e9d9a0c57dd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -179,6 +179,9 @@ protected static function getBundleDefaultConfig() 'magic_call' => false, 'throw_exception_on_invalid_index' => false, ), + 'property_info' => array( + 'enabled' => false, + ), 'assets' => array( 'version' => null, 'version_format' => '%%s?%%s', diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/property_info.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/property_info.php new file mode 100644 index 0000000000000..847e15fa194ff --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/property_info.php @@ -0,0 +1,7 @@ +loadFromExtension('framework', array( + 'property_info' => array( + 'enabled' => true, + ), +)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/property_info.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/property_info.xml new file mode 100644 index 0000000000000..825bc46e74477 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/property_info.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/property_info.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/property_info.yml new file mode 100644 index 0000000000000..fbdf7a7b0d715 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/property_info.yml @@ -0,0 +1,3 @@ +framework: + property_info: + enabled: true diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index a722322993055..575668d652c71 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -488,6 +488,18 @@ public function testSerializerServiceIsNotRegisteredWhenDisabled() $this->assertFalse($container->hasDefinition('serializer')); } + public function testPropertyInfoDisabled() + { + $container = $this->createContainerFromFile('default_config'); + $this->assertFalse($container->has('property_info')); + } + + public function testPropertyInfoEnabled() + { + $container = $this->createContainerFromFile('property_info'); + $this->assertTrue($container->has('property_info')); + } + protected function createContainer(array $data = array()) { return new ContainerBuilder(new ParameterBag(array_merge(array( diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 3f529db8c1a84..f392453ff588e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -47,7 +47,9 @@ "symfony/expression-language": "~2.6|~3.0.0", "symfony/process": "~2.0,>=2.0.5|~3.0.0", "symfony/validator": "~2.5|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + "symfony/yaml": "~2.0,>=2.0.5|~3.0.0", + "symfony/property-info": "~2.8|~3.0.0", + "phpdocumentor/reflection": "^1.0.7" }, "suggest": { "symfony/console": "For using the console commands", @@ -55,7 +57,8 @@ "symfony/form": "For using forms", "symfony/serializer": "For using the serializer service", "symfony/validator": "For using validation", - "symfony/yaml": "For using the debug:config and lint:yaml commands" + "symfony/yaml": "For using the debug:config and lint:yaml commands", + "symfony/property-info": "For using the property_info_extractor service" }, "autoload": { "psr-4": { "Symfony\\Bundle\\FrameworkBundle\\": "" } 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