add_options_page()

このページは前ページの、「管理画面にページを追加」の別パターンといえるページ。
今回は、add_options_page() を使って管理画面の設定メニューに項目を追加した。まぁ、これはプラグインなどですでに何度も使っているものではあるのだけれど。

くどいけれど、これも add_posts_page() と使い方はほぼ同じ。

<?php
    add_action( 'admin_menu', 'addmenu_delete_revisions' );

    function addmenu_delete_revisions() {
        //                      ( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );
        // $icon_url と $position は option
        add_options_page( 'Delete-Post-Revisions', 'Delete Post Revisions', 'administrator', 'strix_delete_revisions', 'mytool_delete_revisions' );
    }   
?>
PHP
CopyExpand

3つ目の $capability に関しては、詳細を codex の説明で見たほうが良いと思われる。
4つ目の $menu_slug はこのページを表示する時の slug として使用されるので重要。
そして 5つ目の $function は実際に表示するこのページの内容のコードとなる関数を指定する。
と、同じ流れで続いていく。

delete revision page

で、今回は何のページを作るかというと。
これも、長い間お世話になってきたプラグインで、Better Delete Revision というものがある。
たまってる revision の投稿を消去するのに重宝してたんだけど、これもそれだけの機能で使っているのなら、プラグインとしてではなく、自作したほうがいいだろう、と思い立った。

そのプラグイン、Better Delete Revision の中を覗かせてもらうと実にシンプルで、それを参考にして作らせてもらった。まぁ、でも、そのプラグインはページ遷移で処理させるのを、自分的には Ajax で実装させた。
ということで、できたページもとてもシンプルでこんなかんじ。

と、いうことで、add_options_page() 関数で指定した、メインとなる関数。
revision 投稿の情報は、プラグインにならって、SQL にて取得。
けれど、実際の削除は WordPress に備わっている、wp_delete_post_revision() という関数に委ねる。この関数は、指定された ID の投稿が revision ならば削除してくれるというもの。まぁ、ちょっと安心なんだな、これが。
Ajax であるからして、ちょっとセキュリティなものも考えて、その認証は、ログインしているのが管理者であることと、WordPress nonce でカバー。まぁ、そんなところ。
Ajax とか style 設定とかの Javascript のコードもページの HTML と一緒に書き出してる。ここで一緒に書き出しておけば、revision 投稿が存在しない時に Javascript は読み込まれない。

<?php
    function mytool_delete_revisions() {
        global $wpdb;// 関数で SQL を使う時のお約束

        // post_status が publish、future、 draft の全ての post_type の投稿の数を得る
        $all_post_count = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->posts WHERE post_status IN ( 'publish', 'future', 'draft' )" );

        // revision の投稿の取得
         $sql = <<< HERE
SELECT a.ID,a.post_date,a.post_title,a.post_modified,b.post_type
FROM $wpdb->posts a, $wpdb->posts b
WHERE a.post_parent = b.ID
AND a.post_type = 'revision'
ORDER BY a.ID DESC
HERE;
            
            $sdr_results = $wpdb->get_results( $sql );

        echo '<div id="options_content" style="font-size:1.4em;"><h2 style="color:blue;text-shadow:3px 3px 2px white,4px 4px 3px grey;">Delete Post Revision </h2>';
        echo '<p>All post count : <span style="color:red;">' . $all_post_count . '</span> ( publish & futrue & draft of all post_type )</p>';

        if ( $sdr_results ) {
            $sdr_res_count = count( $sdr_results );

            //wp nonce の値を取得
            $ajax_nonce = wp_create_nonce( __FILE__ );
?>
            <div id="revisions">
                <p style="color:red;" id="revicount">Revision Posts are <?php echo $sdr_res_count; ?> left.</p>
                <table id="sdr_table" style="border:solid 1px grey;border-radius:5px;">
                    <thead>
                        <tr style="color:blue;">
                            <th width="30">Id</th>
                            <th width="60">Ptype</th>
                            <th width="450">Title</th>
                            <th width="180">Post date</th>
                            <th width="180">Last modified</th>
                        </tr>
                    </thead>
                    <tbody>
<?php
                        for ( $i = 0 ; $i < $sdr_res_count ; ++$i ) {
                            echo '<tr style="background:white;">';
                            echo '<td>' . $sdr_results[ $i ]->ID . '</td>';
                            echo '<td>' . $sdr_results[ $i ]->post_type . '</td>';
                            echo '<td>' . $sdr_results[ $i ]->post_title . '</td>';
                            echo '<td>' . $sdr_results[ $i ]->post_date . '</td>';
                            echo '<td>' . $sdr_results[ $i ]->post_modified . '</td>';
                            echo '</tr>';
                        }
?>
                    </tbody>
                </table>
                <p>Would you like to remove the revision posts? <input type="button" id="removerev" value="Yes! delete" style="color:red;"></p>
            </div>
            <script>
                ( function() {
                    
                    // onload event
                    window.addEventListener( 'load', function() {
                        const doc = document;

                        // style 設定
                        const drtable = doc.getElementById( 'sdr_table' ),
                            chilth = drtable.getElementsByTagName( 'th' );
                            chiltd = drtable.getElementsByTagName( 'td' );

                        for ( let i = 0,chilth_len = chilth.length; i < chilth_len; ++i ) {
                            chilth[ i ].style.cssText = 'padding:4px;font-weight:normal;border:dotted 1px grey;border-radius:5px;text-shadow:3px 3px 3px #e3e3e3;background:white;';
                        }

                        for ( let i = 0,chiltd_len = chiltd.length; i < chiltd_len; ++i ) {
                            chiltd[ i ].style.cssText = 'padding:4px;font-size:0.9em;';
                        }

                        // button の click event に Ajax を設定する
                        doc.getElementById( 'removerev' ).onclick = function() {

                            // const wpajaxurl = 'https://strix.main.jp/wp-admin/admin-ajax.php',
                            const wpajaxurl = 'https://localhost/wp/wp-admin/admin-ajax.php',
                                nonce = '<?php echo $ajax_nonce; ?>',
                                strsend = 'action=deleterevisions&nonce=' + nonce;

                            var req = new XMLHttpRequest();

                            req.onreadystatechange = function() {
                                let result = '',
                                    resstr = '';

                                if (req.readyState == 4) { // 通信の完了時
                                    if (req.status == 200) { // 通信の成功時
                                        result = req.responseText;

                                        if ( -1 !== result.indexOf( 'error' ) ) {
                                            resstr = '<p>failed delete revisions : ' + result + '</p>'; 
                                        } else {
                                            resstr = '<p>' + result + '</p>';
                                        }
                                        document.getElementById( 'revisions' ).innerHTML = resstr;
                                    } else {
                                        resstr = '<p>error : disable ajax send!</p>';
                                        document.getElementById( 'revicount' ).innerHTML = resstr;
                                    }
                                }
                            }

                            req.open( 'POST', wpajaxurl, true );
                            req.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
                            req.send( strsend );
                        };
                    });
                }());
            </script>
<?php
        } else {
            echo '<p id="norevision">Great! You have no revisions now!</p>';
        }
        echo '</div>';
    }
?>
PHP
CopyExpand

で、あとは Ajax を受ける方の php だけ。
これは管理画面の中だけのことなので、Ajax を登録するアクションフックは一つだけですむ。
get_current_user_id() 関数を使って、ログインしているユーザーが管理者であることを確認し、nonce の認証が true ならば、SQL で revision 投稿の ID を取得し、それを WordPress の wp_delete_post_revision() 関数に渡して削除の処理をさせる、といった流れ。なんてことはない。

<?php
    function deleterevisions() {

        // ログインユーザーの id を取得
        $user_id = get_current_user_id();

        if ($user_id == 0) {
            echo 'error:none log-in';
        } else if ( 1 === $user_id ) {

            //nonceの認証を得る nonce の値は $_POST['nonce']
            if ( check_ajax_referer( __FILE__, 'nonce', false ) ) {
                global $wpdb;

                $sdr_revisions = $wpdb->get_results(
                    "SELECT `ID` AS revision_id
                    FROM ($wpdb->posts)
                    WHERE `post_type` = 'revision'
                    ORDER BY `ID` DESC"
                );
                foreach ( $sdr_revisions as $sdr_revision ) {
                    wp_delete_post_revision( $sdr_revision->revision_id );
                }

                $sdr_results = $wpdb->get_results(
                    "SELECT `ID`
                    FROM ( $wpdb->posts )
                    WHERE `post_type` = 'revision'"
                );
                if ( $sdr_results ) {
                    echo 'Oooom left revisions : ' . count( $sdr_results );
                } else {
                    echo 'Success delete all revisions!';
                }
                echo 'Yes, admin log-in : ' . $user_id;
            } else {
                echo 'error: Access denied.';
            }
        } else {
            echo 'error! log-in not admin : ' . $user_id;
        }

        exit;
    }
    add_action( 'wp_ajax_deleterevisions', 'deleterevisions' );
?>
PHP
CopyExpand

以上。
これにて、またひとつプラグインを減らすことができた。

Leave a Reply!

JavaScript is necessary to send a comment.
You can edit and delete your comment if you input a edit key.
Edit key is necessary for attesting you when you edit and delete it.
The tag of HTML cannot be used in comment.
When you comment for the first time, it is displayed after the approval of the administrator.
Because I cannot speak English so much, it takes time to answer.
Required fields are marked *.

※Please enter more than 5 characters only alphabets.
※Edit or delete are possible for 2000 days after approval.

*

♠Simplistic Comment User Editable v4.0

♠When visitors leave comments on the site this site collect the data shown in the comments form, and also the visitor’s IP address and browser user agent string to help spam detection.
♠This site does not use cookie when visitors leave comments and commenter edit comment.
♠This site uses Akismet to reduce spam. Learn how your comment data is processed.

Comments feed

Trackback URL : https://strix.main.jp/wp-trackback.php?p=167488

Sanbanse Funabashi
2011.01.01 sunrise

Top

スクロールさせるか画像をクリックすると元に戻ります。