0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

指定日に記事を削除するWPのプラグインの雛形.

Posted at

おはようございます.指定日に記事を削除するWPのプラグインの雛形を作りましたが記事の削除部分(article_del_R)はご自身で作ってください.削除部分をご自身で作り自分のサイト(WP)を定期的にcronで叩けば削除される仕組みです.
毎度のことですみませんがソースコードを解析してお使いいただければと思います.また、このコードは試作品になります.

WPプラグインの画面はこんな感じです.
image.png

ソースコードはこちら

article-del-R/article-del-R.php
<?php
/*
  Plugin Name: article-del-R
  Plugin URI:
  Description: 指定日に記事を削除する
  Version: 1.0.0
  Author: @taoka_toshiaki
  Author URI: https://taoka-toshiaki.com
 */
if (! defined('ABSPATH')) {
    exit;
}
//ini_set('display_errors',1);

function chatgpt_auto_article_menu()
{
    add_menu_page(
        '指定日に記事を削除する', // ページのタイトル
        '指定日に記事を削除する', // メニューのタイトル
        'manage_options', // 必要な権限
        'article-del-R', // ページの識別子
        'article_del_R_page', // ページのコールバック関数
    );
}

function article_del_R_page()
{
?>
    <div id='app'>
        <input type="text" name="search" v-model="inputText" @input="search">
        <h1>検索結果</h1>
        <div v-if="searchResponse">
            <ul v-for="article in searchResults.data">
                <li :id="'list_' + article.id">
                    <input @click="del(article.id,article.title)" v-model="isChecked" type="checkbox" :value="article.id">
                    {{ article.title }}
                    <input type="datetime-local" :name="'search_dt_' + article.id">
                </li>
            </ul>
        </div>
        <div v-else>
            {{searchResults.data}}
        </div>


        <h1>削除するリスト(チェックすると削除対象から外れます)</h1>
        <div v-if="articlesListResponse">
        <ul v-for="article in articlesList.data">
            <li>
                <input @click="save(article.id)" type="checkbox" :value="article.id">
                {{ article.title }}
                <input type="datetime-local" :name="'dt_' + article.id" :value="article.datetime" readonly>
            </li>
        </ul>
        </div>
        <div v-else>
            {{articlesList.data}}
        </div>
    </div>
    <script type="module">
        import {
            createApp,
            ref,
            onMounted,
            computed
        } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            setup() {
                const isChecked = ref([]);
                const inputText = ref('');
                const searchResults = ref({
                    success: false,
                    data: ''
                });
                const selectedArticles = ref([]);
                const articlesList = ref({
                    success: false,
                    data: 'データが存在しません'
                });
                async function search() {
                    let frm = new FormData();
                    frm.append('action', 'article_del_R_action');
                    frm.append('mode', 'search');
                    frm.append('val', inputText.value);
                    searchResults.value = await getResponse(frm);
                }

                const articlesListResponse = computed(() => {
                    return articlesList.value?.success;
                });

                const searchResponse = computed(() => {
                    return searchResults.value?.success;
                });

                async function articles() {
                    let frm = new FormData();
                    frm.append('action', 'article_del_R_action');
                    frm.append('mode', 'load');
                    articlesList.value = await getResponse(frm);
                }

                async function del(id, title) {
                    if (isChecked) {
                        if (document.getElementsByName('search_dt_' + id)[0].value) {
                            let datetimed = document.getElementsByName('search_dt_' + id)[0].value;
                            let frm = new FormData();
                            frm.append('action', 'article_del_R_action');
                            frm.append('mode', 'del');
                            frm.append('id', id);
                            frm.append('title', title);
                            frm.append('datetime', datetimed);
                            articlesList.value = await getResponse(frm);
                            document.getElementById('list_' + id).remove();
                        } else {
                            alert('日時を指定してください');
                        }
                    } else {
                        alert('チェックしてください');
                    }
                }


                async function save(id) {
                    let frm = new FormData();
                    frm.append('action', 'article_del_R_action');
                    frm.append('mode', 'save');
                    frm.append('id', id);
                    frm.append('datetime', document.getElementsByName('search_dt_' + id).value);
                    articlesList.value = await getResponse(frm);
                }

                async function getResponse(frm) {
                    return await fetch(
                        'https://<?= $_SERVER['SERVER_NAME'] ?>/wp-admin/admin-ajax.php', {
                            method: 'POST',
                            body: frm
                        }).then(res => res.json()).then(data => data).catch(e => {
                        console.log(e);
                    })
                }
                onMounted(() => {
                    articles(); // 初回ロード時に記事リストを取得
                });

                return {
                    inputText,
                    isChecked,
                    searchResponse,
                    search,
                    searchResults,
                    articlesListResponse,
                    articlesList,
                    del,
                    save,
                };
            }
        }).mount('#app');
    </script>
<?php
}

function handle_article_del_R_ajax_request()
{
    switch ($_POST['mode']) {
        case 'search':
            article_del_R_search();
            break;
        case 'load':
            article_del_R_load();
            break;
        case 'del':
            article_del_R_del();
            break;
        case 'save':
            article_del_R_save();
            break;
        default:
            # code...
            break;
    }
    wp_die();
}

function article_del_R_db_connection()
{
    return new SQLite3(__DIR__.'/db.sqlite3');
}

function article_del_R_del()
{
    $db = article_del_R_db_connection();
    if (!article_del_R_select($db, (int)$_POST['id'])->fetchArray(SQLITE3_ASSOC)) {
        $stmt = $db->prepare('INSERT INTO `del` (id,title,`datetime`)VALUES(:id, :title,:datetime)');
        $stmt->bindValue(':id', $_POST['id'], SQLITE3_INTEGER);
        $stmt->bindValue(':title', $_POST['title'], SQLITE3_TEXT);
        $stmt->bindValue(':datetime', $_POST['datetime'], SQLITE3_TEXT);
        $stmt->execute();
    }
    $db->close();
    article_del_R_load();
}

function article_del_R_save()
{
    $db = article_del_R_db_connection();
    if (article_del_R_select($db, (int)$_POST['id'])->fetchArray(SQLITE3_ASSOC)) {
        $stmt = $db->prepare('DELETE FROM `del` where id = :id');
        $stmt->bindValue(':id', $_POST['id'], SQLITE3_INTEGER);
        $stmt->execute();
    }
    $db->close();
    article_del_R_load();
}


function article_del_R_select($db, $id)
{
    $query = "SELECT * FROM `del` WHERE id = :id";
    // プリペアドステートメントを使用してパラメータをバインドする
    $stmt = $db->prepare($query);
    $stmt->bindValue(':id', $id, SQLITE3_INTEGER);
    $result = $stmt->execute();
    return $result;
}

function article_del_R_load()
{
    $db = article_del_R_db_connection();
    $query = "SELECT * FROM `del`";
    // プリペアドステートメントを使用してパラメータをバインドする
    $stmt = $db->prepare($query);
    $result = $stmt->execute();
    $posts = [];
    while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
        $posts[] = [
            'id' => $row['id'],
            'title' => $row['title'],
            'datetime' => $row['datetime'],
        ];
    }
    if (count($posts)) {
        wp_send_json_success($posts);
    } else {
        wp_send_json_error('データが存在しません');
    }
    $db->close();
    wp_die();
}



function article_del_R_search()
{
    // 検索キーワードを取得し、サニタイズ
    $keyword = isset($_POST['val']) ? sanitize_text_field($_POST['val']) : '';

    // キーワードが空でないことを確認
    if (empty($keyword)) {
        wp_send_json_error('キーワードが入力されていません');
        wp_die();
    }

    // WP_Queryを使って記事を検索
    $args = [
        'post_type' => 'post', // 投稿タイプ(必要に応じて変更)
        'posts_per_page' => 10, // 返却する投稿数
        's' => $keyword, // キーワード検索
        'post_status' => 'publish', // 公開状態の投稿
    ];

    $query = new WP_Query($args);
    $posts = [];

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            $posts[] = [
                'id' => get_the_ID(),
                'title' => get_the_title(),
            ];
        }
    }

    // メモリを解放するためにクエリをリセット
    wp_reset_postdata();

    // 検索結果をJSON形式で返す
    if (!empty($posts)) {
        wp_send_json_success($posts);
    } else {
        wp_send_json_error('該当する投稿が見つかりません');
    }
}


function article_del_R() {
    
}

add_action("wp_head", "article_del_R");
add_action('admin_menu', 'chatgpt_auto_article_menu');
// Logged-in ユーザーのためのAjaxハンドラー
add_action('wp_ajax_article_del_R_action', 'handle_article_del_R_ajax_request');

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?