ahDoctrineEasyEmbeddedRelationsPlugin - 1.0.1

Easily embed related forms and add new as well as edit and delete existing related records within one form.

You are currently browsing
the website for symfony 1

Visit the Symfony2 website


« Back to the Plugins Home

Signin


Forgot your password?
Create an account

Tools

Stats

advanced search
Information Readme Releases Changelog Contribute
Show source

ahDoctrineEasyEmbeddedRelations plugin (for symfony 1.3)

The ahDoctrineEasyEmbeddedRelationsPlugin is a symfony plugin that provides a Doctrine base form class to allow easy and more powerful embedding of forms.

For the inspiration of this plugin please read this blog post: Embedding Relations in Forms with Symfony 1.3 and Doctrine. Thanks, Nicolas! :)

Installation

  • Install the plugin (via a package)

    symfony plugin:install ahDoctrineEasyEmbeddedRelationsPlugin
    
  • Install the plugin (via a Subversion checkout)

    svn co http://svn.symfony-project.com/plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk plugins/ahDoctrineEasyEmbeddedRelationsPlugin
    
  • Activate the plugin in config/ProjectConfiguration.class.php

    class ProjectConfiguration extends sfProjectConfiguration
    {
      public function setup()
      {
        $this->enablePlugins(array(
          'sfDoctrinePlugin', 
          'ahDoctrineEasyEmbeddedRelationsPlugin',
          '...'
        ));
      }
    }
  • Change the parent class in lib/form/doctrine/BaseFormDoctrine.class.php

    abstract class BaseFormDoctrine extends ahBaseFormDoctrine
    {
      ...
    }
  • Clear your cache

    symfony cc
    

Embedding relations

Here is an example schema definition:

ahIntranetSubversionRepository:
  actAs:
    Timestampable:  ~
  tableName:        ah_intranet_subversion_repository
  columns:
    id:             { type: integer(4), primary: true, autoincrement: true }
    project_id:     { type: integer(4), notnull: true }
    name:           { type: string(64), notnull: true }
    repo_path:      { type: string(255), notnull: true }
    repo_username:  { type: string(64), notnull: true }
    repo_password:  { type: string(128), notnull: true }
  relations:
    ahProjectmanagerProject: { local: project_id, foreign: id, type: one, onDelete: CASCADE, foreignAlias: Repositories }

To embed one or more relations, add this to one of your form's configure method (or in a plugin form class: to the setup method):

public function configure()
{
  ...
  $this->embedRelations(array(
    'Repositories' => array(
      'considerNewFormEmptyFields' => array('name', 'repo_path', 'repo_username', 'repo_password'),
      'noNewForm' => true,
      'newFormLabel' => 'New repository!!!', 
      'newFormClass' => 'ahIntranetSubversionRepositoryNewForm',
      'newFormClassArgs' => array('sf_user' => $this->getOption('sf_user')),
      'displayEmptyRelations' => false,
      'formClass' => 'ahIntranetSubversionRepositoryEmbeddedForm',
      'formClassArgs' => array('sf_user' => $this->getOption('sf_user'))
    ),
    '...' => array(
      ...
    )
  ));
}

Be careful if you're using the new useFields method as this would unset the embedded forms again!

Also, please be aware that the embedRelations method does not follow the embedRelation method in that you cannot define an alias to use for the relation, you need to specify the relation key you used in the schema, which is, in this case, Repositories!

Each array defines one embedded relation and you can define a handful of options.

  • The minimal code is this:

    public function configure()
    {
      ...
      $this->embedRelations(array(
        'Repositories' => array(
          'considerNewFormEmptyFields' => array('name', 'repo_path', 'repo_username', 'repo_password')
        )
      ));
    }

Options explained

Only the first option is required, the rest can be guessed using the schema and Doctrine. :)

  • considerNewFormEmptyFields (the only required option, array): trouble starts when the user does not want to add a new related object but only wants to edit the main object's properties. As the embedded forms are validated, an error is thrown if one of the embedded form's field's is required. To remedy that you'll have to add all the fields to this array and if all of these are empty (read: only works for text fields for now), the empty form is dropped and no empty object is saved to the database (or validation errors thrown).

  • noNewForm (boolean, not required): if false, no empty form to add a new related object is embedded so you can only manage existing related objects.

  • newFormLabel (string, not required): the label that is shown for the new embedded form. If the form is used in the admin generator, label definitions in the generator.yml take precedence over this option:

    generator:
      ...
      param:
        ...
     
        config:
          actions: ~
          fields:
            ...
            new_Repositories:
              label:           New repository
          list:
            ...

    The key to use in the fields array above is 'new_relationName' ('new_Repositories' in this case, see the example above).

  • newFormClass (string, not required): the form class to use for the empty form

  • newFormClassArgs (array, not required): form class options to pass to the empty form class on instantiation

  • formClass (string, not required): the form class to use for the existing related objects. If you want to use the embedded form on its own but also want to delete related objects inside this embedding form, create a new form (in the example above: ahIntranetSubversionRepositoryEmbeddedForm) extending the original embedded form class (in the example above: ahIntranetSubversionRepositoryForm) and add the following code:

    public function configure()
    {
      parent::configure();
     
      if ($this->object->exists())
      {
        $this->widgetSchema['delete_object'] = new sfWidgetFormInputCheckbox(array('label' => 'Delete'));
        $this->validatorSchema['delete_object'] = new sfValidatorPass();
      }
    }

    When dealing with this inside of plugin classes you'll want to use the setup method for this.

  • formClassArgs (array, not required): form class options to pass to the existing related objects form class on instantiation

  • displayEmptyRelations (boolean, not required): set this to true (false is the default) if you want to check for existing related objects yourself. This can be done in the form template and is useful if you want to let the user know that 'There are no related repositories yet.'. The default is just not displaying anything in this case, which works for me. :)

Questions, bugs, feature requests?

I can be reached via e-mail: info@asapdesign.de

If you find bugs, have questions and/or feature requests, you can post to the symfony-user mailing list, of which I am an avid follower. :)