= sfPropelValidateBehaviorPlugin plugin = [[PageOutline]] The `sfPropelValidateBehaviorPlugin` is a symfony plugin that gives Propel objects access to symfony's native validation system. == Features == * Move your validation logic from the controller to the model, where it belongs * Better security, better encapsulation * Uses symfony's native validation system, with same features and same interface == Installation == * Install the plugin {{{ #!sh cd /path/to/your/symfony/project/plugins/ tar -xzf /path/to/sfPropelValidateBehaviorPlugin-0.1.0.tgz }}} * Enable Propel behavior support in `propel.ini`: {{{ propel.builder.AddBehaviors = true }}} If you have to enable the behavior support, rebuild your model: {{{ #!sh symfony propel-build-model }}} * Activate the behavior for any of your Propel classes: {{{ #!php // lib/model/Article.php class Article { } sfPropelBehavior::add('Article', array('validate' => array('class' => 'Article'))); }}} The 'class' attribute is required, and should match the class name. * Create the config/validate_model/ directory {{{ #!sh mkdir lib/validate_model }}} * Create validation files for your classes, exactly like you would for an action {{{ # config/validate_model/article.yml # File name should match the Propel class name, only lowercase methods: post: [title] fillin: enabled: true validators: myValidator: class: sfRegexValidator param: pattern: /^[\w\s]*$/ match_error: Invalid characters fields: title: required: msg: Required myValidator: }}} == Usage == The plugin changes the behavior of the Propel objects' save() method. Validation is performed at the beginning of the save() method, including a call the the object's own validate() method. If validation succeeds, save() behaves in the normal way. If it fails, * Nothing is submitted to the database * $foobar->save() returns sfPropelValidateBehaviorPlugin::FAIL * The error variables are filled in, just like normal validation $foobar->validateData() will run the same validators, but does not save the object even if the validation is successful. Here is an example. We use the object's validateData() method in the to set validateUpdate() action, to set the error messages given by the model validation. We don't want to call save() at that point, in case there were form errors but no model errors. {{{ #!php <?php class articleActions extends sfActions { public function executeUpdate() { // Set $article attributes if ($article->save() == sfPropelValidateBehavior::FAIL) { $this->forward('patient', 'edit'); } } public function validateUpdate() { $article = new Article(); // Set $article attributes $article->validateData(); } } }}} If all your validation in the model, you can (and should) remove the module/validate files. Otherwise, the server will validate each form field twice.