diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index c9a4482b0b94c..40a5a50e796e9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -120,6 +120,7 @@ private function addFormSection(ArrayNodeDefinition $rootNode)
->info('form configuration')
->canBeEnabled()
->children()
+ ->scalarNode('auto_label')->end()
->arrayNode('csrf_protection')
->treatFalseLike(array('enabled' => false))
->treatTrueLike(array('enabled' => true))
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index f9146c242e044..0983ee1f5b77d 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -177,6 +177,11 @@ private function registerFormConfiguration($config, ContainerBuilder $container,
$config['form']['csrf_protection']['enabled'] = $config['csrf_protection']['enabled'];
}
+ if (array_key_exists('auto_label', $config['form'])) {
+ $loader->load('form_auto_label.xml');
+ $container->setParameter('form.type_extension.auto_label.auto_label', $config['form']['auto_label']);
+ }
+
if ($this->isConfigEnabled($container, $config['form']['csrf_protection'])) {
$loader->load('form_csrf.xml');
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_auto_label.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_auto_label.xml
new file mode 100644
index 0000000000000..a6d8bf1a77a5f
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_auto_label.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+ %form.type_extension.auto_label.auto_label%
+
+
+
diff --git a/src/Symfony/Component/Form/Extension/AutoLabel/AutoLabelExtension.php b/src/Symfony/Component/Form/Extension/AutoLabel/AutoLabelExtension.php
new file mode 100644
index 0000000000000..43425f062f8a8
--- /dev/null
+++ b/src/Symfony/Component/Form/Extension/AutoLabel/AutoLabelExtension.php
@@ -0,0 +1,54 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\Extension\AutoLabel;
+
+use Symfony\Component\Form\AbstractExtension;
+
+/**
+ * Extension for automated label generation.
+ *
+ * @since 2.7
+ * @author Alexandre Salomé
+ */
+class AutoLabelExtension extends AbstractExtension
+{
+ /**
+ * @var string
+ */
+ private $autoLabel;
+
+ /**
+ * Constructs a new form extension.
+ *
+ * The argument "autoLabel" can have placeholders:
+ *
+ * - %type% : the form type name (ex: text, choice, date)
+ * - %name% : the name of the form (ex: firstname)
+ * - %fullname%: the full name of the form (ex: user_firstname)
+ *
+ * @param string $autoLabel a default label for forms
+ */
+ public function __construct($autoLabel)
+ {
+ $this->autoLabel = $autoLabel;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function loadTypeExtensions()
+ {
+ return array(
+ new Type\AutoLabelTypeExtension($this->autoLabel)
+ );
+ }
+}
diff --git a/src/Symfony/Component/Form/Extension/AutoLabel/Type/AutoLabelTypeExtension.php b/src/Symfony/Component/Form/Extension/AutoLabel/Type/AutoLabelTypeExtension.php
new file mode 100644
index 0000000000000..e238274f6d733
--- /dev/null
+++ b/src/Symfony/Component/Form/Extension/AutoLabel/Type/AutoLabelTypeExtension.php
@@ -0,0 +1,99 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\Extension\AutoLabel\Type;
+
+use Symfony\Component\Form\AbstractTypeExtension;
+use Symfony\Component\Form\FormInterface;
+use Symfony\Component\Form\FormView;
+use Symfony\Component\OptionsResolver\Options;
+use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+
+/**
+ * Extension for automated label generation.
+ *
+ * @since 2.7
+ * @author Alexandre Salomé
+ */
+class AutoLabelTypeExtension extends AbstractTypeExtension
+{
+ /**
+ * @var string
+ */
+ private $autoLabel;
+
+ /**
+ * Constructs a new type extension.
+ *
+ * The argument "autoLabel" can have placeholders:
+ *
+ * - %type% : the form type name (ex: text, choice, date)
+ * - %name% : the name of the form (ex: firstname)
+ * - %fullname%: the full name of the form (ex: user_firstname)
+ *
+ * @param string $autoLabel a default label for forms
+ */
+ public function __construct($autoLabel = 'form.%type%.label.%name%')
+ {
+ $this->autoLabel = $autoLabel;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getExtendedType()
+ {
+ return 'form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildView(FormView $view, FormInterface $form, array $options)
+ {
+ if (null === $options['label']) {
+ $autoLabel = $options['auto_label'];
+ $parent = $form->getParent();
+ $fullname = $form->getName();
+
+ while ($parent) {
+ if (null === $autoLabel) {
+ $autoLabel = $parent->getConfig()->getOption('auto_label');
+ }
+ $fullname = $parent->getName().'_'.$fullname;
+ $parent = $parent->getParent();
+ }
+
+ if (null === $autoLabel) {
+ $autoLabel = $this->autoLabel;
+ }
+
+
+ if (null !== $autoLabel) {
+ $view->vars['label'] = strtr($autoLabel, array(
+ '%name%' => $form->getName(),
+ '%fullname%' => $fullname,
+ '%type%' => $form->getConfig()->getType()->getName(),
+ ));
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDefaultOptions(OptionsResolverInterface $resolver)
+ {
+ $resolver->setDefaults(array(
+ 'auto_label' => null
+ ));
+ }
+}
diff --git a/src/Symfony/Component/Form/Tests/Extension/AutoLabel/AutoLabelExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/AutoLabel/AutoLabelExtensionTest.php
new file mode 100644
index 0000000000000..6ded4ac4c08ee
--- /dev/null
+++ b/src/Symfony/Component/Form/Tests/Extension/AutoLabel/AutoLabelExtensionTest.php
@@ -0,0 +1,39 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\Tests\Extension\AutoLabel;
+
+use Symfony\Component\Form\Extension\AutoLabel\AutoLabelExtension;
+
+/**
+ * @covers Symfony\Component\Form\Extension\AutoLabel\AutoLabelExtension
+ */
+class AutoLabelExtensionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var AutoLabelExtension
+ */
+ private $extension;
+
+ public function setUp()
+ {
+ $this->extension = new AutoLabelExtension('foo');
+ }
+
+ public function testLoadTypeExtensions()
+ {
+ $typeExtensions = $this->extension->getTypeExtensions('form');
+
+ $this->assertInternalType('array', $typeExtensions);
+ $this->assertCount(1, $typeExtensions);
+ $this->assertInstanceOf('Symfony\Component\Form\Extension\AutoLabel\Type\AutoLabelTypeExtension', array_shift($typeExtensions));
+ }
+}
diff --git a/src/Symfony/Component/Form/Tests/Extension/AutoLabel/Type/AutoLabelTypeExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/AutoLabel/Type/AutoLabelTypeExtensionTest.php
new file mode 100644
index 0000000000000..ec3fd03fc6a88
--- /dev/null
+++ b/src/Symfony/Component/Form/Tests/Extension/AutoLabel/Type/AutoLabelTypeExtensionTest.php
@@ -0,0 +1,80 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\Tests\Extension\AutoLabel\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Form\Test\TypeTestCase;
+use Symfony\Component\Form\Extension\AutoLabel\AutoLabelExtension;
+
+class AutoLabelTypeExtensionTest_ChildType extends AbstractType
+{
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ $builder->add('name', 'text');
+ }
+
+ public function getName()
+ {
+ return 'auto_label_test';
+ }
+}
+
+class AutoLabelTypeExtensionTest extends TypeTestCase
+{
+ protected function getExtensions()
+ {
+ return array_merge(parent::getExtensions(), array(
+ new AutoLabelExtension('%fullname%.%name%.%type%'),
+ ));
+ }
+
+ public function testDefaultLabelGeneration()
+ {
+ $view = $this->factory->createNamed('firstname', 'text')->createView();
+ $this->assertEquals('firstname.firstname.text', $view->vars['label']);
+ }
+
+ public function testFullnameGeneration()
+ {
+ $view = $this->factory
+ ->createBuilder('form')
+ ->add('form', 'form', array('auto_label' => '%fullname%'))
+ ->getForm()
+ ->createView()
+ ;
+
+ $this->assertEquals('form_form', $view['form']->vars['label']);
+ }
+
+ public function testForcedGeneration()
+ {
+ $view = $this->factory->createNamed('firstname', 'text', null, array('auto_label' => '%fullname%'))->createView();
+ $this->assertEquals('firstname', $view->vars['label']);
+ }
+
+ public function testOverridenLabelGeneration()
+ {
+ $view = $this->factory->createNamed('firstname', 'text', null, array('auto_label' => 'foo.%name%'))->createView();
+ $this->assertEquals('foo.firstname', $view->vars['label']);
+ }
+
+ public function testInheritedOption()
+ {
+ $builder = $this->factory->createNamedBuilder('user', 'form', null, array(
+ 'auto_label' => '%type%.%fullname%'
+ ));
+
+ $view = $builder->add('firstname', 'text')->getForm()->createView();
+ $this->assertEquals('text.user_firstname', $view['firstname']->vars['label']);
+ }
+}