0

I'm trying to display a WP_List_table inside a metabox. The metabox is for questions which are from assessment_question custom post type.The metabox is being displayed on an other custom post type 'cs_questionnaire'. The table columns display some data taken from questions. Also I am using bulk actions to link questions to a questionnaire.

What's happening is that it all looks fine until I click the Publish/Update button on the custom post type edit screen. If the WP_List_Table has bulk actions it will redirect back to the /wp-admin/edit.php page, if I remove the bulk actions then it Works fine. And in both cases, the nonce stays the same and no extra nonce is created.

I've whole code below. I have already overridden the display_tablenav function by commenting the nonce generating code. It stops working when I provide bulk actions else it works fine with the following code.

<?php
/**
 * Generates The User Grade Listing for Admin
 */
if ( ! class_exists( 'WP_List_Table' ) ) {
    require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}


class Class_Conditional_Shortcode_Questions_Listing extends WP_List_Table {
    // define dataset for WP_List_Table => data

    /** Class constructor */
    public function __construct() {

        parent::__construct(
            array(
                'singular' => __( 'Question', 'conditional-shortcode' ), // singular name of the listed records
                'plural'   => __( 'Questions', 'conditional-shortcode' ), // plural name of the listed records
                'ajax'     => false, // does this table support ajax?
            )
        );
    }


    /**
     * Function to filter data based on order , order_by & searched items
     *
     * @param string $orderby
     * @param string $order
     * @param string $search_term
     * @return array $users_array()
     */
    public function list_table_data_fun( $orderby = '', $order = '', $search_term = '' ) {

        $args            = array();
        $questions_array = array();
        $questions       = '';
        $flag            = false;
        if ( ! empty( $search_term ) ) {

            $args = array(
                'fields'         => 'ids',
                'orderby'        => $orderby,
                'order'          => $order,
                'search'         => intval( sanitize_text_field( $_REQUEST['s'] ) ),
                'post_type'      => 'assessment_question',
                'posts_per_page' => -1,
            );
        } else {
            if ( $order == 'asc' && $orderby == 'id' ) {
                $args = array(

                    'orderby'        => 'ID',
                    'order'          => 'ASC',
                    'fields'         => 'ids',
                    'post_type'      => 'assessment_question',
                    'posts_per_page' => -1,
                );
            } elseif ( $order == 'desc' && $orderby == 'id' ) {
                    $args = array(
                        'orderby'        => 'ID',
                        'order'          => 'DESC',
                        'fields'         => 'ids',
                        'post_type'      => 'assessment_question',
                        'posts_per_page' => -1,
                    );

            } elseif ( $order == 'desc' && $orderby == 'title' ) {
                    $args = array(
                        'orderby'        => 'name',
                        'order'          => 'DESC',
                        'fields'         => 'ids',
                        'post_type'      => 'assessment_question',
                        'posts_per_page' => -1,
                    );
            } elseif ( $order == 'asc' && $orderby == 'title' ) {
                $args = array(
                    'orderby'        => 'name',
                    'order'          => 'ASC',
                    'fields'         => 'ids',
                    'post_type'      => 'assessment_question',
                    'posts_per_page' => -1,
                );
            } else {
                $args = array(
                    'orderby'        => 'ID',
                    'order'          => 'DESC',
                    'fields'         => 'ids',
                    'post_type'      => 'assessment_question',
                    'posts_per_page' => -1,
                );
                $flag = true;
            }
        }
        $questions = get_transient( 'pd_questions' );
        if ( $flag == false ) {
            $questions = get_posts( $args );
        } elseif ( $flag == true && ! $questions ) {
            $questions = get_posts( $args );
            set_transient( 'pd_questions', $questions, 1 * DAY_IN_SECONDS );
        }
        if ( count( $questions ) > 0 ) {
            foreach ( $questions as $question_id ) {
                $question          = get_post_meta( $question_id ?? 0, CONDITIONAL_SHORTCODE_ASSESSMENT_QUESTION_META, true )['question'] ?? 'NA';
                $questions_array[] = array(
                    'id'       => $question_id,
                    'title'    => '<b>' . get_the_title( $question_id ) . '</b>',
                    'question' => $question,
                );

            }
        }

        return $questions_array;
    }
    // prepare_items
    public function prepare_items() {

        $orderby = sanitize_text_field( isset( $_GET['orderby'] ) ? trim( $_GET['orderby'] ) : '' );
        $order   = sanitize_text_field( isset( $_GET['order'] ) ? trim( $_GET['order'] ) : '' );

        $search_term = sanitize_text_field( isset( $_POST['s'] ) ? trim( $_POST['s'] ) : '' );
        if ( $search_term == '' ) {

            $search_term = sanitize_text_field( isset( $_GET['s'] ) ? trim( $_GET['s'] ) : '' );
        }

        $datas = $this->list_table_data_fun( $orderby, $order, $search_term );

        $per_page     = 30;
        $current_page = $this->get_pagenum();
        $total_items  = count( $datas );

        $this->set_pagination_args(
            array(
                'total_items' => $total_items,
                'per_page'    => $per_page,
            )
        );

        $this->items = array_slice( $datas, ( ( $current_page - 1 ) * $per_page ), $per_page );

        $columns  = $this->get_columns();
        $hidden   = $this->get_hidden_columns();
        $sortable = $this->get_sortable_columns();

        $this->_column_headers = array( $columns, $hidden, $sortable );
        $this->process_bulk_action();
    }

    public function get_bulk_actions() {

        return array(
            'add_questions'    => __( 'Add Questions', 'conditional-shortcode' ),
            'remove_questions' => __( 'Remove Questions', 'conditional-shortcode' ),
        );

    }
        // get_columns
    public function get_columns() {

        $columns = array(
            'cb'       => '<input type="checkbox" />',
            'id'       => __( 'ID', 'conditional-shortcode' ),
            'title'    => __( 'Title', 'conditional-shortcode' ),
            'question' => __( 'Questions', 'conditional-shortcode' ),
            'action'   => __( 'Action', 'conditional-shortcode' ),
        );

        return $columns;
    }

    public function get_hidden_columns() {
        return array( '' );
    }

    public function get_sortable_columns() {
        return array(
            'title' => array( 'title', true ),
            'id'    => array( 'id', true ),
        );

    }

    /**
     * Generate the table navigation above or below the table.
     *
     * @since 3.1.0
     * @access protected
     *
     * @param string $which
     */
    protected function display_tablenav( $which ) {

        // REMOVED NONCE -- INTERFERING WITH SAVING POSTS ON METABOXES
        // Add better detection if this class is used on meta box or not.
        /*
        if ( 'top' == $which ) {
            wp_nonce_field( 'bulk-' . $this->_args['plural'] );
        }
        */
    
        ?>
        <div class="tablenav <?php echo esc_attr( $which ); ?>">
    
            <div class="alignleft actions bulkactions">
                <?php $this->bulk_actions( $which ); ?>
            </div>
            <?php
            $this->extra_tablenav( $which );
            $this->pagination( $which );
            ?>
    
            <br class="clear"/>
        </div>
        <?php
    }

    // column_default
    public function column_default( $item, $column_name ) {
        $post_id = get_the_ID();
        switch ( $column_name ) {
            case 'cb':
            case 'id':
            case 'title':
            case 'question':
                return $item[ $column_name ];
            case 'action':
                return '<a href="?post=' . $post_id . '&action=edit&action1=add_question&question_id=' . $item['id'] . '&questionnaire_id=' . $post_id . '">Add Question</a>';
            default:
                return 'no value';

        }

    }

    public function column_title( $item ) {
        $post_id = get_the_ID();
        $action  = array(
            'edit' => sprintf( '<a href="?post=%d&action=%s&action1=%s&question_id=%d&questionnaire_id=%d">Add Question</a>', $post_id, 'edit', 'add_question', $item['id'], $post_id ),
        );
        return sprintf( '%1$s %2$s', $item['title'], $this->row_actions( $action ) );
    }

    function column_cb( $item ) {
        return sprintf(
            '<input type="checkbox" name="add-questions[]" value="%d" />',
            $item['id']
        );
    }

    function no_items() {
        esc_html_e( 'No Questions Found.', 'conditional-shortcode' );
    }

    public function process_bulk_action() {
        
        // security check!
        if ( isset( $_POST['_wpnonce'] ) && ! empty( $_POST['_wpnonce'] ) ) {

            $nonce  = filter_input( INPUT_POST, '_wpnonce', FILTER_SANITIZE_STRING );
            $action = 'bulk-' . $this->_args['plural'];

            if ( ! wp_verify_nonce( $nonce, $action ) ) {
                wp_die( 'Nope! Security check failed!' );
            }
        }

        $action = $this->current_action();

        switch ( $action ) {

            case 'delete_questions':
                wp_die( 'Delete something' );
                break;

            case 'add_questions':
                wp_die( 'Save something' );
                break;

            default:
                // do nothing or something else
                return;
                break;
        }
        wp_redirect( esc_url( add_query_arg() ) );
        exit;
        return;
    }

}

/**
 * Shows the List table for all questions.
 *
 * @return void
 */
function conditional_shortcode_questions_list_table_layout() {
    $table = new Class_Conditional_Shortcode_Questions_Listing();

    printf( '<div class="wrap" id="wpse-list-table"><h2>%s</h2>', __( '', 'conditional-shortcode' ) );

    echo '<form id="wpse-list-table-form" method="post">';

    $page  = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRIPPED );
    $paged = filter_input( INPUT_GET, 'paged', FILTER_SANITIZE_NUMBER_INT );

    printf( '<input type="hidden" name="page" value="%s" />', $page );
    printf( '<input type="hidden" name="paged" value="%d" />', $paged );

    $table->prepare_items(); // this will prepare the items AND process the bulk actions
    $table->search_box( __( 'Search question by id' ), 'conditional-shortcode' ); // Needs To be called after $myRequestTable->prepare_items()
    $table->display();

    echo '</form>';

    echo '</div>';

}

conditional_shortcode_questions_list_table_layout();
10
  • Why do you need wp_redirect( esc_url( add_query_arg() ) ); in process_bulk_action() method? Removing this should prevent the redirect OR is it redirecting even if you take the call to wp_redirect out?.
    – Adam
    Commented Dec 31, 2021 at 0:36
  • It is still redirecting if I comment this whole function. The problem that I found is with bulk action markup. Commented Dec 31, 2021 at 6:44
  • @Adam I also tried to override bulk_actions( $which ) function but still the same problem exists I am curious if somehow bulk_actions function has to do something with it. Commented Dec 31, 2021 at 6:46
  • In your prepare_items method, you call set_pagination_args, if you look in WP_List_Table::set_pagination_args, you see a condition where it calls wp_redirect, try and override this method temporarily as a test without including a call to wp_redirect, see if this makes issue go away, then we can go from there.
    – Adam
    Commented Dec 31, 2021 at 14:37
  • @Adam I have overridden set_pagination_args by removing redirect part but still the same error. Only way I can make it work is by not overriding function get_bulk_actions() due to which it calls parent function and gets an empty array so no markup for bulk action and it works. As soon as it renders bulk action markup things stop working. Commented Dec 31, 2021 at 14:47

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.