タグアーカイブ WordPress

WooCommerce 11.0が商品オブジェクトキャッシュを標準化!新規ストアは自動有効

WooCommerce 11.0が商品オブジェクトキャッシュを標準化!新規ストアは自動有効

WooCommerce 11.0がリリースされ、商品オブジェクトキャッシュが新規ストア向けにデフォルトで有効化された。この機能は、商品ページやチェックアウト処理で同じ商品データを何度もデータベースから取得する無駄を省き、ECサイトの表示速度を底上げする。

可変商品がある製品ページでは約9〜12%、バンドル商品を含むチェックアウト処理では6〜12%の処理速度改善が報告されている。今回の変更は、WooCommerce 10.5で実験的導入が始まったキャッシュ機構が安定動作の段階に達したことを示している。

新規にWooCommerce 11.0以上をインストールしたストアには自動で適用されるが、アップグレードした既存ストアの設定は一切変更されない。必要に応じて管理画面から手動でオンにできる仕組みだ。

商品オブジェクトキャッシュの仕組みとパフォーマンス改善の数字

商品オブジェクトキャッシュの仕組みとパフォーマンス改善の数字

リクエスト内で商品データを使い回すメモリ内キャッシュ

このキャッシュは、一度のHTTPリクエストの間だけ生きている、揮発性のメモリ内キャッシュだ。wc_get_product(123)が呼ばれると、キャッシュに保存されていればデータベースに問い合わせず、すぐに商品オブジェクトの複製を返す。リクエストが終わればキャッシュは完全に消去されるため、次のリクエストで古い情報が残る心配はない。

特に、wc_get_product()を同じIDで何度もコールするパターンが多いテーマやプラグインで効果が大きい。各呼び出しが独立したオブジェクトのクローンを返すため、意図せず商品データの状態を共有してしまうバグも防げるようになった。

キャッシュなし(従来)
1回目 wc_get_product(123) DBから取得(遅い)
2回目 wc_get_product(123) DBから再取得(まだ遅い)
3回目 wc_get_product(123) DBからまた取得
キャッシュあり(WC 11.0)
1回目 wc_get_product(123) DBから取得(初回のみ)
2回目 wc_get_product(123) メモリ内キャッシュ(即返却)
3回目 wc_get_product(123) メモリ内キャッシュ(高速)
※各呼び出しで返されるのは常に商品オブジェクトのクローン(複製)。呼び出し元どうしで状態が共有されることはない。

このデモは、同じ商品IDに対する繰り返し呼び出しがキャッシュによってどれだけ無駄を省けるかを示している。実際のECサイトでは、商品ループやセール情報の取得、決済フローの中で wc_get_product() が頻繁に呼ばれるため、体感速度の改善が期待できる。

実測値として9〜12%の高速化

WooCommerce 10.5の実験的導入時に公表されたパフォーマンス測定値は、今回の正式適用後も同じだ。可変商品(サイズや色のバリエーションがある商品)の製品ページでは、読み込み時間が9〜12%短縮された。バンドル商品を含むチェックアウト処理では6〜12%高速化されている。

この改善幅は、商品データを繰り返し取得する重いクエリがページ表示のボトルネックになっている状況で顕著だ。小規模なサイトでは効果が体感しにくいケースもあるが、商品数が多いストアや複雑な製品構成のサイトでは、目に見える速度向上が得られる。

WooCommerce 10.5から11.0への段階的な導入プロセス

WooCommerce 10.5から11.0への段階的な導入プロセス

10.5で実験的機能として登場、10.6で互換性の宣言が「互換」に

商品オブジェクトキャッシュは、WooCommerce 10.5で「実験的機能」として初めて公開された。当時はデフォルトで無効であり、ストア運営者が手動でオンにする必要があった。機能自体は、wc_get_product()の呼び出しをインターセプトし、リクエスト単位のメモリ内キャッシュからデータを返す仕組みだ。

WooCommerce 10.6では、この機能のプラグイン互換性宣言が「非互換」から「互換」に変更された。実験期間中に拡張機能エコシステム全体で互換性の問題が一切報告されなかったため、明示的に互換性を宣言していない拡張機能も、デフォルトで互換とみなされるようになった。

もし拡張機能が明示的に「この機能とは非互換」と宣言している場合は、WooCommerceの機能画面に従来通り非互換の通知が表示される。しかし、そのような宣言が必要になった拡張機能は見つかっていない。

11.0で新規ストアへの自動有効化を実装

WooCommerce 11.0のクリーンインストール時には、インストールプロセスの一環として商品オブジェクトキャッシュが自動で有効になる。機能登録自体は enabled_by_default => false のまま変更されていないが、新規インストール時に明示的に有効化が書き込まれる仕組みをとっている。

これは、HPOS(High-Performance Order Storage)など、他の機能がオプトインから新規インストール時デフォルトへ移行した際と同じパターンだ。バージョンアップだけでは既存ストアの設定を変更しない、慎重な設計が貫かれている。

既存ストアの挙動と手動有効化の手順

既存ストアの挙動と手動有効化の手順

アップグレードしても設定は一切変わらない

WooCommerce 11.0より前に構築されたストアは、11.0へアップグレードしても既存のキャッシュ設定がそのまま維持される。もし以前に無効だった(それが11.0以前のストアのデフォルト設定だ)なら、アップグレード後も無効のままだ。すでに手動で有効にしていたストアは、そのまま有効が継続される。

つまり、次の3パターンに整理できる。

  • WooCommerce 11.0以降を新規インストール → 自動的に有効(操作不要)
  • 既存ストアで機能が無効だった → アップグレード後も無効のまま(手動で有効にできる)
  • 既存ストアで機能が有効だった → アップグレード後も有効のまま(操作不要)

手動で有効化する方法

既存ストアでこの機能を試したい場合、管理画面の WooCommerce → 設定 → 詳細設定 → 機能 にアクセスし、「商品オブジェクトをキャッシュする(Cache Product Objects)」のトグルをオンにすればよい。ただし、設定変更後にサイト全体の動作を一通りチェックしておくことが推奨される。

手動有効化の流れ
STEP 1 WooCommerce → 設定 へ移動
STEP 2 詳細設定 → 機能タブを開く
STEP 3 「Cache Product Objects」をオンにする
STEP 4 変更を保存して動作確認

トグルをオンにすると、その瞬間からリクエスト単位の商品キャッシュが働き始める。とくに、複数の拡張機能が同じ商品データにアクセスする大規模ストアでは、即効性のある改善が期待できるだろう。

拡張機能開発者への影響と注意点

拡張機能開発者への影響と注意点

標準APIを使っていればコード変更は不要

wc_get_product() やその他 WooCommerce 標準 API を通じて商品を取得している拡張機能は、このキャッシュの影響をまったく受けない。キャッシュは内部で透過的に動作し、呼び出し元には変わらず正しい商品オブジェクトが返る。

キャッシュから返されるのは、あくまで独立したクローンなので、取得した商品オブジェクトを編集しても他の処理に副作用が及ぶことはない。したがって、従来のコーディング規約に従っている拡張機能は、そのまま動作し続ける。

直接SQLを実行する拡張機能が注意すべきポイント

注意が必要なのは、WooCommerceのメタフックを経由せずに、商品データに対して直接SQLクエリを発行している拡張機能だ。これらのクエリはキャッシュの無効化フックを迂回するため、更新後のデータがキャッシュに反映されず、古い情報が返ってしまう可能性がある。

この問題は、商品オブジェクトキャッシュに限った話ではなく、WooCommerceのデータ整合性全般に関わる設計課題だ。該当する拡張機能を開発している場合は、標準の wc_get_product() やメタデータ更新用のAPIを使うことで、キャッシュの恩恵を受けつつ、データ不整合も回避できる。

今後のロードマップと全ストアへの有効化計画

今後のロードマップと全ストアへの有効化計画

データ蓄積後に全ストアで有効化へ

今回のリリースは通過点であり、最終的にはすべてのストア(既存ストアも含む)で商品オブジェクトキャッシュを有効化する計画が示されている。現時点で具体的な実施時期は明言されていないが、十分なストアでの稼働データが蓄積された段階で判断される。

すでに実験期間で問題が報告されていないこと、新規インストールのデフォルト有効化でさらなる実績が積み上がることを踏まえると、早ければ数バージョン後には全ユーザー対象の強制有効化に踏み切る可能性が高い。

問題が発生した場合の報告先

もし商品オブジェクトキャッシュに関連して予期せぬ挙動が見つかった場合、WooCommerceのGitHubリポジトリでIssueを報告してほしいと開発チームは呼びかけている。拡張機能開発者やストア運営者からのフィードバックが、今後の安定化に直結する。

この記事のポイント

  • WooCommerce 11.0 で商品オブジェクトキャッシュが新規ストア向けに自動有効化された
  • 可変商品の製品ページ読み込みは 9〜12% 高速化、バンドル商品のチェックアウトは 6〜12% 改善
  • 既存ストアはアップグレードしても設定変更なし、管理画面から手動でオンにできる
  • 標準の WooCommerce API を使う拡張機能はコード変更不要で動作する
  • 最終的には全ストアで有効化される予定で、Issue 報告を募っている
WooCommerceにEU契約撤回ボタンを無料で追加する方法

WooCommerceにEU契約撤回ボタンを無料で追加する方法

2026年6月19日からEU消費者へ販売するオンラインショップには、契約を撤回する「離脱ボタン」をストアフロントに設置する義務が発生する。WooCommerceには標準でこの機能がないため、無料の専用プラグインを見極めて導入すれば、技術的な難しい変更なしに対応できる。

なぜ2026年6月からEU向けWooCommerceに契約撤回ボタンが必要なのか

なぜ2026年6月からEU向けWooCommerceに契約撤回ボタンが必要なのか

EU指令2023/2673(従来の消費者権利指令に第11a条を追加)が、2026年6月19日以降にEU在住の消費者を対象に販売するすべての事業者に対して、契約を撤回するための「明確に表示されたワンクリック機能」の提供を義務付けている。これは商品の返品とは別に、契約そのものから離脱する手段を消費者に与えるものだ。

日本からEUへ越境ECを行う事業者も、現地の消費者をターゲットにしている限り例外ではない。WooCommerce単体ではこの離脱機能に対応しておらず、公式要望トラッカー上で議論は続いているものの、すぐに実装される見込みはない。そのためプラグインによる早期の対応が欠かせない状況になっている。

WooCommerce向け離脱ボタンプラグインで絶対に押さえるべき機能

WooCommerce向け離脱ボタンプラグインで絶対に押さえるべき機能

多数の無料プラグインが出回っているが、法令を満たすために最低限チェックするポイントは変わらない。見落としを防ぐために、以下の基準を事前にリストアップしておくことが大切だ。

ワンクリックで契約撤回が完了する仕組み

消費者がボタンを押すだけで、追加のフォーム入力や本人確認なしに撤回の意思表示が完了しなければならない。撤回の受付通知が自動的にメールで送られる仕組みも必須になる。

わかりやすく目立つボタン表示

「契約を撤回する」といったボタン文言が、注文確認画面やマイアカウントページなど、消費者が容易に見つけられる位置に常に表示される必要がある。テーマのスタイルに埋もれず、かつ法的に十分な表示であることが求められる。

GDPRおよび個人データ取り扱いへの配慮

離脱ボタンの動作に伴って取得される個人データ(注文ID、メールアドレスなど)の取り扱いがGDPRに準拠しているかも確認する。プラグインが不要なデータを保存していないか、またデータ保持期間の設定ができるかが重要な判断材料になる。

多言語対応と日本向けの翻訳品質

EU圏内で複数言語のサイトを運営する場合、ボタン文言や通知メールを各国語に切り替えられる多言語対応が必須になる。日本語で運用しているサイトでも、管理画面表示が適切に翻訳されているか、表示されるフロント文言が自然かを確かめておきたい。

更新の継続性とエコシステムとの相性

WordPress本体やWooCommerceのアップデートに追従しているか、アクティブインストール数や最終更新日を確認する。法典の変更に応じて仕様が変わる可能性もあるため、活発にメンテナンスされているプラグインを選ぶことで将来のリスクを抑えられる。

無料のEU契約撤回プラグインを安全に選んで導入する流れ

無料のEU契約撤回プラグインを安全に選んで導入する流れ

実際にプラグインを選ぶ際には、機能のチェックリストをクリアするだけでなく、自分のサイト環境で競合なく動作するかのテストがとても重要だ。以下の手順で進めれば、手戻りなく導入できる。

STEP 1 公式リポジトリで「withdrawal button」などのキーワードで複数の無料プラグインをリストアップする
STEP 2 前述の必須機能を満たしているか、説明文とスクリーンショットで下調べする
STEP 3 テスト環境またはステージングサイトでプラグインをインストールし、有効化する
STEP 4 ボタンの表示位置や文言、撤回後の自動メール通知を確認し、必要に応じて外観やフックを調整する

上図は一般的な導入手順を示したイメージで、実際のプラグインによって設定画面の構成は異なる。

プラグイン導入後に必ずチェックする項目と表示カスタマイズのコツ

プラグイン導入後に必ずチェックする項目と表示カスタマイズのコツ

プラグインを有効化しただけでは、テーマの都合でボタンが正しく表示されなかったり、通知メールが迷惑メールに振り分けられたりするケースがある。以下のポイントを必ず実機で確認しておく。

Before(対応前)
注文確認ページに契約撤回の手段が一切表示されない
After(プラグイン導入後)
「契約を撤回する」ボタンが目立つ位置に常時表示され、ワンクリックで撤回完了と通知が飛ぶ
対応前  対応後

マイアカウントページと注文詳細画面の両方にボタンが現れるか

購入後の消費者がアクセスするマイアカウント内の注文一覧や個別注文画面、そしてゲスト購入者向けの注文確認ページの両方でボタンが機能するかを必ず検証する。プラグインによってはゲスト購入に対応していないこともあるため注意が必要だ。

撤回後のフローがEC事業者側にも通知されるか

消費者が撤回ボタンを押したあと、店舗運営者にメールや管理画面内の通知が届く仕組みになっているかも重要だ。対応が遅れるとトラブルに発展するため、通知が確実に飛ぶ設定になっているかを最初のテストでつかんでおく。

表示をCSSで微調整したい場合の注意

ボタンの色やサイズをテーマに合わせたいときは、追加CSSに直接スタイルを書いて調整するのが現実的な方法だ。ただし、プラグインが出力するHTMLのクラス名やIDはアップデートで変わることがあるため、子テーマのstyle.cssに依存しすぎないようにし、変更後は必ず再テストを行う。

よくある質問

WooCommerce用のEU離脱ボタンプラグインは本当に無料で使えますか

現在、WordPress公式リポジトリで複数の無料プラグインが公開されている。いずれも基本機能は無料で提供されており、有料版で追加機能が解放される場合もあるが、法令要件を満たすだけなら無料で十分対応できる。

ボタンの設置だけでEUの法律要件はすべて満たせますか

離脱ボタンは指令が求める機能の一部だ。合わせて返品ポリシーの明示や、撤回後の返金手続きを整備する必要がある。プラグインはあくまで技術的な「ボタンの提供」部分を解決するものだと理解しておくことが大事だ。

多言語サイトでボタン文言を日本語にしたい場合の対処法は

多くのプラグインは翻訳ファイルを内包しているか、管理画面でボタン文言を自由にカスタマイズできる。日本語の翻訳が不完全な場合はLoco Translateなどの別の翻訳プラグインを併用して、表示テキストだけを書き換えることも可能だ。

プラグインがWooCommerceの今後のアップデートで動かなくなる心配は

定期的に更新されているプラグインを選ぶことでリスクは下げられる。導入前に最終更新日とアクティブインストール数、サポートフォーラムの反応を確認し、万が一に備えてステージング環境を用意しておくのが堅実な運用だ。

この記事のポイント

  • 2026年6月19日からEU向け販売店に契約撤回ボタンの設置が義務化された
  • WooCommerce標準には機能がなく、無料プラグインでの対応が現実的な解決策
  • プラグイン選びではワンクリック完了、明確な表示、GDPR配慮、多言語対応をチェック
  • 導入後は表示場所とゲスト購入時の動作を必ずテストし、通知設定も確認する
  • 定期更新が続いているプラグインを選び、ステージング環境で動作検証を行う
WooCommerce MyParcelで重大エラーが出た時のデフォルト配送業者設定方法

WooCommerce MyParcelで重大エラーが出た時のデフォルト配送業者設定方法

WooCommerce の MyParcel プラグイン使用時に表示される「このサイトで重大なエラーが発生しました」というエラーは、プラグイン内にデフォルトの配送業者が設定されていないことが原因だ。プラグイン設定画面からデフォルトの配送業者を選択すれば、エラーはすぐに解消する。

なぜデフォルト配送業者が未設定だとエラーになるのか

なぜデフォルト配送業者が未設定だとエラーになるのか

このエラーは PHP の致命的エラー(Fatal Error)であり、MyParcel プラグインが「No default carrier available(利用可能なデフォルトの配送業者がない)」という例外を発生させて停止している。スタックトレースを追うと、発端は受注確認ページ(サンキューページ)などで追跡情報を表示しようとする際、プラグインが内部的に呼び出す getDefaultCarrierOrThrow() メソッドで落ちている。

MyParcel は配送ラベル作成や追跡情報の連携を行うプラグインであり、動作には「どの配送業者をデフォルトで使うか」という情報が必須だ。この設定を一度も行っていなかったり、アップデート時に何らかの理由で消えたりすると、サイトの該当ページでエラーが表示される。

≪ エラー発生時 ≫
MyParcel プラグインがデフォルトの配送業者を取得できず、例外をスロー
≪ 設定後 ≫
デフォルト配送業者が設定され、プラグインが正常に動作
設定未完了状態  設定完了後

デフォルト配送業者を設定する具体的な手順

デフォルト配送業者を設定する具体的な手順
STEP 1 WordPress 管理画面にログインし、左メニューから「WooCommerce」→「MyParcel」を開く
STEP 2 「設定」タブを選択し、「デフォルトの配送業者」項目を探す
STEP 3 プルダウンから利用する配送業者(例: ヤマト運輸や佐川急便など契約中のもの)を選択する
STEP 4 画面下部の「変更を保存」をクリックし、エラーが消えたか確認する

管理画面にアクセスできる状態であれば、この手順だけでエラーは即座に解消する。設定項目の名称はプラグインバージョンによって「デフォルトの配送業者」「Default Carrier」などと表記が異なるが、いずれも一つのプルダウン形式で表示される。

管理画面にすらアクセスできない場合の対処

エラーがサイト全体に影響し、管理画面も真っ白になってしまうケースがある。その場合は FTP またはサーバーのファイルマネージャーを使い、一時的に MyParcel プラグインのフォルダをリネームして無効化する。

  • サーバーに接続し、/wp-content/plugins/ ディレクトリへ移動する
  • woocommerce-myparcel フォルダを woocommerce-myparcel_deactivated などに変更する
  • これでプラグインが停止し、管理画面へアクセスできるようになる
  • 管理画面に入れたら、上の STEP 手順で設定を行い、フォルダ名を元に戻して有効化する

設定を保存してもエラーが再発する場合

設定保存後に再び同じエラーが発生するなら、プラグインまたは関連データベース設定に不整合が起きている可能性が高い。以下の順で追加対応を試す。

  • 一度プラグインを完全に削除し、最新バージョンを再インストールする
  • WooCommerce のシステムステータス画面で、不要なトランジェント(期限付きキャッシュ)をクリアする
  • MyParcel アカウントとの API 接続情報(API キーなど)を再入力する

エラーを未然に防ぐための注意点

エラーを未然に防ぐための注意点

プラグインのメジャーアップデート後や WordPress 本体の自動更新後に、こうした設定がリセットされる事例は珍しくない。MyParcel に限らず、配送系・決済系プラグインは「接続先のデフォルト設定」が必須となるものが多い。アップデート後はテスト環境や低トラフィック時間帯に決済フローとサンキューページの動作を一通り確認する習慣をつけると安心だ。

よくある質問

エラーメッセージが英語で「No default carrier available」と表示されているが日本語環境でも同じ?

日本語環境の WordPress でも管理画面やログに表示されるエラーメッセージは英語のままになる。ただしサイト訪問者には「このサイトで重大なエラーが発生しました」という日本語の汎用エラー画面が表示されるため、管理者はサーバーのエラーログやデバッグモードで英語エラーを確認することになる。

MyParcel 以外の配送プラグインでも同様のエラーは起こる?

配送ラベル生成や追跡機能を持つプラグインは、内部で配送業者を特定する仕組みに依存していることが多く、設定不足で同種のエラーが起きる可能性がある。具体的には「デフォルトの配送業者」「デフォルトの配送方法」が未選択であると、ページ表示時に致命的エラーになる構造は共通している。

Divi テーマを使っていることがエラーと関係ある?

スタックトレースに Divi のパスが含まれているのは、サンキューページを Divi の WooCommerce モジュールで構築しているためだ。エラーの根本原因はあくまで MyParcel プラグイン側の設定不足であり、Divi そのものに問題があるわけではない。

デフォルトの配送業者を設定しても配送ラベルが発行できない

デフォルト配送業者の設定はエラー解消の第一歩だが、実際にラベルを発行するには MyParcel アカウントとの正しい API 接続と、WooCommerce の配送クラスや商品重量の設定が必要になる。エラーが消えた後は、MyParcel の管理画面で接続ステータスが「アクティブ」になっているか確認する。

この記事のポイント

  • PHP の致命的エラーは MyParcel のデフォルト配送業者未設定が原因
  • 管理画面の MyParcel 設定からデフォルト配送業者を選択して保存すれば解決
  • 管理画面に入れない場合はプラグインフォルダのリネームで一時無効化する
  • アップデート後は配送系プラグインの設定リセットに注意が必要
Contact Form 7でスパムメールが大量に届く時の根本対策

Contact Form 7でスパムメールが大量に届く時の根本対策

Contact Form 7から件名や本文が空、または広告だけのスパムメールが大量に届くようになった状態は、ハニーポット(honeypot)と呼ばれる手法やシンプルな送信条件の制限を組み合わせることで、高い精度でブロックできる。

なぜContact Form 7にスパムが届くのか

なぜContact Form 7にスパムが届くのか

お問い合わせフォームを設置したばかりのサイトは、公開直後から自動巡回するスパムボットの標的になる。ボットはPHPで生成されたフォームの構造を解析し、name属性やclass名を把握したうえで、迷惑メールの配信やSEO用の被リンク売り込みなどを自動送信する。Contact Form 7は世界中で使われているため、ボット側も「どのフィールドに何を入れれば送信が通るか」を熟知している。そのため、標準の状態ではほとんどのボットが素通りしてしまう。

ボットが大量のスパムを送り込むことによって、メールサーバーの評判低下や共用サーバーのリソース浪費、管理用メールアドレスのブラックリスト入りといった二次被害が発生する可能性がある。件名や本文が空に近いメールが届くときは、すでにボットによる自動送信が常態化しているとみてよい。

Before(対策なし)
ボットがフォームの全項目を埋めて送信
空の件名・本文のメールが毎分数十件届く
After(ハニーポット+制限)
人間だけが条件をクリアして送信
スパムはサーバー側ではじかれメールも届かない
対策前の状態  対策後の状態

このデモは、対策の有無でスパムの到達状況がどう変わるかを示したイメージだ。対策を入れない限り、ボットはフォームの構造を正確に読んで送信を成功させてしまう。

ハニーポットでボットを静かにブロックする方法

ハニーポットでボットを静かにブロックする方法

ハニーポット(honeypot)とは、人間には見えずボットだけが反応する「罠」のフィールドをフォームに仕込む対策を指す。reCAPTCHAのようにユーザーに手間をかけず、Ajaxの競合リスクも低いため、Contact Form 7との相性が非常によい。

CSSで見えないチェックボックスを設置する

ボットは画面に表示されるかどうかを判断せず、HTMLソース内のすべてのフィールドを機械的に入力しようとする性質を持つ。この行動を利用し、人間には表示されないチェックボックスをフォームに追加する。チェックボックスにチェックが入った状態で送信された場合は、ボットとみなして送信を破棄する、という仕組みだ。

参考までに、公式のContact Form 7は、独自の同意チェックボックスであるacceptance(承諾)タグに対して invert default:on という属性をサポートしている。これは「デフォルトでチェックが入っており、人間だけが外せる」という逆転ロジックを作れる機能だ。ボットはチェックを外す操作を行わないため、罠として機能する。

ただし、acceptanceタグを使う方法は、実際にはCSSでフォーム項目をサイト上で見えなくする処理と組み合わせて使う必要がある。そうしないと、サイトを訪れた人間が混乱する原因になるためだ。

STEP 1 フォーム編集画面で該当フォームを開く
STEP 2 htmlのタグを追加する
<span class=”hp-check”>[acceptance hp-check invert default:on]空のまま送信してください[/acceptance]</span>
STEP 3 サイトの追加CSSに非表示設定を追記する
.hp-check { display:none; }
STEP 4 変更を保存し、動作を確認する
ブラウザのデベロッパーツールでタグが非表示になっているか確認する

この手順ではCSSで視覚的に完全に隠すため、サイト訪問者はこのチェックボックスを一切意識せずに送信できる。一方、ソースコードを解析して全フィールドを埋めようとするボットは、デフォルトでオンになっているチェックを外さないまま送信するため、Contact Form 7のバリデーションでエラー扱いとなりメールが飛ばない。

acceptanceタグのロジックに過度に依存しない

acceptanceの逆転ロジックは簡易なボットに対しては有効だが、高度なボットはチェックボックスの状態を操作できるケースも報告されている。また、CSSを解析してスタイルを操作するスクリプトには、非表示の項目を見抜かれてしまう可能性もある。そのため、ハニーポットはあくまで一次フィルターと捉え、次の追加対策と組み合わせることが現実的な防御線だ。

reCAPTCHA v3でユーザー負荷をかけずに判別する

reCAPTCHA v3でユーザー負荷をかけずに判別する

Contact Form 7はGoogle reCAPTCHA v3のインテグレーションを公式にサポートしている。reCAPTCHA v3は「私はロボットではありません」のチェックボックスや画像選択のような操作をユーザーに一切求めず、ページ滞在中のマウスの動きやスクロールといった行動データをもとにスコアリングし、スパムの可能性が高い送信をブロックする仕組みだ。

設定はGoogle reCAPTCHAの管理画面でサイトキーとシークレットキーを取得し、WordPress管理画面の「Contact」→「Integration」からreCAPTCHAの項目にキーを入力するだけで完了する。v2の「チェックボックス方式」は一部の環境でAjax送信との競合を起こすことがあるが、v3はその心配が少ない。フォームに直接ウィジェットが表示されないため、デザインを損なわない利点もある。

reCAPTCHA 設定フロー
Google管理画面 サイトキー取得 WordPress連携設定 スコア判定で防御
※ v3ではサイト訪問者に操作画面は一切表示されない

このフローは、reCAPTCHA v3導入の全体像を示したものだ。v2と異なり、Widgetの操作ステップが存在しないため、サイトの表示速度やユーザー体験への影響を最小限に抑えつつ、高精度なボット検知を実現できる。

メール本文に日本語必須ルールを追加する

メール本文に日本語必須ルールを追加する

海外から大量に届くスパムの多くは、英語や中国語、あるいは記号だけで構成されている。日本語圏のサイトであれば、送信内容に日本語が含まれていることを必須条件にすると、ボットによる自動送信の大半を止められる。Contact Form 7には、特定の文字種を含んでいるかどうかを検証する正規表現(Regex)の機能は標準で備わっていないが、無料の専用プラグインで補うか、functions.phpにフィルターフックを追加して実装できる。

具体的には、wpcf7_validate_text*wpcf7_validate_textarea* といったバリデーションフックを使い、本文フィールドにひらがな・カタカナ・漢字のいずれかが1文字でも含まれているかをPHPの正規表現でチェックする。条件を満たさない場合はエラーメッセージを返し、メール送信を中止させるという流れだ。この対応は海外発の機械的スパムには極めて有効で、実装の手間に対する防御効果が高い。

よくある質問

ハニーポットを仕込んでもスパムが続く場合は?

ハニーポットだけで防げない場合は、ボットがCSSを解析して非表示フィールドを識別している可能性がある。その場合は、フィールドを完全に非表示にするのではなく、画面上の見えない位置にずらす方法(positionで画面外に飛ばす)や、JavaScriptを使って動的にフィールドを生成する方式に切り替えると効果が上がる。また、reCAPTCHA v3や日本語必須ルールの併用を必ず検討する。

reCAPTCHA v2よりv3のほうが本当に優秀なのか

ボット検知精度はどちらも高いが、v3は操作性と表示速度の面で大きく優れている。v2の画像選択がユーザーの離脱を招いたり、Ajaxフォームとの競合で送信エラーを起こす場面が減るため、問い合わせフォームとの相性という観点ではv3の導入が望ましい。ただし、v3はサイト全体のスコアリングを行うため、プライバシーポリシーへの記載が必要になる。

Contact Form 7以外のフォームに切り替えたほうがよいか

スパム対策だけを理由にフォームプラグインを移行する必要はない。Contact Form 7は世界的に使われている分、ボットの標的になりやすい面はあるが、今回紹介した対策を適切に組み合わせれば実用上十分な防御力を確保できる。移行によって別の競合やカスタマイズの手間が発生するリスクを考えると、まずは手元のContact Form 7を強化する方針が合理的だ。

この記事のポイント

  • Contact Form 7へのスパムは、ボットがフォーム構造を熟知しているために発生する
  • ハニーポット(CSS非表示のチェックボックス)で、人間には影響なくボットをブロックできる
  • reCAPTCHA v3を導入すると、ユーザー操作なしで高精度なスパム判定が可能になる
  • メール本文に日本語の文字種を必須にするルールを追加すると、海外発スパムの大半を遮断できる
  • 単一の対策に頼らず、複数の層を重ねることでボットの突破を防ぐ
Trustindexプラグインの脆弱性、認証なしでトークンが漏洩する問題と対策

Trustindexプラグインの脆弱性、認証なしでトークンが漏洩する問題と対策

Trustindexプラグインのトラブルシューティング用RESTエンドポイントが認証なしでアクセス可能になっていると、Instagram Graph APIのアクセストークンを含む全オプションが外部に漏洩する。HMAC署名のキーに公開情報を使っている設計上の欠陥が原因であり、修正パッチが配布されるまでの間はエンドポイント自体を遮断する応急処置が必要になる。

何が起きているのか 〜 脆弱性の全体像

何が起きているのか 〜 脆弱性の全体像

この問題は、Trustindexの「Instagram Feed」ウィジェットを設置したWordPressサイトで発生する。プラグインは管理画面のトラブルシューティング用に /wp-json/trustindex_feed_hook_instagram/troubleshooting というRESTエンドポイントを用意している。このエンドポイントに正しい署名付きリクエストを送ると、プラグインが保存している全オプション、つまりInstagramのアクセストークンや各種設定をJSON形式で返してしまう。

認証にはHMAC-SHA256による署名検証が使われているが、その署名用の秘密鍵(キー)がサイトごとに公開されている「パブリックID」になっている。このIDは、プラグインが生成するCDNのURL(https://cdn.trustindex.io/wp-feeds/XX/パブリックID/data.json)に含まれ、ページのソースコードやネットワークリクエストを覗けば誰でも取得できる。つまり署名の計算に必要な材料がすべて攻撃者の手に渡ってしまうため、認証がまったく機能していない状態だ。

影響は深刻だ。漏洩したInstagramアクセストークンを使えば、サイト運営者になりすましてInstagram Graph APIを呼び出し、プロフィール情報の取得やメディア投稿の操作が可能になる。トークンの有効期限が切れるか運営者が手動で失効させるまで、不正利用のリスクが続く。

自分のサイトが影響を受けるかどうかの確認方法

自分のサイトが影響を受けるかどうかの確認方法

まず、TrustindexプラグインをインストールしてInstagramフィードを表示しているサイトが対象だ。それ以外のフィード(FacebookやGoogleレビューなど)を使っているだけの場合は、今回のエンドポイントとは関係がない。確認手順は次の3ステップで行える。

STEP 1 ブラウザで自サイトの任意のページを開き、右クリック→「ページのソースを表示」を選択する。
STEP 2 Ctrl+Fで「cdn.trustindex.io」を検索し、URLの中にある英数字2文字+ハイフン+英数字のパブリックIDを見つける。
STEP 3 curlなどのツールでエンドポイントに署名付きリクエストを送り、レスポンスにトークンが含まれていないか調べる。

STEP 3の詳細は、UNIXのターミナルで以下のようなリクエストを投げる。HMACの計算にはパブリックIDと現在のUNIXタイムスタンプを使うため、スクリプトを組むか手動で計算する必要がある。

# PUBLIC_ID と TIMESTAMP は各自の値に置き換える
PUBLIC_ID="取得したパブリックID"
TIMESTAMP=$(date +%s)
SIGNATURE=$(echo -n "$TIMESTAMP" | openssl dgst -sha256 -hmac "$PUBLIC_ID" | awk '{print $2}')
curl -H "X-Signature: $SIGNATURE" -H "X-Timestamp: $TIMESTAMP" \
  "https://あなたのサイトドメイン/wp-json/trustindex_feed_hook_instagram/troubleshooting"

レスポンスに source.access_tokenaccess_token といった文字列が含まれていれば、情報が丸見えの状態だと判断できる。この確認はあくまで自己診断用であり、他者のサイトに対して行ってはならない。

修正パッチが配布されるまでに取るべき応急措置

修正パッチが配布されるまでに取るべき応急措置

プラグイン開発者から公式のアップデートが提供されるまでは、以下のいずれかの方法で該当エンドポイントへの外部アクセスを完全に遮断する。

修正前 誰でもエンドポイントにアクセス可能。トークンが平文で返る
修正後 外部からのアクセスを禁止。管理者のみ必要に応じて利用

.htaccessでエンドポイントをブロックする

サーバーがApacheを使っている場合、WordPressのインストールディレクトリにある.htaccessファイルに以下の記述を追加する。これにより、該当URLへのリクエストは403 Forbiddenで弾かれる。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^wp-json/trustindex_feed_hook_instagram/troubleshooting - [F]
</IfModule>

functions.phpでREST APIアクセスを制限する

テーマのfunctions.php(子テーマ推奨)に下記のコードを追加すると、未ログインユーザーからの該当エンドポイントへのアクセスを拒否できる。管理画面にログインしているユーザーは引き続き利用できるため、サポートが必要になった際にも支障がない。

add_filter( 'rest_authentication_errors', function( $result ) {
    if ( ! empty( $result ) ) {
        return $result;
    }
    $current_route = $GLOBALS['wp']->query_vars['rest_route'] ?? '';
    if ( strpos( $current_route, '/trustindex_feed_hook_instagram/troubleshooting' ) !== false && ! is_user_logged_in() ) {
        return new WP_Error(
            'rest_forbidden',
            'このエンドポイントへのアクセスにはログインが必要です。',
            array( 'status' => 403 )
        );
    }
    return $result;
} );

プラグインを一時停止する判断

Instagramフィードの表示が必須でないなら、脆弱性が修正されるまでプラグイン自体を無効化するのが最も確実だ。フィードが表示されなくなる影響が許容できるビジネスであれば、この選択肢も検討しよう。

すでにトークンが漏洩した可能性がある場合の対処

すでにトークンが漏洩した可能性がある場合の対処

アクセスログを精査して不審なリクエストがなかったか確認するのが先決だが、ログが十分に残っていないケースも多い。疑わしい場合は、以下の手順でトークンを強制的に無効化し、新しいトークンを再発行する。

STEP 1 Facebook開発者コンソールで該当アプリのInstagram Basic DisplayまたはInstagram Graph APIの設定を開く
STEP 2 既存のアクセストークンをすべて取り消し(Revoke)、新しいトークンを生成する
STEP 3 WordPress管理画面でTrustindexプラグインの設定画面を開き、新しいトークンを再入力する

特にInstagram Graph APIのアクセストークンは長期トークン(Long-Lived Token)で運用していることが多く、一度漏洩すると数カ月単位で悪用されるリスクがある。トークン失効後は、フィードが一時的に表示されなくなるが、再設定すればすぐに復旧する。

根本的な原因と再発防止の考え方

根本的な原因と再発防止の考え方

今回の脆弱性の本質は、認証用の秘密情報が公開前提の値になっている設計ミスにある。HMAC署名を使うこと自体は正しいが、秘密鍵が「誰でも見られるURLの一部」にある時点でセキュリティは成り立たない。

プラグイン開発者側が取るべき修正は、プラグイン有効化時にランダムなシークレットを wp_options テーブルに保存し、その値を署名キーに使う方式へ変更することだ。さらに、トラブルシューティングという目的を考えれば、current_user_can('manage_options') で管理者権限を要求するだけでも十分な防御になる。このエンドポイントはあくまでサポートスタッフ向けであり、未認証ユーザーに開放する理由は一切ない。

サイト運営者としても、すべてのプラグインを無条件に信頼するのではなく、導入後に「どんなRESTエンドポイントが増えたか」「公開される情報はないか」をセキュリティプラグインや手動チェックで確認する習慣が身を守る。WordPressのサイトヘルス機能やQuery Monitorのようなツールを普段から使い、異常なAPIリクエストがないか注視しておくことが再発防止につながる。

よくある質問

プラグインのどのバージョンから修正されますか

2026年6月17日時点では、開発者は調査中と回答しており修正バージョンは未発表だ。Trustindexの公式チェンジログとWordPress管理画面の更新通知を定期的に確認し、セキュリティアップデートが配信され次第ただちに適用する必要がある。

応急処置としてプラグインを無効化すると、フィードはどうなりますか

プラグインを無効化すると、Instagramフィードは表示されなくなる。ただ、表示崩れが起こるだけでサイト全体がダウンするわけではない。トークン漏洩のリスクと天秤にかけて、ビジネス上の重要性が高い場合は上記の.htaccessやfunctions.phpによる遮断を選ぶほうが現実的だ。

Instagramのトークンを変えたあと、再度漏洩することはありますか

アプリやサーバー側の脆弱性が修正されていない限り、新しいトークンも同じエンドポイントから再び漏洩する可能性がある。必ず、アクセス制限の応急措置を先に施したうえでトークンを再発行する順序を守ってほしい。

FacebookやGoogleのフィードにも同じ問題はありますか

今回確認されたのは trustindex_feed_hook_instagram のエンドポイントのみだが、同じ認証設計を他のフィード用エンドポイントにも流用している可能性は否定できない。不安があれば、trustindex_feed_hook_facebooktrustindex_feed_hook_google といった類似のエンドポイントが存在しないか、REST APIのルート一覧で確認しておくと安心できる。

自分のサイトがすでに攻撃されたかどうか確かめる方法はありますか

サーバーのアクセスログに /wp-json/trustindex_feed_hook_instagram/troubleshooting へのリクエストが記録されていれば、それが正規のサポート用途か攻撃かを判別する必要がある。あわせて、Instagram Graph APIの使用状況をFacebook開発者コンソールの「アプリのインサイト」で確認し、見覚えのないAPIコールや異常なリクエスト数がないかを調査するのが確実だ。

この記事のポイント

  • Trustindexプラグインのトラブルシューティング用RESTエンドポイントが認証不備によりInstagramアクセストークンを露出させている
  • 原因はHMAC署名の秘密鍵として、誰でも取得できるパブリックIDを使用している設計ミス
  • 修正パッチが配布されるまでは、.htaccessかfunctions.phpでエンドポイントへの外部アクセスを遮断する
  • トークン漏洩が疑われる場合はInstagram側でトークンを即時失効させ再発行する
  • 常にプラグインのREST APIエンドポイントを定期的に監視し、不要な露出がないか確認する習慣が再発防止の鍵
WordPress 7.0リリース後の開発者情報まとめ(2026年6月版)

WordPress 7.0リリース後の開発者情報まとめ(2026年6月版)

2026年5月20日にWordPress 7.0が正式リリースされた。その後1ヵ月の間に、メディア編集の刷新やクライアントサイドでの画像処理、テーマ向けスタイル機能の強化など、開発者にとって見逃せないアップデートが続いている。

本記事では、Developer WordPress News の「What’s new for developers? (June 2026)」を読み解きながら、6月に登場した主要トピックを整理する。プラグイン開発者、テーマ制作者、そしてサイト運営者が押さえておきたいポイントを中心に、実務への影響をわかりやすく解説する。

メディア編集モーダルがデフォルトに、画像処理の進化

メディア編集モーダルがデフォルトに、画像処理の進化

画像の切り抜きがより直感的に

Gutenberg 23.3では、画像の切り抜き操作が専用のモーダルウィンドウで行われるようになった。これまでは編集画面内で直接操作していたが、今回の変更により、縦横比の指定や回転、反転、ズーム、メタデータの編集までひとつのモーダルに集約されている。

操作の入り口はこれまで通り「切り抜き」ボタンだが、編集体験は格段に整理された。プラグインで画像編集機能を独自に拡張している場合や、画像メタデータに依存する処理を組んでいる場合は、実際の画像を使ったキーボード操作やタッチ操作のテストが必要だ。

ブラウザ上で画像リサイズを行うクライアントサイド処理

もうひとつ注目したいのが、クライアントサイドメディア処理のテスト呼びかけだ。これは、可能な場合にはブラウザ上で VIPS/WASM パイプラインを使って画像のサブサイズを生成し、必要に応じてサーバーサイド処理にフォールバックする仕組みである。

対応形式はAVIFやWebP、HEIC、Ultra HDR、JPEG XL、GIFから動画への変換など多岐にわたる。ただし、現時点ではChromiumブラウザと最新のGutenbergプラグインの組み合わせに限られ、FirefoxやSafariでは無効、メモリが2GB以下のデバイスではスキップされる。通信速度が遅い場合やContent Security Policyの worker-src が制限的な場合も利用できない。

従来の画像処理(Before)
ユーザー 画像アップロード サーバー リサイズ処理 サムネイル生成
ブラウザサイド処理(After)
ユーザー アップロード ブラウザが対応判定 VIPS/WASMでリサイズ (失敗時のみサーバーへ)

このデモでは、従来のようにサーバーがすべてのリサイズを担当する方法から、可能なときはブラウザが先に処理を引き受ける流れへの変化を示している。サーバーの負荷軽減とユーザー体験の向上が期待されるが、環境による制限があるため、フォールバックを含めたテストが欠かせない。

プラグインとツールを取り巻く重要な更新

プラグインとツールを取り巻く重要な更新

React 19への移行は一時的に巻き戻されたが準備は続く

WordPress 7.0ではReact 19へのアップグレードが計画されていたが、Gutenbergでは一時的にこの変更が巻き戻された。理由は、複数のプラグインがReact 18のJSXランタイムヘルパーをバンドルしており、React 19と同時に読み込むとクラッシュする問題が発生したためだ。

コアチームはWordPress 7.1でのReact 19導入を目指し、より段階的な戦略で進める方針を示している。コンパイル済みのJSXを同梱しているプラグインや、@wordpress/element を使っている場合、またはエディターのプライベートAPIに触れている場合は、引き続きテスト環境で最新のGutenbergを試すことをおすすめする。

Abilities APIの拡充が進行中

Abilities APIはこれまでのラウンドアップでも取り上げられてきたが、6月も継続的に改良が進んだ。ライフサイクルフィルターや入出力のバリデーションフィルター、wp_get_abilities() へのフィルタリングサポート、サイトやユーザー、環境情報のレスポンス拡張、RESTスキーマの堅牢化などが行われている。

能力(アビリティ)を使った実験を始めている開発者は、以前の想定に頼りすぎず、トランクの最新の挙動を確認しておくとよい。

PHPサポートの明確化とUnicodeメールアドレス対応の提案

WordPress 6.9および7.0では、PHP 8.5を完全にサポートすることが正式に明文化された。これにより、古い「ベータサポート」ラベルは廃止され、WordPress 7.0時点での最低動作バージョンはPHP 7.4、推奨はPHP 8.3に整理されている。

一方で、メールアドレスやユーザー名、スラッグにおけるUnicode対応を拡張する提案も公開され、フィードバックが募られている。この提案は is_email()sanitize_email() などの関数、フィルター、データベース格納、文字の正規化などに影響を及ぼす可能性があり、メールアドレスを扱うプラグインは早めに内容を確認しておく価値がある。

AI Clientを使った画像生成プラグインのチュートリアル

4月・5月のラウンドアップで紹介されたAI ClientとConnectors APIに関する実践的なチュートリアルが登場した。ここでは、画像生成プラグインを構築する方法が解説されており、特に機能検出パターンが参考になる。プラグインは、プロバイダーが設定済みかどうか、そして必要な機能をサポートしているかを確認したうえでUIを表示すべきであり、チュートリアルではメディアライブラリから画像を生成し、添付ファイルとして保存する一連の流れが実装されている。

テーマ開発者向けのスタイルとブロックの改善

テーマ開発者向けのスタイルとブロックの改善

単一ブロックインスタンスへの擬似状態スタイルの適用

Gutenberg 23.3では、個別のブロックインスタンスに対して :hover:focus:visited といった擬似状態のスタイルを設定できるようになった。これまではサイト全体のブロックすべてに影響するスタイルしか設定できなかったが、この変更により、特定のボタンだけホバー時の色を変えるといった細やかな制御が可能になる。

この機能は、Add supports for pseudo states on single block instances というPRで実装されており、長年課題となっていたインタラクティブな状態の標準化に向けた動きとして注目されている。ボタンやリンク、ナビゲーションのデザインにこだわるテーマ制作者は、Gutenbergでテストしてみるとよい。

レスポンシブ対応のスタイル状態がさらに拡張

レスポンシブかつ状態を考慮したスタイル設定は、Gutenberg 23.2と23.3で大きく前進した。23.2ではグローバルなブロックスタイルに状態付きのレスポンシブ設定が導入され、23.3ではレイアウトのレスポンシブスタイルや、状態選択時に一部のコントロールを隠すUI調整が加えられている。

まだGutenbergプラグインでのテスト段階だが、theme.jsonのプリセットや設定、レイアウトプリセット、ブロックサポート、カスタムレスポンシブコントロールに依存しているテーマにとっては影響が大きいため、Responsive style states for blocks 、 iteration for WP 7.1 のIssueを追いかけておくとよい。

その他テーマ向けのブロックアップデート

細かいが実務に効く変更もいくつか入った。グローバルスタイルのカラーパネルでスラッグベースの色選択が統合され、ホームリンクブロックに不足していたコントロールが追加された。パンくずブロックでは視覚的な区切り文字がスクリーンリーダー向けに非表示となり、ナビゲーションでは非推奨化された block_core_navigation_submenu_render_submenu_icon() 関数のシムが復活している。画像ブロックでは幅か高さの片方だけが設定された場合に出力が崩れる問題も修正された。

また、WordPress 7.0では著者アーカイブリンクのデフォルトの title 属性(「Posts by Author」)が削除されている。マークアップのわずかな変更だが、テーマの表示テストやスナップショットテストに影響する可能性があるため注意しておきたい。

WordPress Playgroundの最新動向

WordPress Playgroundの最新動向

wp-nowが非推奨に、Playground CLIへの移行を

ローカル環境を手早く立ち上げるために wp-now を使っていた開発者は、Playground CLIへの移行が必要になる。Developer WordPress Newsの記事によると、2026年6月8日付でwp-nowが非推奨となり、今後の推奨パスはPlayground CLIに一本化された。

移行は比較的スムーズに行えるよう設計されており、テスト用サイトを素早く立ち上げたいプラグイン開発者やテーマ制作者は、早めに切り替えておくとよいだろう。

PRプレビューとPHPスニペットの公式ガイド

Playground関連では、2つの役立つガイドも公開された。ひとつは「PR Preview with WordPress Playground: What changes in version 3 of the GitHub Action」で、プルリクエストのプレビューを自動化するGitHub Actionの最新バージョンについて解説している。プロジェクトでPlaygroundプレビューを利用しているなら、一度目を通しておきたい内容だ。

もうひとつは「Run PHP examples anywhere with WordPress Playground」で、WordPressの開発者向けドキュメントやチュートリアルに、ブラウザ上で実行可能なPHPサンプルを埋め込む方法を紹介している。技術記事を書く立場の開発者にとって、この手法は読者の理解を大きく助ける強力な武器になる。

保存型Playgroundと古いWordPressバージョンの復元

Playground v3.1.35およびv3.1.36では、サイトの保存とSites APIの機能が大きく進んだ。保存したブラウザ上のWordPressサイトに何度も戻れる永続化の仕組み、自動保存からの復元UX、埋め込みPlaygroundでの不要な保存プロンプト回避などが実装されている。

さらに、WordPress 0.7 のような過去のバージョンを丸ごとロードできるようになり、Virtual WordPress Museum のようなデモも登場した。デモやテスト、教育目的の用途が一層広がる変更といえる。

PHP.wasmによる高度なデモやフレームワーク対応

PHP.wasm周辺の開発も活発だ。新しい「Running PHP Frameworks in Playground」ガイドでは、WordPress以外のPHPフレームワークをPlayground上で動かす方法が示されており、ブラウザベースのツール構築の可能性を大きく広げている。また、@php-wasm/compile-extension ワークフローにより、PHP拡張のコンパイルも以前より容易になった。高度なデモやドキュメント用のサンプルを作る開発者には、これらの進歩も見逃せない。

ユーザーインターフェースとアクセシビリティの改良

ユーザーインターフェースとアクセシビリティの改良

実験的なダッシュボードのカスタマイズ機能がウィジェットを追加

カスタマイズ可能なダッシュボードはまだ実験段階だが、Gutenberg 23.3では新たに5つのウィジェット(サイトヘルス、ニュース、イベント、クイックドラフト、サイトプレビュー/URLバー)が追加され、レイアウトの調整も進んだ。ゴーストウィジェットやサイズプリセット、コンテナブレークポイントによるグリッドカラムなど、徐々に実用性が高まっている。

管理者画面の拡張やプラグイン独自の管理パネルを開発しているなら、この実験がどこに向かっているのかを customizable dashboard overview issue で追いかけておくことをおすすめする。

エディターと管理画面でのアクセシビリティの磨き込み

GutenbergとCoreの両方でアクセシビリティ関連の改善が続いている。Gutenberg 23.3ではリビジョン機能が改善され、フォントライブラリのフォーカスナビゲーションも修正された。Core側では、管理画面のカラースキームのコントラスト強化、フロントエンドツールバーのフォーカスアウトライン修正、ハイコントラストモード時のボタンアクティブ状態の不具合対応などが行われている。

カスタム管理画面やエディターパネル、メディア操作UIを提供している場合は、キーボード操作、ハイコントラストモード、文字サイズの拡大設定、標準以外の管理画面カラースキームを組み合わせたテストを定期的に実施することが重要だ。

この記事のポイント

  • メディア編集はモーダルに集約され、クライアントサイド画像処理の実験的テストも始まった。サーバー負荷の低減とUX向上が見込まれる
  • React 19移行は一時停止中だが、WordPress 7.1に向けた準備は継続。プラグイン開発者は互換性を確認しておく
  • テーマ開発では、単一ブロックへの擬似状態スタイル適用やレスポンシブスタイルの拡張など、表現力が高まる変更が多い
  • PlaygroundはCLIへの一本化、保存型サイトの強化、過去バージョン対応などで開発者の実験環境が飛躍的に便利になった
  • アクセシビリティの改良も着実に進行。カスタムUIを作るならテストにキーボード操作やハイコントラストモードを含める
OptinMonsterなど4プラグインのサプライチェーン攻撃、不正管理者を確認する手順

OptinMonsterなど4プラグインのサプライチェーン攻撃、不正管理者を確認する手順

OptinMonster、TrustPulse、PushEngage、Uncanny Automator のいずれかのプラグインを導入している場合、ただちに管理画面の全ユーザー一覧を確認し、身に覚えのない管理者アカウントが作成されていないか点検する必要がある。これらのプラグインに使用されている CDN スクリプトが改ざんされ、悪意ある管理者を自動生成するサプライチェーン攻撃が 2026 年 6 月に確認された。

何が起きたのか 今回のサプライチェーン攻撃の仕組み

何が起きたのか 今回のサプライチェーン攻撃の仕組み

攻撃者はプラグインのソースコードそのものを改変したわけではなく、各プラグインが配信に利用している外部 CDN 上のスクリプトファイルに細工を施した。このため、プラグイン自体のバージョンアップや通常のマルウェアスキャンでは異常を検知しにくいのが特徴だ。

改ざんされたスクリプトは、サイトのフロントエンドに読み込まれる形で実行され、裏側で WordPress のユーザー登録 API を突いて新規の管理者アカウントを作成する。攻撃者がすでに管理者権限を取得している場合、サイトの改ざんや情報の窃取が自由に行える極めて危険な状態となる。

国内の WordPress サイトでも、マーケティングツールとして該当プラグインを導入しているケースは少なくない。攻撃が表面化した時点で、該当プラグインの開発元はすでに CDN 側の改ざんを修正し、侵害された可能性のある顧客への通知を進めているが、すべてのサイト運営者が自らチェックを行うことが被害の深刻化を防ぐうえで決定的に重要だ。

攻撃前
プラグインが正常な CDN スクリプトを配信している。
サイトに悪意ある管理者は存在しない。
攻撃中
CDN 上のスクリプトが改ざんされる。
サイト訪問時に不正スクリプトが実行され、未知の管理者アカウントが自動生成される。
修正後
CDN の改ざんは解除され、不正ユーザーの削除と全パスワード再設定が必須。
改ざん発生時  攻撃の実行  対処後

自分は対象か 影響を受けるプラグインを導入していないか確認する

自分は対象か 影響を受けるプラグインを導入していないか確認する

今回のサプライチェーン攻撃の対象として報告されたのは次の 4 製品だ。いずれか 1 つでも導入している場合は、影響を受けた可能性を前提に全手順を実行する必要がある。

  • OptinMonster(オプティンモンスター)
  • TrustPulse(トラストパルス)
  • PushEngage(プッシュエンゲージ)
  • Uncanny Automator(アンキャニーオートメーター)

プラグイン一覧ページでこれらの名称を検索すれば、導入の有無はすぐに判別できる。ただし、テーマの functions.php に直接コードを埋め込んでいる場合や、カスタム実装で CDN スクリプトを読み込んでいる場合はプラグイン管理画面では発見できないため、サイトのソースコードやタグマネージャーの設定も併せて確認するとより確実だ。

不正な管理者アカウントを特定して削除する手順

不正な管理者アカウントを特定して削除する手順

まず管理画面の「ユーザー」→「ユーザー一覧」を開き、管理者権限を持つアカウントをすべて確認する。身に覚えのない管理者アカウントが存在する場合は、そのアカウントが攻撃によって作成された可能性が極めて高い。

STEP 1 「ユーザー」→「ユーザー一覧」を開き、管理者ロールのアカウントをすべて書き出す。
STEP 2 心当たりのないアカウントがあれば、そのユーザーを即時削除する。
STEP 3 正当な管理者を含むすべてのユーザーのパスワードを強制的にリセットする。
STEP 4 「設定」→「一般」で WordPress アドレスとサイトアドレスに不審な変更がないか確認する。

削除時に「投稿の所有権」をどうするか

不正な管理者を削除する際、WordPress はそのユーザーが作成した投稿の帰属先を尋ねてくる。該当ユーザーが攻撃者である場合、そのアカウントが作成した投稿そのものも悪意あるコンテンツであることが多いため、すべて「削除」を選択して問題ない。もし誤って残す必要がある場合のみ、正当な管理者に帰属を変更する。

不正な管理者アカウントがゼロでも油断できない理由

攻撃スクリプトは任意のタイミングで管理者を作成する仕組みになっている。現在のユーザー一覧に不審点がなくても、改ざんされた CDN スクリプトが過去に読み込まれたことがあれば、攻撃者がすでにアクセストークンや認証情報を窃取している可能性を排除できない。必ず後述の予防措置まで実行する必要がある。

感染後のサイトを安全な状態に戻すために今すぐやるべきこと

感染後のサイトを安全な状態に戻すために今すぐやるべきこと

該当プラグインを完全に削除して再インストールする

単なる無効化では不十分だ。該当プラグインを一度完全に削除し、公式リポジトリまたは開発元から最新版をダウンロードして再インストールする。これにより、仮に攻撃者がプラグインの管理画面内に保存していた設定値や隠しコードを仕込んでいたとしても、完全に除去できる。

全ユーザーのパスワードをリセットし多要素認証を有効にする

攻撃者がすでに正当なユーザーのログイン情報を盗んでいる可能性を想定し、サイトの全ユーザー(特に管理者・編集者権限)のパスワードを変更する。加えて多要素認証(二段階認証)をただちに有効にし、パスワード単体ではログインできない設定に切り替えることが再侵入の防止に直結する。

WP ソルトキーを強制的に無効化する

wp-config.php に定義されている認証用のソルトキー(AUTH_KEY、SECURE_AUTH_KEY、LOGGED_IN_KEY、NONCE_KEY とそれぞれの SALT)をすべて新しい値に置き換える。これで既存のすべてのログインセッションが即座に無効になり、攻撃者が盗んだクッキーではアクセスできなくなる。WordPress の公式ソルト生成ツールを使えば、ランダムな値がすぐに発行できる。

.htaccess や wp-config.php に仕込まれたバックドアを点検する

管理者権限を取得した攻撃者は、テーマファイルやプラグインファイルを編集してバックドアを仕込むことが多い。特に functions.php や wp-config.php、.htaccess に不自然なコードが追記されていないかを FTP またはサーバー管理画面のファイルマネージャーで直接確認する。見慣れない base64 デコード処理や eval 関数を含むコード、不明な外部 URL へのリクエストがあれば攻撃の痕跡だ。

なぜ通常のウイルススキャンでは検知されなかったのか

なぜ通常のウイルススキャンでは検知されなかったのか

一般的なセキュリティプラグインは、サーバー上の PHP ファイルやデータベースの不審なパターンをスキャンする。しかし今回の攻撃は、問題のあるコードがサイト外部の CDN 上にあり、ブラウザの JavaScript 実行を通じて攻撃が成立する仕組みだった。サーバー側のファイルに痕跡が残らないため、従来型のマルウェアスキャンでは検出が困難だった。

この手口が示しているのは、外部リソースに依存するプラグインは、その配信網が侵害された場合にプラグイン本体の安全性とは無関係に危険になりうるという現実だ。CDN から読み込まれるスクリプトに対しては、Subresource Integrity(SRI)属性による改ざん検知が有効だが、これを実装しているプラグインは現状ほとんど存在しないことも今回の問題を深刻にした。

再発を防ぐために導入すべき具体的な対策

外部 CDN スクリプトを監視する仕組みを整える

すべての外部スクリプトをやみくもに拒否するのは現実的ではないが、コンテンツセキュリティポリシー(CSP)ヘッダーを適切に設定することで、どの CDN からのスクリプト実行を許可するかを明示的に制御できる。許可リストにないドメインからのスクリプトはブラウザ側でブロックされるため、未知の改ざんが発生した場合の被害を抑える障壁になる。

管理者ユーザーの監査ログを定期的に確認する

新しい管理者の追加や権限変更を記録する監査ログプラグインを導入しておけば、今回のように見知らぬアカウントが作成されたときに即座に気づける。攻撃が CDN 経由で行われたとしても、サーバー側でユーザーが作成される瞬間をログに残すことができるため、異常検知の有効な補助線になる。

利用プラグインの外部依存関係を定期的に見直す

導入済みのすべてのプラグインが、どの外部ドメインに対してリクエストを送っているかを定期的に棚卸しする習慣をつけると、今回のようなサプライチェーンリスクの芽を早期に見つけやすくなる。プラグインがバックグラウンドで読み込んでいる CDN スクリプトや API エンドポイントを把握していれば、問題発生時に影響範囲を素早く特定できる。

よくある質問

該当プラグインを無効にしただけで安全といえるか

安全とはいえない。改ざんされたスクリプトが過去に読み込まれた時点ですでに不正な管理者が作成されている可能性がある。無効化では既存の被害は解消されず、削除と再インストール、およびユーザー一覧の精査が必須になる。

不正な管理者が見つからなかった場合でも何かすべきことはあるか

全ユーザーのパスワードリセットとソルトキーの変更は必ず実行する。改ざんスクリプトが認証クッキーやアクセストークンを窃取していた場合、攻撃者は管理者アカウントを作らずとも正当なユーザーとしてログインできる可能性があるためだ。

これらのプラグインは今後も使い続けても大丈夫か

各開発元はすでに CDN の改ざんを修正し、再発防止策を強化している。しかしどのプラグインでも外部依存がある以上、同様のリスクをゼロにすることは不可能だ。使用を継続する場合は、この記事で述べた監視と予防の仕組みを併せて導入することが前提になる。

WordPress 本体や他の無関係なプラグインまで影響を受けるのか

今回の攻撃は対象プラグインの CDN スクリプト経由でのみ実行された。ただし管理者権限を奪取された後は、WordPress 本体や他のプラグインを含め、サイト全体が改ざん対象になりうる。該当プラグインを使用していた場合は、サイト全体のファイル整合性チェックを併せて行うとよい。

この記事のポイント

  • OptinMonster、TrustPulse、PushEngage、Uncanny Automator 利用者は要緊急対応
  • 不正な管理者アカウントの有無を「ユーザー一覧」で即座に確認する
  • 該当プラグインの完全削除と再インストールで痕跡を除去する
  • 全ユーザーパスワードのリセットとソルトキー変更が防御の基本線
  • CSP 設定と管理者監査ログで将来の類似攻撃に備える
JavaScriptがログアウト時に動かない原因と直し方

JavaScriptがログアウト時に動かない原因と直し方

管理画面にログインしているときだけ JavaScript が動き、ログアウトすると止まる。この現象の原因は、ほぼ「スクリプトの読み込み順序」と「キャッシュ・最適化プラグインの挙動」のどちらか、あるいは両方の組み合わせだ。ログイン時は管理バー用のスクリプト等が読み込まれるため依存関係が偶然成立し、ログアウト時にそれが外れてエラーになるケースが多い。

ログアウト時だけ JavaScript が動かなくなる仕組み

ログアウト時だけ JavaScript が動かなくなる仕組み
ログイン時(動作する)
jQuery 管理バー用JS スライダーJS
管理バー用のスクリプトが jQuery を読み込むため、後続のスライダーが依存できている
ログアウト時(動作しない)
jQuery 未読込 スライダーJS エラー
管理バーが無いため jQuery が読み込まれず、スライダーの処理が失敗する
ログイン時  ログアウト時

このデモは典型的な依存関係の崩れを示している。ログイン中は WordPress が管理バーやフッターに jQuery を読み込むため、その後に記述されたスクリプトが偶然動く。ログアウトすると jQuery が存在せず、$ is not definedjQuery is not defined といったエラーで止まる。

HTML ブロックに直接書いた JavaScript が招く問題

HTML ブロックに直接書いた JavaScript が招く問題

WordPress の「カスタム HTML」ブロックに <script> タグを直書きする方法は、一見手軽だが制御が難しい。出力される位置がテーマやブロック配置に依存し、jQuery などのライブラリより前に実行されれば必ず失敗する。さらにインラインスクリプトは多くのキャッシュプラグインで最適化対象から外されたり、結合・遅延読み込みの対象にならず、ログアウト時だけ二重に不利な状況を生む。

HTML ブロック直書きスクリプトの3つの弱点

  • 読み込み順序を制御できない(テーマの render 順に依存する)
  • jQuery の依存関係を WordPress に伝えられない
  • キャッシュ・圧縮プラグインがスクリプトとして認識しない場合がある

ログアウト時でも動くようにする正しい組み込み手順

ログアウト時でも動くようにする正しい組み込み手順

原則は「JavaScript は HTML ブロックに直書きせず、WordPress の仕組み(wp_enqueue_script)で読み込む」ことだ。すでに直書きで動いているものを移行するには、以下の手順で進める。

STEP 1 既存の script タグの中身を別ファイルに切り出す
STEP 2 functions.php で wp_enqueue_script を使い、jQuery 依存を明示する
STEP 3 $ の衝突回避のため即時関数または noConflict でラップする
STEP 4 キャッシュプラグインの設定を見直し、スクリプトを除外する

STEP 1 既存の script タグを外部ファイルに移す

HTML ブロック内の <script>〜</script> 部分だけを抜き出し、子テーマのフォルダ内に testimonial-slider.js のような名前で保存する。<script> タグそのものは不要で、中身のコードだけを移す。HTML ブロックにはスライダーの構造(ul や div のマークアップ)だけを残す。

STEP 2 functions.php で安全に読み込む

子テーマの functions.php に以下のコードを追加する。管理画面ではなくフロントエンドだけに読み込ませるために wp_enqueue_scripts フックを使う。依存関係として jquery を指定すれば、WordPress 本体の jQuery が先に読み込まれてから実行される。

function my_testimonial_slider_script() {
    wp_enqueue_script(
        'testimonial-slider',
        get_stylesheet_directory_uri() . '/testimonial-slider.js',
        array('jquery'),
        '1.0.0',
        true
    );
}
add_action('wp_enqueue_scripts', 'my_testimonial_slider_script');

最後の引数 true はフッターで読み込む指定だ。スライダーの DOM 要素が本文中に存在する場合はフッター読み込みで問題ない。もしスライダーを本文より前に実行する必要があるなら false にしてヘッダーで読ませるが、多くのケースではフッターで十分だ。

STEP 3 $ の衝突を防ぐ

WordPress の jQuery は noConflict モードで動作しているため、$ がそのまま使えない環境がある。古いコードを流用している場合は $ is not a function エラーが起きやすい。回避策として、外部ファイル全体を即時実行関数で囲み、引数で $ を受け取る記法が安全だ。

(function($) {
    $(document).ready(function() {
        // ここにスライダーのコード
    });
})(jQuery);

STEP 4 キャッシュプラグインでスクリプトを除外する

ここまで対応しても直らない場合、キャッシュや最適化プラグインが原因の可能性が高い。ログアウト時はページキャッシュが有効になり、スクリプトの遅延読み込みや結合が適用される。自前の testimonial-slider.js をこれらの処理から除外する必要がある。

プラグインの設定画面で「スクリプトの除外」「遅延読み込みの除外」といった項目を探し、testimonial-slider(ハンドル名)または testimonial-slider.js(ファイル名の一部)を指定する。除外後は必ずキャッシュを全削除してからログアウト状態で確認する。

Elementor のフックやテーマのアクションフックを使った場合の注意点

Elementor のフックやテーマのアクションフックを使った場合の注意点

テーマ付属のフック(GeneratePress の Element など)に HTML ブロックごと差し込む方法も考えられるが、根本的にはスクリプトの読み込み順序問題は同じだ。フックで出力する位置を変えても、jQuery より前に呼ばれるリスクは残る。フックを使う場合でも、スクリプト部分は wp_enqueue_script に任せ、フックにはマークアップだけを出力する形が堅実だ。

Elementor Pro の「カスタムコード」機能を使っているなら、その中に script タグを書くのではなく、同様に子テーマのファイルとして切り出してハンドル登録するほうが制御できる。どうしても直書きが必要なら、カスタムコードの「場所」設定を「本文の終了タグ直前」にし、さらにコード内で jQuery を明示的に使う($ を使わない)ことでエラーを減らせる。

よくある質問

コンソールに「$ is not defined」と出るがどう直せばいいか

jQuery が読み込まれる前に $ を使っているか、noConflict モードで $ が無効になっている。即時関数で (function($) { ... })(jQuery); とラップし、すべての $ をこのスコープ内に収めれば解決する。

functions.php を編集せずに直す方法はあるか

「WPCode」などのコードスニペット管理プラグインを使えば、管理画面から wp_enqueue_script のコードを登録できる。functions.php を直接触りたくない場合の現実的な代替手段だ。スニペットの実行場所を「フロントエンドのみ」に設定するのを忘れないようにする。

キャッシュを削除しても直らないのはなぜか

ブラウザキャッシュだけを消していて、サーバー側のページキャッシュや CDN キャッシュが残っているケースが多い。WordPress のキャッシュプラグインの「すべてのキャッシュを削除」を実行し、さらに CDN を使っている場合はその管理画面からもパージする。シークレットウィンドウで確認するとブラウザキャッシュの影響を除外できる。

スライダーのマークアップだけ残して script を外したら表示が消えた

新しく作った JS ファイルが正しく読み込まれていない。ブラウザの開発者ツールの「ネットワーク」タブで testimonial-slider.js が 200 番で返っているか確認する。404 ならパスが間違っている。読み込まれているのに動かない場合は、コンソールに別のエラーが出ていないか調べる。

この記事のポイント

  • ログアウト時だけ JavaScript が動かない原因は、jQuery の依存切れとキャッシュ最適化の複合
  • HTML ブロックへの script 直書きは読み込み順序を制御できず、根本対策にならない
  • wp_enqueue_script で jQuery 依存を明示し、外部ファイルとして切り出すのが正攻法
  • 即時関数で $ の衝突を防ぎ、キャッシュプラグインでは独自スクリプトを除外対象に追加する
  • Elementor やテーマフックを使う場合も、スクリプトだけは enqueue に任せる設計が堅実

特定商品ブロックを設置した固定ページでfatal errorが発生する問題の直し方

特定商品ブロックを固定ページに配置したときに「Uncaught Error Call to a member function get_id() on null」というfatal errorが表示されるのは、PreCart for WooCommerce のバグが原因だ。プラグインを最新バージョンへ更新するか、functions.php へ一時的な修正コードを追加すれば直る。

なぜ固定ページ上の商品ブロックで fatal error が起こるのか

なぜ固定ページ上の商品ブロックで fatal error が起こるのか

PreCart は WooCommerce の商品情報を扱うフィルターフック(woocommerce_product_add_to_cart_text など)にコールバック関数を登録し、その中で global $product から商品オブジェクトを取得して $product->get_id() を呼び出している。しかし、ブロックエディタで「特定商品」ブロックを通常の固定ページに配置すると、WooCommerce のブロック表示パイプラインではグローバル変数 $product が null のままフィルターが走るケースがある。PreCart のコードには null チェックがないため、null に対して get_id() を呼び出してしまい、致命的なエラーでページ全体が落ちる。

STEP 1 固定ページに「特定商品」ブロックを追加し任意の商品を選択
STEP 2 WooCommerce ブロック描画時に PreCart のフィルターが発火
STEP 3 グローバル変数 $product が null のままコールバックが実行される
STEP 4 $product->get_id() で致命的エラー発生(画面が真っ白になる)

影響を受けるメソッドは change_add_to_cart_text()display_pre_order_messgae()display_pre_order_badge() など、いずれも保護コードがない。WooCommerce の商品ブロックを店舗ページ以外で使っているサイトはすべてこの問題に遭遇し得る。

PreCart を更新してエラーを解消する手順

PreCart を更新してエラーを解消する手順

開発元はこの問題を認識しており、すでに修正アップデートがリリースされている。まずは管理画面からプラグインを最新版に上げるのが最も安全で確実な対処法だ。

STEP 1 WordPress 管理画面へログインし「プラグイン」→「インストール済みプラグイン」を開く
STEP 2 PreCart for WooCommerce に更新通知が出ていたら「今すぐ更新」をクリック
STEP 3 サイトのキャッシュ(プラグインキャッシュ、サーバーキャッシュ)をすべて削除
STEP 4 問題のあった固定ページをフロントエンドで再度開き、エラーが出ないことを確認

更新通知が表示されない場合

「ダッシュボード」→「更新」から更新の再確認を行うか、PreCart のプラグインページで一度「プラグインを削除」→ 公式リポジトリから再インストールする方法もある。ただしこの場合、設定がリセットされる可能性があるため、事前に PreCart の設定をメモしておくかエクスポート機能があれば使っておくと安心だ。

functions.php で null チェックを追加して一時的に対処する方法

functions.php で null チェックを追加して一時的に対処する方法

どうしてもすぐにプラグインを更新できない場合や、何らかの理由で更新後に問題が残る場合は、テーマの functions.php にフックを追加して一時的にエラーを回避できる。

/**
 * PreCart の null チェック不足による fatal error を回避(一時的対応)
 */
add_filter( 'woocommerce_product_add_to_cart_text', function( $text, $product ) {
    if ( ! $product || ! is_a( $product, 'WC_Product' ) ) {
        return $text;
    }
    // 以下は原本の処理が走るが、早期リターンで保護
    return $text;
}, 1, 2 );

add_filter( 'woocommerce_single_product_summary', function() {
    global $product;
    if ( ! $product || ! is_a( $product, 'WC_Product' ) ) {
        return;
    }
    // 同様に早期リターン
}, 1 );

上記のコードは PreCart が使っているのと同じフックに、より優先度の高いコールバック(優先度 1)で null チェックを追加し、商品オブジェクトが存在しないときは処理を打ち切る仕組みだ。PreCart のフィルターよりも先に実行されるため、致命的エラーに至る前に関数を抜けられる。

Before(危険)
global $product;
$product->get_id();
null チェックがないためエラー
After(安全)
if ( ! $product || ! is_a( $product, ‘WC_Product’ ) ) { return; }
$product->get_id();
null のときは早期リターン
修正前  修正後

functions.php 編集時の注意点

子テーマを使っていない場合、テーマ更新で修正が上書きされるリスクがある。必ず子テーマの functions.php にコードを追加するか、Code Snippets プラグインでコードを管理するのが望ましい。また、この一時対応はあくまで応急処置であり、PreCart の他の機能が正常に動作しない可能性もゼロではない。早めに公式アップデートを適用して、追加コードは削除する。

手動修正後に確認しておきたいポイント

手動修正後に確認しておきたいポイント
  • 一時的なコードを追加した後、サイトの表示速度やエラーログに変化がないか定期的にチェックする
  • PreCart の機能(カート追加テキストの変更や予約注文バッジなど)が期待どおり動作しているかテストする
  • PHP のエラーログを確認し、別の箇所で同様の null 参照エラーが隠れていないか調べる
  • サイト全体のキャッシュをクリアし、CDN を利用している場合は CDN キャッシュも破棄する
  • PreCart の更新が確認できたら必ずプラグインを最新版に上げ、追加コードを削除する

よくある質問

PreCart 以外のプラグインでも同じように商品ブロックでエラーが出ることはありますか

ある。WooCommerce のブロックを通常ページで使うと、$product グローバルを正しく取り扱っていない他の拡張プラグインでも同様の null 参照エラーが起きるケースが報告されている。エラーの文面に別のプラグイン名が含まれている場合は、そちらの開発元へ報告しつつ、同じように functions.php で早期リターンを追加すれば応急回避できることが多い。

WooCommerce の商品ブロックを固定ページで使うこと自体は問題ないのでしょうか

WooCommerce のブロックは基本的に店舗ページや商品ページで使うことを想定しているが、WordPress の標準ブロックとして技術的にはどの投稿タイプでも利用できる。プラグインがグローバル変数の有無を適切にハンドリングしていれば固定ページで使っても問題は起きない。ただ、テーマやプラグインが認めるまで、動作確認は入念に行ったほうがよい。

エラーメッセージが表示されずに画面が真っ白になる場合はどうすればよいですか

WordPress が致命的エラーを表示しない設定(WP_DEBUG が false)のときは、管理画面のメールに送られる復旧モード用のリンクを探すか、サーバーの PHP エラーログを確認する。wp-config.php で define('WP_DEBUG', true); を一時的に有効にすれば、画面上にエラー詳細が表示され、原因を特定しやすくなる。なお、本番環境ではデバッグモードをすぐに無効に戻すこと。

管理画面にも入れなくなってしまった場合はどうすれば直りますか

FTP またはレンタルサーバーのファイルマネージャーで /wp-content/plugins/precart/ ディレクトリの名前を一時的に変更(例:precart_deactivated)すれば、プラグインが無効化されて管理画面に再ログインできる。その後、前述の更新や一時コードで対処し、ディレクトリ名を元に戻す。

この記事のポイント

  • 固定ページに WooCommerce 商品ブロックを配置したときの fatal error は PreCart の null チェック不足が原因
  • 解決策は PreCart プラグインの最新版への更新が最も安全で確実
  • すぐに更新できない場合は、functions.php にフックで早期リターンを追加すれば応急回避できる
  • functions.php 編集は子テーマで行い、アップデート後は必ず追加コードを削除する
  • 管理画面に入れなくなったら FTP でプラグインフォルダ名を変更し無効化する
AI EngineとJetpackが衝突してGeminiが使えない時の解決策

AI EngineとJetpackが衝突してGeminiが使えない時の解決策

AI Engine プラグインをバージョン 3.5.5 以降にアップデートすれば、この問題は即座に解決する。根本原因は Jetpack が REST API に追加する整数型 enum フィールドを、Google Gemini がツール定義で拒否していたことにある。AI Engine の開発者がこのスキーマ生成ロジックを修正し、文字列型以外の enum を自動除去するようになった。

どのようなエラーが発生するのか

どのようなエラーが発生するのか
エラー発生時 AI Engine が Gemini に送るツール定義に Jetpack の整数 enum が混入
修正後 AI Engine が文字列型以外の enum を自動除去してからツールリストを生成
エラー状態  修正後

Desktop Commander で AI Engine を MCP サーバーとして管理モードで接続し、AI モデルに Google Gemini を指定すると、次のようなエラーで通信が失敗する。

「GenerateContentRequest.tools[0].function_declarations[30].parameters.properties[jetpack_publicize_connections].items.properties[status].enum: only allowed for STRING type」という趣旨のエラーが返る。翻訳すると「enum は STRING 型にしか使えない」という厳格な制約に違反した形だ。

管理画面では具体的に「AI Engine が Gemini API からの応答に失敗しました」といった形で表示され、チャットが開始できないか、途中で止まる。管理モードでなければ発生しないエラーだ。

なぜ Jetpack と AI Engine が衝突するのか

なぜ Jetpack と AI Engine が衝突するのか

核心は Google Gemini API の「ツール定義」に対する極めて厳格なバリデーションにある。Gemini は利用可能な関数のパラメータをスキーマで受け取るが、enum(許容値の固定リスト)を使う場合、そのデータ型を必ず文字列にしなければならない。

一方 Jetpack は、WordPress の投稿作成や更新時に使われる REST API エンドポイントへ、ソーシャルメディア連携用のフィールドを動的に追加している。その中の jetpack_publicize_connections フィールドには status というパラメータがあり、Jetpack はこれを整数型の enum([0, 1])として定義している。

AI Engine が WordPress のスキーマ全体を走査して Gemini 向けのツールリストを組み立てる際、この整数型 enum をそのまま継承してしまう。その結果、Gemini API がリクエスト全体を「400 Bad Request」ではねつける流れだ。

読み取り専用モードならば投稿作成系のツールが含まれないため、このエラーは発生しない。管理モードで書き込み権限を付与する場合に限って表面化する。

AI Engine 3.5.5 以降へのアップデートで恒久修正する

AI Engine 3.5.5 以降へのアップデートで恒久修正する

AI Engine の開発者によって、バージョン 3.5.5 で根本的な修正が加えられた。ツールスキーマを作成する際、文字列型以外の enum 定義を自動的に除去する処理が追加されている。

STEP 1 WordPress 管理画面から AI Engine を最新版(3.5.5 以上)に更新する
STEP 2 更新後、新しいチャットを管理モードで開始する
STEP 3 Gemini が正常に応答すれば修正完了

スキーマキャッシュのバージョンも同時に引き上げられているため、更新後に手動でキャッシュをクリアする必要はない。自動的に再生成され、Jetpack の整数型 enum は除去された状態でツールリストが構築される。

どうしてもアップデートできない場合の手動修正

何らかの理由で AI Engine を最新版にできない場合、子テーマの functions.php または Code Snippets プラグインに以下のコードを追加し、Jetpack の整数型 enum フィールドを強制的に文字列型へ変換できる。

<?php
/**
 * Jetpack と AI Engine、Google Gemini の競合を修正する。
 * Jetpack の status enum フィールドを文字列型に変換する。
 */
add_action( 'wp_enqueue_scripts', 'enqueue_parent_styles' );
function enqueue_parent_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
}

add_action( 'rest_api_init', 'fix_jetpack_enum_for_gemini', 9999 );
function fix_jetpack_enum_for_gemini() {
    global $wp_rest_additional_fields;

    if ( ! empty( $wp_rest_additional_fields ) ) {
        foreach ( $wp_rest_additional_fields as $post_type => $fields ) {
            if ( isset( $wp_rest_additional_fields[$post_type]['jetpack_publicize_connections'] ) ) {
                if ( isset( $wp_rest_additional_fields[$post_type]['jetpack_publicize_connections']['schema']['items']['properties']['status'] ) ) {
                    // 問題を起こす整数 enum を除去
                    unset( $wp_rest_additional_fields[$post_type]['jetpack_publicize_connections']['schema']['items']['properties']['status']['enum'] );
                    // データ型を文字列に明示
                    $wp_rest_additional_fields[$post_type]['jetpack_publicize_connections']['schema']['items']['properties']['status']['type'] = 'string';
                }
            }
        }
    }
}
?>

コード追加だけでは修正されないケースがある。AI Engine はツールリストをデータベースに強力にキャッシュしているため、キャッシュを強制的に再生成させる必要がある。

STEP 1 プラグイン一覧から Jetpack を一時的に無効化する
STEP 2 AI Engine で新しい管理モードチャットを開き、簡単な質問を送信する
STEP 3 Jetpack を再有効化する。以降 PHP フィルタがスキーマを清浄に保つ

Jetpack を無効化した状態でチャットを実行することで、AI Engine は Jetpack 関連フィールドのないスキーマを新規に作成する。Jetpack を再有効化した後は上記のフィルタが働き、問題の enum がスキーマに混入することはなくなる。

よくある質問

Jetpack を使っていなければこの問題は起こらないのか

Jetpack の jetpack_publicize_connections フィールドが原因であるため、Jetpack を導入していなければ発生しない。ただし、他のプラグインも整数型 enum を REST API に追加している場合は似たエラーが出る可能性がある。その場合も AI Engine 3.5.5 以降であれば同様に自動除去される。

読み取り専用モードではなぜ問題ないのか

読み取り専用モードでは、投稿の作成や更新といった書き込み系のツールが Gemini に送信されない。問題の jetpack_publicize_connections フィールドは投稿作成時に登場するため、ツールリストから除外される。管理モードだけが影響を受ける。

AI モデルが Gemini 以外でも同じエラーは出るか

このエラーは Gemini のツール定義バリデーションが特に厳格なために発生する。OpenAI の GPT シリーズなど、他の AI モデルでは整数型 enum を許容するものもあるが、根本原因はスキーマにあるため、どのモデルでも潜在的な問題になりうる。AI Engine 3.5.5 の修正で全モデルに対応できる。

AI Engine 3.5.5 にアップデートした後、スキーマキャッシュは本当に自動クリアされるのか

開発者によれば、スキーマキャッシュのバージョンナンバーが引き上げられているため、更新後の初回リクエスト時に自動的に再生成される。手動でキャッシュを削除する操作は不要。もし不安があれば、AI Engine の設定画面からキャッシュを手動クリアしても問題ない。

この記事のポイント

  • AI Engine 3.5.5 以降のアップデートで根本解決する
  • 原因は Jetpack の整数型 enum を Gemini が拒否するため
  • 読み取り専用モードでは書き込み系ツールが送信されず問題は出ない
  • 手動修正する場合は Jetpack 一時無効化によるキャッシュ再生成が必須
  • 修正後は文字列型以外の enum が自動除去され、あらゆる AI モデルで安定する