# contact-forms/trunk/admin/list-page.php

Contact Forms by Cimatti, version trunk. 408 lines.

- Page: https://pluginprobe.com/plugins/contact-forms/trunk/code/admin/list-page.php
- Raw: https://pluginprobe.com/plugins/contact-forms/trunk/raw/admin/list-page.php
- Modified: 2026-08-21T08:39:40+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/contact-forms/trunk/code/admin/list-page.php#L10-L20`.

```php
<?php
if ( ! defined( 'ABSPATH' ) ) exit;

if (!class_exists('WP_List_Table')) {
  require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
}

class Accua_Forms_List_Table extends WP_List_Table {
  var $message = NULL;
  var $active_items = 0;
  var $del_items = 0;
  var $accua_orderby = null;
  var $accua_order_asc = null;

  function __construct(){
    global $status, $page;
    $this->message = '';
    parent::__construct(array(
      'singular' => 'form',
      'plural' => 'forms',
      'ajax' => false
    ));
  }

  function get_num_of_active_items(){
    return $this->active_items;
  }

  function get_num_of_del_items(){
    return $this->del_items;
  }

  function column_default($item, $column_name){
    if (isset($item[$column_name])) {
      return esc_attr($item[$column_name]);
    } else {
      return '';
    }
  }

  function column_cb($item){
    return sprintf(
      '<input type="checkbox" name="%1$s[]" value="%2$s" />',
      /*$1%s*/ $this->_args['singular'],
      /*$2%s*/ $item['ID']
    );
  }

  function column_title($item){
    if ($item['deleted']) {
      if (isset($item['title'])) {
        $item_name = esc_html($item['title']);
      } else {
        $item_name = $item['ID'];
      }
      $nonced_edit = wp_nonce_url('admin.php?page=accua_forms_list&amp;fid=' . $item['ID'] . '&amp;restore=1', 'edit_posts');
      $actions = array(
        'edit' => "<a href='" . $nonced_edit . "'>" . __("Restore", 'contact-forms') . "</a>",
      );
      return "<strong>" . $item_name . "</strong>" . $this->row_actions($actions);
    } else {
      $nonced_edit = wp_nonce_url('admin.php?page=accua_forms_list&amp;fid=' . $item['ID'], 'edit_posts');
      $nonced_clone = wp_nonce_url('admin.php?page=accua_forms_add&amp;clonefrom=' . $item['ID'], 'clone_posts');
      $nonced_del = wp_nonce_url('admin.php?page=accua_forms_list&amp;fid_del=' . $item['ID'], 'trash_posts');
      $actions = array(
        'edit' => "<a href='{$nonced_edit}'>" . __("Edit", 'contact-forms') . "</a>"
          . " &middot; <a href='{$nonced_clone}'>" . __("Clone", 'contact-forms') . "</a>"
          . " &middot; <a href='admin.php?page=accua_forms_submissions_list&amp;fid={$item['ID']}'>" . __("Report", 'contact-forms') . "</a>"
          . " &middot; <a href='{$nonced_del}'>" . __("Trash", 'contact-forms') . "</a>",
      );
      return "<strong><a class='row-title' href='{$nonced_edit}'>" . esc_html($item['title']) . "</a></strong>" . $this->row_actions($actions);
    }
  }

  function column_submissions($item){
    if ($item['submissions'] != 0)
      return sprintf(
        '<a href="admin.php?page=accua_forms_submissions_list&amp;fid=%1$s">%2$s</a>',
        /*$1%s*/ $item['ID'],
        /*$2%s*/ $item['submissions']
      );
    else
      return "0";
  }

  function get_columns(){
    $columns = array(
      'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
      'title' => __('Title', 'contact-forms'),
      'ID' => 'ID',
      'shortcode' => __('Shortcode', 'contact-forms'),
      'phpcode' => __('PHP code', 'contact-forms'),
      'fromemail' => __('From Email', 'contact-forms'),
      'fromname' => __('From Name', 'contact-forms'),
      'adminemail' => __('Admin Email', 'contact-forms'),
      'bccemail' => __('BCC Email', 'contact-forms'),
      'retention' => __('Data Retention', 'contact-forms'),
      'submissions' => __('Submissions', 'contact-forms'),
    );
    return $columns;
  }

  function column_retention( $item ) {
    return isset( $item['retention'] ) ? esc_html( $item['retention'] ) : '';
  }

  function get_sortable_columns(){
    return array(
      'title' => array('title', false),
      'ID' => array('ID', false),
      'shortcode' => array('ID', false),
      'phpcode' => array('ID', false),
      'fromemail' => array('fromemail', false),
      'fromname' => array('fromname', false),
      'adminemail' => array('adminemail', false),
      'bccemail' => array('bccemail', false),
      'retention' => array('retention_seconds', false),
      'submissions' => array('submissions', false),
    );
  }

  function get_bulk_actions(){
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display logic only, no data processing
    if (isset($_GET['del']) && absint($_GET['del']) === 1) {
      $actions = array();
    } else {
      $actions = array(
        'delete' => __('Move to trash', 'contact-forms')
      );
    }
    return $actions;
  }

  function set_message($single_message){
    $this->message = $single_message;
  }

  function get_message(){
    if ($this->message != NULL)
      return $this->message;
    else
      return NULL;
  }

  function accua_usort_numeric($a, $b){
    $result = ((int)$a[$this->accua_orderby]) - ((int)$b[$this->accua_orderby]);
    if (!$result) {
      $result = ((int)$a['ID']) - ((int)$b['ID']);
    }
    return ($this->accua_order_asc) ? $result : -$result;
  }

  function accua_usort_string($a, $b){
    $result = strcasecmp($a[$this->accua_orderby], $b[$this->accua_orderby]);
    if (!$result) {
      $result = ((int)$a['ID']) - ((int)$b['ID']);
    }
    return ($this->accua_order_asc) ? $result : -$result;
  }

  function process_bulk_action(){
    $current_action = $this->current_action();
    if ($current_action) {
      check_admin_referer('bulk-forms'); //check nonce generated for 'bulk-'.$this->_args['plural']
      // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Values sanitized in array_map below
      $forms_raw = (isset($_GET['form']) && is_array($_GET['form'])) ? wp_unslash($_GET['form']) : array();
      $forms = array_map('sanitize_text_field', $forms_raw);
      if ('delete' === $current_action) {
        $forms_deleted = false;
        $forms_data = get_option('accua_forms_saved_forms', array());
        $trash_data = get_option('accua_forms_trash_forms', array());

        foreach ($forms as $single_form) {
          if (isset($forms_data[$single_form])) {
            $trash_data[$single_form] = $forms_data[$single_form];
            unset($forms_data[$single_form]);
            $forms_deleted = true;
            ?>
              <script type="text/javascript">
                jQuery(function($){
                  // Match the checkbox cell by class, not by tag: WordPress 7.1
                  // renders it as a td where every earlier version rendered a th.
                  jQuery("#the-list tr:has(.check-column input[type='checkbox'][value='<?php echo esc_js( $single_form ); ?>'])").fadeOut();
                });
              </script>
            <?php
          }
        }
        if ($forms_deleted) {
          update_option('accua_forms_trash_forms', $trash_data);
          update_option('accua_forms_saved_forms', $forms_data);
          $this->set_message(__("Forms deleted", 'contact-forms'));
        }

      }
    }
  }

  function prepare_items(){
    global $wpdb, $hook_suffix;
    $per_page = 50;
    $del = isset($_GET['del']) && $_GET['del'] == 1;

    $columns = $this->get_columns();
    $hidden = get_hidden_columns($hook_suffix);
    $sortable = $this->get_sortable_columns();

    $this->_column_headers = array($columns, $hidden, $sortable);

    $current_page = $this->get_pagenum();

    $limit = ($current_page - 1) * $per_page;

    $forms_data = get_option('accua_forms_saved_forms', array());
    $forms_trash = get_option('accua_forms_trash_forms', array());
    $forms_default = get_option('accua_forms_default_form_data', array());

    $this->active_items = count($forms_data);
    $this->del_items = count($forms_trash);

    $data = array();
    $global_retention = get_option( 'accua_forms_retention_data', array() );

    if ($del) {
      check_admin_referer('deleted_forms');
      $start = $forms_trash;
    } else {
      $start = $forms_data;
    }

    foreach ($start as $id => $form) {
      if (isset($form['title']) && (trim($form['title']) !== '')) {
        $title = $form['title'];
      } else {
        $title = __('(no title)', 'contact-forms');
      }

      $data[$id] = array(
        'ID' => $id,
        'title' => $title,
        'submissions' => 0,
        'shortcode' => $del ? '' : '[accua-form fid="' . $id . '"]',
        'phpcode' => $del ? '' : "<?php accua_forms_include('$id'); ?>",
        'deleted' => $del,
      );

      $forminfos = array(
        'fromemail' => 'emails_from',
        'fromname' => 'emails_from_name',
        'adminemail' => 'admin_emails_to',
        'bccemail' => 'emails_bcc',
      );

      foreach ($forminfos as $infodest => $infoid) {
        if (isset($form[$infoid])) {
          $data[$id][$infodest] = $form[$infoid];
        } else {
          $data[$id][$infodest] = $forms_default[$infoid] . " (default)";
        }
      }

      // Compute effective data retention column
      $config = accua_forms_get_retention_config( $id );
      $has_override = ! empty( $form['submission_retention_override'] );
      $unit_labels = array( 'days' => __( 'days', 'contact-forms' ), 'months' => __( 'months', 'contact-forms' ), 'years' => __( 'years', 'contact-forms' ) );
      $mode_labels = array( 'anonymize' => __( 'Anonymize', 'contact-forms' ), 'delete' => __( 'Delete', 'contact-forms' ) );
      $data[$id]['retention_seconds'] = $config['seconds'];
      if ( $config['seconds'] > 0 ) {
        // Reverse-engineer the display value from the form or global settings
        if ( $has_override ) {
          $r_val  = isset( $form['submission_retention_value'] ) ? (int) $form['submission_retention_value'] : 0;
          $r_unit = isset( $form['submission_retention_unit'] ) ? $form['submission_retention_unit'] : 'months';
        } else {
          $r_val  = isset( $global_retention['retention_value'] ) ? (int) $global_retention['retention_value'] : 0;
          $r_unit = isset( $global_retention['retention_unit'] ) ? $global_retention['retention_unit'] : 'months';
        }
        $r_unit_label = $unit_labels[ $r_unit ] ?? $r_unit;
        $r_mode_label = $mode_labels[ $config['mode'] ] ?? $config['mode'];
        $data[$id]['retention'] = sprintf( '%d %s / %s', $r_val, $r_unit_label, $r_mode_label );
      } else {
        $data[$id]['retention'] = __( 'Keep indefinitely', 'contact-forms' );
      }

    }

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table query for form submissions count
    $submissions = $wpdb->get_results(
      $wpdb->prepare(
        "SELECT afs_form_id AS fid, count(*) AS submissions
        FROM `{$wpdb->prefix}accua_forms_submissions`
        WHERE afs_status >= %d
        GROUP BY afs_form_id",
        0
      ),
      OBJECT
    );
    foreach ($submissions as $fsub) {
      if (isset($data[$fsub->fid])) {
        $data[$fsub->fid]['submissions'] = $fsub->submissions;
      } else if ($del) {
        if (!isset($forms_data[$fsub->fid])) {
          $data[$fsub->fid] = array(
            'ID' => $fsub->fid,
            'submissions' => $fsub->submissions,
            'deleted' => true,
            'shortcode' => '',
            'phpcode' => '',
            'fromemail' => '',
            'fromname' => '',
            'adminemail' => '',
            'bccemail' => '',
          );
          $this->del_items++;
        }
      } else if (!isset($forms_trash[$fsub->fid])) {
        $this->del_items++;
      }
    }

    $numeric_keys = array( 'ID', 'submissions', 'retention_seconds' );
    $string_keys  = array( 'title', 'fromemail', 'fromname', 'adminemail', 'bccemail' );
    $allowed_keys = array_merge( $numeric_keys, $string_keys );

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only sort parameter
    $this->accua_orderby = isset($_GET['orderby']) ? sanitize_key(wp_unslash($_GET['orderby'])) : 'ID';
    if ( ! in_array( $this->accua_orderby, $allowed_keys, true ) ) {
      $this->accua_orderby = 'ID';
    }
    // Default order: ascending for string columns, descending for numeric columns
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only sort direction
    if (empty($_GET['order'])) {
      $this->accua_order_asc = in_array( $this->accua_orderby, $string_keys, true );
    } else {
      // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only sort direction
      $this->accua_order_asc = (sanitize_key(wp_unslash($_GET['order'])) !== 'desc');
    }
    if ( in_array( $this->accua_orderby, $numeric_keys, true ) ) {
      usort($data, array(&$this, 'accua_usort_numeric'));
    } else {
      usort($data, array(&$this, 'accua_usort_string'));
    }

    $total_items = count($data);

    $this->items = array_slice($data, $limit, $per_page);

    $this->set_pagination_args(array(
      'total_items' => $total_items,
      'per_page' => $per_page,
      'total_pages' => ceil($total_items / $per_page)
    ));
  }
}

function accua_forms_list_page_table($head = false){
  static $listTable = null;
  //var_dump($_REQUEST);

  if (isset($_GET['fid_del'])) {
    check_admin_referer('trash_posts');
    $fid = sanitize_text_field( wp_unslash( $_GET['fid_del'] ) );
    $forms_data = get_option('accua_forms_saved_forms', array());
    if (isset($forms_data[$fid])) {
      $trash_data = get_option('accua_forms_trash_forms', array());
      $trash_data[$fid] = $forms_data[$fid];
      update_option('accua_forms_trash_forms', $trash_data);
      unset($forms_data[$fid]);
      update_option('accua_forms_saved_forms', $forms_data);
    }
  }

  if ($listTable === null) {
    $listTable = new Accua_Forms_List_Table();
    $listTable->process_bulk_action();
    $listTable->prepare_items();
  }

  if ($head === true) {
    return;
  }

  if ($listTable->get_message() != NULL) { ?>
      <div class="updated"><p><?php echo esc_html( $listTable->get_message() ); ?></p></div>
  <?php } ?>
    <ul class="subsubsub">
      <li>
        <?php $nonced_url = wp_nonce_url('admin.php?page=accua_forms_list', 'home_forms') ?>
          <a <?php if (!isset($_GET['del']) || ($_GET['del'] != 1)) { echo " class='current' "; } ?> href="<?php echo esc_url($nonced_url) ?>">
            <?php esc_html_e("Active", 'contact-forms'); ?></a> (<?php echo esc_html($listTable->get_num_of_active_items()); ?>) |
      </li>
      <li>
        <?php $nonced_url = wp_nonce_url('admin.php?page=accua_forms_list&del=1', 'deleted_forms'); ?>
          <a <?php if (isset($_GET['del']) && ($_GET['del'] == 1)) { echo " class='current' "; } ?> href="<?php echo esc_url($nonced_url) ?>">
            <?php esc_html_e("Trash", 'contact-forms'); ?></a> (<?php echo esc_html($listTable->get_num_of_del_items()); ?>)
      </li>
    </ul>

    <form id="accua-forms-list-filter" method="get">
        <input type="hidden" name="page" value="<?php echo esc_attr( isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : '' ); ?>" />
      <?php
      // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- WP_List_Table display() outputs safe HTML
      $listTable->display();
      ?>
    </form>
  <?php /* echo '<pre>$listTable = ' htmlspecialchars(print_r($listTable, true)); ?></pre> */ ?>
  <?php
}

```
