Hi Matthew

I've had a play with Zend_Form - using Andries Seutens example as a starting point.

Does this look like the correct (read 'efficient'!) way you had intended the form to be populated/processed? It's not quite clear on the proposal - if I call the isValid() method on a form with an array of values, they don't actually save their values to each element (is that intended?).

        $form = new MyForm();

        if ($this->_request->isPost()) {
            $form->populate($this->getRequest()->getPost());
            if ($form->isValid()) {
                ...do something
        } else {
            $form->setDefaults($myDefaults);
        }

I've also 'hacked' in some functionality to allow multidimensional arrays within element names. So you can have:-

myelement
myelement[key]
myelement[foo][bar] ..etc...

Hope this comes in handy - here's the diffs (I imagine you'd probably want to write a new separate inflector for these, but it's a start):-

Index: Zend/Form/Abstract.php
===================================================================
--- Zend/Form/Abstract.php      (revision 194)
+++ Zend/Form/Abstract.php      (working copy)
@@ -196,6 +196,8 @@
      */
     public function populate(array $values)
     {
+        $values = $this->_arrayToBracket($values);
+
         foreach ($values as $name => $value) {
             if (isset($this->_elements[$name])) {
                 $this->_elements[$name]->setValue($value);
@@ -303,6 +305,8 @@
         }

         $this->_errors = array();
+        $spec = $this->_arrayToBracket($spec);
+
         foreach ($this as $name => $element) {
             $value = (isset($spec[$name])) ? $spec[$name] : null;
             if (!$element->isValid($spec[$name])) {
@@ -322,7 +326,7 @@
     {
         $values = array();
         foreach ($this as $name => $element) {
-            $values[$name] = $element->getValue();
+ $values = $this->_bracketToArray($values, $name, $element- >getValue());
         }

         return $values;
@@ -337,7 +341,7 @@
     {
         $values = array();
         foreach ($this as $name => $element) {
-            $values[$name] = $element->getRawValue();
+ $values = $this->_bracketToArray($values, $name, $element- >getRawValue());
         }

         return $values;
@@ -361,9 +365,11 @@
      */
     public function setDefaults(array $defaults)
     {
+        $defaults = $this->_arrayToBracket($defaults);
+
         foreach ($defaults as $key => $value) {
-            if (isset($this[$key])) {
-                $this[$key]->setValue($value);
+            if (isset($this->_elements[$key])) {
+                $this->_elements[$key]->setValue($value);
             }
         }

@@ -401,4 +407,40 @@
     {
         return $this->render();
     }
+
+ protected function _arrayToBracket($values, $filtered = array(), $prefix = null)
+    {
+        foreach ($values as $field => $value) {
+            $idx = $field;
+            if ($prefix !== null) {
+                $idx = $prefix . '[' . $idx . ']';
+            }
+            if (is_array($value)) {
+ $filtered = $this->_arrayToBracket($value, $filtered, $idx);
+            } else {
+                $filtered[$idx] = $value;
+            }
+        }
+
+        return $filtered;
+    }
+
+    protected function _bracketToArray($values, $field, $value)
+    {
+        if (($pos = strpos($field, '[')) !== false) {
+            $key = substr($field, $pos + 1);
+            $field = substr($field, 0, $pos);
+            if (($pos = strpos($key, ']')) === false) {
+ throw new Zend_Form_Exception('invalid form field key specified');
+            }
+            $key = substr($key, 0, $pos) . substr($key, $pos + 1);
+ if (!isset($values[$field]) || ! is_array($values[$field])) {
+                $values[$field] = array();
+            }
+ $value = $this->_bracketToArray($values[$field], $key, $value);
+        }
+
+        $values[$field] = $value;
+        return $values;
+    }
 }

Cheers

--

Simon Mundy | Director | PEPTOLAB

""" " "" """""" "" "" """"""" " "" """"" " """"" "  """""" "" "

202/258 Flinders Lane | Melbourne | Victoria | Australia | 3000
Voice +61 (0) 3 9654 4324 | Mobile 0438 046 061 | Fax +61 (0) 3 9654 4124
http://www.peptolab.com

Reply via email to