Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ee2b8c4

Browse files
committed
merged branch bschussek/bootstrap (PR #5112)
Commits ------- b982883 [Form] Moved FormHelper back to FrameworkBundle cb62d05 [Form] [Validator] Fixed issues mentioned in the PR 2185ca8 [Validator] Added entry point "Validation" for more convenient usage outside of Symfony2 ed87361 [Form] Moved FormHelper creation to TemplatingExtension 87ccb6a [Form] Added entry point "Forms" for more convenient usage outside of Symfony Discussion ---------- [Form] [Validator] Added more convenient entry points for stand-alone usage Bug fix: no Feature addition: no Backwards compatibility break: no Symfony2 tests pass: yes Fixes the following tickets: - Todo: - This PR greatly simplifies the usage of the Form and Validator component when used outside of Symfony2. Check out the below code to get an idea about the simplified usage: ```php <?php use Symfony\Component\Validator\Validation; use Symfony\Component\Validator\Mapping\Cache\ApcCache; use Symfony\Component\Form\Forms; use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension; use Symfony\Component\Form\Extension\Csrf\CsrfExtension; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider; use Symfony\Component\Form\Extension\Templating\TemplatingExtension; use Symfony\Component\Form\Extension\Validator\ValidatorExtension; use Symfony\Component\HttpFoundation\Session; use Symfony\Component\Templating\PhpEngine; $session = new Session(); $secret = 'V8a5Z97e...'; $csrfProvider = new SessionCsrfProvider($session, $secret); $engine = new PhpEngine(/* ... snap ... */); $validator = Validation::createValidator(); // or $validator = Validation::createValidatorBuilder() ->addXmlMapping('path/to/mapping.xml') ->addYamlMapping('path/to/mapping.yml') ->addMethodMapping('loadValidatorMetadata') ->enableAnnotationMapping() ->setMetadataCache(new ApcCache()) ->getValidator(); $formFactory = Forms::createFormFactory(); // or $formFactory = Forms::createFormFactoryBuilder() // custom types, if you're too lazy to create an extension :) ->addType(new PersonType()) ->addType(new PhoneNumberType()) ->addTypeExtension(new FormTypeHelpTextExtension()) // desired extensions (CoreExtension is loaded by default) ->addExtension(new HttpFoundationExtension()) ->addExtension(new CsrfExtension($csrfProvider)) ->addExtension(new TemplatingExtension($engine, $csrfProvider, array( 'FormBundle:Form' )) ->addExtension(new ValidatorExtension($validator)) ->getFormFactory(); $form = $formFactory->createBuilder() ->add('firstName', 'text') ->add('lastName', 'text') ->add('age', 'integer') ->add('gender', 'choice', array( 'choices' => array('m' => 'Male', 'f' => 'Female'), )) ->getForm(); if (isset($_POST[$form->getName()])) { $form->bind($_POST[$form->getName()]); if ($form->isValid()) { // do stuff } } return $engine->render('AcmeHelloBundle:Hello:index.html.php', array( 'form' => $form->createView(), )); ``` --------------------------------------------------------------------------- by bschussek at 2012-07-30T10:08:42Z I should maybe add a comment about the benefits of this change, in case they are not self-explanatory: * class construction with default configuration is now a one-liner * userland code is decoupled from core implementations → userland code doesn't break if we change constructor signatures * easier to understand, since many core classes are now created internally * easy to discover the possible settings → just look at (FormFactory|Validator)BuilderInterface * usage of custom interface implementations is supported, just like before --------------------------------------------------------------------------- by fabpot at 2012-07-31T08:18:53Z The new syntax is great. I have one comment though about this PR about support of PHP as a templating system (support for Twig is provided by the bridge and it was already easy to configure Twig as a templating system for forms -- see Silex for instance). The `FormHelper` has been moved into the Form component. This helper is only useful when using the PHP templating system (which is not what we recommend people to use), but the default templates are still in the Framework bundle. So using the Form component as standalone with PHP as a templating system still requires to install the bundle to get access to the default templates. Am I missing something? Do we want to move the PHP templates to the Form component too? --------------------------------------------------------------------------- by stof at 2012-07-31T08:28:28Z @fabpot it is even worse than that: the FormHelper currently uses the theme by using ``$theme . ':' . $block . '.html.php`` IIRC. This is not compatible with the default template name parser of the component expecting a path. And the FrameworkBundle template name parser does not support accessing a template outside a bundle AFAIK. So moving the templating to the component would require some refactoring in the FormHelper and the template name parser. However, I think it is worth it. Some people complained that using the form rendering (outside the full-stack framework) was requiring either setting up Twig with the bridge, or adding FrameworkBundle in the project (which means including most of the code of the full-stack framework). Having the Templating rendering in the standalone component could be a great idea --------------------------------------------------------------------------- by fabpot at 2012-07-31T08:42:53Z But then, I don't want to promote the Templating component or the PHP templating system. Twig is always a better alternative and this should be what people use most of the time, PHP being the rare exception. Anyway, we are too close from the first 2.1 RC, so any big refactoring will have to wait for 2.2. --------------------------------------------------------------------------- by stof at 2012-07-31T09:02:10Z then maybe we should keep the FormHelper in FrameworkBundle for now as it is tied to the FrameworkBundle template name parser anyway currently. --------------------------------------------------------------------------- by bschussek at 2012-07-31T14:22:35Z > it it is even worse than that: the FormHelper currently uses the theme by using ``$theme . ':' . $block . '.html.php`` IIRC. This is not compatible with the default template name parser of the component expecting a path. This is why the templates are still in FrameworkBundle. I think they should be moved too, but then we have to change * the default theme to an absolute file path * the FrameworkBundle name parser to accept absolute paths I think this can wait until 2.2. Baby steps. > I don't want to promote the Templating component or the PHP templating system. We can both promote Twig while making Templating as easy to use as possible. If people want to use Templating, they probably have a reason. We don't have to make their lives more painful than necessary. Btw: Templating is a *lot* faster for rendering forms than Twig. On Denis' form, Templating takes 1.15 seconds while Twig takes 2. About moving the helpers, we have two choices: * Move each helper to the respective component. This would not require new releases of the Templating component when we add more helpers in other component. * Move all helpers to Templating. This does not make that much sense for Form, as then Form has support for Templating (TemplatingRendererEngine) and Templating has support for Form (FormHelper), which is a bit weird. I personally prefer a stacked architecture, where Templating is at the bottom and Form-agnostic, and Form (or any other component) builds upon that. I'm fine with both approaches. I'll move FormHelper back to FrameworkBundle, and we can decide for a direction in 2.2. --------------------------------------------------------------------------- by bschussek at 2012-07-31T14:36:30Z Done.
2 parents 4b52198 + b982883 commit ee2b8c4

23 files changed

+1288
-92
lines changed

UPGRADE-2.1.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,25 @@
12711271
private $password;
12721272
```
12731273
1274+
* The classes `ValidatorContext` and `ValidatorFactory` were deprecated and
1275+
will be removed in Symfony 2.3. You should use the new entry point
1276+
`Validation` instead.
1277+
1278+
Before:
1279+
1280+
```
1281+
$validator = ValidatorFactory::buildDefault(array('path/to/mapping.xml'))
1282+
->getValidator();
1283+
```
1284+
1285+
After:
1286+
1287+
```
1288+
$validator = Validation::createValidatorBuilder()
1289+
->addXmlMapping('path/to/mapping.xml')
1290+
->getValidator();
1291+
```
1292+
12741293
### Session
12751294
12761295
* Flash messages now return an array based on their type. The old method is

src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,80 +11,98 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper;
1313

14-
use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper;
15-
use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper;
14+
use Symfony\Component\Form\FormView;
15+
use Symfony\Component\Form\Extension\Templating\TemplatingExtension;
16+
use Symfony\Component\Form\Tests\AbstractDivLayoutTest;
1617
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser;
1718
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator;
1819
use Symfony\Component\Templating\PhpEngine;
1920
use Symfony\Component\Templating\Loader\FilesystemLoader;
20-
use Symfony\Component\Form\FormView;
21-
use Symfony\Component\Form\FormRenderer;
22-
use Symfony\Component\Form\Extension\Templating\TemplatingRendererEngine;
23-
use Symfony\Component\Form\Tests\AbstractDivLayoutTest;
21+
22+
// should probably be moved to the Translation component
23+
use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper;
2424

2525
class FormHelperDivLayoutTest extends AbstractDivLayoutTest
2626
{
27-
protected $helper;
27+
/**
28+
* @var PhpEngine
29+
*/
30+
protected $engine;
2831

2932
protected function setUp()
3033
{
34+
if (!class_exists('Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper')) {
35+
$this->markTestSkipped('The "FrameworkBundle" is not available');
36+
}
37+
38+
if (!class_exists('Symfony\Component\Templating\PhpEngine')) {
39+
$this->markTestSkipped('The "Templating" component is not available');
40+
}
41+
3142
parent::setUp();
43+
}
3244

33-
$root = realpath(__DIR__.'/../../../Resources/views');
45+
protected function getExtensions()
46+
{
47+
// should be moved to the Form component once absolute file paths are supported
48+
// by the default name parser in the Templating component
49+
$reflClass = new \ReflectionClass('Symfony\Bundle\FrameworkBundle\FrameworkBundle');
50+
$root = realpath(dirname($reflClass->getFileName()) . '/Resources/views');
3451
$rootTheme = realpath(__DIR__.'/Resources');
3552
$templateNameParser = new StubTemplateNameParser($root, $rootTheme);
3653
$loader = new FilesystemLoader(array());
37-
$engine = new PhpEngine($templateNameParser, $loader);
38-
$engine->addGlobal('global', '');
39-
$rendererEngine = new TemplatingRendererEngine($engine, array('FrameworkBundle:Form'));
40-
$renderer = new FormRenderer($rendererEngine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'));
4154

42-
$this->helper = new FormHelper($renderer);
43-
44-
$engine->setHelpers(array(
45-
$this->helper,
55+
$this->engine = new PhpEngine($templateNameParser, $loader);
56+
$this->engine->addGlobal('global', '');
57+
$this->engine->setHelpers(array(
4658
new TranslatorHelper(new StubTranslator()),
4759
));
60+
61+
return array_merge(parent::getExtensions(), array(
62+
new TemplatingExtension($this->engine, $this->csrfProvider, array(
63+
'FrameworkBundle:Form',
64+
)),
65+
));
4866
}
4967

5068
protected function tearDown()
5169
{
52-
$this->helper = null;
70+
$this->engine = null;
5371
}
5472

5573
protected function renderEnctype(FormView $view)
5674
{
57-
return (string) $this->helper->enctype($view);
75+
return (string) $this->engine->get('form')->enctype($view);
5876
}
5977

6078
protected function renderLabel(FormView $view, $label = null, array $vars = array())
6179
{
62-
return (string) $this->helper->label($view, $label, $vars);
80+
return (string) $this->engine->get('form')->label($view, $label, $vars);
6381
}
6482

6583
protected function renderErrors(FormView $view)
6684
{
67-
return (string) $this->helper->errors($view);
85+
return (string) $this->engine->get('form')->errors($view);
6886
}
6987

7088
protected function renderWidget(FormView $view, array $vars = array())
7189
{
72-
return (string) $this->helper->widget($view, $vars);
90+
return (string) $this->engine->get('form')->widget($view, $vars);
7391
}
7492

7593
protected function renderRow(FormView $view, array $vars = array())
7694
{
77-
return (string) $this->helper->row($view, $vars);
95+
return (string) $this->engine->get('form')->row($view, $vars);
7896
}
7997

8098
protected function renderRest(FormView $view, array $vars = array())
8199
{
82-
return (string) $this->helper->rest($view, $vars);
100+
return (string) $this->engine->get('form')->rest($view, $vars);
83101
}
84102

85103
protected function setTheme(FormView $view, array $themes)
86104
{
87-
$this->helper->setTheme($view, $themes);
105+
$this->engine->get('form')->setTheme($view, $themes);
88106
}
89107

90108
public static function themeBlockInheritanceProvider()

src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,82 +11,98 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper;
1313

14-
use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper;
15-
use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper;
16-
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser;
17-
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator;
1814
use Symfony\Component\Form\FormView;
19-
use Symfony\Component\Form\FormRenderer;
20-
use Symfony\Component\Form\Extension\Templating\TemplatingRendererEngine;
15+
use Symfony\Component\Form\Extension\Templating\TemplatingExtension;
2116
use Symfony\Component\Form\Tests\AbstractTableLayoutTest;
17+
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser;
18+
use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator;
2219
use Symfony\Component\Templating\PhpEngine;
2320
use Symfony\Component\Templating\Loader\FilesystemLoader;
2421

22+
// should probably be moved to the Translation component
23+
use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper;
24+
2525
class FormHelperTableLayoutTest extends AbstractTableLayoutTest
2626
{
27-
protected $helper;
27+
/**
28+
* @var PhpEngine
29+
*/
30+
protected $engine;
2831

2932
protected function setUp()
3033
{
34+
if (!class_exists('Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper')) {
35+
$this->markTestSkipped('The "FrameworkBundle" is not available');
36+
}
37+
38+
if (!class_exists('Symfony\Component\Templating\PhpEngine')) {
39+
$this->markTestSkipped('The "Templating" component is not available');
40+
}
41+
3142
parent::setUp();
43+
}
3244

33-
$root = realpath(__DIR__.'/../../../Resources/views');
45+
protected function getExtensions()
46+
{
47+
// should be moved to the Form component once absolute file paths are supported
48+
// by the default name parser in the Templating component
49+
$reflClass = new \ReflectionClass('Symfony\Bundle\FrameworkBundle\FrameworkBundle');
50+
$root = realpath(dirname($reflClass->getFileName()) . '/Resources/views');
3451
$rootTheme = realpath(__DIR__.'/Resources');
3552
$templateNameParser = new StubTemplateNameParser($root, $rootTheme);
3653
$loader = new FilesystemLoader(array());
37-
$engine = new PhpEngine($templateNameParser, $loader);
38-
$engine->addGlobal('global', '');
39-
$rendererEngine = new TemplatingRendererEngine($engine, array(
40-
'FrameworkBundle:Form',
41-
'FrameworkBundle:FormTable'
42-
));
43-
$renderer = new FormRenderer($rendererEngine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'));
4454

45-
$this->helper = new FormHelper($renderer);
46-
47-
$engine->setHelpers(array(
48-
$this->helper,
55+
$this->engine = new PhpEngine($templateNameParser, $loader);
56+
$this->engine->addGlobal('global', '');
57+
$this->engine->setHelpers(array(
4958
new TranslatorHelper(new StubTranslator()),
5059
));
60+
61+
return array_merge(parent::getExtensions(), array(
62+
new TemplatingExtension($this->engine, $this->csrfProvider, array(
63+
'FrameworkBundle:Form',
64+
'FrameworkBundle:FormTable',
65+
)),
66+
));
5167
}
5268

5369
protected function tearDown()
5470
{
55-
$this->helper = null;
71+
$this->engine = null;
5672
}
5773

5874
protected function renderEnctype(FormView $view)
5975
{
60-
return (string) $this->helper->enctype($view);
76+
return (string) $this->engine->get('form')->enctype($view);
6177
}
6278

6379
protected function renderLabel(FormView $view, $label = null, array $vars = array())
6480
{
65-
return (string) $this->helper->label($view, $label, $vars);
81+
return (string) $this->engine->get('form')->label($view, $label, $vars);
6682
}
6783

6884
protected function renderErrors(FormView $view)
6985
{
70-
return (string) $this->helper->errors($view);
86+
return (string) $this->engine->get('form')->errors($view);
7187
}
7288

7389
protected function renderWidget(FormView $view, array $vars = array())
7490
{
75-
return (string) $this->helper->widget($view, $vars);
91+
return (string) $this->engine->get('form')->widget($view, $vars);
7692
}
7793

7894
protected function renderRow(FormView $view, array $vars = array())
7995
{
80-
return (string) $this->helper->row($view, $vars);
96+
return (string) $this->engine->get('form')->row($view, $vars);
8197
}
8298

8399
protected function renderRest(FormView $view, array $vars = array())
84100
{
85-
return (string) $this->helper->rest($view, $vars);
101+
return (string) $this->engine->get('form')->rest($view, $vars);
86102
}
87103

88104
protected function setTheme(FormView $view, array $themes)
89105
{
90-
$this->helper->setTheme($view, $themes);
106+
$this->engine->get('form')->setTheme($view, $themes);
91107
}
92108
}

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,4 @@ CHANGELOG
177177
* made FormView properties public and deprecated their accessor methods
178178
* made the normalized data of a form accessible in the template through the variable "form.vars.data"
179179
* made the original data of a choice accessible in the template through the property "choice.data"
180+
* added convenience class Forms and FormFactoryBuilderInterface
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Extension\Templating;
13+
14+
use Symfony\Component\Form\AbstractExtension;
15+
use Symfony\Component\Form\FormRenderer;
16+
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
17+
use Symfony\Component\Templating\PhpEngine;
18+
use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper;
19+
20+
/**
21+
* Integrates the Templating component with the Form library.
22+
*
23+
* @author Bernhard Schussek <[email protected]>
24+
*/
25+
class TemplatingExtension extends AbstractExtension
26+
{
27+
public function __construct(PhpEngine $engine, CsrfProviderInterface $csrfProvider = null, array $defaultThemes = array())
28+
{
29+
$engine->addHelpers(array(
30+
new FormHelper(new FormRenderer(new TemplatingRendererEngine($engine, $defaultThemes), $csrfProvider))
31+
));
32+
}
33+
}

src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
use Symfony\Component\Validator\ValidatorInterface;
1818
use Symfony\Component\Validator\Constraints\Valid;
1919

20+
/**
21+
* Extension supporting the Symfony2 Validator component in forms.
22+
*
23+
* @author Bernhard Schussek <[email protected]>
24+
*/
2025
class ValidatorExtension extends AbstractExtension
2126
{
2227
private $validator;
@@ -25,6 +30,12 @@ public function __construct(ValidatorInterface $validator)
2530
{
2631
$this->validator = $validator;
2732

33+
// Register the form constraints in the validator programmatically.
34+
// This functionality is required when using the Form component without
35+
// the DIC, where the XML file is loaded automatically. Thus the following
36+
// code must be kept synchronized with validation.xml
37+
38+
/** @var \Symfony\Component\Validator\Mapping\ClassMetadata $metadata */
2839
$metadata = $this->validator->getMetadataFactory()->getClassMetadata('Symfony\Component\Form\Form');
2940
$metadata->addConstraint(new Form());
3041
$metadata->addPropertyConstraint('children', new Valid());

src/Symfony/Component/Form/FormFactory.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ public function __construct(FormRegistryInterface $registry, ResolvedFormTypeFac
3737
/**
3838
* {@inheritdoc}
3939
*/
40-
public function create($type, $data = null, array $options = array(), FormBuilderInterface $parent = null)
40+
public function create($type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null)
4141
{
4242
return $this->createBuilder($type, $data, $options, $parent)->getForm();
4343
}
4444

4545
/**
4646
* {@inheritdoc}
4747
*/
48-
public function createNamed($name, $type, $data = null, array $options = array(), FormBuilderInterface $parent = null)
48+
public function createNamed($name, $type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null)
4949
{
5050
return $this->createNamedBuilder($name, $type, $data, $options, $parent)->getForm();
5151
}
@@ -61,7 +61,7 @@ public function createForProperty($class, $property, $data = null, array $option
6161
/**
6262
* {@inheritdoc}
6363
*/
64-
public function createBuilder($type, $data = null, array $options = array(), FormBuilderInterface $parent = null)
64+
public function createBuilder($type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null)
6565
{
6666
$name = $type instanceof FormTypeInterface || $type instanceof ResolvedFormTypeInterface
6767
? $type->getName()
@@ -73,7 +73,7 @@ public function createBuilder($type, $data = null, array $options = array(), For
7373
/**
7474
* {@inheritdoc}
7575
*/
76-
public function createNamedBuilder($name, $type, $data = null, array $options = array(), FormBuilderInterface $parent = null)
76+
public function createNamedBuilder($name, $type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null)
7777
{
7878
if (null !== $data && !array_key_exists('data', $options)) {
7979
$options['data'] = $data;

0 commit comments

Comments
 (0)