Tha django-multilingual style for I18n forms

Submitted by:Andreas Serghiou

Date added:30 December, 2010

Category:PHP

his snippet was created under the inspiration of using the django-multilingual package. Also an additional code is used to solve the problem of saving the many-to-many relations in embedded forms (http://trac.symfony-project.org/ticket/5867#comment:21).

The idea is that in all embedded I18n forms appears checkbox "delete" for each translation. When creating a new object this checkbox is checked for all translation form. To use the translation it's necessary to clear the checkbox in this translation form. When you save a form such I18n embedded form is also being validated and saved, and the forms with checkboxes checked are not validated and not saved. Also the objects of I18n embedded forms with checked checkbox are removed.

Probably it's not ideal solution but it works good for me. If you have any idea how to improve it you're always welcome.

The changes in code are only in one file /lib/forms/doctrine/BaseFormDoctrine.class.php

Tags: embedded forms , multilingual style

Code Snippet:

<?php

/**
* Project form base class.
*
* @package symfony
* @subpackage form
* @author Svyatoslav Mankovski <slawka@slawka.net>
* @version SVN: $Id: sfDoctrineFormBaseTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
*/
abstract class BaseFormDoctrine extends sfFormDoctrine {

protected static $I18nDeleteFieldName = '_i18n_delete';

public function __construct($object = null, $options = array(), $CSRFSecret = null) {

parent::__construct($object, $options, $CSRFSecret);

$this->addI18nDeleteField();

$this->resetFormFields();
}

public function addI18nDeleteField() {

if ($this->getObject()->getTable()->getParentGenerator() instanceof Doctrine_I18n) {
$this->widgetSchema[self::$I18nDeleteFieldName] = new sfWidgetFormInputCheckbox(array(
'label' => sfContext::getInstance()->getI18N()->__('Remove'),
));
$this->setDefault(self::$I18nDeleteFieldName, $this->isNew());
$this->widgetSchema->moveField(self::$I18nDeleteFieldName, sfWidgetFormSchema::FIRST);
$this->validatorSchema[self::$I18nDeleteFieldName] = new sfValidatorPass();
}

return $this;
}

public function bind(array $taintedValues = null, array $taintedFiles = null) {

if ($this->getObject()->getTable()->hasGenerator('Doctrine_I18n')) {
$forms = 0;
$deletes = 0;
$first_form = '';
foreach ($taintedValues as $name => $field) {
if (is_array($field)) {
$first_form = $first_form == '' ? $name : $first_form;
$forms++;
if (isset($field[self::$I18nDeleteFieldName])) {
$deletes++;
}
}
}
foreach ($taintedValues as $name => $field) {
if (is_array($field) && isset($field[self::$I18nDeleteFieldName])) {
if ($forms > $deletes || $forms == $deletes && $first_form != $name) {
unset($this->validatorSchema[$name]);
$this->validatorSchema[$name] = new sfValidatorPass();
} else {
unset($taintedValues[$name][self::$I18nDeleteFieldName]);
}
}
}
}

parent::bind($taintedValues, $taintedFiles);
}

public function bindAndSave($taintedValues, $taintedFiles = null, $con = null) {

if ($this->getObject()->getTable()->getParentGenerator() instanceof Doctrine_I18n) {
if (isset($taintedValues[self::$I18nDeleteFieldName])) {
unset($taintedValues[self::$I18nDeleteFieldName]);

$object = clone $this->getObject();

$object->delete($con);

return true;
}
}

return parent::bindAndSave($taintedValues, $taintedFiles, $con);
}

public function saveEmbeddedForms($con = null, $forms = null, $taintedValues = null) {
if (null === $con) {
$con = $this->getConnection();
}

if (null === $forms) {
$forms = $this->embeddedForms;
}

if (null === $taintedValues) {
$taintedValues = $this->taintedValues;
}

foreach ($forms as $name => $form) {
$values = isset($taintedValues[$name]) ? $taintedValues[$name] : array();
if ($form instanceof sfFormObject) {
unset($form[self::$CSRFFieldName]);

$form->bindAndSave($values, $this->taintedFiles, $con);
$form->saveEmbeddedForms($con, null, $values);
} else {
$this->saveEmbeddedForms($con, $form->getEmbeddedForms(), $values);
}
}
}

}

 
 

Comments