/**
  * adds a List_Query_Filter object to the where clauses
  * 
  * @param string $column      the name of the field to target
  * @param string $operator     the operator
  * @param string $search_term the term to filter by
  * @param string $logic       the logic term to add to the array
  * @param bool   $shortcode   true if the current filter is from the shortcode
  * @return null
  */
 private function _add_single_statement($column, $operator, $search_term = '', $logic = 'AND', $shortcode = false)
 {
     /*
      * don't add an 'id = 0' clause if there is a user search. This gives us a 
      * way to create a "search results only" list if the shortcode contains 
      * a filter for 'id=0'
      * 
      * we flag it for suppression. Later, if there is no other clause for the ID 
      * column, the list display will be suppressed
      */
     if ($column == 'id' and $search_term == '0') {
         $this->suppress = true;
         return false;
     }
     /*
      * if the column is not valid skip this statement
      */
     if (!Participants_Db::is_column($column)) {
         return false;
     }
     $field_atts = Participants_Db::get_column($column);
     $filter = new PDb_List_Query_Filter(array('field' => $column, 'logic' => $logic, 'shortcode' => $shortcode, 'term' => trim(urldecode($search_term)), 'index' => $this->clause_index));
     $this->increment_clause_index();
     $statement = false;
     /*
      * set up special-case field types
      */
     if (in_array($field_atts->form_element, array('date', 'timestamp')) and $filter->is_string_search()) {
         /*
          * if we're dealing with a date element, the target value needs to be 
          * conditioned to get a correct comparison
          */
         $search_term = Participants_Db::parse_date($filter->get_raw_term(), $field_atts);
         // if we don't get a valid date, skip this statement
         if ($search_term === false) {
             return false;
         }
         $operator = in_array($operator, array('>', '<')) ? $operator : '=';
         if ($field_atts->form_element == 'timestamp') {
             //$statement = 'DATE(p.' . $column . ') ' . $operator . ' CONVERT_TZ(FROM_UNIXTIME(' . $search_term . '), @@session.time_zone, "+00:00") ';
             $statement = 'DATE(p.' . $column . ') ' . $operator . ' DATE(FROM_UNIXTIME(' . $search_term . ')) ';
         } else {
             $statement = 'p.' . $column . ' ' . $operator . ' CAST(' . $search_term . ' AS SIGNED)';
         }
     } elseif ($filter->is_empty_search()) {
         if ($operator === 'NOT LIKE' or $operator === '!') {
             $pattern = '(p.%1$s IS NOT NULL AND p.%1$s <> "")';
         } else {
             $pattern = '(p.%1$s IS NULL OR p.%1$s = "")';
         }
         $statement = sprintf($pattern, $column);
     } else {
         if ($operator === NULL) {
             $operator = 'LIKE';
         }
         $delimiter = array('"', '"');
         /*
          * set the operator and delimiters
          */
         switch ($operator) {
             case '~':
             case 'LIKE':
                 $operator = 'LIKE';
                 $delimiter = $filter->wildcard_present() ? array('"', '"') : array('"%', '%"');
                 break;
             case '!':
             case 'NOT LIKE':
                 $operator = 'NOT LIKE';
                 $delimiter = $filter->wildcard_present() ? array('"', '"') : array('"%', '%"');
                 break;
             case 'ne':
             case '!=':
             case '<>':
                 $operator = '<>';
                 break;
             case 'eq':
             case '=':
                 /*
                  * if the field's exact value will be found in an array (actually a 
                  * serialized array), we must prepare a special statement to search 
                  * for the double quotes surrounding the value in the serialization
                  */
                 if (in_array($field_atts->form_element, array('multi-checkbox', 'multi-select-other', 'link', 'array'))) {
                     $delimiter = array('\'%"', '"%\'');
                     $operator = 'LIKE';
                     /* 
                      * this is so the search term will be treated as a comparison string 
                      * in a LIKE statement
                      */
                     $filter->like_term = true;
                 } elseif ($filter->wildcard_present()) {
                     $operator = 'LIKE';
                 } else {
                     $operator = '=';
                 }
                 break;
             case 'gt':
             case '>':
                 $operator = '>=';
                 break;
             case 'lt':
             case '<':
                 $operator = '<';
                 break;
             default:
                 // invalid operator: don't add the statement
                 return false;
         }
         $statement = sprintf('p.%s %s %s%s%s', $column, $operator, $delimiter[0], $filter->get_term(), $delimiter[1]);
     }
     if ($statement) {
         $filter->update_parameters(array('statement' => $statement));
         $this->subclauses[$column][] = $filter;
     }
 }
 /**
  * sets up the fields object
  * 
  * this will use a different method for each type of object used to instantiate the class
  *
  * @var object $object the instantiating object
  */
 private function _setup_fields(&$object)
 {
     $this->base_type = get_class($object);
     $this->module = $object->module;
     $this->fields = new stdClass();
     $this->groups = array();
     switch ($this->base_type) {
         case 'PDb_List':
             $this->record = '';
             // the list module does not have a record iterator
             $this->values = $object->record->values;
             foreach ($object->record->fields as $field_object) {
                 $name = $field_object->name;
                 $value = $field_object->value;
                 $this->fields->{$name} = Participants_Db::get_column($name);
                 $this->fields->{$name}->module = $object->module;
                 $this->fields->{$name}->value = $value;
             }
             reset($object->record->fields);
             break;
         case 'PDb_Signup':
         case 'PDb_Single':
         case 'PDb_Record':
         default:
             if (!isset($object->record)) {
                 error_log(__METHOD__ . ' cannot instantiate ' . __CLASS__ . ' object. Class must be instantiated with full module object.');
                 break;
             }
             $this->record = $object->record;
             $this->values = $object->participant_values;
             foreach ($this->values as $name => $value) {
                 if (Participants_Db::is_column($name)) {
                     $this->fields->{$name} = Participants_Db::get_column($name);
                     $this->fields->{$name}->module = $object->module;
                     $this->fields->{$name}->value = $value;
                     //$this->fields->{$name}->value = PDb_FormElement::get_field_value_display($this->fields->{$name});
                 } else {
                     unset($this->values[$name]);
                 }
             }
             foreach ($this->record as $name => $values) {
                 $this->groups[$name] = new stdClass();
                 $this->groups[$name]->name = $name;
                 $this->groups[$name]->title = $values->title;
                 $this->groups[$name]->description = $values->description;
             }
             break;
     }
     //unset($this->record->options);
 }
 /**
  * sets up the fields object
  * 
  * this will use a different method for each type of object used to instantiate the class
  */
 private function _setup_fields()
 {
     $this->base_type = get_class($this->shortcode_object);
     $this->values = $this->base_type !== 'PDb_List' ? $this->shortcode_object->participant_values : Participants_Db::get_participant($this->shortcode_object->record->record_id);
     $this->set_edit_page();
     $this->set_detail_page();
     $this->module = $this->shortcode_object->module;
     $this->id = $this->values['id'];
     $this->edit_link = $this->cat_url_var($this->edit_page, 'pid', $this->values['private_id']);
     $this->detail_link = $this->cat_url_var($this->detail_page, 'pdb', $this->id);
     $this->fields = new stdClass();
     $this->groups = array();
     switch ($this->base_type) {
         case 'PDb_List':
             foreach ($this->shortcode_object->record->fields as $field_object) {
                 $name = $field_object->name;
                 $value = isset($field_object->value) ? $field_object->value : '';
                 $this->fields->{$name} = Participants_Db::get_column($name);
                 $this->fields->{$name}->module = $this->shortcode_object->module;
                 $this->fields->{$name}->value = $value;
             }
             reset($this->shortcode_object->record->fields);
             $this->_setup_list_record_object();
             break;
         case 'PDb_Signup':
         case 'PDb_Single':
         case 'PDb_Record':
         default:
             if (!isset($this->shortcode_object->record)) {
                 error_log(__METHOD__ . ' cannot instantiate ' . __CLASS__ . ' object. Class must be instantiated with full module object.');
                 break;
             }
             $this->record = clone $this->shortcode_object->record;
             foreach ($this->shortcode_object->fields as $name => $field) {
                 $this->fields->{$name} = $field;
                 $this->fields->{$name}->module = $this->shortcode_object->module;
                 $this->fields->{$name}->value = $this->values[$name];
             }
             foreach ($this->record as $name => $group) {
                 $this->groups[$name] = $this_group = new stdClass();
                 $this_group->name = $name;
                 $this_group->title = $group->title;
                 $this_group->description = $group->description;
                 $this_group->fields = array();
                 foreach ($group->fields as $group_field) {
                     $this_group->fields[] = $group_field->name;
                 }
                 reset($group->fields);
             }
             reset($this->record);
             break;
     }
     //unset($this->record->options);
 }
 /**
  * sets up the null select for dropdown elements
  */
 protected function _set_null_select()
 {
     $field = Participants_Db::get_column($this->name);
     $default = '';
     if ($field) {
         $default = $field->default;
     }
     /*
      * this is to add a blank mull select option if there is no default, no defined 
      * null select and no set field value
      */
     if (self::is_empty($default) && !isset($this->options['null_select']) && self::is_empty($this->value)) {
         $this->options['null_select'] = '';
     }
     parent::_set_null_select();
 }