Using symfony built-in propel widgets in symfony 1.0

This article has moved to this location.


In my previous post, i’ve shown you how to use symfony form in symfony 1.0. The main questions now is, can we mixing built-in propel forms and widgets in symfony 1.0? should we upgrade propel version from 1.2 to 1.3 or to newer version?.
The answer for the first question is yes. Symfony or propel forms, widgets and validators are independent library, pluggable for any php projects (except for propel forms, widgets and validators, you have to use propel ORM as database layer).
The answer for the second question is optional. If you don’t have spare time to upgrade to propel 1.3 or to newer version, you can still use the propel 1.2 version, but with a litte effort of course.
Here are step by step you have to do before you begin:

  1. copy all forms, widgets and validators files from symfony 1.2.x or 1.3.x or 1.4.x. In this post, i package them as a plugin.

    Note :

    • util folder contain only one file, sfCallable.class.php
    • if you want to use propel forms from symfony 1.3.x or symfony 1.4.x, you have to copy folder event_dispatcher too.

    sfPropelForm1xPlugin
    lib
    form (copied from symfony lib folder)
    propel
    form (copied from sfPropelPlugin lib folder)
    validator (copied from sfPropelPlugin lib folder)
    widget (copied from sfPropelPlugin lib folder)
    event_dispatcher (copied from symfony lib folder)
    util (copied from symfony lib folder)
    validator (copied from symfony lib folder)
    widget (copied from symfony lib folder)

  2. Add a const to every object model. const PEER = ‘YourModelPeer’. For example:
    const PEER = ‘ApplicationUserPeer’;
    We have to do this, because this const will be called in every built-in propel forms, widgets and validators.
  3. Generate all forms and filters object by symfony 1.2.x > in the separate project (i recommended this way instead of creating them by hand), then copied them (form and filter folder) to your project lib folder.
  4. Open BaseFormPropel.class.php in the form folder you’ve just copied. Override the save() function (if you are using propel 1.3, you can skip this step)
    public function save($con = null)
    {
        if (!$this->isValid())
        {
          throw $this->getErrorSchema();
        }
        if (null === $con)
        {
          $con = $this->getConnection();
        }
        try
        {
          $con->begin();
          $this->doSave($con);
          $con->commit();
        }
        catch (Exception $e)
        {
          $con->rollBack();
          throw $e;
        }
        return $this->getObject();
    }
    

After you’ve completed the step by step above, now you are ready to use the plugin in your symfony 1.0 project.
Ok.. let’s try our plugin by creating the simple project. The schema below is taken from Jobeet tutorial

propel:
  _attributes:   { noXsd: false, defaultIdMethod: native, package: lib.model }

  jobeet_category:
    id:           ~
    name:      { type: varchar(255), required: true, index: unique }

  jobeet_job:
    id:           ~
    category_id:  { type: integer, foreignTable: jobeet_category, foreignReference: id, required: true }
    type:         { type: varchar(255) }
    company:      { type: varchar(255), required: true }
    logo:         { type: varchar(255) }
    url:          { type: varchar(255) }
    position:     { type: varchar(255), required: true }
    location:     { type: varchar(255), required: true }
    description:  { type: longvarchar, required: true }
    how_to_apply: { type: longvarchar, required: true }
    token:        { type: varchar(255), required: true, index: unique }
    is_public:    { type: boolean, required: true, default: 1 }
    is_activated: { type: boolean, required: true, default: 0 }
    email:        { type: varchar(255), required: true }
    expires_at:   { type: timestamp, required: true }
    created_at:   ~
    updated_at:   ~
  1. Generate the models, then open JobeetCategory.class.php and JobeetJob.class.php. Add the const to this classess.
    //JobeetJob
    const PEER = 'JobeetJobPeer';
    
    //JobeetCategory
    const PEER = 'JobeetCategoryPeer';
    

    Don’t forget to generate forms and filters (step 3).

  2. Generate the module : php symfony propel-generate-crud frontend job JobeetJob
  3. Here is the final code (taken from Jobeet tutorial with a few modification)
    //job/actions/actions.class.php
    public function executeCreate()
    {
        $this->jobeet_job = new JobeetJob();
        $this->jobeet_job->setType('full-time');
        $this->form = new JobeetJobForm($this->jobeet_job);
        $this->setTemplate('edit');
    }
    
    public function executeEdit()
    {
       $this->jobeet_job = JobeetJobPeer::retrieveByPk($this->getRequestParameter('id'));
        $this->forward404Unless($this->jobeet_job);
        $this->form = new JobeetJobForm($this->jobeet_job);
    }
    
    public function executeUpdate()
    {
        $this->jobeet_job = JobeetJobPeer::retrieveByPk($this->getRequestParameter('id'));
        $this->form = new JobeetJobForm($this->jobeet_job);
        $this->processForm($this->getRequest(), $this->form);
        $this->setTemplate('edit');
    }
    
    protected function processForm(sfWebRequest $request, sfForm $form)
    {
       $form->bind($request->getParameter($form->getName()),	$request->getFiles($form->getName()));
    
      if ($form->isValid())
      {
         	$job = $form->save();
        	$this->redirect('job/edit?id='.$job->getId());
       }
    }
    
    //job/templates/editSuccess.php
    <?php
    // auto-generated by sfPropelCrud
    // date: 2010/01/16 15:14:31
    ?>
    <?php echo form_tag('job/update?id='.$form->getObject()->getId()) ?>
    <table>
    <?php echo $form ?>
    </table>
    <hr />
    <?php echo submit_tag('save') ?>
    <?php if (false === $form->getObject()->isNew()): ?>
      &nbsp;<?php echo link_to('delete', 'job/delete?id='.$form->getObject()->getId(), 'post=true&confirm=Are you sure?') ?>
      &nbsp;<?php echo link_to('cancel', 'job/show?id='.$form->getObject()->getId()) ?>
    <?php else: ?>
      &nbsp;<?php echo link_to('cancel', 'job/list') ?>
    <?php endif; ?>
    </form>
    
    //lib/model/JobeetCategory.class.php
    const PEER = 'JobeetCategoryPeer';
    
    public function __toString()
    {
       return $this->getName();
    }
    
    //lib/model/JobeetJob.class.php
    const PEER = 'JobeetJobPeer';
    
    public function save($con = null)
    {
       if (!$this->getToken())
       {
          $this->setToken(sha1($this->getEmail().rand(11111, 99999)));
       }
       return parent::save($con);
    }
    
    //lib/model/form/JobeetJobForm.class.php
    public function configure()
      {
        unset(
          $this['created_at'], $this['updated_at'],
          $this['expires_at'], $this['is_activated'],
          $this['token']
        );
    
        $this->validatorSchema['email'] = new sfValidatorAnd(array(
          $this->validatorSchema['email'],
          new sfValidatorEmail(),
        ));
    
        $this->widgetSchema['type'] = new sfWidgetFormChoice(array(
          'choices' => JobeetJobPeer::$types,
          'expanded' => true,
        ));
        $this->validatorSchema['type'] = new sfValidatorChoice(array(
          'choices' => array_keys(JobeetJobPeer::$types),
        ));
    
        $this->widgetSchema['logo'] = new sfWidgetFormInputFile(array(
          'label' => 'Company logo',
        ));
    
        $this->widgetSchema->setLabels(array(
          'category_id'    => 'Category',
          'is_public'      => 'Public?',
          'how_to_apply'   => 'How to apply?',
        ));
    
        $this->validatorSchema['logo'] = new sfValidatorFile(array(
          'required'   => false,
          'path'       => sfConfig::get('sf_upload_dir').'/jobs',
          'mime_types' => 'web_images',
        ));
    
        $this->widgetSchema->setHelp('is_public', 'Whether the job can also be published on affiliate websites or not.');
      }
    

Oh ya.. for version 1.0, i use symfony 1.0.21 and the built-in propel widgets are taken from symfony 1.4.1.
If you need the full source code, contact me by email at nibsirahsieu@gmail.com.
Thanks you for your patient to read my post..
Have fun with symfony my friends.. cheers 😉

Advertisements

2 responses to “Using symfony built-in propel widgets in symfony 1.0

  1. Dale Attree July 14, 2010 at 4:16 am

    Thanks. This really helped.

  2. Atiq December 8, 2010 at 8:29 pm

    nice article. . . . . . . . . . . .. .

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: