Author: annis
Date: 2010-02-10 05:31:47 +0100 (Wed, 10 Feb 2010)
New Revision: 27795
Added:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/LICENSE
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/README
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/ahDoctrineEasyEmbeddedRelationsPlugin-1.0.0.tgz
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahBaseFormDoctrine.class.php
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/package.xml
Log:
initial import
Added: plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/LICENSE
===================================================================
--- plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/LICENSE
(rev 0)
+++ plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/LICENSE 2010-02-10
04:31:47 UTC (rev 27795)
@@ -0,0 +1,19 @@
+Copyright (c) 2009-2010 asaphosting (Daniel Lohse & Steve Guhr)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
Added: plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/README
===================================================================
--- plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/README
(rev 0)
+++ plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/README 2010-02-10
04:31:47 UTC (rev 27795)
@@ -0,0 +1,164 @@
+# 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](http://prendreuncafe.com/blog/post/2009/11/29/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`
+
+ [php]
+ class ProjectConfiguration extends sfProjectConfiguration
+ {
+ public function setup()
+ {
+ $this->enablePlugins(array(
+ 'sfDoctrinePlugin',
+ 'ahDoctrineEasyEmbeddedRelationsPlugin',
+ '...'
+ ));
+ }
+ }
+
+ * Change the parent class in `lib/form/doctrine/BaseFormDoctrine.class.php`
+
+ [php]
+ abstract class BaseFormDoctrine extends ahBaseFormDoctrine
+ {
+ ...
+ }
+
+ * Clear your cache
+
+ symfony cc
+
+## Embedding relations ##
+
+Here is an example schema definition:
+
+ [yml]
+ 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):
+
+ [php]
+ 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:
+
+ [php]
+ 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:
+
+ [yml]
+ 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:
+
+ [php]
+ 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
displaying anything in this case which works for me. :)
+
+## Questions, bugs, feature requests? ##
+
+I can be reached via e-mail: [email protected]
+
+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. :)
\ No newline at end of file
Added:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/ahDoctrineEasyEmbeddedRelationsPlugin-1.0.0.tgz
===================================================================
(Binary files differ)
Property changes on:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/ahDoctrineEasyEmbeddedRelationsPlugin-1.0.0.tgz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php
===================================================================
---
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php
(rev 0)
+++
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php
2010-02-10 04:31:47 UTC (rev 27795)
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * ahDoctrineEasyEmbeddedRelationsPlugin configuration.
+ *
+ * @package ahDoctrineEasyEmbeddedRelationsPlugin
+ * @subpackage config
+ * @author Daniel Lohse, Steve Guhr <[email protected]>
+ * @version SVN: $Id: PluginConfiguration.class.php 12675 2008-11-06
08:07:42Z Kris.Wallsmith $
+ */
+class ahDoctrineEasyEmbeddedRelationsPluginConfiguration extends
sfPluginConfiguration
+{
+ /**
+ * @see sfPluginConfiguration
+ */
+ public function initialize()
+ {
+ }
+}
Added:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahBaseFormDoctrine.class.php
===================================================================
---
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahBaseFormDoctrine.class.php
(rev 0)
+++
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahBaseFormDoctrine.class.php
2010-02-10 04:31:47 UTC (rev 27795)
@@ -0,0 +1,160 @@
+<?php
+
+/**
+ * Doctrine form base class that makes it pretty easy to embed one or multiple
related forms including creation forms.
+ *
+ * @package ahDoctrineEasyEmbeddedRelationsPlugin
+ * @subpackage form
+ * @author Daniel Lohse, Steve Guhr <[email protected]>
+ */
+abstract class ahBaseFormDoctrine extends sfFormDoctrine
+{
+ protected $scheduledForDeletion = array(); // related objects scheduled for
deletion
+ protected $embedRelations = array();
+
+ public function embedRelations(array $relations)
+ {
+ $this->embedRelations = $relations;
+ foreach (array_keys($relations) as $relationName)
+ {
+ if (!isset($relations[$relationName]['noNewForm']) ||
!$relations[$relationName]['noNewForm'])
+ {
+ $relation = $this->getObject()->getTable()->getRelation($relationName);
+ $formClass = !isset($relations[$relationName]['newFormClass']) ?
$relation->getClass().'Form' : $relations[$relationName]['newFormClass'];
+ $formArgs = !isset($relations[$relationName]['newFormClassArgs']) ?
array() : $relations[$relationName]['newFormClassArgs'];
+ $r = new ReflectionClass($formClass);
+
+ $newForm = $r->newInstanceArgs($formArgs);
+ $newForm->setDefault($relation->getForeignColumnName(),
$this->object[$relation->getLocalColumnName()]);
+ if (isset($relations[$relationName]['newFormLabel']))
+ {
+
$newForm->getWidgetSchema()->setLabel($relations[$relationName]['newFormLabel']);
+ }
+ $this->embedForm('new_'.$relationName, $newForm);
+ }
+
+ $formClass = !isset($relations[$relationName]['formClass']) ? null :
$relations[$relationName]['formClass'];
+ $formArgs = !isset($relations[$relationName]['formClassArgs']) ? array()
: $relations[$relationName]['formClassArgs'];
+ $this->embedRelation($relationName, $formClass, $formArgs);
+
+ if (
+ count($this->getEmbeddedForm($relationName)->getEmbeddedForms()) === 0
&&
+ (!isset($relations[$relationName]['displayEmptyRelations']) ||
!$relations[$relationName]['displayEmptyRelations'])
+ )
+ {
+ unset($this[$relationName]);
+ }
+ }
+ }
+
+ /**
+ * Here we just drop the embedded creation forms if no value has been
provided for them (this simulates a non-required embedded form),
+ * please provide the fields for the related embedded form in the call to
$this->embedRelations() so we don't throw validation errors
+ * if the user did not want to add a new related object
+ *
+ * @see sfForm::doBind()
+ */
+ protected function doBind(array $values)
+ {
+ foreach ($this->embedRelations as $relationName => $keys)
+ {
+ if (!isset($keys['noNewForm']) || !$keys['noNewForm'])
+ {
+ foreach ($keys['considerNewFormEmptyFields'] as $key)
+ {
+ if ('' === trim($values['new_'.$relationName][$key]))
+ {
+ unset($values['new_'.$relationName], $this['new_'.$relationName]);
+ break;
+ }
+ }
+ }
+
+ if (isset($values[$relationName]))
+ {
+ foreach ($values[$relationName] as $i => $relationValues)
+ {
+ if (isset($relationValues['delete_object']) && $relationValues['id'])
+ {
+ $this->scheduledForDeletion[$relationName][$i] =
$relationValues['id'];
+ }
+ }
+ }
+ }
+
+ parent::doBind($values);
+ }
+
+ /**
+ * Updates object with provided values, dealing with eventual relation
deletion
+ *
+ * @see sfFormDoctrine::doUpdateObject()
+ */
+ protected function doUpdateObject($values)
+ {
+ if (count($this->scheduledForDeletion))
+ {
+ foreach ($this->scheduledForDeletion as $relationName => $ids)
+ {
+ foreach ($ids as $index => $id)
+ {
+ unset($values[$relationName][$index]);
+ unset($this->object[$relationName][$index]);
+
Doctrine::getTable((string)$this->getObject()->getTable()->getRelation($relationName)->getClass())->findOneById($id)->delete();
+ }
+ }
+ }
+
+ parent::doUpdateObject($values);
+ }
+
+ /**
+ * Saves embedded form objects.
+ *
+ * @param mixed $con An optional connection object
+ * @param array $forms An array of sfForm instances
+ *
+ * @see sfFormObject::saveEmbeddedForms()
+ */
+ public function saveEmbeddedForms($con = null, $forms = null)
+ {
+ if (null === $con) $con = $this->getConnection();
+ if (null === $forms) $forms = $this->getEmbeddedForms();
+
+ foreach ($forms as $form)
+ {
+ if ($form instanceof sfFormObject)
+ {
+ $relationName = $this->getRelationByEmbeddedFormClass($form);
+
+ if (($relationName && !array_key_exists($form->getObject()->getId(),
array_flip($this->scheduledForDeletion[$relationName]))) || !$relationName)
+ {
+ $form->saveEmbeddedForms($con);
+ $form->getObject()->save($con);
+ }
+ }
+ else
+ {
+ $this->saveEmbeddedForms($con, $form->getEmbeddedForms());
+ }
+ }
+ }
+
+ /**
+ * Get the used relation alias when given an embedded form
+ *
+ * @param sfForm $form A sfForm instance
+ */
+ private function getRelationByEmbeddedFormClass($form)
+ {
+ foreach ($this->getObject()->getTable()->getRelations() as $relation)
+ {
+ if ($relation->getClass() === get_class($form->getObject()))
+ {
+ return $relation->getAlias();
+ }
+ }
+
+ return false;
+ }
+}
Added: plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/package.xml
===================================================================
--- plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/package.xml
(rev 0)
+++ plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/package.xml
2010-02-10 04:31:47 UTC (rev 27795)
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0"
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.4.1"
version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd">
+ <name>ahDoctrineEasyEmbeddedRelationsPlugin</name>
+ <channel>plugins.symfony-project.org</channel>
+ <summary>Easily embed related forms and add new as well as edit and delete
existing related records within one form.</summary>
+ <description>Easily embed related forms and add new as well as edit and
delete existing related records within one form.</description>
+ <lead>
+ <name>Daniel Lohse</name>
+ <user>annis</user>
+ <email>[email protected]</email>
+ <active>yes</active>
+ </lead>
+ <date>2010-02-10</date>
+ <version>
+ <release>1.0.0</release>
+ <api>1.0.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.symfony-project.org/license">MIT license</license>
+ <notes>-</notes>
+ <contents>
+ <dir name="/">
+ <dir name="config">
+ <file
name="ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php"
role="data"/>
+ </dir>
+ <dir name="lib">
+ <dir name="form">
+ <file name="ahBaseFormDoctrine.class.php" role="data"/>
+ </dir>
+ </dir>
+ <file name="LICENSE" role="data"/>
+ <file name="README" role="data"/>
+ </dir>
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.4</min>
+ </php>
+ <pearinstaller>
+ <min>1.4.1</min>
+ </pearinstaller>
+ <package>
+ <name>symfony</name>
+ <channel>pear.symfony-project.com</channel>
+ <min>1.3.0</min>
+ <max>1.5.0</max>
+ <exclude>1.5.0</exclude>
+ </package>
+ </required>
+ </dependencies>
+
+ <phprelease>
+ </phprelease>
+
+ <changelog>
+ <release>
+ <version>
+ <release>1.0.0</release>
+ <api>1.0.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.symfony-project.com/license">MIT
license</license>
+ <date>2010-02-10</date>
+ <license>MIT</license>
+ <notes>
+ Initial release.
+ </notes>
+ </release>
+ </changelog>
+</package>
--
You received this message because you are subscribed to the Google Groups
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/symfony-svn?hl=en.