/** * builds a validated array of selected fields * * this looks for the 'field' attribute in the shortcode and if it finds it, goes * through the list of selected fields and sets up an array of valid fields that * can be used in a database query */ protected function _set_display_columns() { // if this has already been set, we're done if (is_array($this->display_columns)) { return; } $this->display_columns = array(); if (isset($this->shortcode_atts['fields'])) { $raw_list = explode(',', str_replace(array("'", '"', ' ', "\r", "\n"), '', $this->shortcode_atts['fields'])); if (is_array($raw_list)) { foreach ($raw_list as $column) { if (Participants_Db::is_column($column)) { $this->display_columns[] = $column; } } } } /* * if the field list has not been defined in the shortcode, get it from the global settings */ if (count($this->display_columns) == 0) { $this->_set_shortcode_display_columns(); } }
/** * 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 a field value * * this does no field format checking, you must use a compatible value, for instance * if the field stores it's value as an array, you must store an array * * @param string $name of the field * @param int|string $value the value to set the field to */ public function set_value($name, $value) { if (Participants_Db::is_column($name)) { $this->_setvalue($name, $value); } }
/** * takes the $_POST array and constructs a filter statement to add to the list shortcode filter */ private function _make_filter_statement($post) { if (!Participants_Db::is_column($post['search_field'])) { return ''; } $this->filter['search_field'] = $post['search_field']; switch ($post['operator']) { case 'LIKE': $operator = '~'; break; case 'NOT LIKE': case '!=': $operator = '!'; break; case 'gt': $operator = '>'; break; case 'lt': $operator = '<'; break; default: $operator = '='; } $this->filter['operator'] = $operator; if (empty($post['value'])) { return ''; } $this->filter['value'] = $post['value']; return $this->filter['search_field'] . $this->filter['operator'] . $this->filter['value']; }