Beispiel #1
0
 /**
  * Fetch an element of $arr array using "complex" key $name.
  *
  * $name can be in form of "zzz[aaa][bbb]", 
  * it means $arr[zzz][aaa][bbb].
  *
  * If $name contain auto-indexed parts (e.g. a[b][]), replace
  * it by corresponding indexes.
  * 
  * $name may be scalar name or array (already splitted name,
  * see _splitMultiArray() method).
  * 
  * @param array &$arr          Array to fetch from.
  * @param mixed &$name         Complex form-field name.
  * @param array &$autoindexes  Container to hold auto-indexes
  * @return found value, or false if $name is not found.
  */
 function _deepFetch(&$arr, &$name, &$autoindexes)
 {
     if (is_scalar($name) && strpos($name, '[') === false) {
         // Fast fetch.
         return isset($arr[$name]) ? $arr[$name] : false;
     }
     // Else search into deep.
     $parts = HTML_FormPersister::_splitMultiArray($name);
     $leftPrefix = '';
     foreach ($parts as $i => $k) {
         if (!strlen($k)) {
             // Perform auto-indexing.
             if (!isset($autoindexes[$leftPrefix])) {
                 $autoindexes[$leftPrefix] = 0;
             }
             $parts[$i] = $k = $autoindexes[$leftPrefix]++;
         }
         if (!is_array($arr)) {
             // Current container is not array.
             return false;
         }
         if (!array_key_exists($k, $arr)) {
             // No such element.
             return false;
         }
         $arr =& $arr[$k];
         $leftPrefix = strlen($leftPrefix) ? $leftPrefix . "[{$k}]" : $k;
     }
     if (!is_scalar($name)) {
         $name = $parts;
     } else {
         $name = $leftPrefix;
     }
     return $arr;
 }
Beispiel #2
0
 /**
  * Convert plain metadata to multidimension array (as in $_GET and $_POST).
  * Used for forms with complex field names: a[b][c][] etc.
  * Called usually ONLY on POST form processing, not each time page loaded.
  * Also check if field values are consistent with metadata (e.g. hidden 
  * field is unchanged manually and "select" value is present in <option>'s).
  * Each resulting elements will have the following structure:
  * elementName => array(
  *   'type'      => text | action | single | multiple,
  *   'label'     => corresponding <label>...</label> content
  *   'value'     => entered value (if MF_USE_VALUES is true)
  *   'name'      => full name of form element (e.g. field[key1][key2])
  *   'original'  => original value of the element (for hidden fields and forms)
  *   'items'     => array(items of selects, checkboxes etc.)
  * );
  */
 function _decodeFormMeta($metas, $valuesArray)
 {
     require_once 'HTML/FormPersister.php';
     // Second pass: make meta tree.
     $flatMetas = $metas['items'];
     $treeMetas = $autoindexes = $values = array();
     foreach ($flatMetas as $k => $meta) {
         // Get name structure.
         $name = $meta['name'];
         $nameParts = HTML_FormPersister::_splitMultiArray($name);
         // may be modified later!
         // Set values.
         if ($this->MF_USE_VALUES) {
             $value = null;
             // Fetch the value.
             if ($meta['type'] == "action" && count($nameParts) == 1) {
                 // This is possibly <input type="image" name="aaa"> field. E.g.,
                 // $_GET contains "aaa_x" and "aaa_y" fieds.
                 if (is_numeric($x = @$valuesArray["{$name}_x"]) && is_numeric($y = @$valuesArray["{$name}_y"])) {
                     $value = array($x, $y);
                 }
             }
             if ($value === null) {
                 // This is not "image" field, or "image" with [] parts
                 // (PHP always ignores .x and .y after [] part, so - remain only "y" coord).
                 if (($v = HTML_FormPersister::_deepFetch($valuesArray, $nameParts, $autoindexes)) !== false) {
                     $value = $v;
                 }
             }
             // For multi-selects value is ALWAYS array.
             if ($value === null && $meta['type'] == "multiple") {
                 $value = array();
             }
             // Single select with size>1 and set of radio-buttons without
             // checked item ALSO could generate NULL in value. But we must
             // process such cases via meta:dynamic attribute.
             // Flag-based checkbox may need correction.
             if ($meta['type'] == 'flag') {
                 if ($meta['key'] === null) {
                     // If checkbox has no 'value' attribute - completely
                     // boolean element (browser sends "on").
                     $value = intval(!!$value);
                 }
                 unset($meta['key']);
             }
             // Make values array ("trusted $_POST").
             $curValue =& $values;
             foreach ($nameParts as $part) {
                 $curValue =& $curValue[$part];
             }
             $curValue = $value;
             // Save new value back to meta.
             $meta['value'] = $value;
         }
         // Make deep (tree-like) array.
         $curTree =& $treeMetas;
         foreach ($nameParts as $part) {
             if (!strlen($part)) {
                 break;
             }
             $curTree =& $curTree[$part];
         }
         $curTree = $meta;
         // Save modified meta back to array.
         $flatMetas[$k] = $meta;
     }
     // Create resulting metadata.
     $metas['items'] = $flatMetas;
     $metas['tree'] = $treeMetas;
     if ($this->MF_USE_VALUES) {
         $metas['value'] = $values;
     }
     // Return full meta-information.
     return $metas;
 }