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