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

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    Favorites, Groups & Events

    symfony: Simplify your professional web development with PHP (IPC Frankfurt 2007) - Presentation 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

    + Fabien PotencierFabien Potencier, 2 months ago

    custom

    387 views, 0 favs, 0 embeds more stats

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 387
      • 387 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 0
    • Downloads 10
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories

    Tags