diff --git a/src/Pluf/DB/Field.php b/src/Pluf/DB/Field.php index 4438e7b..4325de8 100644 --- a/src/Pluf/DB/Field.php +++ b/src/Pluf/DB/Field.php @@ -97,7 +97,7 @@ class Pluf_DB_Field } } foreach (array_keys($def) as $key) { - if (!in_array($key, array('widget', 'label', 'required', + if (!in_array($key, array('widget', 'label', 'required', 'multiple', 'initial', 'choices', 'widget_attrs'))) { unset($def[$key]); } diff --git a/src/Pluf/DB/Field/Manytomany.php b/src/Pluf/DB/Field/Manytomany.php index 29cf24b..b668f61 100644 --- a/src/Pluf/DB/Field/Manytomany.php +++ b/src/Pluf/DB/Field/Manytomany.php @@ -25,15 +25,18 @@ class Pluf_DB_Field_Manytomany extends Pluf_DB_Field { public $type = 'manytomany'; - function formField($def, $form_field='Pluf_Form_Field_Varchar') + function formField($def, $form_field='Pluf_Form_Field_Integer') { $method = 'get_'.$def['name'].'_list'; - $items = $def['model_instance']->$method(); - $choices = array(); - foreach ($items as $item) { - $choices[(string) $item] = $item->id; + $def['multiple'] = true; + $def['initial'] = array(); + foreach ($def['model_instance']->$method() as $item) { + $def['initial'][(string) $item] = $item->id; + } + $def['choices'] = array(); + foreach (Pluf::factory($def['model'])->getList() as $item) { + $def['choices'][(string) $item] = $item->id; } - $def['choices'] = $choices; if (!isset($def['widget'])) { $def['widget'] = 'Pluf_Form_Widget_SelectMultipleInput'; } diff --git a/src/Pluf/Form/Field.php b/src/Pluf/Form/Field.php index 268be40..99cff49 100644 --- a/src/Pluf/Form/Field.php +++ b/src/Pluf/Form/Field.php @@ -51,6 +51,10 @@ class Pluf_Form_Field */ public $hidden_widget = 'Pluf_Form_Widget_HiddenInput'; public $value = ''; /**< Current value of the field. */ + /** + * Returning multiple values (select multiple etc.) + */ + public $multiple = false; protected $empty_values = array('', null, array()); /** @@ -111,13 +115,64 @@ class Pluf_Form_Field */ function clean($value) { - if ($this->required and in_array($value, $this->empty_values)) { + if (!$this->multiple and $this->required + and in_array($value, $this->empty_values)) { + throw new Pluf_Form_Invalid(__('This field is required.')); + } + if ($this->multiple and $this->required and empty($value)) { throw new Pluf_Form_Invalid(__('This field is required.')); } return $value; } /** + * Set the default empty value for a field. + * + * @param mixed Value + * @return mixed Value + */ + function setDefaultEmpty($value) + { + if (in_array($value, $this->empty_values) and !$this->multiple) { + $value = ''; + } + if (in_array($value, $this->empty_values) and $this->multiple) { + $value = array(); + } + return $value; + } + + /** + * Multi-clean a value. + * + * If you are getting multiple values, you need to go through all + * of them and validate them against the requirements. This will + * do that for you. Basically, it is cloning the field, marking it + * as not multiple and validate each value. It will throw an + * exception in case of failure. + * + * If you are implementing your own field which could be filled by + * a "multiple" widget, you need to perform a check on + * $this->multiple. + * + * @see Pluf_Form_Field_Integer::clean + * + * @param array Values + * @return array Values + */ + public function multiClean($value) + { + $field = clone($this); + $field->multiple = false; + reset($value); + while (list($i, $val) = each($value)) { + $value[$i] = $field->clean($val); + } + reset($value); + return $value; + } + + /** * Returns the HTML attributes to add to the field. * * @param object Widget diff --git a/src/Pluf/Form/Field/Integer.php b/src/Pluf/Form/Field/Integer.php index 058fdf1..b9819f1 100644 --- a/src/Pluf/Form/Field/Integer.php +++ b/src/Pluf/Form/Field/Integer.php @@ -30,22 +30,11 @@ class Pluf_Form_Field_Integer extends Pluf_Form_Field public function clean($value) { parent::clean($value); - if (in_array($value, $this->empty_values)) { - $value = ''; - } - if (is_array($value)) { - reset($value); - while (list($i, $val) = each($value)) { - if (!preg_match('/[0-9]+/', $val)) { - throw new Pluf_Form_Invalid(__('The value must be an integer.')); - } - $this->checkMinMax($val); - $value[$i] = (int) $val; - } - reset($value); - return $value; + $value = $this->setDefaultEmpty($value); + if ($this->multiple) { + return $this->multiClean($value); } else { - if (!preg_match('/[0-9]+/', $value)) { + if (!preg_match('/^[\+\-]?[0-9]+$/', $value)) { throw new Pluf_Form_Invalid(__('The value must be an integer.')); } $this->checkMinMax($value); diff --git a/src/Pluf/Form/Model.php b/src/Pluf/Form/Model.php index 9b15961..fa3b034 100644 --- a/src/Pluf/Form/Model.php +++ b/src/Pluf/Form/Model.php @@ -47,8 +47,11 @@ class Pluf_Form_Model extends Pluf_Form } foreach ($cols as $name=>$def) { $db_field = new $def['type']('', $name); - $defaults = array('blank' => true, 'verbose' => $name, 'help_text' => '', 'editable' => true); - $def = array_merge($defaults, $def); + $def = array_merge(array('blank' => true, + 'verbose' => $name, + 'help_text' => '', + 'editable' => true), + $def); if ($def['editable']) { // The 'model_instance' and 'name' are used by the // ManyToMany field. diff --git a/src/Pluf/Model.php b/src/Pluf/Model.php index eae0cb8..644fac5 100644 --- a/src/Pluf/Model.php +++ b/src/Pluf/Model.php @@ -196,10 +196,22 @@ class Pluf_Model /** * Get the raw data of the object. * + * For the many to many relations, the value is an array of ids. + * * @return array Associative array of the data. */ function getData() { + foreach ($this->_a['cols'] as $col=>$val) { + $field = new $val['type'](); + if ($field->type == 'manytomany') { + $this->_data[$col] = array(); + $method = 'get_'.strtolower($col).'_list'; + foreach ($this->$method() as $item) { + $this->_data[$col][] = $item->id; + } + } + } return $this->_data; }