web-dev-qa-db-ja.com

WP_list_table bulk_actionの編集と削除

私は本当にこれについての文書を手に入れていないようです。それについての他のスタック交換でさえ、私にはそれをはっきりとはわかりません。私はこれがどのように機能するのかわからないからだと思います。

だから私は管理者ページを作成していると私は自分が作成したデータベーステーブルを読んでいます。 Wordpressフレームワーク内で作業するための単一の削除(および編集)と一括削除(および編集)の方法がわからないのです。

だからここにコードがあります:

class Designit_Countries_Table extends Designit_List_Table
{

    private $order;
    private $orderby;
    private $posts_per_page = 25;

    public function __construct()
    {
        global $status, $page;

        parent :: __construct(array(
            'singular' => "country",
            'plural' => "countries",
            'ajax' => true
        ));

        $this->set_order();
        $this->set_orderby();
    }

    private function get_sql_results()
    {
        global $wpdb;
        $args = array('id', 'name', 'title', 'country', 'image', 'time');
        $sql_select = implode(', ', $args);
        $sql_results = $wpdb->get_results("SELECT " . $sql_select . " FROM " . $wpdb->prefix . "designitcountries ORDER BY $this->orderby $this->order ");
        return $sql_results;
    }

    public function set_order()
    {
        $order = 'ASC';
        if (isset($_GET['order']) AND $_GET['order'])
            $order = $_GET['order'];
        $this->order = esc_sql($order);
    }

    public function set_orderby()
    {
        $orderby = 'id';
        if (isset($_GET['orderby']) AND $_GET['orderby'])
            $orderby = $_GET['orderby'];
        $this->orderby = esc_sql($orderby);
    }

    public function ajax_user_can()
    {
        return current_user_can('edit_posts');
    }

    public function no_items()
    {
        _e('No countries found.');
    }

    public function get_views()
    {
        return array();
    }

    public function get_columns()
    {
        $columns = array(
            'cb' => '<input type="checkbox" />',
            'name' => __('Name'),
            'title' => __('Title'),
            'country' => __('Country'),
            'image' => __('Image'),
            'time' => __('Created on'),
            'id' => __('id')
        );
        return $columns;
    }

    function get_bulk_actions() {
        $actions = array(
            'delete'    => 'Delete'
        );
        return $actions;
    }
    public function get_sortable_columns()
    {
        $sortable = array(
            'id' => array('id', true),
            'title' => array('Title', true),
            'name' => array('Name', true),
            'country' => array('Country', true),
            'image' => array('Image', true),
            'time' => array('Created on', true),
        );
        return $sortable;
    }

    public function prepare_items()
    {
        $columns = $this->get_columns();
        $hidden = array();
        $sortable = $this->get_sortable_columns();
        $this->_column_headers = array(
            $columns,
            $hidden,
            $sortable
        );

        // SQL results
        $posts = $this->get_sql_results();
        empty($posts) AND $posts = array();

        # >>>> Pagination
        $per_page = $this->posts_per_page;
        $current_page = $this->get_pagenum();
        $total_items = count($posts);
        $this->set_pagination_args(array(
            'total_items' => $total_items,
            'per_page' => $per_page,
            'total_pages' => ceil($total_items / $per_page)
        ));
        $last_post = $current_page * $per_page;
        $first_post = $last_post - $per_page + 1;
        $last_post > $total_items AND $last_post = $total_items;

        // Setup the range of keys/indizes that contain
        // the posts on the currently displayed page(d).
        // Flip keys with values as the range outputs the range in the values.
        $range = array_flip(range($first_post - 1, $last_post - 1, 1));

        // Filter out the posts we're not displaying on the current page.
        $posts_array = array_intersect_key($posts, $range);
        # <<<< Pagination
        // Prepare the data
        $permalink = __('Edit:');
        foreach ($posts_array as $key => $post) {
            $link = get_edit_post_link($post->id);
            $no_name = __('No name set');
            $name = !$post->name ? "<em>{$no_name}</em>" : $post->name;
            $posts[$key]->name = "{$name}";
        }
        $this->items = $posts_array;

        $this->process_bulk_action();

    }

    /**
     * A single column
     */
    public function column_default($item, $column_name)
    {
        return $item->$column_name;
    }


    /**
     * Disables the views for 'side' context as there's not enough free space in the UI
     * Only displays them on screen/browser refresh. Else we'd have to do this via an AJAX DB update.
     *
     * @see WP_List_Table::extra_tablenav()
     */
    public function extra_tablenav($which)
    {
        global $wp_meta_boxes;
        $views = $this->get_views();
        if (empty($views)) return;

        $this->views();
    }

    //edit buttons

    function column_name(){
        global $wpdb;
        $args = array('id', 'name');
        $sql_select = implode(', ', $args);
        $sql_results = $wpdb->get_results("SELECT " . $sql_select . " FROM " . $wpdb->prefix . "designitcountries ORDER BY $this->orderby $this->order ");

        foreach ($sql_results as $sql_result) {
            $name = $sql_result->name;
            $id = $sql_result->id;
            $actions = array(
                'edit' => sprintf('<a href="?page=%s&action=%s&name=%s">Edit</a>', $_REQUEST['page'], 'edit', $id),
                'delete' => sprintf('<a href="?page=%s&action=%s&name=%s">Delete</a>', $_REQUEST['page'], 'delete', $id),
            );
            return sprintf('%1$s %2$s', $name, $this->row_actions($actions));
        }
    }

    function column_cb($item) {
            return sprintf(
                '<input type="checkbox" name="book[]" value="%s" />',
                $this->_args['singular'],
                $item->id
            );
        }

    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':
                foreach($_GET['country'] as $country) {



                }

                wp_die( 'You have deleted this succesfully' );
                break;

            case 'edit':
                wp_die( 'This is the edit page.' );
                break;

            default:
                // do nothing or something else
                return;
                break;
        }

        return;
    }

}

それはたどるのにたくさんのコードですので、私は私の問題のためにいくつかに切り分けさせてください。

結果はこれを示しています: Countries admin page 

これは、私が作成した国のページと、現在実行しているアクション、およびチェックボックスを示しています。

だから私はこのようなチェックボックスを実装します。

public function get_columns()
{
    $columns = array(
        'cb' => '<input type="checkbox" />',
        'name' => __('Name'),
        'title' => __('Title'),
        'country' => __('Country'),
        'image' => __('Image'),
        'time' => __('Created on'),
        'id' => __('id')
    );
    return $columns;
}
    function column_cb($item) {
        return sprintf(
            '<input type="checkbox" name="book[]" value="%s" />',
            $this->_args['singular'],
            $item->id
        );
    }

それから私はまた単一の編集と削除ボタンを持っています:

function column_name(){
    global $wpdb;
    $args = array('id', 'name');
    $sql_select = implode(', ', $args);
    $sql_results = $wpdb->get_results("SELECT " . $sql_select . " FROM " . $wpdb->prefix . "designitcountries ORDER BY $this->orderby $this->order ");

    foreach ($sql_results as $sql_result) {
        $name = $sql_result->name;
        $id = $sql_result->id;
        $actions = array(
            'edit' => sprintf('<a href="?page=%s&action=%s&name=%s">Edit</a>', $_REQUEST['page'], 'edit', $id),
            'delete' => sprintf('<a href="?page=%s&action=%s&name=%s">Delete</a>', $_REQUEST['page'], 'delete', $id),
        );
        return sprintf('%1$s %2$s', $name, $this->row_actions($actions));
    }
}

そして、その一括処理と処理:

function get_bulk_actions() {
    $actions = array(
        'delete'    => 'Delete'
    );
    return $actions;
}

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':
                foreach($_GET['country'] as $country) {



                }

                wp_die( 'You have deleted this succesfully' );
                break;

            case 'edit':
                wp_die( 'This is the edit page.' );
                break;

            default:
                // do nothing or something else
                return;
                break;
        }

        return;
    }

今私はそれを取得していないところ

'delete'の場合は削除し、 'edit'の場合は編集する必要があると思います。しかし、実際に削除されるようにチェックボックスで選択された行を選択する方法がわかりません。あるいは、あなたが '削除ボタン'を使用して一括アクションではなくその行だけが削除され、編集機能が全体的にどのように機能するのかという場合。

どちらか適切な例を見つけることができないので、私はあなたのうちの一人が私を助けてくれることを願っています!

'delete'を押すと表示されるページ: enter image description here 

更新

それで私はそれにすべてをそれ自身のIDを与えることによって機能させました

function column_cb($item) {
    return sprintf(
        '<input type="checkbox" name="country[]" value="%s" />',
        $item->id
    );
}
function column_name($item){
    $item_json = json_decode(json_encode($item), true);
    $actions = array(
        'edit' => sprintf('<a href="?page=%s&action=%s&id=%s">Edit</a>', $_REQUEST['page'], 'edit', $item_json['id']),
        'delete' => sprintf('<a href="?page=%s&action=%s&id=%s">Delete</a>', $_REQUEST['page'], 'delete', $item_json['id']),
    );
    return '<em>' . sprintf('%s %s', $item_json['name'], $this->row_actions($actions)) . '</em>';
}

次に、その参照を使用してSQLクエリでテーブルを削除します。

 case 'delete':
                global $wpdb;
                $table_name = $wpdb->prefix . 'designitcountries';
                $ids = isset($_REQUEST['id']) ? $_REQUEST['id'] : array();
                var_dump($ids);
                    if (is_array($ids)) $ids = implode(',', $ids);
                    if (!empty($ids)) {
                        $wpdb->query("DELETE FROM $table_name WHERE id IN($ids)");
                }

                wp_die( 'You have deleted this succesfully' );
                break;

_ただし_

削除ボタンを使用した場合は機能しますが、一括アクション削除を実行した場合は機能しません(1を選択した場合でも)。

「削除」ボタンのA hrefのURLにIDを入れます。私はどのように私は同じように行動するためにチェックボックスを使ってそれをすることになっているのか分からない

3
CompactCode

それで、私は問題を見つけました。

まず第一に、私は自分のチェックボックスまたはボタン上で正しいIDを選択していなかったので、そうするためにコードに変更しました:

function column_name($item){
    $item_json = json_decode(json_encode($item), true);
    $actions = array(
        'edit' => sprintf('<a href="?page=%s&action=%s&id=%s">Edit</a>', $_REQUEST['page'], 'edit', $item_json['id']),
        'delete' => sprintf('<a href="?page=%s&action=%s&id=%s">Delete</a>', $_REQUEST['page'], 'delete', $item_json['id']),
    );
    return '<em>' . sprintf('%s %s', $item_json['name'], $this->row_actions($actions)) . '</em>';
}

ここに私が必要とするすべてのデータを手に入れる$itemsがいることに注意してください。 JSONのデコードとエンコードを行い、それを配列に変換します。その後、必要に応じてsprinttf()でJSON配列のidまたはnameを呼び出すことができます。

チェックボックスも同じです(JSONは除く)。

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

その後、私はこれを私のケース「削除」に追加しました:

case 'delete':
                global $wpdb;
                $table_name = $wpdb->prefix . 'designitcountries';

                if ('delete' === $this->current_action()) {
                    $ids = isset($_REQUEST['id']) ? $_REQUEST['id'] : array();
                    if (is_array($ids)) $ids = implode(',', $ids);

                    if (!empty($ids)) {
                        $wpdb->query("DELETE FROM $table_name WHERE id IN($ids)");
                    }
                }

                wp_die( 'You have deleted this succesfully' );
                break;

今私はボタンからとチェックボックスから削除する作業方法があります。

2
CompactCode