/** * supplies an image/file upload location * * relative to WP root * * @return string relative path to the plugin files location */ public static function files_location() { /** * @version 1.6.0 * filter: pdb-files_location * * allows access to the "image_upload_location" plugin setting value */ return Participants_Db::set_filter('files_location', Participants_Db::plugin_setting('image_upload_location')); }
/** * supplies an image/file upload location * * relative to WP root * * @return string realtive path to the plugin files location */ public static function files_location() { return Participants_Db::set_filter('files_location', Participants_Db::plugin_setting('image_upload_location')); }
public static function get_types() { $types = array('text-line' => __('Text-line', 'participants-database'), 'text-area' => __('Text Area', 'participants-database'), 'rich-text' => __('Rich Text', 'participants-database'), 'checkbox' => __('Checkbox', 'participants-database'), 'radio' => __('Radio Buttons', 'participants-database'), 'dropdown' => __('Dropdown List', 'participants-database'), 'date' => __('Date Field', 'participants-database'), 'dropdown-other' => __('Dropdown/Other', 'participants-database'), 'multi-checkbox' => __('Multiselect Checkbox', 'participants-database'), 'select-other' => __('Radio Buttons/Other', 'participants-database'), 'multi-select-other' => __('Multiselect/Other', 'participants-database'), 'link' => __('Link Field', 'participants-database'), 'image-upload' => __('Image Upload Field', 'participants-database'), 'file-upload' => __('File Upload Field', 'participants-database'), 'hidden' => __('Hidden Field', 'participants-database'), 'password' => __('Password Field', 'participants-database'), 'captcha' => __('CAPTCHA', 'participants-database')); /* * this gives access to the list of form element types for alteration before * it is set */ return Participants_Db::set_filter('set_form_element_types', $types); }
/** * sets the default path to the image directory * */ public function set_image_directory() { $this->image_directory = Participants_Db::set_filter('image_base_path', PDb_Path::files_path(), $this); $this->image_directory_uri = Participants_Db::set_filter('image_base_uri', PDb_Path::files_uri(), $this); }
/** * parses a date string into UNIX timestamp * * if "strict dates" is set, this function uses the DateTime or IntlDateFormatter * class to parse the string according to a specific format. If it is not, we * use the conventional strtotime() function, with the enhancement that if the * non-American style format is used with slashes "d/m/Y" the string is prepared * so strtotime can parse it correctly * * @param string $string the string to parse; if not given, defaults to now * @param object $column_atts the column object; used to identify the field for * user feedback * @param bool $zero_time if set, zero the time portion of the date so it * won't interfere with date comparisons * @return int|bool UNIX timestamp or false if parse fails */ public static function parse_date($string = false, $column = '', $zero_time = false) { if (false === $string) { return false; } $string = Participants_Db::set_filter('parse_date', $string, $column); // it's already a timestamp if (self::is_valid_timestamp($string)) { //if (WP_DEBUG and is_object($column)) error_log(__METHOD__.' tried to parse timestamp from '. $column->name); return $string; } $date = false; // if it is a default zero timestamp or other empty value, treat it as "no date" if ($string == '0000-00-00 00:00:00' || empty($string)) { return false; } /* * we have two options to parse a date string into a timestamp: the * IntlDateFormatter class or the DateTime class. The IntlDateFormatter * class can parse localized text dates, but it seems commonly unavailable, * at least on English-speaking servers. The DateTime class is widely * available, but can't parse non-English text dates. It can parse numeric * date representations, so if the intl module is not available, we try to * use DateTime. If that is not available, we use strtotime with the added trick * of swapping out the separators if they are slashes so slashed European * notation can be correctly parsed */ $mode = 'none'; $timestamp = is_object($column) && $column->form_element == 'timestamp' || preg_match('#^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$#', $string) == 1 ? true : false; if (self::$plugin_options['strict_dates'] == 1 and is_object($column) and !$timestamp) { if (class_exists('IntlDateFormatter')) { $mode = 'Intl'; $DateFormat = new IntlDateFormatter(WPLANG, IntlDateFormatter::LONG, IntlDateFormatter::NONE, NULL, NULL, Participants_Db::get_ICU_date_format(self::$date_format)); //error_log(__METHOD__.' format object:'.print_r($DateFormat,1)); $timestamp = $DateFormat->parse($string); $the_Date = new DateTime(); $the_Date->setTimestamp($timestamp); } else { if (class_exists('DateTime')) { $mode = 'DateTime'; $the_Date = DateTime::createFromFormat(self::$date_format, $string); } } //error_log(__METHOD__.' date:'.print_r($the_Date,1)); if (is_array(date_get_last_errors()) && !empty($string)) { $errors = date_get_last_errors(); if ($errors['warning_count'] > 0 || $errors['error_count'] > 0) { $the_Date = false; if (is_object(self::$validation_errors) and is_object($column)) { self::$validation_errors->add_error($column->name, sprintf(__('The date for "%s" was invalid. Please input the date with the exact format shown', 'participants-database'), $column->title)); } } } /* * if we have a valid date, convert to timestamp */ if ($the_Date) { /* * zero the time so date equality comparisons can be made */ if ($zero_time) { $the_Date->setTime(0, 0); } $date = $the_Date->format('U'); } } // ob_start(); // var_dump($date); // error_log(__METHOD__.' date value:'.ob_get_clean().' mode:'.$mode); /* * if we haven't got a timestamp, parse the date the regular way */ if ($date === false or !self::is_valid_timestamp($date)) { $mode = 'strtotime'; if (is_object($column) && $column->form_element == 'date') { /* * deal with the common special case of non-American-style numeric date with slashes */ if (false !== strpos($string, '/')) { $date_parts = explode('/', self::$date_format); $day_index = array_search('d', $date_parts) !== false ? array_search('d', $date_parts) : array_search('j', $date_parts); $month_index = array_search('m', $date_parts) !== false ? array_search('m', $date_parts) : array_search('n', $date_parts); if ($day_index !== false && $month_index !== false && $day_index < $month_index) { $string = str_replace('/', '-', $string); } } } elseif (is_object($column) && $column->form_element == 'timestamp') { if ($zero_time) { /* * we need to zero the time, we first try to do it using the DateTime class */ $the_Date = new DateTime($string); if (is_object($the_Date)) { $the_Date->setTime(0, 0); $string = $the_Date->format(self::$date_format); } else { /* * remove the time portion of the timestamp */ $string = preg_replace('# [0-9]{2}:[0-9]{2}:[0-9]{2}$#', '', $string); $string .= ' 00:00 -0'; } } } /* * Most of the time, the default PHP timezone is the current setting, but * experience has shown it's necessary to reset it for the conversion to make * sure. We also must assume that the database server and PHP server are on * the same TZ. */ date_default_timezone_set(ini_get('date.timezone')); // ini_get('date.timezone') $date = strtotime($string); } //if (WP_DEBUG) error_log(__METHOD__.' mode: ' . $mode . ' timestamp:' . $date); return $date; }
/** * validates a single field submitted to the main database * * receives a validation pair and processes it, adding any error to the * validation status array * * @param string $value the submitted value of the field * @param string $name the name of the field * @param string $validation validation method to use: can be NULL (or absent), * 'no', 'yes', 'email', 'other' (for regex or match * another field value) * @param string $form_element the form element type of the field * @return NULL */ protected function _validate_field($value, $name, $validation = NULL, $form_element = false) { $error_type = false; $field = (object) compact('value', 'name', 'validation', 'form_element', 'error_type'); /* * this filter sends the $field object through a filter to allow a custom * validation to be inserted * * if a custom validation is implemented, the $field->error_type must be set * to a validation method key string. If the key string is a defined validation * method, that method will be applied. If $field->validation is set to false * by the filter callback, no further processing will be applied. * */ Participants_Db::set_filter('before_validate_field', $field); /* * if there is no validation method defined, exit here */ if (empty($field->validation) || $field->validation === NULL || $field->validation == 'no' || $field->validation === FALSE) { return; } /* * if the validation method is set and the field has not already been * validated (error_type == false) we test the submitted field for empty using * a defined method that allows 0, but no whitespace characters. * * a field that has any validation method and is empty will validate as empty first */ if ($field->error_type === false) { // we can validate each form element differently here if needed switch ($field->form_element) { case 'file-upload': case 'image-upload': /* * only "required" validation is allowed on this. Restricting file types * is done in the "values" field or in the settings */ $field->validation = 'yes'; if ($this->is_empty($field->value)) { $field->error_type = 'empty'; } break; case 'link': // a "link" field only needs the first element to be filled in if ($this->is_empty($field->value[0])) { $field->error_type = 'empty'; } break; default: if ($this->is_empty($field->value)) { $field->error_type = 'empty'; } } // if the field validation is 'yes' we're done if ($field->error_type === false && $field->validation == 'yes') { $field->error_type = 'valid'; } } /* * if the field has still not been validated, we process it with the remaining validation methods */ if ($field->error_type === false) { $regex = ''; $test_value = false; switch (true) { /* * the validation method key for an email address was formerly 'email' This * has been changed to 'email-regex' but will still come in as 'email' from * legacy databases. We test for that by looking for a field named 'email' * in the incoming values. */ case $field->validation == 'email-regex' || $field->validation == 'email' && $field->name == 'email': $regex = '#^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$#i'; break; case 'captcha' == strtolower($field->validation): $field->value = isset($field->value[1]) ? $field->value[1] : ''; // grab the value and the validation key list($info, $value) = isset($this->post_array[$field->name][1]) ? $this->post_array[$field->name] : array($this->post_array[$field->name][0], $field->value); $info = json_decode(urldecode($info)); /* * if we don't have a regex, assume it's a plugin CAPTCHA and decode it's validation regex */ if (empty($regex)) { $regex = $this->xcrypt($info->nonce, PDb_CAPTCHA::get_key()); } //error_log(__METHOD__.' $info:'.print_r($info,1).' $field->value:'.$field->value.' regex:'.$regex); break; case $this->_is_regex($field->validation): $regex = $field->validation; break; /* * if it's not a regex, test to see if it's a valid field name for a match test */ /* * if it's not a regex, test to see if it's a valid field name for a match test */ case isset($this->post_array[strtolower($field->validation)]): $test_value = $this->post_array[strtolower($field->validation)]; break; default: } if ($test_value !== false) { if ($field->value != $test_value) { $field->error_type = 'nonmatching'; } } elseif ($regex !== false) { $test_result = preg_match($regex, $field->value); if ($test_result === 0) { $field->error_type = $field->validation == 'captcha' ? 'captcha' : 'invalid'; } elseif ($test_result === false) { error_log(__METHOD__ . ' captcha regex error with regex: "' . $regex . '"'); } } } if ($field->error_type) { if ($field->error_type != 'valid') { $this->_add_error($name, $field->error_type, false); } $valid = $field->error_type; } else { $valid = 'valid'; } /* * the result of a captcha validation are stored in a session variable */ if (strtolower($validation) === 'captcha' || $field->form_element == 'captcha') { Participants_Db::$session->set('captcha_result', $valid); } if (false) { error_log(__METHOD__ . ' field: ' . $name . ' element: ' . $field->form_element . ' value: ' . (is_array($field->value) ? print_r($field->value, 1) : $field->value) . ' validation: ' . (is_bool($field->validation) ? $field->validation ? 'true' : 'false' : $field->validation) . ' submitted? ' . ($this->not_submitted($name) ? 'no' : 'yes') . ' empty? ' . ($this->is_empty($field->value) ? 'yes' : 'no') . ' error type: ' . $field->error_type); } }
/** * sets up the captcha * * this uses the type to set up the captcha parameters. Externally-defined captcha * types will be processed here. External definitions will be expected to set the * 'validation and 'HTML' properties, and optionally, the 'info' array. The * math_captcha method should be studied for an example of a captcha definition. * * the captcha setup sets three object properties: * validation this is a regex to validate the user input with * HTML the is the HTML needed to present the captcha challenge to the user * captcha_params this is an array of values used to reconstruct the captcha in order * to provide user feedback (optional) * * @return null */ private function captcha_setup() { /* * the pdb-capcha_setup filter expects the PDb_CAPTCHA::HTML property to be * filled with the HTML of the custom captcha element. The validation of the * response should be included as a regex string in PDb_CAPTCHA::validation */ Participants_Db::set_filter('captcha_setup', $this); if (empty($this->HTML)) { switch ($this->captcha_type) { case 'math': $this->math_capcha(); break; } } /* * the $info array will be used to pass values to the validation object; What * we are calling 'nonce' is actually the XOR-encrypted regex. If we need to * expand the types of CAPTCHAS in the future, we can use this to tell the * validation object how to validate the field */ $this->info = array('type' => $this->captcha_type, 'nonce' => PDb_FormValidation::xcrypt($this->validation, $this->key), 'info' => $this->captcha_params); }
_e('<strong>Submit:</strong> save record and return to list<br><strong>Apply:</strong> save record and continue with same record<br><strong>Next:</strong> save record and then start a new one', 'participants-database'); ?> <br /> <?php if (!empty($input_id)) { _e('<strong>Previous:</strong> save and move to previous record', 'participants-database'); } ?> </td> </tr> <?php } else { ?> <tr> <th><h3><?php echo Participants_Db::set_filter('translate_string', $options['save_changes_label']); ?> </h3></th> <td class="submit-buttons"> <input class="button button-primary pdb-submit" type="submit" value="<?php _e($options['save_changes_button']); ?> " name="save"> <input name="submit_button" type="hidden" value="<?php echo self::$i18n['apply']; ?> "> </td> </tr> <?php }
/** * processes the shortcode filter string * * @return array of where clauses */ private function _process_shortcode_filter() { $clauses = array(); $this->shortcode_atts['filter'] = Participants_Db::set_filter('list_filter', $this->shortcode_atts['filter']); if (isset($this->shortcode_atts['filter'])) { $statements = explode('&', html_entity_decode($this->shortcode_atts['filter'])); foreach ($statements as $statement) { if (false !== strpos($statement, '|')) { // check for OR clause $or_statements = explode('|', $statement); $or_clause = array(); foreach ($or_statements as $or_statement) { $or_clause[] = $this->_make_single_statement($or_statement); if (end($or_clause) === false) { // parse failed, abort $clause = false; continue 2; } } $clause = '(' . implode(' OR ', $or_clause) . ')'; } else { $clause = $this->_make_single_statement($statement); } if ($clause === false) { continue; } // add the clause $clauses[] = $clause; } // each $statement } // done processing shortcode filter statements return $clauses; }
/** * prepare a field for display * * primarily to deal with encoded characters, quotes and slashes * * @param string $string the value to be prepared */ protected function prepare_display_value($string) { return Participants_Db::set_filter('translate_string', $string); //str_replace(array('"',"'"), array('"','''), stripslashes($string)); //htmlspecialchars( stripslashes( $string ), ENT_QUOTES, "UTF-8", false ); }
/** * sends a user receipt email */ private function _do_receipt() { if (filter_var($this->recipient, FILTER_VALIDATE_EMAIL) === false) { error_log(Participants_Db::$plugin_title . ': no valid email address was found for the user receipt email, mail could not be sent.'); return NULL; } /** * filter * * pdb-receipt_email_template * pdb-receipt_email_subject * * @param string email template * @param array of current record values * * @return string template */ $this->_mail($this->recipient, $this->_proc_tags(Participants_Db::set_filter('receipt_email_subject', $this->receipt_subject, $this->participant_values)), Participants_Db::process_rich_text($this->_proc_tags(Participants_Db::set_filter('receipt_email_template', $this->receipt_body, $this->participant_values)))); }
/** * provides the name of the plugin options * * this is to allow a filter to modify the name * * @param string $settings_name the base setting name for the plugin * @return string */ public function settings_name($settings_name = '') { $settings_name = empty($settings_name) ? $this->aux_plugin_settings : $settings_name; if (is_admin()) { return Participants_Db::set_filter('aux_plugin_admin_settings_name', $settings_name); } return Participants_Db::set_filter('aux_plugin_settings_name', $settings_name); }
/** * applies conditioning and escaping to the incoming value, also allows for a filter callback * * @global object $wpdb * @param type $value * @return string */ function process_value($value) { global $wpdb; return Participants_Db::set_filter('csv_import_value', $wpdb->escape($this->_enclosure_trim($value, '', $this->CSV->enclosure))); }
/** * creates a translated key string of the format title (name) where "name" is untranslated * * @param string $title the title string * @param string $name the name string * * @return string the translated title with the untranslated name added (if supplied) */ public static function title_key($title, $name = '') { if (empty($name)) { return Participants_Db::set_filter('translate_string', $title); } return sprintf('%s (%s)', Participants_Db::set_filter('translate_string', $title), $name); }
/** * sets up the template iteration object * * this takes all the fields that are going to be displayed and organizes them * under their group so we can easily run through them in the template */ public function _setup_iteration() { // the list query object can be modified at this point to add a custom search do_action(Participants_Db::$prefix . 'list_query_object', $this->list_query); // allow the query to be altered before the records are retrieved $list_query = Participants_Db::set_filter('list_query', $this->list_query->get_list_query()); if (WP_DEBUG) { error_log(__METHOD__ . ' list query: ' . $this->list_query->get_list_query()); } // get the $wpdb object global $wpdb; // get the number of records returned $this->num_records = $wpdb->get_var(preg_replace('#^SELECT.+FROM #', 'SELECT COUNT(*) FROM ', $list_query)); $this->_set_list_limit(); // set up the pagination object $pagination_defaults = array('link' => $this->prepare_page_link($this->shortcode_atts['filtering'] ? filter_input(INPUT_POST, 'pagelink') : $_SERVER['REQUEST_URI']), 'page' => $this->current_page, 'size' => $this->page_list_limit, 'total_records' => $this->num_records, 'filtering' => $this->shortcode_atts['filtering'], 'add_variables' => 'instance=' . $this->instance_index . '#' . $this->list_anchor); // instantiate the pagination object $this->pagination = new PDb_Pagination($pagination_defaults); /* * get the records for this page, adding the pagination limit clause * * this gives us an array of objects, each one a set of field->value pairs */ $records = $wpdb->get_results($list_query . ' ' . $this->pagination->getLimitSql(), OBJECT); /* * build an array of record objects, indexed by ID */ $this->records = array(); foreach ($records as $record) { $id = $record->id; if (!in_array('id', $this->display_columns)) { unset($record->id); } $this->records[$id] = $record; } if (!empty($this->records)) { foreach ($this->records as $record_id => $record_fields) { /* * @version 1.6 * * this array now contains all values for the record */ // set the values for the current record $this->participant_values = Participants_Db::get_participant($record_id); foreach ($record_fields as $field => $value) { /* * as of 1.5.5, we don't fill up the records property with all the field properties, * just the current props, like value and link. The field properties are added when * the list is displayed to use less memory */ $field_object = new stdClass(); $field_object->name = $field; // set the current value of the field $this->_set_field_value($field_object); $this->_set_field_link($field_object); // add the field to the record object $this->records[$record_id]->{$field_object->name} = $field_object; } } } reset($this->records); /* * at this point, $this->records has been defined as an array of records, * each of which is an object that is a collection of objects: each one of * which is the data for a field */ // error_log( __METHOD__.' all records:'.print_r( $this->records,1)); }
/** * determines if a field type is "linkable" * * meaning it is displayed as a string that can be wrapped in an anchor tag * * @param object $field the field object * @return bool true if the type is linkable */ public static function field_is_linkable($field) { $linkable = in_array($field->form_element, array('text-line', 'image-upload', 'file-upload', 'dropdown', 'checkbox', 'radio')); return Participants_Db::set_filter('field_is_linkable', $linkable, $field->form_element); }
/** * prints a table header row */ private static function _print_header_row() { $head_pattern = ' <th class="%2$s" scope="col"> <span>%1$s%3$s</span> </th> '; $sortable_head_pattern = ' <th class="%2$s" scope="col"> <span><a href="' . self::sort_link_base_URI() . '&column_sort=%2$s">%1$s%3$s</a></span> </th> '; $sorticon_class = strtolower(self::$filter['ascdesc']) === 'asc' ? 'dashicons-arrow-up' : 'dashicons-arrow-down'; // template for printing the registration page link in the admin $sorticon = '<span class="dashicons ' . $sorticon_class . ' sort-icon"></span>'; // print the "select all" header ?> <th scope="col" style="width:3em"> <?php if (current_user_can(Participants_Db::plugin_capability('plugin_admin_capability', 'delete participants'))) { ?> <?php /* translators: uses the check symbol in a phrase that means "check all" printf('<span class="checkmark" >✔</span>%s', __('all', 'participants-database'))s */ ?> <input type="checkbox" name="checkall" id="checkall" ><span class="glyphicon glyphicon-edit" style="opacity: 0"></span> <?php } ?> </th> <?php // print the top header row foreach (self::$display_columns as $column) { $title = Participants_Db::set_filter('translate_string', strip_tags(stripslashes($column->title))); $field = Participants_Db::$fields[$column->name]; printf($field->sortable ? $sortable_head_pattern : $head_pattern, str_replace(array('"', "'"), array('"', '''), $title), $column->name, $column->name === self::$filter['sortBy'] ? $sorticon : ''); } }
/** * parses a date string into UNIX timestamp * * if "strict dates" is set, this function uses the DateTime or IntlDateFormatter * class to parse the string according to a specific format. If it is not, we * use the conventional strtotime() function, with the enhancement that if the * non-American style format is used with slashes "d/m/Y" the string is prepared * so strtotime can parse it correctly * * @param string $string the string to parse; if not given, defaults to now * @param object $column_atts the column object; used to identify the field for * user feedback * @param bool $zero_time if set, zero the time portion of the date so it * won't interfere with date comparisons * @return int|bool UNIX timestamp or false if parse fails */ public static function parse_date($string = false, $column = '', $zero_time = false) { if (false === $string) { return false; } $string = Participants_Db::set_filter('parse_date', $string, $column); // is it already a timestamp? if (self::is_valid_timestamp($string)) { //if (WP_DEBUG and is_object($column)) error_log(__METHOD__.' tried to parse timestamp from '. $column->name); return $string; } $date = false; // if it is a default zero timestamp, treat it as "no date" if ($string === '0000-00-00 00:00:00') { return false; } /* * we have two options to parse a date string into a timestamp: the * IntlDateFormatter class or the DateTime class. The IntlDateFormatter * class can parse localized text dates, but it seems commonly unavailable, * at least on English-speaking servers. The DateTime class is widely * available, but can't parse non-English text dates. It can parse numeric * date representations, so if the intl module is not available, we try to * use DateTime. If that is not available, we use strtotime with the added trick * of swapping the date/month if they are slashes so slashed European notation * can be correctly parsed */ self::$date_mode = 'none'; $errors = false; $the_Date = false; // test for MySQL-format timestamp $is_MySQL_timestamp = preg_match('#^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$#', $string) === 1 ? true : false; //error_log(__METHOD__.' object? '.(is_object($column)?'yes':'no').' strict dates? '.(self::plugin_setting_is_true('strict_dates', false)?'yes':'no').' timestamp? '.($is_MySQL_timestamp?'yes':'no')); if (self::plugin_setting_is_true('strict_dates', false) and is_object($column) and !$is_MySQL_timestamp) { //error_log(__METHOD__.' intl? '.(class_exists('IntlDateFormatter')?'yes':'no').' datetime? '.(class_exists('DateTime')?'yes':'no')); if (class_exists('IntlDateFormatter')) { self::$date_mode = 'Intl'; $DateFormat = new IntlDateFormatter(get_locale(), IntlDateFormatter::LONG, IntlDateFormatter::NONE, NULL, NULL, Participants_Db::get_ICU_date_format(self::$plugin_options['input_date_format'])); $DateFormat->setLenient(false); // we want it strict $timestamp = $DateFormat->parse($string); if ($DateFormat->getErrorCode() !== 0) { $errors = array('code' => $DateFormat->getErrorCode(), 'error' => $DateFormat->getErrorMessage()); } if (!$errors) { $the_Date = new DateTime(); $the_Date->setTimestamp($timestamp); } elseif (WP_DEBUG) { error_log(__METHOD__ . ' IntlDateFormatter error: format string: ' . Participants_Db::get_ICU_date_format(self::$plugin_options['input_date_format']) . ' timestamp: ' . $timestamp . ' formatter error: ' . $DateFormat->getErrorMessage()); } } if (!$the_Date && class_exists('DateTime')) { self::$date_mode = 'DateTime'; $the_Date = DateTime::createFromFormat(self::$plugin_options['input_date_format'], $string); } if (is_object($the_Date)) { $errors = $the_Date->getLastErrors(); if ($errors['warning_count'] === 0 && $errors['error_count'] === 0) { $errors = false; } } if (is_array($errors) && !empty($string)) { $the_Date = false; if (is_object(self::$validation_errors) and is_object($column)) { self::$validation_errors->add_error($column->name, sprintf(__('The date for "%s" was invalid. Please input the date with the exact format shown', 'participants-database'), $column->title)); } if (WP_DEBUG) { error_log(__METHOD__ . ' DateTime parse error: ' . implode(', ', $errors)); } } /* * if we have a valid date, convert to timestamp */ if ($the_Date) { /* * zero the time so date equality comparisons can be made */ if ($zero_time) { $the_Date->setTime(0, 0); } $date = $the_Date->format('U'); } } /* * if we haven't got a timestamp, parse the date the regular way */ if ($date === false or !self::is_valid_timestamp($date)) { $date = false; // no valid date yet if (is_object($column) && $column->form_element == 'timestamp') { if ($zero_time) { /* * we need to zero the time, we first try to do it using the DateTime class */ $the_Date = new DateTime($string); if (is_object($the_Date)) { $the_Date->setTime(0, 0); $string = $the_Date->format(self::$date_format); } else { /* * remove the time portion of the timestamp */ $string = preg_replace('# [0-9]{2}:[0-9]{2}:[0-9]{2}$#', '', $string); $string .= ' 00:00 -0'; } } } /* * @version 1.6 * Most of the time, the default PHP timezone is the current setting, but * experience has shown it's necessary to reset it for the conversion to make * sure. We also must assume that the database server and PHP server are on * the same TZ. */ date_default_timezone_set(self::get_timezone()); setlocale(LC_ALL, get_locale()); /* * @version 1.6 * added strptime method for locaized dates * * this only works for known formats...so timestamps and when "strict dates" is enabled */ if (function_exists('strptime') && (self::plugin_setting_is_true('strict_dates', false) || $is_MySQL_timestamp)) { self::$date_mode = 'strptime'; if ($is_MySQL_timestamp) { $format = '%Y-%m-%d'; } else { $format_setting = Participants_Db::plugin_setting_is_set('input_date_format') ? Participants_Db::plugin_setting('input_date_format') : get_bloginfo('date_format'); $format = Participants_Db::translate_date_format($format_setting, 'strftime'); } $date_array = strptime($string, $format); $date = mktime($date_array['tm_hour'], $date_array['tm_min'], $date_array['tm_sec'], $date_array['tm_mon'] + 1, $date_array['tm_mday'], $date_array['tm_year'] + 1900); } if ($date === false) { self::$date_mode = 'strtotime'; $date = strtotime(self::date_order_fix($string)); } } return $date; }
/** * applies conditioning and escaping to the incoming value, also allows for a filter callback * * @param type $value * @return string */ function process_value($value) { return Participants_Db::set_filter('csv_import_value', esc_sql($this->_enclosure_trim($value, '', $this->CSV->enclosure))); }
/** * sets up the template iteration object * * this takes all the fields that are going to be displayed and organizes them * under their group so we can easily run through them in the template */ protected function _setup_iteration() { $this->_setup_hidden_fields(); $this->record = new stdClass(); $groups = Participants_Db::get_groups(); foreach ($this->display_groups as $group_name) { $group_fields = $this->_get_group_fields($group_name); $this->record->{$group_name} = (object) $groups[$group_name]; $this->record->{$group_name}->fields = new stdClass(); $field_count = 0; $all_empty_fields = true; foreach ($group_fields as $field) { // set the current value of the field $this->_set_field_value($field); /* * hidden fields are stored separately for modules that use them as * hidden input fields */ if ($field->form_element !== 'hidden') { $this->_set_field_link($field); /* * add the field object to the record object */ if (in_array($field->name, $this->display_columns)) { $field_count++; if (!$this->_empty($field->value)) { $all_empty_fields = false; } /** * @version 1.6 'pdb-before_field_added_to_iterator' filter * @param $field object */ $this->record->{$group_name}->fields->{$field->name} = Participants_Db::set_filter('before_field_added_to_iterator', $field); } } } } if ($field_count === 0) { // remove the empty group from the iterator unset($this->record->{$group_name}); } elseif ($all_empty_fields) { $this->record->{$group_name}->class[] = 'empty-field-group'; } // save the number of groups $this->group_count = count((array) $this->record); }
/** * selects the template to use * */ private function _find_template() { $template = false; $template = get_stylesheet_directory() . '/templates/pdb-' . $this->module . '-' . $this->template_name . '.php'; if (!file_exists($template)) { /* * we do this here so that the callback can choose to provide a default template * or override the custom template. */ $template = Participants_Db::set_filter('template_select', $template); } if (!file_exists($template)) { $template = Participants_Db::$plugin_path . '/templates/pdb-' . $this->module . '-' . $this->template_name . '.php'; } if (!file_exists($template)) { $template = Participants_Db::$plugin_path . '/templates/pdb-' . $this->module . '-default.php'; } if (!file_exists($template)) { error_log(__METHOD__ . ' template not found: ' . $template); } // pass the found template value through a filter so it can be changed by a plugin $this->template = $template; }
private function _get_pagelist($with_none = false, $with_blank = false) { $pagelist = array(); if ($with_blank) { $pagelist['null_select'] = ''; } if ($with_none) { $pagelist[__('Same Page', 'participants-database')] = 'none'; } $pages = get_posts(array('post_type' => 'page', 'posts_per_page' => -1)); foreach ($pages as $page) { $pagelist[Participants_Db::set_filter('translate_string', $page->post_title)] = $page->ID; } /* * if you wish to include posts in the list of pages where the shortcode can be found, uncomment this block of code */ /* $posts = get_posts( array( 'numberposts' => -1 ) ); foreach( $posts as $post ) { $pagelist[ $post->post_title ] = $post->ID; } */ return $pagelist; }
/** * builds an option series * * if an element in the options array has a value of bool false, it will open an * optgroup using the key as the group * * @var string|bool label of the "other" option if any */ protected function _add_option_series($otherlabel = false) { if (empty($this->options)) { return; } foreach ($this->_make_assoc($this->options) as $title => $value) { if (($value === false or $value === 'false' or $value === 'optgroup') and !empty($title)) { $this->_add_options_divider($title); } elseif ($value === 'other') { $otherlabel = $title; } elseif (!empty($value) or $value === 0) { $this->_addline('<option value="' . $value . '" ' . $this->_set_selected($value, $this->value, 'selected') . ' >' . Participants_Db::set_filter('translate_string', stripslashes($title)) . '</option>', -1); } } // add the "other" option if ($otherlabel !== false) { $this->_addline('<option ' . ($this->value !== '' ? $this->_set_selected($this->options, $this->value, 'selected', false) : '') . ' value="other" >' . $otherlabel . '</option>'); } if ($this->inside) { $this->_addline('</optgroup>'); $this->inside = false; } }