The new form framework
-
Upload
bernhard-schussek -
Category
Technology
-
view
12.315 -
download
4
Transcript of The new form framework
![Page 1: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/1.jpg)
The new form frameworkBernhard Schussek
![Page 2: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/2.jpg)
What is different in the new form framework?
![Page 3: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/3.jpg)
Domain Model
sfForm
User
symfony 1.x
Controller
![Page 4: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/4.jpg)
Domain Model
sfForm
User
symfony 1.x
Controller Business Logic
![Page 5: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/5.jpg)
Domain Model
sfForm
User
Controller Business Logic
unit testable!!
symfony 1.x
![Page 6: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/6.jpg)
Domain Model
sfFormDoctrine / sfFormPropel
User
symfony 1.x
function configure(){ unset($this['foo']); unset($this['bar']); unset($this['moo']); unset($this['comeon!']); ...
![Page 7: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/7.jpg)
New architecture
![Page 8: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/8.jpg)
Simplicity and Reusability
![Page 9: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/9.jpg)
Embrace your domain model
![Page 10: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/10.jpg)
Domain Model
Form
User
Symfony 2
![Page 11: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/11.jpg)
Domain Model
Form
User
Symfony 2
Presentation
Business Logic
designed by you™
![Page 12: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/12.jpg)
class Customer{
public $name = 'Default';
public getGender();
public setGender($gender);
}
Business Logic
![Page 13: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/13.jpg)
Business Logic Presentation
class Customer{
public $name = 'Default';
public getGender();
public setGender($gender);
}
Form
TextField
ChoiceField
![Page 14: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/14.jpg)
$form = new Form('customer', $customer, ...);
$form->add(new TextField('name'));
$form->add(new ChoiceField('gender', array( 'choices' => array('male', 'female'),)));
![Page 15: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/15.jpg)
$form = new Form('customer', $customer, ...);
...
if (isset($_POST['customer'])){ $form->bind($_POST['customer']);}
![Page 16: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/16.jpg)
Business Logic Presentation
class Customer{
public $address;
}
Form
FieldGroupto-one relations
![Page 17: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/17.jpg)
$group = new FieldGroup('address');
$group->add(...);$group->add(...);$group->add(...);
$form->add($group);
![Page 18: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/18.jpg)
Business Logic Presentation
class Customer{
public $emails;
}
Form
CollectionField
FieldGroup
FieldGroup
to-many relations
![Page 19: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/19.jpg)
$group = new FieldGroup('emails');
$group->add(...);$group->add(...);
$form->add(new CollectionField($group));
![Page 20: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/20.jpg)
TextField
TextareaField
CheckboxField
ChoiceField
PasswordField
HiddenField
NumberField
IntegerField
PercentField
MoneyField
DateField
BirthdayField
TimeField
TimezoneField
DateTimeField
RepeatedField
CollectionField
FieldGroup
Default Localized
Special
![Page 21: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/21.jpg)
CheckboxField CheckboxField
ChoiceField ChoiceField
DateField
?
● Field groups— light-weight subforms— compose other fields or field groups
![Page 22: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/22.jpg)
Form Rendering
![Page 23: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/23.jpg)
<?php echo $form->renderFormTag('url') ?>
<?php echo $form->renderErrors() ?> <?php echo $form->render() ?>
<input type="submit" value="Submit" />
</form>
![Page 24: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/24.jpg)
<label for="<?php echo $form['name']->getId() ?>"> Enter a name</label>
<?php echo $form['name']->renderErrors() ?><?php echo $form['name']->render() ?>
![Page 25: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/25.jpg)
<?php echo $form['date']['day']->render() ?><?php echo $form['date']['month']->render() ?><?php echo $form['date']['year']->render() ?>
![Page 26: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/26.jpg)
Validation
![Page 27: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/27.jpg)
symfony 1.x
sfForm
sfValidator
Domain Model
Doctrine_Validator
Controller
![Page 28: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/28.jpg)
symfony 1.x
sfForm
sfValidator
Domain Model
Doctrine_Validator
Controller Duplicate validationlogic
Failed validationleads to 505 errors
![Page 29: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/29.jpg)
Symfony 2
Form
Domain Model
![Page 30: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/30.jpg)
Symfony 2
Form
Domain Model
Validator
![Page 31: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/31.jpg)
Symfony 2
Form
Domain Model
Validator
Validation Metadata
"how shall the domain model be validated?"
![Page 32: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/32.jpg)
Customer: properties: name: - MinLength: 6 birthday: - Date: ~ gender: - Choice: [male, female]
![Page 33: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/33.jpg)
<class name="Customer"> <property name="name"> <constraint name="MinLength">6</constraint> </property> <property name="birthday"> <constraint name="Date" /> </property> <property name="gender"> <constraint name="Choice"> <value>male</value> <value>female</value> </constraint> </property></class>
![Page 34: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/34.jpg)
class Customer{ /** @Validation({ @MinLength(6) }) */ public $name;
/** @Validation({ @Choice({"male", "female"}) }) */ public function getGender();
/** @Validation({ @Valid }) */ public $gender;}
![Page 35: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/35.jpg)
AssertTrue
AssertFalse
Blank
Null
Blank
NotBlank
NotNull
AssertType
Choice
Valid
Collection
Date
DateTime
Time
File
Min
MaxMaxLength Max
MinLength
Regex
Url
Type Check String Other
![Page 36: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/36.jpg)
● Constraints can be put on— Classes— Properties— Methods with a "get" or "is" prefix
![Page 37: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/37.jpg)
$validator = $container->getService('validator');
$validator->validate($customer);
![Page 38: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/38.jpg)
Independent from Symfony 2
Doctrine 2Zend Propel
![Page 39: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/39.jpg)
How does all this fit into the form framework?
![Page 40: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/40.jpg)
$form = new Form('customer', $customer, $this->container->getService('validator'));
![Page 41: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/41.jpg)
$form->bind($_POST['customer']);
if ($form->isValid()){ // do something with $customer}
![Page 42: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/42.jpg)
● The validation is launched automatically upon submission
![Page 43: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/43.jpg)
Common Questions
![Page 44: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/44.jpg)
Q: What if my form does not translate 1:1 to a domain model?
![Page 45: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/45.jpg)
A: Then the domain model doesn't exist yet ;-)
![Page 46: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/46.jpg)
● Use Case— Extend our form for a checkbox to accept terms
and conditions— Should not be stored as field in the Customer
class
![Page 47: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/47.jpg)
class Registration { /** @Validation({ @Valid }) */ public $customer;
/** * @Validation({ * @AssertTrue(message="Please accept") * }) */ public $termsAccepted = false;
public function process() { // save $customer, send emails etc. }}
![Page 48: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/48.jpg)
$form->add(new CheckboxField('termsAccepted'));
$group = new FieldGroup('customer');$group->add(new TextField('name'));...
$form->add($group);
![Page 49: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/49.jpg)
if ($form->isValid()){ $registration->process();}
![Page 50: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/50.jpg)
● The Registration class— can be reused (XML requests, …)— can be unit tested
![Page 51: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/51.jpg)
Q: What if I don't want to validate all attributes of an object?
![Page 52: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/52.jpg)
A: Use Constraint groups
![Page 53: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/53.jpg)
● Use Case— Administrators should be able to create
Customers with empty names— Normal users not
![Page 54: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/54.jpg)
class Customer{ /** * @Validation({ * @NotBlank(groups="User") * }) */ public $name;
...}
![Page 55: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/55.jpg)
$validator->validate($customer, 'User');
![Page 56: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/56.jpg)
$form->setValidationGroups('User');$form->bind($_POST('customer'));
if ($form->isValid()){ ...}
![Page 57: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/57.jpg)
● Constraint groups can be sequenced— first validate group "Fast"— then, if "Fast" was valid, validate group "Slow"
![Page 58: The new form framework](https://reader034.fdocuments.in/reader034/viewer/2022052504/554a0640b4c905e56c8b567a/html5/thumbnails/58.jpg)
Questions?