/**
  * Query the last list count and set it in FormStorage
  * @param string $form The form name to set.
  */
 protected function queryLastListCount($form)
 {
     $num_rows = $this->db->queryRow("SELECT FOUND_ROWS() AS num_rows");
     if (!I2CE::pearError($num_rows, "Couldn't get total number of results.")) {
         I2CE_FormStorage::setLastListCount($form, (int) $num_rows->num_rows);
     }
 }
 /**
  * @param string $form.  THe form name
  * @param array $fields of string. The fields we want returned
  * Can include the special field 'last_modified' to get the last modification time for any of the fields of that form which is returned in the format  "Y-m-d H:i:s"
  * @param boolean $parent. Defaults to false.    If it is scalar and non-boolean, it is consider to be the ID of the parent, 
  * and then we get all forms with parent the given id. If true, we return the parent as one of the fields.
  * @param array $where_data.  contains the  where clause information about this form or a nested      
  * @param array $ordering. An array of fields to order by.  Defaults to the empty array.  Prepend a - to order by in descending order.
  * @param mixed $limit Defaults to false.  It true, returns only one result.  If an integer it is the numeber of records to limit to.
  *  If it is as an array of two integers, it is the offset and then number of results to limit to.
  * @param integer $mod_time. Defaults to -1.  If non-negative, we only list the requested fields for an id if at least one of them has a modification
  *  time greater than or equal to  $mod_time.  If the form storage has no way of tracking modifucation time, all entries are listed.  
  * @returns mixed an array with key id's and value and array of values.  the array of values has as keys the fields with their corresponding value.
  */
 public function listDisplayFields($form, $fields, $parent = false, $where_data = array(), $ordering = array(), $limit = false, $mod_time = -1)
 {
     $vals = array();
     $data_fields = $fields;
     if (($key = array_search('parent', $data_fields)) !== false) {
         unset($data_fields[$key]);
         if ($parent === false) {
             $parent = true;
         }
     }
     $order_fields = array();
     $order_func = false;
     if (count($ordering) > 0) {
         $order_func = '';
         foreach ($ordering as $order) {
             if (!is_string($order) || strlen($order) == 0) {
                 continue;
             }
             if ($order[0] == '-') {
                 $order = substr($order, 1);
                 $order_fields[] = $order;
                 $order_func .= "if ( array_key_exists('{$order}',\$a) && array_key_exists('{$order}',\$b)) { if (\$a['{$order}'] < \$b['{$order}']) return 1; if (\$a['{$order}'] > \$b['{$order}']) return -1;}";
             } else {
                 $order_fields[] = $order;
                 $order_func .= "if ( array_key_exists('{$order}',\$a) && array_key_exists('{$order}',\$b)) { if (\$a['{$order}'] < \$b['{$order}']) return -1; if (\$a['{$order}'] > \$b['{$order}']) return 1;}";
             }
         }
         $order_func .= 'return 0;';
         $order_func = @create_function('$a,$b', $order_func);
     }
     $all_fields = array_unique(array_merge($data_fields, $this->getLimitedFields($where_data), $order_fields));
     $new_fields = array_diff($all_fields, $data_fields);
     $factory = I2CE_FormFactory::instance();
     $formObj = $factory->createContainer($form);
     if (!$formObj instanceof I2CE_Form && $this->config->is_parent("forms/{$form}")) {
         I2CE::raiseError("No data for form {$form} is stored in magic data");
         return array();
     }
     $func = $formObj->createCheckFunction($where_data);
     if ($func === false) {
         I2CE::raiseError("Bad limit data");
         return array();
     }
     if (is_array($mod_time) && array_key_exists('mod_time', $mod_time)) {
         $mod_time = $mod_time['mod_time'];
     }
     if (is_scalar($mod_time) && $mod_time >= 0) {
         $mod_time = I2CE_Date::now(I2CE_Date::DATE_TIME, $mod_time);
     } else {
         $mod_time = false;
     }
     if (!$this->config->is_parent("forms/{$form}")) {
         return array();
     }
     $forms = $this->config->traverse("forms/{$form}");
     if (count($order_fields) == 0) {
         foreach ($forms as $id => $form_config) {
             if (!$form_config instanceof I2CE_MagicDataNode) {
                 continue;
             }
             if ($mod_time && $form_config->is_scalar('last_modified') && $mod_time->compare(I2CE_Date::fromDB($form_config->last_modified)) == -1) {
                 continue;
             }
             $data = array();
             foreach ($all_fields as $field) {
                 if ($field == "id") {
                     $data[$field] = $id;
                 } else {
                     if ($field == 'parent') {
                         $data['parent'] = null;
                         $form_config->setIfIsSet($data['parent'], 'parent');
                     } else {
                         if ($field == 'last_modified') {
                             $data['last_modified'] = date("Y-m-d H:i:s", 0);
                             $form_config->setIfIsSet($data['last_modified'], 'last_modified');
                         } else {
                             $data[$field] = null;
                             $form_config->setIfIsSet($data[$field], "fields/{$field}");
                         }
                     }
                 }
             }
             if ($func && $func($data) !== true) {
                 continue;
             }
             foreach ($new_fields as $field) {
                 unset($data[$field]);
             }
             if ($parent === true) {
                 $data['parent'] = 0;
                 $form_config->setIfIsSet($data['parent'], 'parent');
             }
             $vals[$id] = $data;
         }
     } else {
         foreach ($forms as $id => $form_config) {
             if (!$form_config instanceof I2CE_MagicDataNode) {
                 continue;
             }
             if ($mod_time && $form_config->is_scalar('last_modified') && $mod_time->before(I2CE_Date::now(I2CE_Date::DATE_TIME, $form_config->last_modified))) {
                 continue;
             }
             $data = array();
             $displays = array();
             foreach ($all_fields as $field) {
                 if ($field == "id") {
                     $data[$field] = $id;
                 } else {
                     if ($field == 'parent') {
                         $data['parent'] = null;
                         $form_config->setIfIsSet($data['parent'], 'parent');
                     } else {
                         if ($field == 'last_modified') {
                             $data['last_modified'] = date("Y-m-d H:i:s", 0);
                             $form_config->setIfIsSet($data['last_modified'], 'last_modified');
                         } else {
                             $fieldObj = $formObj->getField($field);
                             $data[$field] = null;
                             if ($fieldObj instanceof I2CE_FormField && $form_config->setIfIsSet($dbval, "fields/{$field}")) {
                                 $fieldObj->setFromDB($dbval);
                                 $data[$field] = $dbval;
                                 $displays[$field] = $fieldObj->getDisplayValue();
                             } else {
                                 $data[$field] = null;
                             }
                         }
                     }
                 }
             }
             if ($func && $func($data) !== true) {
                 continue;
             }
             if ($parent === true) {
                 $data['parent'] = 0;
                 $form_config->setIfIsSet($data['parent'], 'parent');
             }
             foreach ($displays as $field => $disp) {
                 $data[$field] = $disp;
             }
             $vals[$id] = $data;
         }
         if ($order_func) {
             uasort($vals, $order_func);
         }
         if (count($new_fields) > 0) {
             foreach ($vals as &$data) {
                 foreach ($new_fields as $field) {
                     unset($data[$field]);
                 }
             }
         }
     }
     I2CE_FormStorage::setLastListCount($form, count($vals));
     if ($limit === true) {
         return array_slice($vals, 0, 1);
     } else {
         if (is_numeric($limit)) {
             return array_slice($vals, 0, $limit);
         } else {
             if (is_array($limit)) {
                 list($offset, $limit) = $limit;
                 return array_slice($vals, $offset, $limit);
             } else {
                 return $vals;
             }
         }
     }
 }