protected function doPreSave(Doctrine_Record $record, sfForm $form)
 {
     // loop through relations
     if ($relations = $form->getOption('dynamic_relations')) {
         foreach ($relations as $field => $config) {
             $collection = $record->get($config['relation']->getAlias());
             // collect form objects for comparison
             $search = array();
             foreach ($form->getEmbeddedForm($field)->getEmbeddedForms() as $i => $embed) {
                 $search[] = $embed->getObject();
             }
             foreach ($collection as $i => $object) {
                 if (false === ($pos = array_search($object, $search, true))) {
                     // if a related object exists in the record but isn't represented
                     // in the form, the reference has been removed
                     $collection->remove($i);
                     // if the foreign column is a notnull columns, delete the object
                     $column = $config['relation']->getTable()->getColumnDefinition($config['relation']->getForeignColumnName());
                     if ($object->exists() && isset($column['notnull']) && $column['notnull']) {
                         $object->delete();
                     }
                 }
             }
         }
     }
 }
 protected function doPreSave(Doctrine_Record $record, sfForm $form)
 {
     // loop through relations
     if ($relations = $form->getOption('dynamic_relations')) {
         foreach ($relations as $field => $config) {
             $collection = $record->get($config['relation']->getAlias());
             // collect form objects for comparison
             $search = array();
             try {
                 foreach ($form->getEmbeddedForm($field)->getEmbeddedForms() as $i => $embed) {
                     $search[] = $embed->getObject();
                 }
             } catch (InvalidArgumentException $e) {
                 // previously embedded form was removed at the end of form.filter_values as there were no values for it.
                 // @see sfDoctrineDynamicFormRelations::correctValidators()
             }
             foreach ($collection as $i => $object) {
                 $pos = array_search($object, $search, true);
                 if (false === $pos && $this->filterObject($object, $config['arguments'])) {
                     // if a related object exists in the record but isn't represented
                     // in the form, the reference has been removed
                     $collection->remove($i);
                     // if the foreign column is a notnull columns, delete the object
                     $column = $config['relation']->getTable()->getColumnDefinition($config['relation']->getForeignColumnName());
                     if ($object->exists() && isset($column['notnull']) && $column['notnull']) {
                         $object->delete();
                     }
                 }
             }
         }
     }
 }
 /**
  * Does the actual embedding.
  *
  * This method is called when a relation is dynamically embedded during form
  * configuration and again just before input values are validated.
  *
  * @param sfForm                    $form   A form
  * @param string                    $field  A field name to use for embedding
  * @param Doctrine_Collection|array $values An collection of values (objects or arrays) to use for embedding
  */
 protected function doEmbed(sfForm $form, $field, $values)
 {
     $relations = $form->getOption('dynamic_relations');
     $config = $relations[$field];
     $r = new ReflectionClass($config['class']);
     $parent = new BaseForm();
     foreach ($values as $i => $value) {
         if (is_object($value)) {
             $child = $r->newInstanceArgs(array_merge(array($value), array($config['arguments'])));
         } elseif (!empty($value['id'])) {
             $child = $this->findEmbeddedFormById($form, $field, $value['id']);
             if (!$child) {
                 throw new InvalidArgumentException(sprintf('Could not find a previously embedded form with id "%s".', $value['id']));
             }
         } else {
             $object = $config['relation']->getTable()->create();
             $object->fromArray($value);
             $form->getObject()->get($config['relation']->getAlias())->add($object);
             $child = $r->newInstanceArgs(array_merge(array($object), array($config['arguments'])));
         }
         // form must include PK widget
         if (!isset($child['id'])) {
             throw new LogicException(sprintf('The %s form must include an "id" field to be embedded as dynamic relation.', get_class($child)));
         }
         $parent->embedForm($i, $child);
     }
     // workaround embedding despite being bound
     // this is why this class extends sfForm
     $wasBound = $form->isBound;
     $form->isBound = false;
     $form->embedForm($field, $parent);
     $form->isBound = $wasBound;
 }
Example #4
0
 /**
  * Returns the embedder form if any, false otherwise.
  * So we can use this static method for basic sfForms
  * 
  * @param sfForm $form
  */
 public static function getFormEmbedder(sfForm $form)
 {
     return $form->getOption('embedder', false);
 }