Featured image of post 【WordPress】SQLでインサートした「下書き」の投稿(post)を自動で公開する時に「公開予約」となってしまい公開することが出来ない場合の対処法

【WordPress】SQLでインサートした「下書き」の投稿(post)を自動で公開する時に「公開予約」となってしまい公開することが出来ない場合の対処法

タイトルの通りです。以下のような状況となりました。

  • PHPのスクリプト上のSQLで、WordPressのDBに直接postを下書きとしてインサート
  • 下書きのpostのstatusをdraft->publishにするスクリプトを実行
  • statusがなぜかfutureとして更新されてしまい自動で記事が公開されない

スクリプトの目的

2つスクリプトがあって、1つ目は下書きとして記事をDBに登録するもの、2つ目は下書きの記事を取得して公開にステータスに変更するものとなります。

なぜ一度下書きとして登録した後に公開するのか?

JetpackでTwitterに投稿を自動でツイートするようにしているのですが、SQLでDBにstatusを「publish」として直接インサートすると自動ツイートが上手く働いてくれないためです。

どういったスクリプト?

1つ目の記事をDBに登録するもの

以下となります。 $pdo変数は事前に定義されてあるものとします。

以下のコードでDBに下書きとしてpostを保存することが出来ます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
$datetime = new DateTime();
$now = $datetime->format('Y-m-d H:i:s');

$datetime->setTimezone(new DateTimeZone('GST'));
$now_gmt = $datetime->format('Y-m-d H:i:s');

$data = [
  'post_author' => 1,
  'post_date' => $now,
  'post_date_gmt' => $now_gmt,
  'post_content' => $body,
  'post_title' => $title,
  'post_excerpt' => '',
  'post_status' => 'draft',
  'comment_status' => 'open',
  'ping_status' => 'open',
  'post_password' => '',
  'post_name' => '',
  'to_ping' => '',
  'pinged' => '',
  'post_modified' => $now,
  'post_modified_gmt' => $now_gmt,
  'post_content_filtered' => '',
  'post_parent' => 0,
  'guid' => '',
  'menu_order' => 0,
  'post_type' => 'post',
  'post_mime_type' => '',
  'comment_count' => 0,
];

$sql = "INSERT INTO wp_posts (
  post_author,
  post_date,
  post_date_gmt,
  post_content,
  post_title,
  post_excerpt,
  post_status,
  comment_status,
  ping_status,
  post_password,
  post_name,
  to_ping,
  pinged,
  post_modified,
  post_modified_gmt,
  post_content_filtered,
  post_parent,
  guid,
  menu_order,
  post_type,
  post_mime_type,
  comment_count
) VALUES (
  :post_author,
  :post_date,
  :post_date_gmt,
  :post_content,
  :post_title,
  :post_excerpt,
  :post_status,
  :comment_status,
  :ping_status,
  :post_password,
  :post_name,
  :to_ping,
  :pinged,
  :post_modified,
  :post_modified_gmt,
  :post_content_filtered,
  :post_parent,
  :guid,
  :menu_order,
  :post_type,
  :post_mime_type,
  :comment_count
)";
$stmt= $pdo->prepare($sql);
$stmt->execute($data);

2つ目の登録された下書きのpostを公開にするもの – 動作しなかったもの

こちらがDBから下書きの記事を取得して公開にするスクリプトです。

1つ目のものと違い、WordPressのloaderを読み込んでおり、WordPressの関数を使うようにしています。

こちらが今回上手く動作しなかったものとなります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
require_once(dirname( __FILE__ ) . '/../wp-load.php');

$sql = "select * from `wp_posts` where `post_status` = 'draft' and `post_type` = 'post';";
$results = $wpdb->get_results($sql);

foreach ($results as $key => $value) {
  $datetime = new DateTime();
  $datetime->setTimezone(new DateTimeZone('Asia/Tokyo'));
  $publish_date = $datetime->format('Y-m-d H:i:s');

  $post = get_post($value->ID);
  $post->post_status = 'publish';
  $post->post_date = $publish_date;
  wp_update_post($post);
}

解決策

2つ目のスクリプトが動かず色々試してみました。

post_date_gmtをセットしてみたり、DBにデータを入れる時、statusをdraftではなく、future(公開予約)で既に入れてしまい、2つ目のスクリプトでfuture->publishに変更する等です。

ですが結論以下となりました。

1
2
3
4
5
6
7
8
9
require_once(dirname( __FILE__ ) . '/../wp-load.php');

$sql = "select * from `wp_posts` where `post_status` = 'draft' and `post_type` = 'post';";
$results = $wpdb->get_results($sql);

foreach ($results as $key => $value) {
  $post = get_post($value->ID);
  wp_publish_post($post);
}

wp_publish_postという関数が用意されていて、こちらがWordPressで公開に必要な色々な処理を行ってくれているようでして、こちらを使用することで今回の問題が解決されました。

同じような問題で悩んでいる方の参考になればと思います。

Built with Hugo
テーマ StackJimmy によって設計されています。