/**
  * intializes the object with a setup array
  *
  * @param array $config an array of optional parameters:
  *                     'filename' => an image path, filename or URL
  *                     'classname' => a classname for the image
  *                     'wrap_tags' => array of open and close HTML
  *                     'link' URI for a wrapping anchor tag
  *                     'relstring' => string to show in the "rel" attribute of the image
  *                     'mode' => display mode: as an image or a filename or both
  *                     'module' => calling module
  */
 function __construct($config)
 {
     parent::__construct($config);
     $this->classname .= ' ' . Participants_Db::$prefix . 'image image-field-wrap';
     if (empty($this->link)) {
         $this->link = $this->image_defined && Participants_Db::plugin_setting_is_true('image_link') ? $this->image_uri : '';
     }
 }
 /**
  * construct the class
  * 
  * we check the setting for using PHP session, if false, we use a WP Transient-based session
  * 
  * we are just using this alternate form of session mnagement instead of PHP 
  * sessions for now
  */
 public function __construct()
 {
     $this->use_php_sessions = Participants_Db::plugin_setting_is_true('use_php_sessions');
     $this->session_name = Participants_Db::$prefix . 'session';
     if ($this->use_php_sessions) {
         if (!session_id()) {
             add_action('init', 'session_start', -2);
         }
     } else {
         // Use WP_Session (default)
         require_once plugin_dir_path(__FILE__) . 'wp-session.inc.php';
         if (!defined('WP_SESSION_COOKIE')) {
             define('WP_SESSION_COOKIE', Participants_Db::$prefix . 'wp_session');
         }
     }
     add_action('plugins_loaded', array($this, 'init'), -1);
 }
 /**
  * supplies the current empty state logic value
  * 
  * true - empty search allowed
  * false - empty searches not allowed
  * 
  * @return bool
  */
 public function empty_search_allowed()
 {
     if ($this->is_shortcode() || Participants_Db::plugin_setting_is_true('empty_search', false)) {
         return true;
     }
     return false;
 }
 /**
  * conditionally removes line breaks from a buffered output
  * 
  * @param string $input the buffer input
  * @return string processed string
  */
 protected function strip_linebreaks($input)
 {
     if (Participants_Db::plugin_setting_is_true('strip_linebreaks')) {
         $input = str_replace(PHP_EOL, '', $input);
     }
     return $input;
 }
 /**
  * indicates whether groups are to be printed in the form
  *
  * signup and record forms print group titles/descriptions only if the setting for that form is true
  * all other shortcodes always print groups, but they're really only seen in single record displays
  * 
  * @return bool true if groups are to be printed
  */
 public function printing_groups()
 {
     switch ($this->module) {
         case 'signup':
             $optionname = 'signup_show_group_descriptions';
             break;
         case 'record':
             $optionname = 'show_group_descriptions';
             break;
         default:
             return true;
     }
     return Participants_Db::plugin_setting_is_true($optionname);
 }
Пример #6
0
 /**
  * processes any POST requests
  * 
  * this is called on the 'init' hook
  * 
  * @global object $wpdb
  * @return null
  */
 public static function process_page_request()
 {
     $post_sanitize = array('subsource' => FILTER_SANITIZE_STRING, 'action' => FILTER_SANITIZE_STRING, 'pdb_data_keys' => FILTER_SANITIZE_STRING, 'submit_button' => FILTER_SANITIZE_STRING, 'filename' => FILTER_SANITIZE_STRING, 'base_filename' => FILTER_SANITIZE_STRING, 'CSV_type' => FILTER_SANITIZE_STRING, 'include_csv_titles' => FILTER_VALIDATE_BOOLEAN, 'nocookie' => FILTER_VALIDATE_BOOLEAN, 'previous_multipage' => FILTER_SANITIZE_STRING);
     /*
      * $post_input is used for control functions, not for the dataset
      */
     $post_input = filter_input_array(INPUT_POST, $post_sanitize);
     // only process POST arrays from this plugin's pages
     if (empty($post_input['subsource']) or $post_input['subsource'] != self::PLUGIN_NAME or empty($post_input['action'])) {
         return;
     }
     // add a filter to check the submission before anything is done with it
     $check = true;
     self::set_filter('check_submission', $check);
     if ($check === false) {
         return;
     }
     // error_log( __METHOD__.' post:'.print_r( $_POST, true ) );
     /*
      * the originating page for a multipage form is saved in a session value
      * 
      * if this is an empty string, it is assumed the submission was not part of a multipage form series
      */
     self::$session->set('previous_multipage', $post_input['previous_multipage']);
     /*
      * get the defined columns for the submitting shortcode (if any)
      * 
      * this is needed so that validation will be performed on the expected list 
      * of fields, not just what's found in the POST array
      */
     $columns = false;
     if (!empty($post_input['pdb_data_keys'])) {
         $columns = self::get_data_key_columns($post_input['pdb_data_keys']);
     }
     /*
      * instantiate the validation object if we need to. This is necessary
      * because another script can instantiate the object in order to add a
      * feedback message
      * 
      * we don't validate administrators in the admin
      */
     if (!is_object(self::$validation_errors)) {
         if (Participants_Db::is_form_validated()) {
             self::$validation_errors = new PDb_FormValidation();
         }
     }
     switch ($post_input['action']) {
         case 'update':
         case 'insert':
             /*
              * we are here for one of these cases:
              *   a) we're adding a new record in the admin
              *   b) a user is updating their record on the frontend
              *   c) an admin is updating a record
              *
              * signups are processed in the case 'signup' section
              * 
              * set the raw post array filters. We pass in the $_POST array, expecting 
              * a possibly altered copy of it to be returned
              * 
              * filter: pdb-before_submit_update
              * filter: pdb-before_submit_add
              */
             $post_data = self::set_filter('before_submit_' . ($post_input['action'] === 'insert' ? 'add' : 'update'), $_POST);
             if (isset($_POST['id'])) {
                 $id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT, array('options' => array('min_range' => 1)));
             } elseif (isset($_GET['id'])) {
                 $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, array('options' => array('min_range' => 1)));
             } else {
                 $id = false;
             }
             $participant_id = self::process_form($post_data, $post_input['action'], $id, $columns);
             if (false === $participant_id) {
                 // we have errors; go back to form and show errors
                 return;
             }
             /*
              * set the stored record hook.
              * 
              * hook: pdb-after_submit_update
              * hook: pdb-after_submit_add
              */
             $wp_hook = self::$prefix . 'after_submit_' . ($post_input['action'] == 'insert' ? 'add' : 'update');
             do_action($wp_hook, self::get_participant($participant_id));
             /*
              * if we are submitting from the frontend, set the feedback message and 
              * send the update notification
              */
             if (!is_admin()) {
                 /*
                  * if the user is an admin, the validation object won't be instantiated, 
                  * so we do that here so the feedback message can be shown.
                  */
                 if (!is_object(self::$validation_errors)) {
                     self::$validation_errors = new PDb_FormValidation();
                 }
                 self::$validation_errors->add_error('', self::$plugin_options['record_updated_message']);
                 if (self::$plugin_options['send_record_update_notify_email'] && Participants_Db::$session->get('form_status') !== 'multipage') {
                     $sent = wp_mail(self::$plugin_options['email_signup_notify_addresses'], self::proc_tags(self::$plugin_options['record_update_email_subject'], $participant_id, 'all'), self::proc_tags(self::$plugin_options['record_update_email_body'], $participant_id, 'all'), self::$email_headers);
                 }
                 /*
                  * if the "thanks page" is defined as another page, save the ID in a session variable and move to that page.
                  */
                 if (isset($post_data['thanks_page']) && $post_data['thanks_page'] != $_SERVER['REQUEST_URI']) {
                     self::$session->set('pdbid', $post_data['id']);
                     $redirect = $post_input['action'] == 'insert' ? $post_data['thanks_page'] : self::add_uri_conjunction($post_data['thanks_page']) . 'action=update';
                     wp_redirect($redirect);
                     exit;
                 }
                 return;
             }
             // redirect according to which submit button was used
             switch ($post_input['submit_button']) {
                 case self::$i18n['apply']:
                     $redirect = get_admin_url() . 'admin.php?page=' . self::PLUGIN_NAME . '-edit_participant&id=' . $participant_id;
                     break;
                 case self::$i18n['next']:
                     $get_id = $post_input['action'] == 'update' ? '&id=' . self::next_id($participant_id) : '';
                     $redirect = get_admin_url() . 'admin.php?page=' . self::PLUGIN_NAME . '-edit_participant' . $get_id;
                     break;
                 case self::$i18n['previous']:
                     $get_id = $post_input['action'] == 'update' ? '&id=' . self::next_id($participant_id, false) : '';
                     $redirect = get_admin_url() . 'admin.php?page=' . self::PLUGIN_NAME . '-edit_participant' . $get_id;
                     break;
                 case self::$i18n['submit']:
                 default:
                     $redirect = get_admin_url() . 'admin.php?page=' . self::PLUGIN_NAME;
             }
             wp_redirect($redirect);
             exit;
         case 'output CSV':
             $csv_role = Participants_Db::plugin_setting_is_true('editor_allowed_csv_export') ? 'editor' : 'admin';
             if (!Participants_Db::current_user_has_plugin_role($csv_role, 'csv export')) {
                 die;
             }
             $header_row = array();
             $title_row = array();
             $data = array();
             $filename = !empty($post_input['filename']) ? $post_input['filename'] : '';
             switch ($post_input['CSV_type']) {
                 // create a blank data array
                 case 'blank':
                     // add the header row
                     foreach (self::get_column_atts('CSV') as $column) {
                         $header_row[] = $column->name;
                     }
                     $data[] = $header_row;
                     $i = 2;
                     // number of blank rows to create
                     while ($i > 0) {
                         $data[] = array_fill_keys($header_row, '');
                         $i--;
                     }
                     break;
                 case 'participant list':
                     global $wpdb;
                     $import_columns = '';
                     foreach (self::get_column_atts('CSV') as $column) {
                         $import_columns .= sprintf('`%s`,', $column->name);
                         $header_row[] = $column->name;
                         $title_row[] = $column->title;
                     }
                     $data['header'] = $header_row;
                     if ($post_input['include_csv_titles']) {
                         $data['titles'] = $title_row;
                     }
                     global $current_user;
                     $query = get_transient(Participants_Db::$prefix . 'admin_list_query' . $current_user->ID);
                     if ($query) {
                         $query = str_replace('*', ' ' . trim($import_columns, ',') . ' ', $query);
                         $data += self::_prepare_CSV_rows($wpdb->get_results($query, ARRAY_A));
                     }
                     break;
             }
             // CSV type
             if (!empty($filename)) {
                 $base_filename = substr($filename, 0, strpos($filename, PDb_List_Admin::filename_datestamp() . '.csv'));
                 /*
                  * @version 1.6
                  * base filename is now saved as a preference
                  */
                 global $user_ID;
                 PDb_List_Admin::$user_settings = Participants_Db::$prefix . PDb_List_Admin::$user_settings . '-' . $user_ID;
                 PDb_List_Admin::set_admin_user_setting('csv_base_filename', $base_filename);
                 // create a file pointer connected to the output stream
                 $output = fopen('php://output', 'w');
                 //header('Content-type: application/csv'); // some sources say it should be this
                 header('Content-Type: text/csv; charset=utf-8');
                 header("Cache-Control: no-store, no-cache");
                 header('Content-Disposition: attachment; filename="' . $filename . '"');
                 // output the data lines
                 foreach ($data as $line) {
                     fputcsv($output, $line, ',', self::$CSV_enclosure);
                 }
                 fclose($output);
                 // we must terminate the script to prevent additional output being added to the CSV file
                 exit;
             }
             return $data;
         case 'retrieve':
             if (self::nonce_check(filter_input(INPUT_POST, 'session_hash', FILTER_SANITIZE_STRING), self::$main_submission_nonce_key)) {
                 self::_process_retrieval();
             }
             return;
         case 'signup':
             if (!self::nonce_check(filter_input(INPUT_POST, 'session_hash', FILTER_SANITIZE_STRING), self::$main_submission_nonce_key)) {
                 return;
             }
             $_POST['private_id'] = '';
             $columns[] = 'private_id';
             /*
              * route the $_POST data through a callback if defined
              * 
              * filter: pdb-before_submit_signup
              */
             $post_data = self::set_filter('before_submit_signup', $_POST);
             /*
              * the signup form should update the current record if it is revisited during a multipage form session
              */
             $submit_action = 'insert';
             if (self::$session->get('pdbid') !== false) {
                 $submit_action = 'update';
             }
             // submit the data
             $post_data['id'] = self::process_form($post_data, $submit_action, self::$session->get('pdbid'), $columns);
             if (false !== $post_data['id']) {
                 /* 
                  * hook: pdb-after_submit_signup
                  */
                 $wp_hook = self::$prefix . 'after_submit_signup';
                 do_action($wp_hook, self::get_participant($post_data['id']));
                 $redirect = $post_data['thanks_page'];
                 self::$session->set('pdbid', $post_data['id']);
                 wp_redirect($redirect);
                 exit;
             }
             return;
     }
     // $_POST['action']
 }
    /**
     * prints an individual group tab content
     * 
     * @param string $group current group name
     */
    protected function print_group_tab_content($group)
    {
        $internal_group = $group === 'internal';
        $hscroll = Participants_Db::plugin_setting_is_true('admin_horiz_scroll');
        ?>
      <div id="<?php 
        echo $group;
        ?>
" class="manage-fields-wrap" >
        <form id="manage_<?php 
        echo $group;
        ?>
_fields" method="post" autocomplete="off">
          <h3><?php 
        echo $this->group_titles[$group], ' ', $this->i18n['fields'];
        ?>
</h3>
          <p>
            <?php 
        if (!$internal_group) {
            // "add field" functionality
            PDb_FormElement::print_element(array('type' => 'submit', 'value' => $this->i18n['add field'], 'name' => 'action', 'attributes' => array('class' => 'button button-default', 'disabled' => 'disabled')));
            PDb_FormElement::print_element(array('type' => 'text', 'name' => 'title', 'value' => '', 'attributes' => array('placeholder' => $this->i18n['new field title'] . '&hellip;', 'class' => 'add_field')));
        }
        // skip internal groups
        // number of rows in the group
        $num_group_rows = count($this->fields_data[$group]);
        $last_order = $num_group_rows > 1 ? $this->fields_data[$group][$num_group_rows - 1]['order'] + 1 : 1;
        PDb_FormElement::print_hidden_fields(array('group' => $group, 'order' => $last_order));
        ?>
          </p>
          <?php 
        if ($hscroll) {
            ?>
          <div class="pdb-horiz-scroll-scroller">
          <div class="pdb-horiz-scroll-width">
            <?php 
        }
        ?>
            <table class="wp-list-table widefat fixed manage-fields" >
            <thead>
              <tr>
                <?php 
        if (!$internal_group) {
            ?>
                  <th scope="col" class="delete vertical-title"><span><?php 
            echo $this->table_header('delete');
            ?>
</span></th>
                  <?php 
        }
        // internal group test
        foreach ($this->attribute_columns[$group] as $attribute_column) {
            if ($internal_group && in_array($attribute_column, array('order'))) {
                continue;
            }
            $column_class = $attribute_column;
            $column_class .= in_array($attribute_column, array('order', 'persistent', 'sortable', 'admin_column', 'display_column', 'CSV', 'signup', 'display', 'readonly')) ? ' vertical-title' : '';
            $column_class .= in_array($attribute_column, array('admin_column', 'display_column')) ? ' number-column' : '';
            ?>
                  <th scope="col" class="<?php 
            echo $column_class;
            ?>
"><span><?php 
            echo $this->table_header($attribute_column);
            ?>
</span></th>
                <?php 
        }
        ?>
              </tr>
            </thead>
            <tbody id="<?php 
        echo $group;
        ?>
_fields">
              <?php 
        if ($num_group_rows < 1) {
            // there are no rows in this group to show
            ?>
                <tr><td colspan="<?php 
            echo count($this->attribute_columns[$group]) + 1;
            ?>
"><?php 
            _e('No fields in this group', 'participants-database');
            ?>
</td></tr>
                    <?php 
        } else {
            // add the rows of the group
            foreach ($this->fields_data[$group] as $database_row) {
                ?>
                  <tr id="db_row_<?php 
                echo $database_row['id'];
                ?>
">
                      <?php 
                if (!$internal_group) {
                    ?>
                      <td>
                        <?php 
                }
                // hidden field test
                // add the hidden fields
                foreach (array('id') as $attribute_column) {
                    $value = Participants_Db::prepare_value($database_row[$attribute_column]);
                    $element_atts = array_merge($this->get_edit_field_type($attribute_column), array('name' => 'row_' . $database_row['id'] . '[' . $attribute_column . ']', 'value' => $value));
                    PDb_FormElement::print_element($element_atts);
                }
                PDb_FormElement::print_element(array('type' => 'hidden', 'value' => '', 'name' => 'row_' . $database_row['id'] . '[status]', 'attributes' => array('id' => 'status_' . $database_row['id'])));
                if (!$internal_group) {
                    ?>
                          <a href="javascript:return false" title="<?php 
                    echo $database_row['id'];
                    ?>
" data-thing-name="delete_<?php 
                    echo $database_row['id'];
                    ?>
" class="delete" data-thing="<?php 
                    _e('field', 'participants-database');
                    ?>
"><span class="glyphicon glyphicon-remove"></span></a>
                      </td>
                      <?php 
                }
                // internal group test
                // list the fields for editing
                foreach ($this->attribute_columns[$group] as $attribute_column) {
                    $edit_field_type = $this->get_edit_field_type($attribute_column);
                    if ($internal_group && in_array($attribute_column, array('order'))) {
                        continue;
                    }
                    // preserve backslashes in regex expressions
                    if ($attribute_column == 'validation') {
                        if ($database_row['name'] == 'email' && $database_row[$attribute_column] == 'email') {
                            $database_row[$attribute_column] = 'email-regex';
                        }
                    }
                    $value = Participants_Db::prepare_value($database_row[$attribute_column]);
                    $element_atts = array_merge($edit_field_type, array('name' => 'row_' . $database_row['id'] . '[' . $attribute_column . ']', 'value' => $this->prep_value($value, in_array($attribute_column, array('title', 'description')))));
                    ?>
                      <td class="<?php 
                    echo $attribute_column;
                    ?>
"><?php 
                    PDb_FormElement::print_element($element_atts);
                    ?>
</td>
                    <?php 
                }
                // columns
                ?>
                  </tr>
                <?php 
            }
            // rows
        }
        // num group rows
        ?>
            </tbody>
          </table>
            <?php 
        if ($hscroll) {
            ?>
          </div>
          </div>
          <?php 
        }
        ?>
          <p class="submit">
            <?php 
        PDb_FormElement::print_element(array('type' => 'submit', 'name' => 'action', 'value' => $this->i18n['update fields'], 'class' => 'button button-primary manage-fields-update'));
        ?>
          </p>
        </form>
      </div><!-- tab content container -->
  <?php 
    }
 /**
  * returns an internationalized date string from a UNIX timestamp
  * 
  * @param int $timestamp a UNIX timestamp
  * @param bool $time if true, adds the time of day to the format
  * @return string a formatted date or input string if invalid
  */
 public static function format_date($timestamp, $time = false)
 {
     // if it's not a timestamp, we attempt to convert it to one
     if (!Participants_Db::is_valid_timestamp($timestamp)) {
         $timestamp = Participants_Db::parse_date($timestamp);
     }
     if (Participants_Db::is_valid_timestamp($timestamp)) {
         $format = Participants_Db::plugin_setting_is_true('strict_dates') ? Participants_Db::plugin_setting('input_date_format') : Participants_Db::$date_format;
         if ($time) {
             $format .= ' ' . get_option('time_format');
         }
         return date_i18n($format, $timestamp);
     } else {
         // not a timestamp: return unchanged
         return $timestamp;
     }
 }
 /**
  * returns a concatenated string from an array of HTML lines
  * 
  * @version 1.6 added option to assemble HTML without linebreaks
  * 
  * @param array $output
  * @return type
  */
 public function output_HTML($output = array())
 {
     $glue = Participants_Db::plugin_setting_is_true('strip_linebreaks') ? '' : PHP_EOL;
     return implode($glue, $output);
 }
    /**
     * prints the main body of the list, including headers
     *
     * @param string $mode dtermines the print mode: 'noheader' skips headers, (other choices to be determined)
     */
    private static function _main_table($mode = '')
    {
        $hscroll = Participants_Db::plugin_setting_is_true('admin_horiz_scroll');
        ?>
            <?php 
        if ($hscroll) {
            ?>
            <div class="pdb-horiz-scroll-scroller">
              <div class="pdb-horiz-scroll-width" style="width: <?php 
            echo count(self::$display_columns) * 10;
            ?>
em">
    <?php 
        }
        ?>
        <table class="wp-list-table widefat fixed pages pdb-list stuffbox" cellspacing="0" >
          <?php 
        $PID_pattern = '<td><a href="%2$s">%1$s</a></td>';
        //template for outputting a column
        $col_pattern = '<td>%s</td>';
        if (count(self::$participants) > 0) {
            if ($mode != 'noheader') {
                ?>
              <thead>
                <tr>
        <?php 
                self::_print_header_row();
                ?>
                </tr>
              </thead>
              <?php 
            }
            // table header row
            // print the table footer row if there is a long list
            if ($mode != 'noheader' && count(self::$participants) > 10) {
                ?>
              <tfoot>
                <tr>
        <?php 
                self::_print_header_row();
                ?>
                </tr>
              </tfoot>
              <?php 
            }
            // table footer row
            ?>
            <tbody>
            <?php 
            // output the main list
            foreach (self::$participants as $value) {
                ?>
                <tr>
        <?php 
                // print delete check
                ?>
                  <td>
                          <?php 
                if (current_user_can(Participants_Db::plugin_capability('plugin_admin_capability', 'delete participants'))) {
                    ?>
                            <input type="checkbox" class="delete-check" name="pid[]" value="<?php 
                    echo $value['id'];
                    ?>
" />
                    <?php 
                }
                ?>
                            <a href="admin.php?page=<?php 
                echo 'participants-database';
                ?>
-edit_participant&amp;action=edit&amp;id=<?php 
                echo $value['id'];
                ?>
" title="<?php 
                _e('Edit', 'participants-database');
                ?>
"><span class="glyphicon glyphicon-edit"></span></a>
                  </td>
              <?php 
                foreach (self::$display_columns as $column) {
                    // this is where we place form-element-specific text transformations for display
                    switch ($column->form_element) {
                        case 'image-upload':
                            $image_params = array('filename' => basename($value[$column->name]), 'link' => '', 'mode' => Participants_Db::plugin_setting_is_true('admin_thumbnails') ? 'image' : 'filename');
                            if (Participants_Db::is_single_record_link($column)) {
                                $page_link = get_permalink(Participants_Db::plugin_setting('single_record_page'));
                                $image_params['link'] = Participants_Db::add_uri_conjunction($page_link) . 'pdb=' . $value['id'];
                            }
                            // this is to display the image as a linked thumbnail
                            $image = new PDb_Image($image_params);
                            $display_value = $image->get_image_html();
                            break;
                        case 'date':
                        case 'timestamp':
                            if (!empty($value[$column->name])) {
                                $format = Participants_Db::$date_format;
                                if (Participants_Db::plugin_setting_is_true('show_time') and $column->form_element == 'timestamp') {
                                    // replace spaces with &nbsp; so the time value stays together on a broken line
                                    $format .= ' ' . str_replace(' ', '&\\nb\\sp;', get_option('time_format'));
                                }
                                $time = Participants_Db::is_valid_timestamp($value[$column->name]) ? (int) $value[$column->name] : Participants_Db::parse_date($value[$column->name], $column->name, $column->form_element == 'date');
                                $display_value = $value[$column->name] == '0000-00-00 00:00:00' ? '' : date_i18n($format, $time);
                                //$display_value = date_i18n($format, $time);
                            } else {
                                $display_value = '';
                            }
                            break;
                        case 'multi-select-other':
                        case 'multi-checkbox':
                            // multi selects are displayed as comma separated lists
                            $column->value = $value[$column->name];
                            $display_value = PDb_FormElement::get_field_value_display($column, false);
                            //$display_value = is_serialized($value[$column->name]) ? implode(', ', unserialize($value[$column->name])) : $value[$column->name];
                            break;
                        case 'link':
                            $link_value = maybe_unserialize($value[$column->name]);
                            if (count($link_value) === 1) {
                                $link_value = array_fill(0, 2, current((array) $link_value));
                            }
                            $display_value = Participants_Db::make_link($link_value[0], $link_value[1]);
                            break;
                        case 'rich-text':
                            if (!empty($value[$column->name])) {
                                $display_value = '<span class="textarea">' . $value[$column->name] . '</span>';
                            } else {
                                $display_value = '';
                            }
                            break;
                        case 'text-line':
                            if (Participants_Db::is_single_record_link($column)) {
                                $url = get_permalink(Participants_Db::plugin_setting('single_record_page'));
                                $template = '<a href="%1$s" >%2$s</a>';
                                $delimiter = false !== strpos($url, '?') ? '&' : '?';
                                $url = $url . $delimiter . 'pdb=' . $value['id'];
                                $display_value = sprintf($template, $url, $value[$column->name]);
                            } elseif (Participants_Db::plugin_setting_is_true('make_links')) {
                                $field = new stdClass();
                                $field->value = $value[$column->name];
                                $display_value = PDb_FormElement::make_link($field);
                            } else {
                                $display_value = $value[$column->name] === '' ? $column->default : esc_html($value[$column->name]);
                            }
                            break;
                        case 'hidden':
                            $display_value = $value[$column->name] === '' ? '' : esc_html($value[$column->name]);
                            break;
                        default:
                            $column->value = $value[$column->name];
                            $display_value = PDb_FormElement::get_field_value_display($column, false);
                    }
                    if ($column->name === 'private_id' && Participants_Db::plugin_setting_is_set('registration_page')) {
                        printf($PID_pattern, $display_value, Participants_Db::get_record_link($display_value));
                    } else {
                        printf($col_pattern, $display_value);
                    }
                }
                ?>
                </tr>
                <?php 
            }
            ?>
            </tbody>

              <?php 
        } else {
            // if there are no records to show; do this
            ?>
            <tbody>
              <tr>
                <td><?php 
            _e('No records found', 'participants-database');
            ?>
</td>
              </tr>
            </tbody>
              <?php 
        }
        // participants array
        ?>
        </table>
                  <?php 
        if ($hscroll) {
            ?>
              </div>
            </div>
    <?php 
        }
        ?>
      </form>
              <?php 
    }
 /**
  * outputs a "record not found" message
  *
  * the message is defined in the plugin settings
  */
 protected function _not_found()
 {
     if (Participants_Db::plugin_setting_is_true('no_record_use_template')) {
         $this->_print_from_template();
     } else {
         $this->output = empty(Participants_Db::$plugin_options['no_record_error_message']) ? '' : '<p class="alert alert-error">' . Participants_Db::plugin_setting('no_record_error_message') . '</p>';
     }
 }
 /**
  * prints a private link retrieval link
  * 
  * @param string $linktext
  */
 public function print_retrieve_link($linktext = '', $open_tag = '<span class="pdb-retrieve-link">', $close_tag = '</span>')
 {
     $linktext = empty($linktext) ? Participants_Db::$plugin_options['retrieve_link_text'] : $linktext;
     if (Participants_Db::plugin_setting_is_true('show_retrieve_link')) {
         $retrieve_link = Participants_Db::plugin_setting('link_retrieval_page') !== 'none' ? get_permalink(Participants_Db::plugin_setting('link_retrieval_page')) : $_SERVER['REQUEST_URI'];
         echo $open_tag . '<a href="' . Participants_Db::add_uri_conjunction($retrieve_link) . 'm=r">' . Participants_Db::set_filter('translate_string', $linktext) . '</a>' . $close_tag;
     }
 }