Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
1. symfony
Simplify your professional
web development with PHP
Fabien Potencier
http://www.symfony-project.com/
http://www.sensiolabs.com/
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
2. Sensio
• French Web Agency, founded in 1998
– 150 people
– 30 people dedicated to Web technologies
SENSIO
Web Agency
Web
Webmarketing
Technologies
Open Source
Technologies
(Framework PHP)
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
3. Sensio Labs
• Open-Source technologies
– Linux
– Apache
– MySQL / PostgreSQL
– PHP / Perl / Python
• Open-Source dedicated team
• Big company customers
– Web Consulting symfony
PHP Framework
– Audit / Training
– Web Development
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
4. The symfony Framework
• PHP 5 Web Framework
• Based on 9 years of Sensio experience
• Based on well-known projets (Mojavi, Propel, Prado)
• Open-Source
• Built for :
– Professional Websites
– Complex needs
– Demanding environments Licence
MIT
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
5. The symfony Goals
• Bring together the « Entreprise World »
and the Open-Source World
• Develop Faster
• Don’t Reinvent the Wheel
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
6. Develop Faster
• Each line of code has a cost
– To write the line less code
– To test it
less complexity
– To maintain it
less bugs
• Write less code
– Architecture : controller, ORM, … more productivity
– Configuration
more time
– Autoloading
– Generators
– Helpers
• More time for business rules, edge cases, …
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
7. Don’t Reinvent the Wheel
• Follow best practices
• MVC Pattern : Model / View / Controller
• Unit and functional test framework
• Environment and deployment support
• Configurability
• Security (XSS and CSRF protection by default)
• Extensible (plugin system)
Simplify
• Admin Generator your Dev. Life
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
8. Main Selling Points
• symfony is about good code but also …
• Documentation
– GFDL book (450p)
– The askeet tutorial (250p)
• 1.0 maintained for a long time
– 1 release a month (only bug fixes) 1.0
– Commercial support
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
9. Let’s see some features
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
10. Controller
# apps/frontend/modules/blog/actions/actions.class.php
class blogActions extends sfActions
{ Controller blog/show
function executeShow()
{
$id = $this->getRequestParameter('id');
Model call (Propel)
$this->post = PostPeer::retrieveByPk($id);
For the View
$this->forward404Unless($this->post);
}
Shortcut
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
11. Controller
class blogActions extends sfActions
{ 1.0
function executeShow()
{
$this->forward404Unless(
$this->post = PostPeer::retrieveByPk($this->getRequestParameter('id'))
);
}
}
class blogActions extends sfActions
{ 1.1
function showAction($request)
{
$this->forward404Unless(
$this->post = PostPeer::retrieveByPk($request->getParameter('id'))
);
}
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
12. Controller (Doctrine)
# apps/frontend/modules/blog/actions/actions.class.php
class blogActions extends sfActions
{
function executeShow()
{
$id = $this->getRequestParameter('id');
$this->post = Doctrine::getTable('Post')->find($id);
$this->forward404Unless($this->post);
}
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
13. Model (Propel)
// lib/model/Author.php
class Author extends BaseAuthor
{
function getFullName()
{
return $this->getFirstName().' '.$this->getLastName();
}
}
$author = new Author();
$author->setFirstName('Fabien');
$author->setLastName('Potencier');
$author->save();
$post = new Post();
$post->setAuthor($author);
$post->setPublishedOn('tomorrow 12:00');
$post->isPublished(true);
$post->save();
$posts = PostPeer::doSelect(new Criteria());
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
14. Model (Doctrine)
// lib/model/doctrine/lib/Author.php
class Author extends BaseAuthor
{
function getFullName()
{
return $this->getFirstName().' '.$this->getLastName();
}
}
$author = new Author();
$author->setFirstName('Fabien');
$author->setLastName('Potencier');
Same as in Propel
$author->save();
$post = new Post();
$post->setAuthor($author);
$post->setPublishedOn('tomorrow 12:00');
$post->isPublished(true);
$post->save();
$posts = Doctrine::getTable('Post')->findAll();
$post = Doctrine::getTable('Post')->find($request->getParameter('id'));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
15. View / Template
# apps/frontend/modules/post/templates/showSuccess.php
<h1 class="title">
<?php echo $post->getTitle() ?>
</h1>
<h2>
par <?php echo $post->getAuthor()->getFullName() ?>
</h2>
Escaped Escaped
<p>
<?php echo $post->getHtmlContent(ESC_RAW) ?>
</p>
Raw Value
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
19. Functional Tests
• Navigation simulation
// test/functional/frontend/blogActionsTest.php
$browser = new sfTestBrowser();
$browser->initialize();
$browser->
get('/blog/1')-> Fluent
isStatusCode(200)-> Interface
checkResponseElement('h1.title', '/IPC 2007 Conference/');
The power of CSS selectors
TDD
Test Driven Development
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
20. Be Happy… or not
$ ./symfony test-functional frontend
# get /
ok 1 - status code is 200
not ok 2 - response selector h1 does not match regex /IPC 2007 Conference/
1..2
Looks like you failed 1 tests of 2.
$ ./symfony test-functional frontend
# get /
ok 1 - status code is 200
ok 2 - response selector h1 matches regex /IPC 2007 Conference/
1..2
Looks like everything went fine.
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
22. Functional Tests
class ApplicationBrowser extends sfTestBrowser
{
public function signin($user, $password)
{
return $this->
post('/signin', array('username' => $user, 'password' => $password))->
isRedirect()->
followRedirect()->
checkResponseElement('div.username', 'Welcome back Fabien');
}
public function signout()
{
return $this->get('/signout');
} DSL
} Your own specific browser
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
23. Admin Generator: Backend Creation
• Automatic generation of an Administration
Backend, ready for production usage
– Lists – Filters
– Pagination – Validation
– Sorting – CRUD
$ ./symfony propel-init-admin frontend post Post
1) Creates a post module
2) Generates configuration
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
24. Admin Generator
• Generated code is MVC and customizable
– Configuration file (generator.yml)
– Extend the Controller
– Override some Templates / Partials
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
31. What’s New in symfony 1.1?
• A new task framework
• Decoupling
– Remove singletons
– Remove dependencies between core classes
– New Event Dispatcher system
• Form / Validation framework
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
32. New Task Framework
• Easier to extend the symfony tasks
• Task namespaces
• Built-in help system
• Tasks are decoupled from the CLI
– Can be called from the CLI
– … or from your own code… easily
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
33. Task Namespaces
generate
:app Generates a new application (init-app)
:batch Generates a new batch (init-batch)
:controller Generates a new controller (init-controller)
:module Generates a new module (init-module)
:project Generates a new project (init-project)
test
:all Launches all tests
:functional Launches functional tests
:unit Launches unit tests
i18n
:extract Extracts i18n strings from php files
:find Finds non "i18n ready" strings in an application
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
34. Task Help
$ ./symfony help plugin:install
Usage:
symfony plugin:install [--stability|-s="..."] [--release|-r="..."] [--channel|-
c="..."] [--install_deps|-d] name
Aliases: plugin-install
Arguments:
name The plugin name
Options:
--stability (-s) The preferred stability (stable, beta, alpha)
--release (-r) The preferred version
--channel (-c) The PEAR channel name
--install_deps (-d) Whether to force installation of required dependencies
Description:
…
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
35. Task Help
Description:
The plugin:install task installs a plugin:
./symfony plugin:install sfGuargPlugin
By default, it installs the latest stable release.
If you want to install a plugin that is not stable yet,
use the stability option:
./symfony plugin:install --stability=beta sfGuargPlugin
./symfony plugin:install -s beta sfGuargPlugin
You can also force the installation of a specific version:
./symfony plugin:install --release=1.0.0 sfGuargPlugin
./symfony plugin:install -r 1.0.0 sfGuargPlugin
To force installation of all required dependencies, use the install_deps flag:
./symfony plugin:install --install-deps sfGuargPlugin
./symfony plugin:install -d sfGuargPlugin
By default, the PEAR channel used is symfony-plugins
(plugins.symfony-project.org).
You can specify another channel with the channel option:
./symfony plugin:install --channel=mypearchannel sfGuargPlugin
./symfony plugin:install -c mypearchannel sfGuargPlugin
…
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
36. Task Calls in your Code
# Somewhere in your code
$task = new sfCacheClearTask($dispatcher);
$task->run();
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
39. sfEventDispatcher
• Based on Cocoa Notification Center
// sfUser
$event = new sfEvent($this, 'user.change_culture', array('culture' => $culture));
$dispatcher->notify($event);
// sfI18N
$callback = array($this, 'listenToChangeCultureEvent');
$dispatcher->connect('user.change_culture', $callback);
• sfI18N and sfUser are decoupled
• « Anybody » can listen to any event
• You can notify existing events or create new ones
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
40. Form & Validation Framework
• Not a refactoring
• A different approach
• Almost no shared code
• Symfony 1.1 can still use the old system
– set compat_10: on in settings.yml (off by default)
– you can use the new and the old system in the same
application
– symfony 1.0 sfValidator class has been renamed to
sfValidatorBase to avoid class name conflicts
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
41. The New Approach
• Form as a first class object
• Widget classes for form helpers
• Validators validate arrays (it doesn’t care if it
comes from a request, an XML file or a model
object)
• A decoupled system
– Can be used without any other symfony class
– 3 differents sub-systems
• Validators: can be used by themselves
• Widgets: can be used by themselves
• Form: glue between validators and widgets
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
42. Validators
• Every validator extends sfValidator
• A validator cleans and validates input values
• sfValidator provides some common features
– required (validation) > true by default
– trim (cleaning) > false by default
• Each validator can have options:
– sfValidatorString: max_length, min_length
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
43. Validators
// create a new string validator
$v = new sfValidatorString(array('min_length' => 4));
// clean and validate data
$value = $v->clean('Fabien');
// returns the input value
$value == 'Fabien'
// change some option
$v->setOption('trim', true);
$value = $v->clean(' Fabien ');
// trims the input value
$value == 'Fabien' Validator objects
are stateless
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
44. Custom Validator
class CustomValidator extends sfValidator
{
protected function configure($options = array(), $messages = array())
{
$this->setOption('min_length', null);
$this->setMessage('min_length', 'Too short.');
}
protected function doClean($value)
{
if (strlen($value) < $this->getOption('min_length'))
{
throw sfValidatorError($this, 'min_length', array('value' => $value));
}
return $value;
}
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
45. Validators
$v = new sfValidatorString(array('min_length' => 4));
// throws a sfValidatorError
$v->clean('Jon');
$e->getCode() == 'min_length'
$e->getMessage() == '"Jon" is too short (4 characters min).'
$v->setMessage('min_length', 'Too short (%name%).');
$e->getMessage() == 'Too short (Jon).'
Use error codes
or error messages
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
46. Errors Internationalization
$v = new sfValidatorString(array('min_length' => 4));
try
{
$value = $v->clean('Jon');
}
catch (sfValidatorError $e)
{
echo $i18n->__($e->getMessageFormat(), $e->getArguments())."n";
// or
echo $i18n->__($e->getCode(), $e->getArguments())."n";
}
Error messages
are i18n ready
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
47. sfValidator(All|Any)
• You can aggregate validators to create a new validator:
– sfValidatorAll: All validators must pass
– sfValidatorAny: At least one validator must pass
$v1 = new sfValidatorString(array('min_length' => 4));
$v2 = new sfValidatorString(array('max_length' => 10));
$v = new sfValidatorAll(array($v1, $v2));
// values must validate both validators
$v->clean('Fabien');
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
48. sfValidator(All|Any)
• As they are validators themselves, you can create
complex logic to validate your values:
// v1 && (v2 || v3)
$v = new sfValidatorAll(
array($v1, sfValidatorAny($v2, $v3))
);
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
49. sfValidatorSchema
• A validator schema is composed of fields
• A field is a named validator
$v1 = new sfValidatorString(array('min_length' => 4));
$v = new sfValidatorSchema(array(
'first_name' => $v1,
'last_name' => $v1,
));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
50. sfValidatorSchema
• The clean() method takes an array of named
values and returns an array:
$v->clean(array(
'first_name' => 'Fabien',
'last_name' => 'Potencier',
));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
51. sfValidatorSchema
• It collects all errors for all fields
• It throws an exception with all errors
sfValidatorErrorSchema:
first_name: "Jon" is too short (4 characters min).
last_name: "Jon" is too short (4 characters min).
in ….php on line …
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
52. sfValidatorSchema
• A named validator does not have access to the
whole array of inputs, just its named value
• Two special validators:
– _pre_validator and _post_validator
– They takes the array of values as input
– They throw « global » errors
Isolation
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
53. sfValidatorSchema
$v2 = new sfValidatorSchemaCompare(
'password', '==', 'password_bis'
);
$v = new sfValidatorSchema(array(
'password' => $v1,
'password_bis' => $v1,
'_post_validator' => $v2,
));
sfValidatorErrorSchema:
"pass" does not match "word".
in ….php on line …
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
54. sfValidatorSchema
• sfValidatorSchema is a sfValidator, so you can nest them
$authorValidator = new sfValidatorSchema(array(
'first_name' => $v1,
'last_name' => $v1,
));
$bookValidator = new sfValidatorSchema(array(
'title' => $v1,
'sub_title' => $v1,
'author' => $authorValidator,
));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
56. sfValidatorSchema
• Secure by default
– allow_extra_fields (false by default)
– filter_extra_fields (true by default)
• If you pass a value with no matching validator, sfValidatorSchema
will throw an error
• If you switch allow_extra_fields to true, then extra fields won’t
trigger an error but will be removed from the cleaned values
• If you also switch filter_extra_fields to false, then extra fields won’t
be removed from the cleaned values
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
57. sfValidatorSchemaForEach
$choiceValidator = new sfValidatorSchema(array(
'choice' => $v1,
));
$choicesValidator = new sfValidatorSchemaForEach($choiceValidator, 3);
$pollValidator = new sfValidatorSchema(array(
'question' => $v1,
'choices' => $choicesValidator,
));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
58. sfValidatorSchemaForEach
$pollValidator->clean(array(
'question' => 'Do you like symfony?',
'choices' => array(
array('choice' => 'Yes'),
array('choice' => 'This is the best'),
array('choice' => 'A lot'),
),
));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
59. Validators as Strings
$postValidator = new sfValidatorOr(array(
new sfValidatorSchemaFilter('age', new sfValidatorInteger(array('min' => 18))),
new sfValidatorAll(array(
new sfValidatorSchemaFilter('age', new sfValidatorInteger(array('max' => 18))),
new sfValidatorSchemaFilter('is_young', new sfValidatorBoolean(array('required' => true))),
)),
));
$string = $postValidator->asString();
'
age:Integer({min: 18})
or
age:Integer({max: 18}) and is_young:Boolean({required: true})
'
$postValidator = new sfValidatorFromDescription($string);
$postValidator->asPhp();
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
60. Available Validators
• Boolean • All
• Choice • Any
• ChoiceMany • Callback
• Date • Decorator
• DateTime • Pass
• Email • FromDescription
• Integer
• Number
• Schema
• Regex
• SchemaForEach
• String
• SchemaCompare
• Time
• SchemaFilter
• Url
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
61. Widgets
• Every widget extends sfWidget
• A widget is an object that can be rendered as an HTML
string
• sfWidget provides some common features
– renderTag()
– renderContentTag()
– Charset support
– XHTML or HTML closing tags
• Each widget can have HTML attributes:
– Takes care of escaping
– Fixes double escaping problems
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
62. sfWidgetForm
• Base class for all form widgets
• Some more properties like isHidden()
• Generates an id if none provided and the widget
has a name
– Default id is the widget name
– Can be customized
$w = new sfWidgetFormInput();
$w->setIdFormat('id_%s');
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
63. sfWidgetForm classes
// create a new input widget
$w = new sfWidgetFormInput();
// render widget
echo $w->render('first_name', 'Fabien');
// returns the widget as HTML
<input type="text" name="first_name" value="Fabien" id="first_name" />
// change some attributes
$w->setAttribute('class', 'foo');
<input … class="foo" /> Widget objects
are stateless
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
64. sfWidgetForm classes
// add default HTML attributes
$w = new sfWidgetFormInput(array('class' => 'foo'));
// render widget with some HTML attributes
echo $w->render('first_name', 'Fabien', array('class' => 'foo'));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
65. sfWidgetFormSchema
• A widget schema is composed of fields
• A field is a named widget
$w1 = new sfWidgetFormInput();
$w = new sfWidgetFormSchema(array(
'first_name' => $w1,
'last_name' => $w1,
));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
66. sfWidgetFormSchema
• The render() method takes an array of named
values and returns an HTML string:
$w->render(null, array(
'first_name' => 'Fabien',
'last_name' => 'Potencier',
));
• You can also render individual fields
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
67. sfWidgetFormSchema
• sfWidgetFormSchema is a sfWidget, so you can nest
them
$authorWidget = new sfWidgetFormSchema(array(
'first_name' => $w1,
'last_name' => $w1,
));
$bookWidget = new sfWidgetFormSchema(array(
'title' => $w1,
'sub_title' => $w1,
'author' => $authorValidator,
));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
69. sfWidgetFormSchema
• The render() method can also render
– Errors
– Nested form schema
• The render() method uses a formatter class
– sfWidgetFormSchemaFormatterList
– sfWidgetFormSchemaFormatterTable
– Or build your own
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
70. Forms
• A sfForm is the glue between
– A validator schema
– A widget schema
$validator = new sfValidatorSchema();
$widget = new sfWidgetFormSchema();
$form = new sfForm();
$form->setValidatorSchema($validator);
$form->setWidgetSchema($widget);
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
71. sfForm
• You can also create your own form class
class BookForm extends sfForm
{
public function configure()
{
$validator = new BookValidatorSchema();
$widget = new BookWidgetFormSchema();
$this->setValidatorSchema($validator);
$this->setWidgetSchema($widget);
}
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
72. A Form in a Form
$authorForm = new AuthorForm();
$bookForm->embedForm($authorForm);
$choiceForm = new ChoiceForm();
$pollForm->embedFormForEach($choiceForm, 4);
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
73. sfForm
$form = new AuthorForm();
$input = array('first_name' => 'Fabien', 'last_name' => 'Potencier');
$form->bind($input);
if ($form->isValid())
{
// do something with the cleaned values
$form->getValues();
}
else
{
// do something with the errors
$form->getErrorSchema();
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
74. sfForm
• sfForm can take default values
$form = new AuthorForm(array('first_name' => 'Fabien'));
• sfFormField objects are widgets bound to the
input or default values
echo $form->getFormField('first_name')->render();
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
75. sfForm
$form = new AuthorForm();
echo $form->getFormField('first_name')->render();
// ===
echo $form['first_name']->render();
// ===
echo $form['first_name'];
// name and value are bound to the sfFormField object
<input type="text" name="first_name" value="Fabien" id="first_name" />
// add some HTML attributes
echo $form['first_name']->render(array('class' => 'foo'));
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
76. For the laziest
echo $form
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
78. Forms: In a symfony Action
class bookActions extends sfActions
{
public function executeEdit($request)
{
$this->form = new AuthorForm();
if ($request->isMethod('post'))
{
$this->form->bind($request->getParameter('book'));
if ($this->form->isValid())
{
$values = $this->form->getValues();
$this->redirect('@homepage');
}
}
}
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
79. sfFormPropel
• Generated forms for Propel objects
• Fully customizable
• Introspects the Propel schema
– Maps Propel/Creole types to symfony validators and
widgets
– Foreign keys
– Many to many relationships
– Internationalized tables
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
80. sfFormPropel
class bookActions extends sfActions
{
public function executeEdit($request)
{
$this->book = BookPeer::retrieveByPk($request->getParameter('id'));
$this->form = new AuthorForm($this->book);
if ($request->isMethod('post'))
{
$this->form->bind($request->getParameter('book');
if ($this->form->isValid())
{
$book = $this->form->save();
$this->redirect('@book?id='.$book->getId());
}
}
}
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
81. Customize Propel Forms
class BookForm extends BaseBookForm
{
public function configure()
{
$this->embedI18n(array('en', 'fr'));
$this->widgetSchema['en']->setLabel('en', 'English');
unset($this['created_at']);
$this->validatorSchema['foo'] = new sfValidatorPass();
$this->widgetSchema['foo'] = new sfWidgetIdentity();
$this->setDefault('published_on', time());
}
}
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
82. A Professional Web Framework
• Built from experience
• 1.0 stable, maintained with commercial support
• Growing community
– Developers in more than 80 countries
– 200 000 visitors per month on symfony-project.com
– 200 plugins in just 8 months
• Open-Source Documentation
– The book (450 pages - GFDL)
– Askeet Tutorial (250 pages)
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
83. Yahoo! uses symfony
• Yahoo! Bookmarks
– 20 millions users
– Web 2.0 / AJAX
• del.icio.us
– New beta on symfony
– preview.delicious.com
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
84. Next symfony Workshops
En français : Paris, France - Dec 05, 2007
In English : Paris, France - Feb 13, 2008
More info on www.sensiolabs.com
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
85. Join Us
• Sensio Labs is recruiting in France
– project managers
– web developers
• You have a passion for the web?
– Web Developer : You have a minimum of 3 years experience in
web development with Open-Source projects and you wish to
participate to development of Web 2.0 sites using the best
frameworks available.
– Project Manager : You have more than 5 years experience as a
developer and/or a project manager and you want to manage
complex Web projects for prestigious clients.
International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com