Saving forms as libraries

Sometimes you want to reuse a form across an application. Using Formation or Forge for that matter this becomes easy. You simple save an instance of Formation or Forge as a library in a libraries folder. You can then instantiate the form with all rules, messages and everything else.

//File libraries/Some_Form.php
class Some_Form_Core extends Formation{
   public function __construct()
   {
      parent::__construct();
      $this->legend='Some legend';
      $this->add_element('input','email')->add_rule('Rule_Required');
      $this->add_element('input','username')->add_rule('Rule_Required');
      $this->add_element('submit','Submit');
   }
}
 
//Your controller controllers/user.php
public function create()
{
   $form=new Some_Form;
   echo $form->render();
   if($form->validate())
   {
       echo 'validates';
       //save the form to the database or do something else
   }
}
public function edit($id){
   $id = (int) $id;
   $user=new User_Model($id);
   if($user->exists())//see exists method in another post
   {
       $form=new Some_Form;
       $form->set_values($user->as_array());// form fields and db fields 
       //are the same so they map to each other
       echo $form->render();
 
   //Normally you would expand on this with saving the form to the model etc.
   }
   else 
   {
        Event::run('system.404'); //nifty trick to launch a 404 when the user doesn't exist.
   }
}

You see, I store the form as a library and call it with $form=new Some_Form; and hurray we got our form with rules and all. This is extremely useful when you have need the same form for editing and creating some record.

I hope the example is clear and is useful for some.


10 Responses to “Saving forms as libraries”

  1. neovive Says:

    Very nice example. Do you tend to use Events for other things as well? Events would probably make a good tutorial, since the docs are pretty empty. Thanks for all these great articles.

  2. admin Says:

    You can use events anywhere you need an observer pattern. For example in a MY_ORM.php you override the save() method (copy the whole thing) and after the empty(this->changed) statement you add:

    Event::run(get_class($this).'.before_save');

    Then in your User_Model constructor for example:

    Event::add('User_Model.before_save',array($this,set_datetime);

    And as a method in your User_Model

    public function set_datetime()
    {
       if(!$this->exists())
       {
    //if record doesn't exist it must be created with a time of creation
           $this->created=gmdate("Y-m-d H:i:s", time());
       }
    //Always set a new modifed time
       $this->modified=gmdate("Y-m-d H:i:s", time());
    }

    You could add a property to ORM which when true will invalidate the save() so you can set it in the callback and stop the saving process. Other events: after_save, before_delete, after_delete, before_update, insert or also a before_validate if you validate in your models.
    On the other side you can also implement a before_save() method in ORM so you can override it in your models which might be easier sometimes.

    I hope all this code works since I just made it up (I might test it and make it into a post)

  3. Learning Kohana » Blog Archive » Blog tutorial (1) Says:

    [...] statement is that I load a library which is a Formation form. It’s explained in an earlier post on this blog. This library looks like this: class Post_Form_Core extends Formation{ public function [...]

  4. noob Says:

    The Formation class will not work by default with Kohana v2.2, as it uses Log and Config classes. These were located in /system/core/ (v2.1.3), but in my default installation of v2.2 they aren’t there anymore. Haven’t checked yet if Formation works with files copied from 2.1.3 to 2.2.

  5. dlib Says:

    I am aware of this and my local edition already has this fixed, together with some other stuff. I hope to put out a new release shortly.

  6. toulon Says:

    Friday I downloaded the formation from svn and received the following errror when I attempted the first form from http://code.google.com/p/kohana-mptt/wiki/Formation_Documentation

    I am using the latest official version of kohana 2.2

    Error
    Fatal error: Class ‘Log’ not found in /export/home/wwwroot/kohana/modules/formation/libraries/Formation.php on line 34

    Line 34: Log::add(’debug’, ‘Formation library initialized’);

  7. dlib Says:

    Remove the lines Log::add from Formation.php and Validation.php, also ditch the line with Config::item in /elements/Element_Label.php

  8. toulon Says:

    I assume you meant Validate.php not Validation.php as Log::add was only in Validate.php. Also Config::item shows up only in Validate.php, elements/Element_Upload.php, and in rules/Rule_Upload_Allowed.php

    Validate.php
    // Set the extension prefix
    empty($prefix) and $prefix = Config::item(’core.extension_prefix’);

    elements/Element_Upload.php
    // Use the global upload directory by default
    empty($dir) and $dir = Config::item(’upload.upload_directory’);
    .
    .
    .
    if (Config::item(’upload.remove_spaces’))
    {
    // Remove spaces, due to global upload configuration
    $filename = preg_replace(’/\s+/’, ‘_’, $this->get_filename());
    }

    rules/Rule_Upload_Allowed.php
    if (in_array($mime, Config::item(’mimes.’.$type)))
    {
    // Type is valid
    $allow = TRUE;
    break;
    }

    I removed the lines listed above in Validate.php, elements/Element_Upload.php, and rules/Rule_Upload_Allowed.php

    Now I am getting error
    Fatal error: Class ‘Element_Input’ not found in /export/home/wwwroot/kohana/modules/formation/libraries/Formation.php on line 156

    Element_Input.php exists and is located at ./modules/formation/libraries/elements/Element_Input.php

  9. dlib Says:

    I’m sorry, you’re right. I am just terribly busy these days, and I want to move the module to the new style class naming as well. I’m not sure why element_input cannot be found. Try the new syntax add_element(’input’,'name’) perhaps or debug the auto loader.

    At least the coming two weeks I have zero time whatsoever to do anything Kohana related.

  10. toulon Says:

    That’s okay. I will see what I can figure out in the next two weeks. Don’t sweat it.

Leave a Comment