Created
November 22, 2011 21:16
-
-
Save nclavaud/1386997 to your computer and use it in GitHub Desktop.
Symfony2 standalone Form component example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @author Nicolas Clavaud <nclavaud@gmail.com> | |
* http://n.clavaud.free.fr/blog/index.php?article31/symfony2-standalone-form-component-tutorial | |
*/ | |
namespace Me\MyApp; | |
use Symfony\Component\ClassLoader\UniversalClassLoader; | |
use Symfony\Component\Form\AbstractType; | |
use Symfony\Component\Form\FormBuilder; | |
use Symfony\Component\Form\FormFactory; | |
use Symfony\Component\Form\Extension\Core\CoreExtension; | |
use Symfony\Component\EventDispatcher\EventDispatcher; | |
use Symfony\Component\Templating\TemplateNameParser; | |
use Symfony\Component\Templating\TemplateNameParserInterface; | |
use Symfony\Component\Templating\TemplateReference; | |
use Symfony\Component\Templating\Loader\FilesystemLoader; | |
use Symfony\Component\Templating\PhpEngine; | |
use Symfony\Component\Translation\MessageSelector; | |
use Symfony\Component\Translation\Translator; | |
use Symfony\Component\Translation\TranslatorInterface; | |
use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper; | |
use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper; | |
// validation | |
use Symfony\Component\Form\Extension\Validator\ValidatorExtension; | |
use Symfony\Component\Validator\Validator; | |
use Symfony\Component\Validator\Mapping\ClassMetadata; | |
use Symfony\Component\Validator\Mapping\ClassMetadataFactory; | |
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader; | |
use Symfony\Component\Validator\ConstraintValidatorFactory; | |
use Symfony\Component\Validator\Constraints as Constraints; | |
/** | |
* Load and configure autoloader | |
* @see http://symfony.com/doc/2.0/cookbook/tools/autoloader.html | |
*/ | |
require_once 'Symfony/Component/ClassLoader/UniversalClassLoader.php'; | |
$loader = new UniversalClassLoader(); | |
$loader->register(); | |
$loader->registerNamespace('Symfony', __DIR__.'/'); | |
/** | |
* Parameters | |
*/ | |
$locale = null; | |
/** | |
* Entity | |
*/ | |
class Message | |
{ | |
public $sender; | |
public $recipient; | |
public $message; | |
// validation | |
public static function loadValidatorMetadata(ClassMetadata $metadata) | |
{ | |
$metadata->addPropertyConstraint('sender', new Constraints\NotBlank()); | |
$metadata->addPropertyConstraint('sender', new Constraints\Email()); | |
$metadata->addPropertyConstraint('recipient', new Constraints\NotBlank()); | |
$metadata->addPropertyConstraint('recipient', new Constraints\Email()); | |
$metadata->addPropertyConstraint('message', new Constraints\NotBlank()); | |
$metadata->addPropertyConstraint('message', new Constraints\MinLength(10)); | |
} | |
} | |
/** | |
* Form Class | |
* @see http://symfony.com/doc/2.0/book/forms.html#creating-form-classes | |
*/ | |
class MessageType extends AbstractType | |
{ | |
public function buildForm(FormBuilder $builder, array $options) | |
{ | |
$builder | |
->add('sender', 'email') | |
->add('recipient', 'email') | |
->add('message', 'textarea'); | |
} | |
public function getName() | |
{ | |
return 'message'; | |
} | |
public function getDefaultOptions(array $options) | |
{ | |
return array( | |
'data_class' => 'Me\MyApp\Message', | |
); | |
} | |
} | |
/** | |
* Template name parser | |
* @see Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser | |
* | |
* Needed to load the templates used for rendering form items. | |
*/ | |
class StubTemplateNameParser implements TemplateNameParserInterface | |
{ | |
private $root; | |
private $rootTheme; | |
public function __construct($root, $rootTheme) | |
{ | |
$this->root = $root; | |
$this->rootTheme = $rootTheme; | |
} | |
public function parse($name) | |
{ | |
list($bundle, $controller, $template) = explode(':', $name); | |
if ($template[0] == '_') { | |
$path = $this->rootTheme.'/Custom/'.$template; | |
} elseif ($bundle === 'TestBundle') { | |
$path = $this->rootTheme.'/'.$controller.'/'.$template; | |
} else { | |
$path = $this->root.'/'.$controller.'/'.$template; | |
} | |
return new TemplateReference($path, 'php'); | |
} | |
} | |
/** | |
* Create an entity | |
*/ | |
$message = new Message(); | |
$message->sender = 'nclavaud@gmail.com'; | |
/** | |
* Build a form from a form factory | |
*/ | |
$form_factory = new FormFactory(array( | |
new CoreExtension(), | |
// validation | |
new ValidatorExtension( | |
new Validator( | |
new ClassMetadataFactory( | |
new StaticMethodLoader() | |
), | |
new ConstraintValidatorFactory() | |
) | |
) | |
)); | |
$form = $form_factory->create(new MessageType(), $message); | |
/** | |
* Create a PHP template engine | |
*/ | |
$root = realpath(__DIR__ . '/Symfony/Bundle/FrameworkBundle/Resources/views'); | |
$rootTheme = realpath(__DIR__ . '/Symfony/Bundle/FrameworkBundle/Resources'); | |
$templateNameParser = new StubTemplateNameParser($root, $rootTheme); | |
$loader = new FilesystemLoader(array()); | |
$engine = new PhpEngine($templateNameParser, $loader); | |
/** | |
* This helper will help rendering form items | |
*/ | |
$form_helper = new FormHelper($engine, array( | |
'FrameworkBundle:Form', | |
)); | |
/** | |
* Bind it to the engine | |
*/ | |
$engine->setHelpers(array( | |
$form_helper, | |
new TranslatorHelper(new Translator($locale, new MessageSelector())), | |
)); | |
/** | |
* Bind submitted data | |
*/ | |
$submitted = false; | |
$valid = null; | |
if (isset($_POST[$form->getName()])) { | |
$form->bind($_POST[$form->getName()]); | |
$submitted = true; | |
// validation | |
if ($valid = $form->isValid()) { | |
// you may want to redirect at this state | |
} | |
} | |
/** | |
* Create the form view | |
*/ | |
$form_view = $form->createView(); | |
/** | |
* Now, it's time to render HTML! | |
*/ | |
header('Content-type: text/html; charset=utf-8'); | |
?> | |
<!DOCTYPE html> | |
<html> | |
<body> | |
<form action="" method="post" | |
<?php print $form_helper->enctype($form_view) ?> | |
novalidate="novalidate"> | |
<?php print $form_helper->widget($form_view) ?></div> | |
<input type="submit" /> | |
</form> | |
<?php if ($submitted && $valid) : ?> | |
<p><strong>Submitted form is valid.</strong></p> | |
<?php endif; ?> | |
<p><em>Message object:</em></p> | |
<pre><?php print print_r($message, true); ?></pre> | |
</body> | |
</html> |
Thanks nclavaud for this example, it's been very useful for me!
Big thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://api.symfony.com/2.3/Symfony/Component/Form/Forms.html
Here there's an explanation of how to add all needed Extensions to the Form Component, so it can be rendered in a template, validated, Csrf Protected, Translated, etc...
protected function getFormExtensions()
{
// should be moved to the Form component once absolute file paths are supported
// by the default name parser in the Templating component
$reflClass = new \ReflectionClass('Symfony\Bundle\FrameworkBundle\FrameworkBundle');
$root = realpath(dirname($reflClass->getFileName()).'/Resources/views');
$rootTheme = realpath(DIR.'/Resources');
$templateNameParser = new FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser($root, $rootTheme);
$loader = new \Symfony\Component\Templating\Loader\FilesystemLoader(array());
Then you just need acces to the PhpEngine->get('form') helper's form() method with an instance of a $formView
My compser.json "require": { "symfony/form": "_", "symfony/validator": "_", "symfony/http-foundation": "_", "symfony/framework-bundle": "_", "symfony/routing": "_", "symfony/http-kernel": "_", "symfony/event-dispatcher": "*" },