質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

913閲覧

wp_schedule_single_eventでwp-cronに登録されたイベントを上書きしたい

Samson818

総合スコア162

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2023/03/10 02:57

実現したいこと

wp_schedule_single_eventでwp-cronに登録されたイベントを記事ID指定して上書きしたい

前提

https://www.sofplant.com/blog/tech/schedule-to-draft-or-trash/
上記ページ中の「3. 再びプラグインを使わないできちんとスケジュールするカスタマイズ方法」を参照して、
記事の非公開時間を作成いたしました。

WP Crontrolというプラグインを使用して確認したところ、
上記の方法では記事の削除時間の変更が全く想定されておらず、2度登録されていることがわかりました。

例えば、誤って記事の非公開時間を2023年3月10日12:00と指定し更新したとします。
誤りに気づき非公開時間を2024年3月10日12:00に修正します。
この場合、記事の非公開が2023年と2024年の2度発動してしまい、
2024年に非公開を迎えたいという修正を反映出来ていないのではないかと思います。

WP Crontrolで閲覧すると以下のようになっていました。
my_new_event [ 44 //記事ID] 2023-03-10 12:00:00 //非公開時間 my_update_post() ]
my_new_event [ 44 //記事ID] 2024-03-10 12:00:00 //非公開時間 my_update_post() ]

該当のソースコード

php

1<?php 2/* 表示時間 */ 3add_action('admin_menu', 'create_custom_fields'); 4function create_custom_fields() 5{ 6 add_meta_box( 7 'sample_setting', //編集画面セクションID 8 '表示時間/公開終了日', //編集画面セクションのタイトル 9 'insert_custom_fields', //編集画面セクションにHTML出力する関数 10 'post', //投稿タイプ名 11 'normal' //編集画面セクションが表示される部分 12 ); 13} 14 15function insert_custom_fields() 16{ 17 global $post; 18 $public = get_post_meta($post->ID, 'public-day', true); 19 $end = get_post_meta($post->ID, 'close_time', true); 20?> 21<form method="post" action="admin.php?page=site_settings"> 22 <label for="public">表示日時:</label> 23 <input id="public" type="datetime-local" name="public-day" value="<?php echo $public ?>"> 24 <label for="sample2">公開終了日時:</label> 25 <input id="sample2" type="datetime-local" name="close_time" value="<?php echo $end ?>"> 26</form> 27 28<?php 29} 30add_action('save_post', 'save_custom_fields',20); 31function save_custom_fields($post_id){ 32 if (isset($_POST['public-day'])) { 33 update_post_meta($post_id, 'public-day', $_POST['public-day']); 34 } 35 if (isset($_POST['close_time'])) { 36 update_post_meta($post_id, 'close_time', $_POST['close_time']); 37 } 38} 39 40/* 記事の終了時間が過ぎたら非公開にする*/ 41add_action('save_post','my_expire_event',30); 42function my_expire_event($post_id) { 43 if (get_post_meta($post_id, 'close_time', true) != '' 44 && date_i18n('Y-m-d H:i') < get_post_meta($post_id, 'close_time', true)) { 45 // 設定されていて未来の日付ならスケジュールをセット 46 $time_stamp = strtotime(get_post_meta($post_id, 'close_time', true) . ' JST'); 47 wp_schedule_single_event($time_stamp, 'my_new_event', array($post_id)); 48 } 49} 50// スケジュールされる動作を記述 51function my_update_post($post_id) { 52 wp_update_post(array( 'ID' => $post_id, 'post_status' => 'private' ) ); 53} 54add_action('my_new_event', 'my_update_post');

試したこと

wp_schedule_single_eventの関数リファレンス
/wp-includes/cron.php の内容のチェック
wp_reschedule_event について調査中ですが、どうやら繰り返しの予定を変更するもので、singleに対しては使えない様子。
wp_reschedule_single_event が欲しいところですが、wp_reschedule_single_event は対応が無さそうです。

wp_unschedule_event に可能性を感じて調査中です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

上記phpの47行目「wp_schedule_single_event」の前に以下のコードを足して修正出来ました。

php

1wp_clear_scheduled_hook('my_new_event', array($post_id));

さらに「wp_schedule_single_event」が10分に1度しか発動しない仕様なので、
オリジナルで「my_schedule_single_event」を作成して使用することで解決しました。

php

1function my_schedule_single_event( $timestamp, $hook, $args = array() ) { 2 // Make sure timestamp is a positive integer 3 if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { 4 return false; 5 } 6 $event = (object) array( 7 'hook' => $hook, 8 'timestamp' => $timestamp, 9 'schedule' => false, 10 'args' => $args, 11 ); 12 $pre = apply_filters( 'pre_schedule_event', null, $event ); 13 if ( null !== $pre ) { 14 return $pre; 15 } 16 $crons = (array) _get_cron_array(); 17 $key = md5( serialize( $event->args ) ); 18 $duplicate = false; 19 if ( $event->timestamp < time() + 10 * MINUTE_IN_SECONDS ) { 20 $min_timestamp = 0; 21 } else { 22 $min_timestamp = $event->timestamp - 10 * MINUTE_IN_SECONDS; 23 } 24 if ( $event->timestamp < time() ) { 25 $max_timestamp = time() + 10 * MINUTE_IN_SECONDS; 26 } else { 27 $max_timestamp = $event->timestamp + 10 * MINUTE_IN_SECONDS; 28 } 29 $event = apply_filters( 'schedule_event', $event ); 30 // A plugin disallowed this event 31 if ( ! $event ) { 32 return false; 33 } 34 $crons[ $event->timestamp ][ $event->hook ][ $key ] = array( 35 'schedule' => $event->schedule, 36 'args' => $event->args, 37 ); 38 uksort( $crons, 'strnatcasecmp' ); 39 return _set_cron_array( $crons ); 40}

どなたかの参考になれば幸いです。

投稿2023/03/10 09:02

Samson818

総合スコア162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問