Wordpress で記事予約の cron を正しく実装する

サイトアクセス時にcron実行するのは、無駄な負荷がかかる点と、キャッシュを設定した場合は適切なタイミングで実行されないため、選択はあり得ません。

サイトアクセス時の cron 実行を 無効化

vi ./wp-config.php

// こちらで無効化
define( 'DISABLE_WP_CRON', true );

実行処理

以下の方法ではうまくいきませんが、模範的な方法。
定期実行するスクリプトを用意。なんらかの方法で定期的に起動してください。

事前に wp-cli をインストールした状態になっている前提です。

vi ./cron.sh

#! /usr/bin/env bash
wp cron event run --allow-root --quiet --due-now
マルチサイトの場合
#! /usr/bin/env bash

for url in = $(wp site list --allow-root --field=url --deleted=0 --archived=0)
do
  if [[ $url == "http"* ]]; then
    wp cron event run --allow-root --quiet --due-now --url="$url"
  fi
done

こちら、全ての条件を調べてはいませんが、記事の予約が公開にならない現象が起きます。
例えばアップデートが実行されるときは、記事の公開処理は実行されないことを確認しています。
コードを見て調査していませんが、他の条件もありそうです。

上記の公開されない場合に対応するには、プラグインの利用が考えられると思いますが、
存在するいくつかのプラグインは、ユーザーがサイトアクセス時に、公開されていないものを公開する、という処理になっており、こちらは選択肢になりません。

適切ではないかと考える対応方法

#! /usr/bin/env bash

for url in = $(wp site list --allow-root --field=url --deleted=0 --archived=0)
do
  if [[ $url == "http"* ]]; then
    echo $url

    table_prefix=$(wp eval --allow-root --url="$url" 'global $table_prefix; echo $table_prefix;')
    post_ids=$(wp db query --allow-root "select ID from ${table_prefix}posts where post_status = 'future' AND post_date_gmt < UTC_TIMESTAMP()" | awk '{print $1}' | grep -v 'ID')

    for post_id in $post_ids; do
      echo "post ID = ${post_id}"
      wp eval --allow-root --url="$url" "wp_publish_post(${post_id});"
    done
  fi
done