Your SlideShare is downloading. ×
0
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007)

5,177

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,177
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
60
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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
  • 16. Routing homepage: / param: { module: blog, action: recent } url_for('@homepage') url: / homepage: / param: { module: blog, action: list } url: / recent: /recent param: { module: blog, action: recent } url: /recent post: link_to( param: { module: blog, action: show } /blog/1 $post->getTitle(), requirements: '@post?id='.$post->getId() id: d+ ) url: /blog/:id International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 17. Routing in a Template <?php echo link_to($post->getTitle(), '@post?id='.$post->getId()) ?> <a href="<?php echo url_for('@post?id='.$post->getId()) ?>">Next Post</a> <?php echo link_to('Google', 'http://www.google.com/') ?> <a href="http://www.google.com/">Google</a> Be pragmatic International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 18. Tests: Database Fixtures • Test data # data/fixtures/data.yml Author: fabien: first_name: Fabien last_name: Potencier Post: first_post: author_id: fabien title: IPC 2007 Conference $ ./symfony propel-load-data frontend 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
  • 21. Functional Tests # simple CSS selectors checkResponseElement('h1.title', '/IPC 2007 Conference/') checkResponseElement('#title', '/IPC 2007 Conference/') # attribute selectors checkResponseElement('ul li a[class~="title"]', '/IPC 2007 Conference/') # combinators: > and + checkResponseElement('ul > li', '/IPC 2007 Conference/') # some CSS3 selectors checkResponseElement('#list li:first-child', '/IPC 2007 Conference/') checkResponseElement('#list li:nth-child(3)', '/IPC 2007 Conference/') checkResponseElement('#list li:contains("IPC 2007 Conference")') 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
  • 25. Admin Generator: Configurability # apps/frontend/modules/post/config/generator.yml generator: class: sfPropelAdminGenerator param: model_class: Post list: display: [=title, author, created_at] filters: [title, author_id, published_on] max_per_page: 5 International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 26. Admin Generator • List International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 27. Admin Generator • Edition __toString() widgets m2m relationship International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 28. Admin Generator: Extensibility • Module extension class postActions extends autoPostActions { protected function addFiltersCriteria($c) Generated { module parent::addFiltersCriteria($c); $c->add(PostPeer::IS_PUBLISHED, true); } } • Template customization _edit_* : actions, footer, form, header, messages _list_* : footer, header, messages, td_actions, t(d|h)_stacked, t(d|h)_tabular _filters, editSuccess, listSuccess International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 29. Debugging Tools • Web Debug Toolbar International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 30. Debugging Tools • Error messages 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
  • 37. symfony 1.0 Dependencies sfView sfResponse sfContext sfI18N sfRequest sfLogger sfStorage sfUser sfRouting Cleanup dependency Dependencies singleton International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com
  • 38. symfony 1.1 Dependencies sfRequest sfView sfResponse sfI18N sfEventDispatcher sfUser sfRouting sfStorage sfLogger sfContext Cleanup dependency Dependencies singleton 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
  • 55. sfValidatorSchema $bookValidator->clean(array( 'title' => 'The symfony book', 'sub_title' => 'The definitive guide', 'author' => array( 'first_name' => 'Fabien', 'last_name' => 'Potencier', ), )); 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
  • 68. sfWidgetFormSchema $bookWidget->render(null, array( 'title' => 'The symfony book', 'sub_title' => 'The definitive guide', 'author' => array( 'first_name' => 'Fabien', 'last_name' => 'Potencier', ), )); 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
  • 77. Customize your Forms $bookForm['author'] <table> $bookForm['author']['first_name']->renderRow() <tr> <th> $bookForm['author']['first_name']->renderLabel() <label for="book_author_first_name">First Name</label> $bookForm['author']['first_name']->renderLabelName() </th> <td> <ul class="error_list"> <li>Required.</li> $bookForm['author']['first_name']->renderError() </ul> <input type="text" name="book[author][first_name]" id="book_author_first_name" /> $bookForm['author']['first_name'] </td> </tr> ... </table> 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
  • 86. SENSIO S.A. 26, rue Salomon de Rothschild 92 286 SURESNES cedex FRANCE Tél. : +33 1 40 99 80 80 Fax : +33 1 40 99 83 34 Contact Fabien Potencier fabien.potencier@sensio.com http://www.sensiolabs.com/ http://www.symfony-project.com/ International PHP 2007 Conference www.symfony-project.com fabien.potencier@sensio.com www.sensiolabs.com

×