Category Archive お悩み・トラブル解決

カートが0円だとWooCommerceの注文が完了しない時の直し方

なぜカート合計が0円だとチェックアウトが完了しないのか

なぜカート合計が0円だとチェックアウトが完了しないのか

WooCommerce の最低購入金額制御プラグイン(たとえば Minimum Purchase Amount Control など)は、指定した金額未満の注文を受け付けないように設計されている。このプラグインは通常、カートの合計金額が設定した最低金額を下回るとチェックアウトをブロックする。しかし「無料商品を許可する」「クーポンで0円になる場合を許可する」といった例外ルールを設定していても、内部的にはチェックアウト処理の最終段階で金額を再評価し、ブロックをかけてしまうケースがある。

このとき画面上では「注文する」ボタンを押せてしまい、一見すると購入が完了したように見える。ところが実際には注文データが正しく確定されず、商品がカートに取り残される。リダイレクト先の注文確認ページ(サンキューページ)にも遷移しない。プラグインを停止すると問題が消えることから、プラグインのゼロ円ブロック機能が直接の原因だ。

フィルターフックでゼロ円チェックアウトを許可する手順

フィルターフックでゼロ円チェックアウトを許可する手順

このプラグインには、ゼロ円の注文を許可するための専用フィルターフック ct_mpac_allow_zero_total が用意されている。このフックを有効にすれば、無料商品やクーポンで合計が0円になったカートでも問題なくチェックアウトが完了するようになる。

以下の手順では、子テーマの functions.php に数行のコードを追加する。子テーマを使っていない場合は、Code Snippets プラグインなどを利用しても同じ結果が得られる。

STEP 1 子テーマの functions.php を開く(外観 → テーマファイルエディター)
STEP 2 ファイル末尾に以下のコードを追加する
STEP 3 ファイルを更新して保存する
STEP 4 0円になる商品をカートに入れてチェックアウトをテストする

追加するコードは次のとおりだ。

add_filter( 'ct_mpac_allow_zero_total', '__return_true' );

この1行で、プラグインがゼロ円の注文を許可するようになる。__return_true は WordPress の組み込み関数で、単純に true を返す。フィルターにこれを渡すことで「常に許可する」という挙動に切り替わる仕組みだ。

Code Snippets プラグインを使う場合は、新規スニペットを追加し、上記のコードを貼り付けて「サイト全体で実行」に設定すればよい。

コード追加後も改善しない場合の確認ポイント

コード追加後も改善しない場合の確認ポイント

フィルター名がプラグインのバージョンと合っているか確認する

プラグインのバージョンアップによってフィルター名が変更されている可能性がある。プラグインの公式ドキュメントやソースコード内で apply_filters を検索し、最新のフック名を確認するのが確実だ。特にプラグイン名が似ている別の最低購入金額プラグインに乗り換えた場合は、フック名がまったく異なるため注意が必要になる。

キャッシュ系プラグインやサーバーキャッシュの影響を疑う

functions.php を更新したのに改善しない場合、WordPress のキャッシュプラグインやサーバーレベルのキャッシュ(OPcache など)が原因で変更が反映されていないことがある。キャッシュをすべてクリアし、さらにブラウザのシークレットモードで動作をテストしてみる。OPcache が効いているレンタルサーバーでは、ファイル更新から数分間は古いコードが動き続けるケースもある。

決済ゲートウェイ側のゼロ円制限を調べる

ごくまれに、WooCommerce の決済ゲートウェイ自体が0円のトランザクションを許可していない場合がある。プラグインの問題が解消されたあともチェックアウトが進まないときは、Stripe や PayPal などのゲートウェイ設定で「0円の注文を許可する」オプションが存在しないか確認する。テスト用に代金引換や銀行振込など、実決済を伴わないゲートウェイに切り替えて試すのも有効な切り分け方法だ。

よくある質問

このフィルターはどのプラグインに対応しているのか

ct_mpac_allow_zero_total は、主に「Minimum Purchase Amount Control for WooCommerce」系のプラグインで使われるフックだ。プラグインの作者が異なるとフック名も変わるため、必ず利用中のプラグインのドキュメントを参照してほしい。

フィルターを追加する以外の解決策はあるか

プラグインの設定画面で「無料商品を許可」「クーポン適用後の0円を許可」といったチェックボックスが用意されていれば、そちらを有効にするだけで直ることもある。設定が存在しない場合や、設定を入れても効かないときにフィルターを使うのが確実な方法だ。

ゼロ円の注文を許可するとセキュリティ上のリスクはあるか

意図した無料商品や割引クーポン以外で0円になるカートが発生しないよう、クーポンの利用条件や商品価格の設定を適切に管理していれば大きなリスクにはならない。ただし、テストや不正利用対策として、定期的に0円注文のログを確認する運用は推奨する。

子テーマを使わずにコードを追加する方法はあるか

Code Snippets プラグインや WPCode プラグインを利用すれば、テーマファイルを直接編集せずにフィルターフックを安全に追加できる。テーマのアップデートでコードが消える心配もなく、管理画面からオンオフを切り替えられるため、まずはこちらを試すのが安心だ。

この記事のポイント

  • WooCommerce の最低購入金額プラグインが0円の注文をブロックし、チェックアウトが完了しない
  • フィルターフック ct_mpac_allow_zero_totalfunctions.php に追加すればゼロ円注文を許可できる
  • Code Snippets プラグインを使えば子テーマの編集なしで安全にコードを追加可能
  • 改善しない場合はキャッシュのクリアや決済ゲートウェイの0円制限も確認する
データベース接続確立エラーの原因と復旧手順

データベース接続確立エラーの原因と復旧手順

「データベース接続確立エラー」でサイトがダウンした場合、まずはサーバー会社に連絡してデータベースサーバーの稼働状況を確認し、wp-config.php の接続情報を照合するのが最短の復旧手順だ。自分でできる対処は限られているため、慌てずに切り分けを進める。

なぜ「データベース接続確立エラー」が突然発生するのか

なぜ「データベース接続確立エラー」が突然発生するのか

このエラーは WordPress がデータベースに接続できないときに表示される。日本語環境では「データベース接続確立エラー」というメッセージが画面に表示され、サイト全体が表示できなくなる。原因は大きく4つに分けられる。

  • wp-config.php 内のデータベース名・ユーザー名・パスワード・ホスト名のいずれかが誤っている
  • データベースサーバー自体がダウンしている(サーバー障害・メンテナンス)
  • データベースサーバーは稼働しているが、負荷集中で応答不能になっている
  • データベースが破損している(テーブルクラッシュなど)

サイトを長期間触っていなかったのに突然エラーが出た場合は、サーバー側で MySQL や MariaDB のバージョンアップ、パスワード変更、セキュリティ設定の変更が行われた可能性が高い。WordPress 側の設定ファイルは変わらないまま、サーバー側の接続条件だけが変わることで不一致が起きる。

Before(エラー発生中)
ブラウザに「データベース接続確立エラー」が表示される
wp-config.php とデータベースの認証情報が不一致、または DB サーバーが停止
After(復旧後)
サイトが正常表示される
正しい接続情報で WordPress がデータベースにアクセスできる状態
エラー状態  復旧後

エラーが出たらまず試す3つの切り分け

エラーが出たらまず試す3つの切り分け
STEP 1 サーバー会社にデータベースサーバーの稼働状況を確認する
STEP 2 wp-config.php の接続情報をサーバー管理画面の値と照合する
STEP 3 phpMyAdmin などでデータベースに直接接続できるか試す

サーバー会社にデータベースサーバーの状態を問い合わせる

最も確実で早いのが、利用しているサーバー会社のサポートに連絡することだ。データベースサーバーがダウンしていれば、自分で何をしても復旧しない。管理画面にログインできなくても、サーバー会社のコントロールパネル(cPanel や独自管理画面)にアクセスできれば、そこからデータベースの状態を確認できる場合もある。

特に共有サーバー(複数ユーザーで1台のサーバーを共有するプラン)では、他のユーザーの影響でデータベースサーバーに負荷がかかり、一時的に応答しなくなることがある。この場合もサーバー会社側で対処が必要になる。

wp-config.php の接続情報を確認する

FTP ソフトやサーバーのファイルマネージャーで WordPress のインストールディレクトリにある wp-config.php を開き、以下の4つの定数を確認する。

define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );

これらの値がサーバーのデータベース管理画面(phpMyAdmin やサーバー会社のコントロールパネル)で設定した値と完全に一致しているか確認する。サーバー会社がパスワードをリセットした場合や、セキュリティアップデートでホスト名が localhost から mysqlcluster2.example.com のような専用ホスト名に変更されるケースがある。

wp-config.php に一時的な確認コードを入れる

接続情報が正しいかどうかを切り分けるには、wp-config.php に以下のテストコードを追加する方法も有効だ。エラーメッセージの詳細が表示され、単なる認証エラーなのか、サーバー自体に到達できないのかが判別できる。

$link = mysqli_connect( DB_HOST, DB_USER, DB_PASSWORD, DB_NAME );
if ( ! $link ) {
    die( '接続失敗: ' . mysqli_connect_error() );
}
echo '接続成功';
die();

このコードを wp-config.php/* That's all, stop editing! Happy blogging. */ より上に追記し、サイトにアクセスする。「接続失敗」と表示されれば認証情報かサーバー到達性の問題、「接続成功」と表示されれば WordPress 本体やプラグイン側の別の要因が疑われる。確認が終わったら必ずこのコードを削除する。

phpMyAdmin からデータベースに直接接続する

サーバー会社のコントロールパネルから phpMyAdmin にアクセスし、該当のデータベースを開けるか確認する。開ければ、データベースサーバーは稼働しており、認証情報も正しいことがわかる。開けない場合は、ユーザー名・パスワードが誤っているか、そのユーザーにデータベースへのアクセス権限が付与されていない。

phpMyAdmin 自体が開けない、または読み込みに極端に時間がかかる場合は、データベースサーバーの高負荷やダウンが原因だ。この場合もサーバー会社への連絡が必要になる。

データベースの修復が必要なケース

データベースの修復が必要なケース

wp-config.php の情報が正しく、データベースサーバーも稼働しているのに接続エラーが出る場合、データベースのテーブルが破損している可能性がある。この修復は WordPress の自動修復機能で対応できる。

wp-config.php に以下の1行を追加する。

define( 'WP_ALLOW_REPAIR', true );

その後、ブラウザで https://あなたのサイトのURL/wp-admin/maint/repair.php にアクセスすると、データベース修復画面が表示される。「データベースを修復」または「データベースを修復して最適化」ボタンをクリックすれば修復が実行される。修復完了後は、セキュリティのために必ず追加した行を削除する。

管理画面にログインできない場合の対処

管理画面にログインできない場合の対処

「データベース接続確立エラー」が出ている間は、WordPress の管理画面(/wp-admin)にもアクセスできない。この状態では wp-config.php の確認や修正を WordPress の管理画面から行うことはできず、必ずサーバー側のファイルマネージャーか FTP ソフトを使う必要がある。

FTP の接続情報がわからない場合も、サーバー会社のサポートに連絡すれば、コントロールパネルへのログイン方法やファイルマネージャーの使い方を案内してもらえる。WordPress のログイン情報よりも先に、サーバーの管理画面にアクセスできる状態を確保することが復旧の第一歩だ。

再発を防ぐための日常的な対策

再発を防ぐための日常的な対策

データベース接続エラーは突然発生し、サイト全体が完全に停止するため、予防と早期発見の仕組みを整えておくことが重要だ。

  • サーバー会社のデータベース稼働状況を定期的にチェックする(障害通知メールの設定)
  • データベースの定期バックアップを自動化する(サーバー側のバックアップ機能やプラグインを利用)
  • wp-config.php のバックアップを手元に保管し、接続情報をメモしておく
  • サーバー会社のコントロールパネルと FTP のログイン情報を常に最新に保つ

特にレンタルサーバーの共有プランを利用している場合、サーバー会社がメンテナンスやセキュリティアップデートでデータベースの接続設定を変更することがある。変更の予告メールを見逃さないよう、サーバー会社からのメールは確実に受信できるアドレスに設定しておく。

よくある質問

データベース接続エラーと「重大なエラー」は別のものか

別のエラーだ。「データベース接続確立エラー」はデータベースとの通信そのものができない状態で、サイト全体が表示されない。「このサイトで重大なエラーが発生しました」は WordPress 本体やプラグインの PHP エラーで、管理画面にメールが届く場合もある。後者はデータベースに接続できていることが前提になる。

wp-config.php を修正したのに直らない場合はどうすればよいか

データベースサーバー自体が停止しているか、MySQL のサービスが落ちている可能性が高い。サーバー会社のコントロールパネルで MySQL の状態を確認し、停止していれば再起動を試みる。操作権限がない場合はサーバー会社に依頼する。

データベースのユーザー名やパスワードを忘れた場合はどうするか

サーバーのコントロールパネル(cPanel の「MySQL データベース」など)から確認または再設定できる。WordPress の管理画面からは確認できないため、必ずサーバー側の管理画面を使う。パスワードをリセットした場合は、wp-config.php の DB_PASSWORD も新しい値に更新する必要がある。

データベースの修復でデータが消えることはあるか

WP_ALLOW_REPAIR による修復は、破損したテーブルの構造を修復する機能で、保存されている投稿や設定データを削除することはない。ただし、修復作業の前には必ずデータベースのバックアップを取得しておくことが望ましい。

エラーが断続的に発生する場合の原因は何か

データベースサーバーの負荷が一時的に高まっているか、同時接続数の上限に達している可能性がある。アクセス集中時だけエラーが出る場合は、サーバースペックやプランの見直しを検討する。また、プラグインが非効率なデータベースクエリを大量に発行していないかも確認する。

この記事のポイント

  • データベース接続エラーは wp-config.php の誤りかサーバー側の障害が主因
  • エラー発生時は管理画面にログインできないため、FTP やサーバー管理画面で対応する
  • サーバー会社に連絡してデータベースサーバーの稼働状態を確認するのが最短の復旧手段
  • テーブル破損が疑われる場合は WP_ALLOW_REPAIR で修復を試みる
  • 日常的にバックアップと接続情報の控えを取っておくことで復旧時間を短縮できる
WordPress会員データが大量削除された時の原因と復旧手順

WordPress会員データが大量削除された時の原因と復旧手順

WordPress サイトで会員データが突然数千件単位で削除され、WP Activity Log に「Unknown user」として記録される事態は、データベースへの直接アクセスか管理者権限の乗っ取りによる攻撃の可能性が高い。即座にサイトをメンテナンスモードに切り替え、被害拡大を防ぎつつバックアップから復旧し、侵入経路を特定して再発を防ぐ必要がある。

なぜ突然会員データが大量削除されたのか

この事象の最大の特徴は、削除を実行したユーザーが「Unknown user」と表示される点にある。通常、WordPress の操作ログにはユーザー名かユーザー ID が記録されるが、ここに名前が出ないということは、wp_users テーブルを経由しない削除が行われていることを示している。考えられる原因は大きく3つに絞られる。

データベースへの直接操作

最も深刻なケースとして、攻撃者が SQL インジェクションや phpMyAdmin への不正アクセス、あるいはサーバーに仕込んだマルウェア経由でデータベースに直接 DELETE 文を実行している状況だ。この場合、WordPress のアクションやフィルターフックを一切通過しないため、WP Activity Log を含むどの監査プラグインもユーザーを特定できず「Unknown」となる。

管理者アカウントの乗っ取り

管理者権限を持つアカウントが乗っ取られ、攻撃者がそのアカウントで MemberPress の会員一括操作機能やデータベースクリーニング系プラグインを実行したケースだ。ただし、この場合は通常ユーザー名がログに残る。残っていないということは、攻撃者が操作後にユーザーごと削除したか、別の手段を使った可能性が高い。

REST API や XML-RPC の悪用

WordPress の REST API や XML-RPC に認証の弱点があると、外部から会員データの削除リクエストを送信される場合がある。特に、API 経由で直接データベース操作を行うカスタムエンドポイントがテーマやプラグインに存在すると、認証をすり抜けて大量削除が実行される危険がある。

大量削除が発生する3つの経路
A. データベース直接操作 SQL インジェクションやサーバー侵入により、DELETE 文を直接実行。WordPress のログを一切通過しないため「Unknown」になる。
B. 管理者アカウント乗っ取り 乗っ取った管理者で管理画面から一括削除。通常はユーザー名が残るが、アカウントごと削除された可能性もある。
C. REST API や XML-RPC の悪用 認証の脆弱性を突き、API 経由で削除リクエストを送信。プラグイン独自のエンドポイントに注意が必要。
最も深刻な経路  緊急調査が必要な経路

同時に多数のプラグイン更新が表示され、WordPress 7.0.1 への更新も同日にリリースされたという状況は、実際に重大な脆弱性が公表され、各開発者が一斉にパッチを配布している可能性を示唆している。更新が突如10件以上積み上がるのは、テーマやプラグインに含まれる共通ライブラリに脆弱性が見つかった場合によく見られるパターンだ。

攻撃を受けた直後にとるべき緊急対応の手順

攻撃を受けた直後にとるべき緊急対応の手順

被害の発覚から時間が経つほど、データ消失や情報流出の範囲は広がる。以下の手順を発見後30分以内に実行することで、二次被害を最小限に抑えられる。

STEP 1 サイトをメンテナンスモードに切り替え、外部からの全アクセスを遮断する
STEP 2 全プラグインとテーマを強制無効化し、攻撃者が仕込んだマルウェアの実行を止める
STEP 3 WP Activity Log をエクスポートし、攻撃元 IP と操作内容の全記録を保全する
STEP 4 直近の正常なバックアップからデータベースを復元する

メンテナンスモードでアクセスを遮断する

まず、攻撃が継続している可能性を想定し、サイト全体をメンテナンスモードに切り替える。管理画面にアクセスできる状態であれば、.maintenance ファイルを手動で作成する方法が最も確実だ。WordPress のルートディレクトリに .maintenance ファイルを配置し、以下の内容を記述すると、全訪問者にメンテナンス画面が表示される。

<?php
$upgrading = time();
?>

FTP やサーバーのファイルマネージャーでアクセスできない場合は、サーバー管理パネルから Web サーバー(Apache や Nginx)自体を停止するか、.htaccess に IP 制限をかけて特定の IP 以外をすべて拒否する方法も有効だ。

プラグインとテーマを強制的に無効化する

管理画面からプラグインを一括停止できない、あるいは管理画面自体が攻撃者にロックされている場合、FTP で /wp-content/plugins/ ディレクトリごとリネームする(例: plugins_backup)。これにより、WordPress は全プラグインを無効化した状態で起動する。同様に、/wp-content/themes/ から現在のテーマを除く全テーマを別ディレクトリに退避し、標準テーマ(Twenty Twenty-Five 等)のみを残す。

ログを保全して侵入経路を特定する

WP Activity Log のデータは攻撃者に消去される前にエクスポートする。CSV または JSON でダウンロードし、ローカルに保存する。このとき、サーバーのアクセスログ(access.log)とエラーログ(error.log)も必ず取得する。ログから得るべき情報は「攻撃元 IP」「削除が実行された正確な日時」「リクエスト URL(特に POST リクエスト)」「User-Agent」の4点だ。

「Unknown user」による削除操作が大量に記録されている場合、リクエスト URL が wp-admin/admin-ajax.phpwp-json/ を含んでいないかを重点的に確認する。これらが含まれていれば、AJAX や REST API 経由の攻撃である可能性が高い。

バックアップからの復旧とデータ整合性の確認

バックアップからの復旧とデータ整合性の確認

攻撃発生前の正常な状態がわかっているバックアップがあれば、それをリストアする。このケースのように2日前のバックアップが存在する場合、消失した会員データはその時点のものに戻るが、2日間に新規登録した会員や更新されたデータは失われるため、復旧後に差分を手動で補完する必要がある。

復旧の Before / After
Before(攻撃を受けた状態)
MemberPress 会員テーブルが数千件消失し「Unknown user」の削除ログのみが残っている。プラグイン更新が20件積み上がり、WP 7.0.1 が未適用。
After(復旧完了後)
バックアップから会員データをリストア。全プラグインと WP 本体を最新に更新し、不正ファイルを除去した状態でサイトを再公開。
攻撃直後の状態  復旧後の安全な状態

データベースをリストアする手順

バックアップが SQL ダンプファイル(.sql または .sql.gz)の場合、phpMyAdmin またはサーバーのコマンドラインからインポートする。WordPress のデータベース全体を置き換える場合は、まず現在の全テーブルを削除(DROP)してからインポートする。この操作は取り返しがつかないため、必ず現在のデータベースも別名でエクスポートしてから実行する。

# コマンドラインでのリストア例
mysql -u ユーザー名 -p データベース名 < backup.sql

リストア後、MemberPress の会員数が期待通りに戻っているか、会員のサブスクリプション状況や支払い履歴が正しく関連付けられているかを必ず確認する。特に、WooCommerce と連携している場合は wp_usermeta テーブルの整合性もチェックする必要がある。

再発を防ぐための恒久対策

再発を防ぐための恒久対策

復旧が完了したら、同じ攻撃を二度と受けないようにするための対策を即座に実施する。サーバー侵入を許した原因が残ったままだと、再度同じ経路から攻撃される危険が極めて高い。

全ファイルの改ざんチェックとマルウェアスキャン

WordPress のコアファイル、プラグイン、テーマのすべてについて、オリジナルの配布ファイルと比較して改ざんされていないかを確認する。WordPress の管理画面から「サイトヘルス」→「情報」→「ファイルの整合性」でコアファイルのチェックが可能だが、プラグインとテーマは手動かセキュリティプラグイン(Wordfence や Sucuri 等)を使ってスキャンする。特に、wp-content/uploads/ 内に .php ファイルが存在していないかを重点的に調べる。

管理者アカウントの総点検とパスワード再設定

すべての管理者アカウントについて、覚えのないユーザーが追加されていないか、権限が勝手に昇格されていないかを確認する。wp_users テーブルと wp_usermeta を直接確認し、不審な管理者を削除する。その上で、全管理者と編集者のパスワードを強制的にリセットし、可能であれば二要素認証(2FA)を導入する。WordPress 6.8 以降は標準でパスキー認証が利用できるため、セキュリティキーを使ったログインも有効な選択肢だ。

データベースのアクセス制限と監査の強化

データベースへの外部からの直接アクセスを遮断するため、phpMyAdmin などの管理ツールを公開ディレクトリに置かない、または IP 制限と HTTP 認証をかける。また、wp-config.php に以下の定数を追加して、WordPress のファイル編集機能を無効化しておくことで、管理画面を乗っ取られた場合でもテーマやプラグインのコードが書き換えられることを防げる。

define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true); // 必要な場合のみ

XML-RPC と REST API のアクセス制限

XML-RPC を使用していない場合は .htaccess でブロックするか、プラグインで完全に無効化する。REST API は多くのプラグインが依存しているため完全には無効化できないが、認証が必要なエンドポイントに対して適切な権限チェックが実装されているかを確認する。特に、MemberPress やカスタムプラグインが提供する REST API エンドポイントは、開発元のドキュメントでセキュリティ設定を再確認する。

よくある質問

WP Activity Log に「Unknown user」と表示されるのは必ずハッキングか

必ずしもそうとは限らないが、高い確率で不正アクセスが疑われる。プラグインのバグやデータベースの不整合でも発生しうるが、同時に大量のデータが削除されている場合は攻撃の可能性を第一に考えるべきだ。特に、管理者権限を持たない IP からの操作が記録されている場合はほぼ確実に侵入されている。

プラグインの更新が突然大量に表示されたのはなぜか

共通ライブラリやフレームワークに重大な脆弱性が見つかり、複数のプラグインが一斉にセキュリティアップデートをリリースした可能性が高い。WordPress 本体の緊急アップデートが同日にリリースされていることも、何らかの広範囲に影響する脆弱性が公表されたことを示唆している。これらの更新は速やかに適用すべきだ。

バックアップから復旧した後、消えたデータは完全に戻るのか

バックアップ取得時点のデータは戻るが、それ以降に追加・変更されたデータは復元されない。MemberPress の会員情報の場合、新規登録者やサブスクリプションの変更履歴が失われるため、復旧後に会員からの問い合わせをもとに手動で補完する必要がある。決済情報は決済代行サービス側に残っていることが多いため、そちらを参照して復元できる場合もある。

WP 7.0.1 への更新はすぐに適用すべきか

重大なセキュリティ修正を含むマイナーアップデートの場合、速やかな適用が推奨される。ただし、大量削除が発生した環境では、まずバックアップからの復旧と侵入経路の遮断を完了させてから更新を行う。更新前に全ファイルの改ざんチェックを済ませ、マルウェアが残っていない状態で適用するのが安全だ。

この記事のポイント

  • 「Unknown user」による大量削除はデータベース直接操作か管理者乗っ取りが原因の可能性が高い
  • 発見後は即座にメンテナンスモードでサイトを遮断し、プラグインを強制無効化して攻撃を止める
  • WP Activity Log とサーバーログを直ちにエクスポートし、攻撃元 IP と侵入経路を特定する
  • バックアップからデータベースをリストアし、復旧後に全ファイルの改ざんチェックとマルウェアスキャンを実施する
  • XML-RPC の無効化、REST API の権限確認、二要素認証の導入で再発を防ぐ
myCred Toolkit Pro アップデート後の致命的エラーと復旧手順

myCred Toolkit Pro アップデート後の致命的エラーと復旧手順

WordPress サイトで myCred Toolkit Pro をアップデートした直後に「Class MWP_Module not found」という致命的エラーが発生し管理画面にもアクセスできなくなった場合は、最新バージョンで修正済みの可能性が高い。修正がまだ提供されていない場合でも、クラスファイルの読み込み順序を確認し手動で修正すれば復旧できる。

MWP_Module クラスが見つからない致命的エラーはなぜ起こるのか

MWP_Module クラスが見つからない致命的エラーはなぜ起こるのか

このエラーは、myCred Toolkit Pro 内の WooCommerce Plus 改修版アドオンが読み込まれる際、ベースクラス(親クラス)である MWP_Module がまだ定義されていない状態で、子クラスが呼び出されるために発生する。具体的には class-mwp-module-coupons.phpMWP_Module を継承しようとするが、その元となる抽象クラスファイルが先に読み込まれていないのだ。

本来なら abstract/class-mwp-abstract-module.php が先にロードされるべきところ、プラグインのアップデート時にファイルの欠落が起きたり、オートローダーの設定不備で読み込み順序が狂ったりすると、このエラーが表面化する。PHP は未定義クラスへの継承を許さないため、サイト全体が致命的エラーで停止してしまう。

アップデート直後にサイトがダウンした場合の緊急復旧手順

アップデート直後にサイトがダウンした場合の緊急復旧手順

エラーによって WordPress 管理画面にも入れなくなった状態では、FTP クライアントやサーバーのファイルマネージャを使ってプラグインを強制的に無効化する必要がある。データベースを直接操作する方法もあるが、ファイル名の変更がもっとも手軽で確実だ。

STEP 1 FTP クライアントでサーバーに接続し、/wp-content/plugins/ ディレクトリへ移動する
STEP 2 mycred-toolkit-pro フォルダを右クリックし、「名前の変更」で末尾に _disabled を付ける
STEP 3 ブラウザでサイトにアクセスし、管理画面 /wp-admin/ へログインできるか確認する
STEP 4 管理画面に入れたら、プラグイン一覧で Toolkit Pro が「無効」になっていることを確認し、旧バージョンへ差し替える準備をする

上の手順でプラグインを無効化すれば、サイトは正常に表示されるようになる。続いて、動作していた旧バージョン(例として 1.0.4)を再インストールして有効化するか、修正版が配布されているかを確認する。

手動でクラスファイルの読み込み順序を確認し修正する方法

手動でクラスファイルの読み込み順序を確認し修正する方法

開発元の修正版がまだ提供されていない、あるいは修正を待てない場合は、プラグインのファイルを手動で編集してクラスの読み込み順序を修正できる。修正の要点は、class-mwp-module-coupons.php に到達する前にベースクラスを確実に読み込ませることだ。

問題のファイルと修正箇所を特定する

エラーログに出力されたパスをもとに、wp-content/plugins/mycred-toolkit-pro/includes/addons/mycred-woocommerce-plus/mycred-woocommerce-plus-revamped/modules/class-mwp-module-coupons.php を開く。7 行目付近で MWP_Module を継承しているクラス定義があるはずだ。

ベースクラスのファイルは wp-content/plugins/mycred-toolkit-pro/includes/addons/mycred-woocommerce-plus/mycred-woocommerce-plus-revamped/abstract/class-mwp-abstract-module.php に存在する。これが読み込まれていないことが原因なので、子クラスのファイルの先頭で明示的に require_once を追加する。

修正前(エラー発生)
1 <?php
2
3 // エラー: 親クラスが不明
4 class MWP_Module_Coupons extends MWP_Module {
5
修正後(正常動作)
1 <?php
2 require_once plugin_dir_path( __FILE__ ) .
3 ../abstract/class-mwp-abstract-module.php‘;
4
5 class MWP_Module_Coupons extends MWP_Module {
6
修正前(親クラス未定義のまま実行)  修正後(require_once で事前に読み込み)

上記のように require_once を追加することで、クラス定義より前にベースクラスを確実に読み込める。ただし、この修正は自作テーマの functions.php に書くような一時しのぎとは異なり、プラグインのコアファイルを直接編集するため、アップデートで上書きされる可能性がある点を理解しておく必要がある。

オートローダーの確認と修正

モダンなプラグインは PHP のオートローダー(Composer の autoload など)を使ってクラスを動的に読み込む仕組みを採用している。myCred Toolkit Pro も Composer ベースのオートロードを利用している可能性が高く、composer.json の autoload 設定や名前空間のマッピングが正しいかを確認すると根本的な解決につながる。

プラグインディレクトリで composer dump-autoload -o を実行し、クラスマップを再生成するのも有効な手だ。ただし、サーバーに Composer がインストールされている必要があるため、ローカル環境で再生成してからファイルをアップロードする方法が現実的だ。

修正版がリリースされている場合の安全なアップデート手順

修正版がリリースされている場合の安全なアップデート手順

開発元から修正版が提供された場合、本番環境にいきなり適用するのは避け、最初にステージング環境で動作確認を行うのが鉄則だ。致命的エラーはサイト全体を巻き込むため、万が一のときに備えて必ずバックアップを取る。

STEP 1 本番サイトのデータベースと全ファイルをバックアップする(プラグイン「UpdraftPlus」やサーバー側のスナップショット機能を使う)
STEP 2 ステージング環境にバックアップを復元し、Toolkit Pro を最新版へアップデートする
STEP 3 WooCommerce のポイント付与やクーポン連携が正常に動くか、テスト注文を行って検証する
STEP 4 問題なければメンテナンス時間帯を設け、本番環境でも同様にアップデートする

ステージング環境がない場合は、本番環境の深夜帯などアクセスが少ない時間にメンテナンスモードへ切り替えてから実施する。アップデート後すぐに管理画面へアクセスできるか、フロントエンドにエラーが出ていないかを確認し、問題があればすぐに旧バージョンへロールバックできるよう、ファイルのバックアップを手元に残しておく。

よくある質問

myCred 本体をアップデートしていないと同様のエラーは起きるか

プラグインによっては、本体(myCred コア)とアドオン(Toolkit Pro)のバージョンに互換性が要求される。MWP_Module クラスは Toolkit Pro 内部の抽象クラスなので myCred コアのバージョンに直接は依存しないが、コアが古すぎると別の非互換エラーを引き起こす可能性がある。常に両方を最新に保つことが望ましい。

修正版が出るまでサイトを止めておくべきか

致命的エラーでサイトが完全に停止しているなら、前述の緊急復旧手順でプラグインを無効化するか旧バージョンへ巻き戻し、通常運用を再開してよい。ポイント機能が止まる影響を考慮し、必要なら代替手段を顧客に案内する。

エラーログはどこで確認できるか

WordPress のデバッグモードを有効にしていれば /wp-content/debug.log にエラー詳細が出力される。有効でない場合は wp-config.phpdefine( 'WP_DEBUG', true );define( 'WP_DEBUG_LOG', true ); を記述する。レンタルサーバーによってはエラーログが管理画面から閲覧できる場合もある。

子テーマの functions.php で読み込み順序を修正できるか

テーマの functions.php はプラグインより後に読み込まれるため、この方法では MWP_Module クラスを事前に定義することはできない。プラグインファイルの直接編集が必須になる。

この記事のポイント

  • myCred Toolkit Pro アップデート後の MWP_Module クラス欠落エラーは、読み込み順序の不備が主因
  • 緊急復旧は FTP でプラグインフォルダをリネームし、旧バージョンへ差し替える
  • 手動修正では子クラスのファイル冒頭に require_once を追加する
  • 開発元修正版を適用する際は必ずバックアップとステージング検証を行う
  • PHP のオートローダー設定や Composer のクラスマップ再生成も有効なアプローチ
Shield SecurityのcookieがNginxキャッシュを止める時の解決策

Shield SecurityのcookieがNginxキャッシュを止める時の解決策

Shield Security の icwp-wpsf-notbot cookie がサーバーのページキャッシュを妨害する問題は、Shield の設定で「silentCAPTCHA」の複雑度を「なし」にし、かつカスタムフィルターで匿名ユーザーへの cookie 送信を停止することで解決できる。

なぜ Shield Security が全ページでキャッシュを止めてしまうのか

なぜ Shield Security が全ページでキャッシュを止めてしまうのか

Shield Security はボット判定や silentCAPTCHA の動作のために icwp-wpsf-notbot という cookie をフロントエンドの全ページで発行する仕様になっている。Nginx のキャッシュ機構は原則として Set-Cookie ヘッダを含むレスポンスをキャッシュしないため、この cookie がすべてのページキャッシュを無効化してしまう。結果として x-proxy-cache: MISS が返り続け、サーバーへのリクエストが毎回発生し、レスポンスタイムが 1000ms を超える状況に陥る。

Before(Shield 有効時)
リクエストのたびに Set-Cookie が発生
Nginx はレスポンスをキャッシュせず破棄
レスポンスタイム 1000ms〜1600ms
After(cookie 停止後)
キャッシュ可能なレスポンスが返る
初回 MISS → 2回目以降 HIT で高速表示
レスポンスタイム 約100ms
cookie がキャッシュを妨害している状態  cookie 停止後

サーバー側で特定の cookie だけをキャッシュ対象から除外する設定ができない場合、プラグイン側でこの cookie を止めるのが唯一の現実的な解決策になる。

管理画面で silentCAPTCHA の複雑度を「なし」にする

管理画面で silentCAPTCHA の複雑度を「なし」にする

Shield Security の silentCAPTCHA は、ボット防御のためにフロントエンドのページにも cookie をセットする。設定を最小限に絞り込むには、まず管理画面から操作する。

STEP 1 WordPress 管理画面 → 左メニュー「Shield」→「設定」
STEP 2 「CAPTCHA」タブを開き「silentCAPTCHA」セクションを探す
STEP 3 「複雑度」を なし に変更して保存
STEP 4 「ログイン保護」「スパムボットブロック」などで不要な silentCAPTCHA の利用をすべてオフにする

これだけでは cookie の出力が止まらないケースが多い。Shield は silentCAPTCHA の設定に関わらず、フロントエンドの訪問者に対して一律に icwp-wpsf-notbot をセットする内部ロジックを持っているためだ。ここから先はコードレベルの対応が必要になる。

フィルターフックで匿名ユーザーへの cookie 送信を無効化する

フィルターフックで匿名ユーザーへの cookie 送信を無効化する

Shield Security は icwp-wpsf-notbot cookie を制御するための専用フィルターを提供している。テーマの functions.php に数行のコードを追加すれば、ログインしていない一般訪問者に対する cookie の送信だけを停止できる。

functions.php に追加するコード

以下のコードを子テーマの functions.php に追加する。子テーマを使用していない場合は、Code Snippets プラグインなどで追加してもよい。テーマの直接編集はアップデートで消えるため避ける。

/**
 * Shield Security の icwp-wpsf-notbot cookie をログインしていないユーザーには送信しない
 */
add_filter( 'icwp_shield_set_notbot_cookie', function( $set_cookie ) {
    if ( ! is_user_logged_in() ) {
        return false;
    }
    return $set_cookie;
} );

このフィルターは icwp-wpsf-notbot cookie をセットする直前に呼び出される。ログインしていないユーザーの場合は false を返して cookie の発行をブロックし、ログイン済みユーザーには通常通り cookie を許可する。管理画面のログイン保護や IP ブロック、ファイアウォールなどのコア機能には影響しない。

動作確認の手順

  • シークレットウィンドウでサイトにアクセスする
  • ブラウザの開発者ツール(F12)→「アプリケーション」タブ→「Cookie」で icwp-wpsf-notbot が存在しないことを確認する
  • レスポンスヘッダーから Set-Cookie が消えていることを確認する
  • 2回目以降のアクセスで x-proxy-cache: HIT が返ることを確認する

全プラグインを最新に保って不要な干渉を防ぐ

全プラグインを最新に保って不要な干渉を防ぐ

Shield Security はアップデートの頻度が高く、バージョンによって内部のフィルター名が変更されることがある。Shield 22.1.3 および WordPress 7.0.1、PHP 8.2 環境では上記のフィルターが有効だが、プラグインが更新された際にはフィルター名が維持されているかを確認する必要がある。

また、キャッシュ系プラグインや CDN を併用している場合は、cookie 停止後にキャッシュを完全にクリアしてからテストすること。古いキャッシュが残っていると HIT になっていてもレスポンスが遅いままに見える場合がある。

よくある質問

SilentCAPTCHA を無効にしただけでは cookie は消えないのか

多くの場合、管理画面の設定だけでは cookie の出力は止まらない。Shield は silentCAPTCHA が無効でもフロントエンドの全リクエストに cookie をセットする内部挙動を持っている。確実に止めるにはフィルターフックの追加が必要だ。

このフィルターでログイン保護やファイアウォールは機能しなくなるか

今回のコードは匿名ユーザーへの icwp-wpsf-notbot cookie 送信だけを止めるもので、IP ブロックやブルートフォース保護、ファイアウォールといった Shield の主要防御機能はすべて通常通り動作する。ログインしたユーザーには引き続き cookie がセットされる。

functions.php を直接編集するのはリスクがないか

テーマの functions.php を直接編集すると、テーマのアップデートで変更が失われる。必ず子テーマを作成するか、Code Snippets のようなコード管理プラグインを使用する。また、コード追加前にサイトのバックアップを取得しておくと安全だ。

フィルターが効かない場合の確認ポイントは

Shield のバージョンが古い、あるいは逆に新しすぎてフィルター名が変更されている可能性がある。Shield の公式ドキュメントや変更履歴を確認する。また、キャッシュ系プラグインでサーバー側のキャッシュとは別にページキャッシュが残っていると、cookie 停止後も古いレスポンスが返り続けるため、すべてのキャッシュをクリアしてからテストする。

レンタルサーバーのキャッシュ設定で cookie ごとの除外はできないのか

共用サーバーの Nginx キャッシュ設定はサーバー全体で一律に適用されることが多く、特定の cookie だけを除外する柔軟な設定は提供されないケースがほとんどだ。サーバー側で対応できない以上、プラグイン側で cookie を止めるのが最も確実な方法になる。

この記事のポイント

  • Shield Security の icwp-wpsf-notbot cookie が Nginx のページキャッシュを全面的に阻害する
  • 管理画面で silentCAPTCHA の複雑度を「なし」にしても cookie は止まらない
  • functions.php にカスタムフィルターを追加しログインしていないユーザーへの cookie 送信を停止する
  • フィルター追加後はシークレットウィンドウで Set-Cookie ヘッダーと x-proxy-cache の値を確認する
  • プラグインのアップデート後はフィルター名の変更に注意しキャッシュを完全クリアして再テストする
Elementorテキストエディタで段落が勝手に横並びになる時の直し方

Elementorテキストエディタで段落が勝手に横並びになる時の直し方

Elementorのテキストエディタウィジェットで複数段落を入力したとき、編集画面では問題ないのに公開ページで急に横並びになる現象は、WoodMartテーマが組み込むフレックスボックス(Flexbox)のグローバルスタイルや、テーマ側の段組み(カラム)レイアウト用CSSが誤って適用されていることが主な原因だ。

なぜElementorの段落が公開サイトで横並びになるのか

なぜElementorの段落が公開サイトで横並びになるのか

WoodMartテーマは、WPBakeryと並んでElementor対応を謳う多機能テーマだ。その内部ではグリッドレイアウトや商品カードの並びを柔軟に制御するため、.entry-content.elementor-widget-text-editor といったコンテナに対して display: flexflex-wrap: wrap をデフォルトCSSとして指定しているケースがある。

このような設定が有効だと、コンテナ直下の <p> タグはフレックスアイテムとして扱われ、利用可能な幅の中で自動的に横方向へ配置されるのだ。通常のブロック要素であれば改行されるため縦に積み重なるが、フレックスコンテナの子要素はこの規則から外れる。その結果、編集画面では普通に見えていても、テーマのグローバルCSSがロードされるフロントエンドでのみ崩れが発生するという、なかなか気づきにくいトラブルになる。

ほかにも、Elementorの「段組み」設定の競合や、意図せず有効化されたCSSの最適化機能が影響することもあるが、ほとんどはWoodMartのベーススタイルが起点だ。次の項で切り分け手順を確かめつつ修正していく。

問題の再現状況をデモで確認する

問題の再現状況をデモで確認する
Before(公開ページで横並び)

「会社概要についての本文がここにあります。WoodMartの特徴を活かしたレイアウトです。」

「サービス一覧のご案内です。Elementorを使って自由に編集した内容がここに入ります。」

2つの段落が横に並んでいる(フレックスアイテム化している)
After(CSS追加で縦並びに修正)

「会社概要についての本文がここにあります。WoodMartの特徴を活かしたレイアウトです。」

「サービス一覧のご案内です。Elementorを使って自由に編集した内容がここに入ります。」

各段落が改行され、通常のブロック要素として縦に積まれている
エラー状態(横並び)  修正後(縦並び)

フレックスコンテナの子要素だから横に並ぶ、という仕組みをこのデモで示している。原因のCSSを特定し、段落の並びをブロック表示に戻せば解決できる。

ElementorとWoodMartで段落が横並びになるCSSの特定と修正手順

ElementorとWoodMartで段落が横並びになるCSSの特定と修正手順

ここからは実際にサイトを修正するための手順を説明する。作業は大きく3ステップだ。修正用のCSSは数行で済むが、きちんと原因を突き止める手順を踏まないと、後日ほかのレイアウト崩れを引き起こす可能性がある。

ブラウザの検証ツールで適用されているスタイルを調べる

まずはChromeのデベロッパーツール(F12キー)を使って、公開ページ上のテキストエディタ部分を調べる。<p> タグを右クリックし「検証」を選択すると、スタイルパネルで各要素に適用されているCSSを確認できる。

ここで最も注目すべきは、テキストエディタのラッパー要素(たいていは .elementor-widget-text-editor か、WoodMartが生成する固有のクラスが付いたdiv)に対して display: flexdisplay: grid が指定されていないかどうかだ。仮に以下のようなCSSが表示された場合、これが横並びの直接的な原因になる。

.elementor-widget-text-editor {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

このCSSがWoodMartの親テーマ、または子テーマのスタイルシートから読み込まれている場合は、検証ツールの右上にファイル名と行番号が表示される。原因となるファイルが特定できたら、次の手順で上書きするCSSを追加しよう。

修正用CSSを追加する場所を選ぶ

原因となっている display: flex を打ち消すには、以下のようなCSSを適用すればよい。要素をブロック表示に戻すには display: block を指定し、内部の段落が確実に積み重なるようにする。

.elementor-widget-text-editor {
    display: block !important;
}
.elementor-widget-text-editor p {
    display: block;
    width: 100%;
}

このCSSは以下のいずれかの場所に追加する。優先順位順に記す。

  1. 管理画面の「外観」→「カスタマイズ」→「追加CSS」(最も手軽で、テーマに関係なく安全)
  2. WoodMartのテーマオプションにあるカスタムCSS欄
  3. Elementorのサイト設定内のカスタムCSS

注意点として、追加CSSに !important を使うのはどうしても優先度で負ける場合の最終手段だ。まずは !important なしで試し、効かなければ付与するという手順を踏むほうが、意図しないカスケード崩れを防げる。上記のコード例では !important を付記したが、自身の環境で不要なら省略して構わない。

Elementorとキャッシュのクリアを忘れずに行う

CSSを追加してもすぐに反映されない場合、Elementor固有のキャッシュや、サーバー側のキャッシュが影響している。Elementorの「ツール」メニューから「CSSとデータを再生成」を実行し、さらに「Elementor」→「設定」→「高度な設定」でCSSの出力方法を「外部ファイル」から「内部埋め込み」に切り替えて一時的に様子を見るのもひとつの手だ。

サーバーでLiteSpeed CacheやW3 Total Cacheなどのキャッシュ系プラグインを使っているなら、管理画面から全キャッシュを削除しておく。とくに「CSSの最適化」や「CSSの結合」をオンにしている場合、追加したCSSが適用されない原因になりやすい。キャッシュをクリアしたあとに、シークレットモードで公開ページを開いて検証する。

テーマをアップデートする際の注意点と恒久対策

テーマをアップデートする際の注意点と恒久対策

今回の現象はあくまでテーマの全体的なスタイル指定が原因であり、Elementorのバグではない。WoodMartが将来のアップデートでこのフレックスボックス指定を変更する可能性もゼロではないが、テーマのアップデートに依存するのはリスクが高い。

恒久的な対策としては、親テーマを直接編集せず、子テーマの style.css か「追加CSS」に上書きルールを残すことだ。もしテーマのバージョンアップ後に問題が再発したら、原因のCSSセレクタが変わっていないか検証ツールで再確認し、セレクタを合わせて更新すればすぐに直せる。

複数ページで同じテキストエディタウィジェットを使っている場合は、サイト全体に影響する「追加CSS」での対応が推奨だ。特定のページや投稿タイプでのみ発生しているなら、該当ページのElementor編集画面で「サイト設定」→「カスタムCSS」を使い、スコープを絞った指定をする手もある。

よくある質問

テキストエディタ以外のウィジェットでも同じ症状は出るのか

見出しウィジェットや画像ウィジェットなど、直下に複数のブロック要素がぶら下がらない種類のウィジェットでは、この現象はまず起きない。ただし「内部セクション」や「Flexboxコンテナ」などの新しめのコンテナ系ウィジェットを使っていると、似た横並びが発生することがある。

WoodMart以外のテーマでも同じことが起きるのか

汎用的なテーマでは稀だが、カラム多用型の多機能テーマ(Avada、The7、Flatsomeなど)でも同様の報告がある。いずれの場合も、根本原因はテーマが付与しているフレックスボックスやグリッドのグローバルCSSだ。

追加CSSで直したのにスマホ表示だけ直らない

デスクトップでは修正されても、モバイル用のメディアクエリ内で再度 flex-direction: row が指定されている可能性がある。検証ツールでデバイスモードに切り替え、同じテキストエディタで適用されているスタイルを再確認する。必要ならメディアクエリを追加して上書きしよう。

子テーマのstyle.cssに書いても効かないのはなぜか

読み込み順の問題がほとんどだ。親テーマのCSSが子テーマより後で読み込まれていると、詳細度が同じなら後勝ちで上書きされる。functions.phpで子テーマのCSSを依存関係付きで読み込んでいるか確認し、どうしても効かないなら「追加CSS」機能(wp_headの最後で出力される)を使うほうが確実だ。

この記事のポイント

  • Elementor編集画面では正常でもフロントエンドでテキスト段落が横並びになる場合、WoodMartが付与するflex指定が原因
  • ブラウザの検証ツールで適用されているdisplayプロパティを特定し、追加CSSでブロック表示に戻す
  • 修正CSSは外観カスタマイズの「追加CSS」がもっとも安全で確実
  • CSS追加後はElementorのCSS再生成とサーバーキャッシュのクリアをセットで行う
  • テーマアップデート後も再発しにくいよう、恒久対策として上書きルールを残しておく
Mollie決済プラグインでPHP警告「Undefined array key」が出たときの対処法

Mollie決済プラグインでPHP警告「Undefined array key」が出たときの対処法

Mollie Payments for WooCommerce で「PHP Warning: Undefined array key “identifier”」という警告が出ても、決済フローや Apple Pay の動作に支障はない。この警告は PHP 側の配列キー未定義による軽微な通知であり、プラグイン開発元が修正を予定している。緊急の対応が必要でなければ、エラーログへの出力を抑える設定で一時的に回避できる。

なぜ「Undefined array key “identifier”」警告が発生するのか

なぜ「Undefined array key “identifier”」警告が発生するのか

この警告は、PHP 8.0 以降で強化された型と配列アクセスの安全性チェックによって表面化したものだ。Mollie プラグインの Apple Pay 関連クラス内で、変数やリクエストデータに「identifier」というキーが存在しない状態で配列アクセスを行っているために出力される。

PHP 8.0 以降の配列アクセスへの影響

PHP 7.x までは、配列内に存在しないキーを参照しても通知(Notice)または軽微な警告(Warning)で済む場面が多かった。しかし PHP 8.0 からは「Undefined array key」が Warning に格上げされている。テーマやプラグインが最新の PHP に完全対応していないと、こうした警告が表面化しやすい。

Mollie プラグインの該当コードが生む状況

警告の発生箇所は ResponsesToApple.php の 89 行目と ApplePayDataObjectHttp.php の 193 行目付近だ。Apple Pay のトークン処理やデータオブジェクトの動的生成時に、送信されてくるパラメータが一部欠落している場合や、プロパティが未定義のままアクセスされている場合に警告が記録される。

もう一つの「Creation of dynamic property」は PHP 8.2 で導入された非推奨通知で、クラスに明示的に宣言されていないプロパティへ動的に値を代入している場合に発生する。いずれも決済処理の本筋を妨げるエラーではなく、サーバーのエラーログに記録されるだけの通知レベルだ。

修正前(警告が発生している状態)
PHP Warning: Undefined array key “identifier” in ResponsesToApple.php on line 89
PHP Deprecated: Creation of dynamic property … in ApplePayDataObjectHttp.php on line 193
※ 決済処理は通常通り完了するが、ログに警告が残る
修正後(警告を抑制した状態)
エラーログに警告が出力されず、運用上のノイズがなくなる
※ プラグイン側の根本修正はアップデートを待つ
修正前(警告あり)  修正後(警告を抑制)

エラーログを確認して影響度を判断する

エラーログを確認して影響度を判断する

警告の発生頻度や実際の影響を把握するには、まずサーバーのエラーログを確認する。多くの国内レンタルサーバーでは管理画面のログビューアから確認できるほか、FTP で /wp-content/ 内の debug.log を直接ダウンロードしてもよい。

エラーログの保存場所と見方

WordPress のデバッグモードを有効にしている場合、wp-config.php に定義された WP_DEBUG_LOG の設定に従い、エラーログが出力される。デフォルトでは /wp-content/debug.log に保存される。

ログを開くと日付とともにエラーレベルが記録されている。「PHP Warning」と「PHP Deprecated」の行を探し、該当のプラグイン名とファイルパスが含まれているかを確認する。もし1時間に数千回単位で記録されているようであれば、ログファイルが肥大化してディスク容量を圧迫する可能性があるため対応が必要だ。

警告の発生頻度を調べる簡単なコマンド

SSH 接続が可能なサーバーであれば、grep コマンドで頻度を数えられる。以下のように実行すると「identifier」を含む警告の出現回数がわかる。

grep -c "Undefined array key \"identifier\"" /home/user/domains/example.com/public_html/wp-content/debug.log

数十件程度であれば運用上の支障は少ないが、数百件以上ある場合は早めの抑制を検討する。

PHP 警告を一時的に非表示にする方法

PHP 警告を一時的に非表示にする方法

根本的な修正がプラグイン側で提供されるまでの間、エラーログへの出力を抑える設定で運用上のノイズを減らせる。複数の段階的な手法があるので、サイトの状況に合わせて選択する。

エラーレポートレベルを変更する

wp-config.php に以下の定数を追加すると、Warning と Deprecated をログから除外できる。この設定は本番環境で推奨される標準的なエラー抑制の手法だ。

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'error_reporting', E_ALL & ~E_WARNING & ~E_DEPRECATED );

WP_DEBUG_DISPLAYfalse にすることで画面表示を防ぎ、error_reporting のビット演算で Warning と Deprecated だけを除外する。Fatal error など重大なエラーは引き続き記録されるため、サイトの異常を見逃すリスクは低い。

Mollie プラグイン固有のフックで抑制する

よりピンポイントに対処するなら、Mollie が提供するフィルターフックを利用する方法もある。ただし、これはプラグインのバージョンによって動作が異なるため、公式ドキュメントを参照のうえ実装する必要がある。

多くの場合、前述のエラーレポート設定で十分に警告は抑制できる。プラグイン更新後に設定を元に戻すことを忘れずに、スケジュールに組み込んでおく。

STEP 1 FTP またはサーバー管理画面で wp-config.php を開く
STEP 2 WP_DEBUG_DISPLAYfalse に設定する
STEP 3 error_reporting を設定して Warning と Deprecated を除外
STEP 4 ファイルを保存し、数時間ログを監視して警告が出ていないか確認する

プラグインのアップデートを待つときの注意点

プラグインのアップデートを待つときの注意点

Mollie の開発チームはこの警告を認識しており、将来のバージョンで修正が行われる見込みだ。プラグインの更新を待つ間は、以下の点に注意してサイトを運用する。

自動アップデートを有効にしておく

WordPress の管理画面で Mollie Payments for WooCommerce の自動アップデートをオンにしておくと、修正版がリリースされた際に即座に適用される。更新を手動で行う場合は、Mollie の changelog を定期的にチェックし、「identifier」や「dynamic property」に関する修正が含まれているかを確認する。

ログのローテーションを設定する

警告が高頻度で出ていると debug.log が急速に肥大化する。サーバーのログローテーション機能や、WordPress 用のログ管理プラグインを導入して、一定期間で古いログを圧縮・削除する仕組みを整えておく。これによりディスク容量の圧迫を防げる。

よくある質問

この警告が出ていても決済は正常に動くのか

多くの場合、クレジットカードや Apple Pay の決済処理に影響はない。PHP Warning や Deprecated は実行を停止させるエラーではなく、処理は継続される。実際に決済が通っているかは、テスト購入を行って確認するのが確実だ。

他の決済プラグインでも同じ警告は出るのか

PHP 8.0 以降に完全対応していないプラグインであれば、同様の「Undefined array key」警告が発生する可能性がある。Stripe や PayPal の公式プラグインでも、過去に似たような警告が報告され修正されている。プラグインが最新かどうかを常に確認することが重要だ。

プラグインを自分で修正してもよいのか

PHP の知識があるなら、該当行に isset() によるキー存在チェックを追加すれば警告は消える。ただし、プラグインのアップデートで修正が上書きされるため、修正を維持するには継続的な管理が必要だ。本番環境では推奨しない。

PHP のバージョンを下げれば解決するか

PHP 7.4 に戻せばこの警告は出なくなるが、PHP 7.4 はすでにセキュリティサポートが終了している。サイト全体の安全性を損なうため、PHP のダウングレードは避けるべきだ。サーバー環境は常にサポート対象の PHP バージョンを維持する。

「Creation of dynamic property」も同じ対処でよいのか

同じエラーレポートレベルの設定で抑制できる。こちらも PHP 8.2 以降の非推奨通知であり、機能停止を伴わない。根本対応はプラグイン側でプロパティ宣言を追加する必要があるため、開発元のアップデートを待つ形になる。

この記事のポイント

  • 「Undefined array key」警告は決済機能に影響しない軽微な通知
  • PHP 8.0 以降の配列アクセス厳格化によって表面化している
  • エラーレポートレベルの変更で一時的にログ出力を抑制できる
  • プラグインの自動アップデートを有効にして修正版の適用に備える
  • PHP バージョンのダウングレードはセキュリティリスクがあるため避ける
WooCommerce決済が「処理中」で止まりサンクスページに遷移しない場合の対処法

WooCommerce決済が「処理中」で止まりサンクスページに遷移しない場合の対処法

WooCommerceでRazorpay決済を利用しているサイトで、支払い自体は成功しているのにチェックアウト画面が「処理中です。しばらくお待ちください」と表示されたまま止まり、注文完了ページへ遷移しない問題は、RazorpayのJavaScript SDKが正常に読み込まれていないか、他のプラグインとの競合によってフォーム送信処理が破損している場合に起こる。

特にサンドボックスモードでは正常に動作するのに本番環境でのみ発生する場合、APIキーの設定ミスや決済スクリプトのパス解決エラーが根本原因である可能性が高い。ブラウザの開発者コンソールを開くと GET .../build/undefined 403document.razorpayform.submit is not a function といったエラーが記録されているはずだ。以下では原因の特定から具体的な修正手順までを順に解説する。

ブラウザコンソールでエラーの全体像を把握する

ブラウザコンソールでエラーの全体像を把握する

まず最初に行うべきは、問題が起きているページで開発者ツールを開き、コンソールタブとネットワークタブに出力されているエラーを確認することだ。Razorpayの処理フローはほぼすべてフロントエンドのJavaScriptで制御されているため、バックエンドのログだけでは見えない問題がここに集中して現れる。

Chromeの場合、決済画面で F12 を押してDevToolsを開き、以下の手順で記録を取る。

STEP 1 コンソールタブを開き、ゴミ箱アイコンでログをクリアする
STEP 2 ネットワークタブを開き「プリザーブログ」にチェックを入れる
STEP 3 実際に決済を実行し、処理が止まるまでの全リクエストとエラーを記録する

記録した中で特に注目すべきは以下の2種類のエラーだ。

  • GET https://checkout-static-next.razorpay.com/build/undefined 403 というリクエストが発生している場合、Razorpay SDKのビルドパスが正しく解決されていない。末尾が /undefined になっているのが最大の手がかりだ。
  • Uncaught TypeError: document.razorpayform.submit is not a function は、決済フォームの送信メソッドが何らかの理由で失われていることを示す。他のJavaScriptによって上書きされているか、Razorpayのスクリプト自体が最後まで読み込まれていない可能性が高い。

GET …/build/undefined 403 エラーが示す根本原因

GET .../build/undefined 403 エラーが示す根本原因

Razorpayのチェックアウトスクリプトは、プラグインが動的に生成するパスに基づいて checkout-static-next.razorpay.com/build/【バージョン番号】 というURLから読み込まれる。このバージョン番号が何らかの理由で空になると /build/undefined という不正なURLが生成され、当然ながら403 Forbiddenで拒否される。

この現象は主に次の3つの状況で起こる。

本番用APIキーが未設定または誤ったキーが入力されている

Razorpayプラグインの設定画面(WooCommerce → 設定 → 決済 → Razorpay)を開き「本番用キーID」と「本番用キーシークレット」の両方が 本番環境用の正しい値 になっているか確認する。サンドボックス用のキーが誤って本番フィールドに入力されていると、スクリプトパスの生成に失敗する。キーはRazorpayダッシュボードの「Settings → API Keys」から再発行できる。

プラグインのバージョンが古いか不完全に更新されている

公式の「Razorpay for WooCommerce」プラグインが最新版かどうかを確認する。過去のバージョンには、特定の条件下でSDKバージョン文字列が空になる不具合が報告されている。wp-adminのプラグイン一覧で更新があれば適用し、問題が継続する場合は一度プラグインを完全に削除してから再インストールする。削除前に必ずAPIキーをメモしておくこと。

マルチカレンシープラグインがRazorpayの設定を上書きしている

WooCommerce Currency Switcher(FOXやAeliaなど)を使用している場合、通貨切り替えの過程でRazorpayの決済スクリプトに渡すパラメータが改変されることがある。特にジオベースで通貨を自動切り替えしている環境では、チェックアウトページ読み込み時に想定外の通貨コードがRazorpayに渡され、SDKの初期化に失敗するケースが確認されている。

通貨スイッチャー側の設定で、チェックアウトページと決済完了ページを通貨切り替えの対象外にするルールを追加しても改善しない場合、以下の方法で問題の所在を明確にできる。

Before(通貨スイッチャー有効時)
Razorpayに渡される通貨コードが undefined になり、スクリプトパスが /build/undefined
NGscript読み込み失敗 → 403
After(通貨スイッチャー無効化後)
Razorpayに正しい通貨コード(INR)が渡り、スクリプトパスが /build/v3.45.0 など正常に
OKscript読み込み成功 → 決済完了
エラー状態  修正後

document.razorpayform.submit is not a function を解消する

document.razorpayform.submit is not a function を解消する

このTypeErrorは、決済フォームを送信するタイミングで razorpayform オブジェクトの submit メソッドが存在しないことを意味する。原因は主に2つに絞られる。

JavaScriptの最適化や結合によるメソッド破損

LiteSpeed CacheやAutoptimizeなどのキャッシュ・最適化プラグインがJavaScriptを結合(Combine)したり、圧縮(Minify)したり、遅延読み込み(Defer)したりする設定が有効だと、Razorpayのフォームオブジェクトが初期化される前に他のスクリプトが実行され、document.razorpayform が不完全な状態になる。

JavaScriptの最適化機能をすべてオフにしても改善しない場合でも、LiteSpeed Cacheにはページ単位の最適化設定や「ゲストモード」など追加の最適化機能が存在する。プラグインを完全に無効化してテストした上で、それでも直らなければキャッシュ以外の競合を疑う。

サンクスページカスタマイズプラグインによるリダイレクト干渉

「WooCommerce Thank You Page」のような注文完了ページをカスタマイズするプラグインは、通常のリダイレクトフックを上書きする。Razorpayが決済完了後に実行する razorpayform.submit() が、この上書きされたフローと衝突し、メソッド呼び出し自体が失敗するケースがある。

サンクスページプラグインを無効化してテストした結果、問題が解消するのであれば、そのプラグインが原因だ。Razorpayとの互換性をプラグイン開発者に確認するか、よりシンプルなフックベースのカスタマイズ(テーマのfunctions.phpで制御)に切り替える。

プラグインの競合を段階的に切り分ける手順

プラグインの競合を段階的に切り分ける手順

エラーのパターンから明らかな原因を特定できない場合は、標準的なトラブルシューティングの手順で競合を絞り込む。本番サイトで作業する前に、必ずステージング環境を用意するか、メンテナンスモードを有効にしてから行う。

STEP 1 Razorpay以外の全プラグインを無効化する
STEP 2 標準テーマ(Twenty Twenty-Fourなど)に切り替える
STEP 3 本番APIキーでテスト決済を実行し、正常に動作するか確認する
STEP 4 プラグインを1つずつ有効化し、どのタイミングで問題が再発するか特定する

STEP 4では、まず通貨スイッチャーとキャッシュ系プラグインを最初に有効化してテストする。この2つが最も競合を起こしやすい。次にPixelYourSiteなどの外部スクリプトを注入するプラグインをテストし、最後にサンクスページプラグインを検証する。

RazorpayのWebhook設定も再確認する

フロントエンドのJavaScriptエラーに加えて、バックエンドのWebhookが正しく設定されていないと、決済完了後に注文ステータスが更新されない。Razorpayダッシュボードの「Settings → Webhooks」で以下を確認する。

  • Webhook URLが https://あなたのサイトURL/wc-api/razorpay_webhook/ になっている。
  • イベントに payment.authorizedrefund.created が最低限含まれている。
  • WebhookシークレットがWooCommerce側のRazorpay設定に入力した値と完全に一致している。
  • 重複したWebhook登録がない(過去のテストで作成した古いWebhookが残っていると競合する)。

よくある質問

サンドボックスでは正常なのに本番だけで止まるのはなぜですか?

本番用のAPIキー設定ミスか、本番環境専用のプラグイン(セキュリティや最適化)がRazorpayのスクリプトに干渉している可能性が高い。サンドボックスと本番で異なるキーを使っていることを再確認し、本番環境にのみ有効なプラグインを一時停止して切り分ける。

Razorpay以外の決済ゲートウェイでも同じ現象は起こりますか?

StripeやPayPalなど他の決済プラグインでも、JavaScriptの競合やリダイレクトフックの干渉によって同様の「処理中」ループが発生することがある。原因の切り分け手順はほぼ共通しているため、本記事のSTEPを他のゲートウェイにも応用できる。

コンソールにエラーが出ていないのに処理が止まる場合は?

PHPのメモリ不足や実行時間制限が原因で、決済完了後のサーバーサイド処理が途中で止まっている可能性がある。WooCommerceのステータスレポートでPHPのメモリ制限が256MB以上、最大実行時間が300秒以上あるか確認する。サーバーのエラーログも併せて調査する。

Razorpayプラグインを最新にしても直らない場合は?

プラグインの公式GitHubリポジトリで同様のIssueが報告されていないか確認する。解決策としてパッチが提供されていることもある。また、Razorpayのカスタマーサポートに本番環境のドメインとエラーの詳細を伝えて調査を依頼する方法も有効だ。APIキーの発行元アカウントに制限がかかっていないかも合わせて確認してもらえる。

PixelYourSiteを無効化せずに共存させる方法はありますか?

PixelYourSiteの設定で「チェックアウトページでのスクリプト実行を遅延させる」オプションをオフにするか、カスタムコードでRazorpayのスクリプトがPixelYourSiteより先に読み込まれるよう wp_enqueue_scripts の優先度を調整する。functions.phpに以下のようなコードを追加する方法もある。

add_action('wp_enqueue_scripts', function() {
    if (is_checkout()) {
        wp_dequeue_script('pys');
        wp_enqueue_script('pys', 'path/to/pys.js', array('razorpay'), null, true);
    }
}, 100);

このコードはあくまで概念を示すもので、実際のハンドル名やパスはプラグインのソースを確認して書き換える必要がある。

この記事のポイント

  • ブラウザコンソールで /build/undefined 403エラーや razorpayform.submit TypeErrorを確認する
  • 本番用APIキーが正しく入力されているか、Razorpayダッシュボードで再確認する
  • 通貨スイッチャーがチェックアウトページで干渉していないか検証する
  • JavaScript最適化プラグインを完全無効化し、サンクスページカスタマイズプラグインを停止してテストする
  • 全プラグイン無効化と標準テーマ切り替えで競合を段階的に切り分ける
GTranslateで重大エラーが発生した時の原因と復旧手順

GTranslateで重大エラーが発生した時の原因と復旧手順

複数サイトで突然「このサイトで重大なエラーが発生しました」と表示され管理画面にアクセスできなくなった場合、GTranslate プラグインの翻訳ファイル(.po / .mo)に含まれる誤ったフォーマット指定子が原因である可能性が高い。

エラーログに “Unknown format specifier” と出ていれば、特定の言語ファイルに壊れた翻訳文字列が混入している。管理画面を復旧するには、問題のプラグインフォルダを一時的にリネームして無効化し、誤った翻訳文字列を修正したうえで再有効化する手順を踏む。

なぜ GTranslate で突然重大エラーが発生するのか

なぜ GTranslate で突然重大エラーが発生するのか

エラーの直接原因は翻訳ファイルの壊れた sprintf 指定子

WordPress でプラグインの翻訳を担うのは .po(翻訳テンプレート)と、それをコンパイルした .mo(機械可読ファイル)だ。プラグイン開発者が sprintf() で動的に文字列を組み立てている箇所に、翻訳者が誤って不完全な置換指定子(例:"%1$t" など)を入れてしまうと、PHP が文字列フォーマットを解釈できず E_ERROR(致命的エラー)を投げる。

とくに、GTranslate の無料版では管理画面の上部に「ニューラルネット翻訳へのアップグレードを促す通知バナー」を表示している。この通知文のスペイン語(es_ES)翻訳に、%1$s と書くべきところを %1$t とタイプミスした翻訳が混入し、スペイン語ロケールのサイトだけでなく、他の言語設定のサイトでも GTranslate が管理画面を読み込むたびにクラッシュする事象が確認されている。

なぜ他言語サイトまで影響を受けるのか

一見すると日本語や英語のサイトには無関係に思える。しかし GTranslate の管理画面通知は、サイトの表示言語に関係なく、プラグインに同梱された全翻訳ファイルを読み込んだうえで表示言語に合致する文字列を選択する実装になっている。この読み込み段階で誤った .mo ファイルがパースされると、sprintf() が例外をスローし、管理画面全体が停止する。

問題 スペイン語翻訳ファイルに %1$t が混入
結果 管理画面がすべての言語で「重大なエラー」停止
対処 プラグイン無効化 → 翻訳ファイル修正 → 再有効化
エラー発生箇所  修正後の流れ

管理画面にアクセスできない状態からの復旧手順

管理画面にアクセスできない状態からの復旧手順

FTP またはホスティングのファイルマネージャーでプラグインを強制無効化する

管理画面に入れないため、通常の「プラグイン」メニューからの無効化は使えない。FTP クライアント(FileZilla や Cyberduck など)、または契約しているレンタルサーバーのファイルマネージャー機能を使い、サーバー上のディレクトリを直接操作する。

STEP 1 FTP で /wp-content/plugins/ に移動
STEP 2 フォルダ名 gtranslate を右クリック → 「名前の変更」
STEP 3 gtranslategtranslate_deactivated に変更する
STEP 4 管理画面にアクセスできるか確認する

WordPress は指定されたフォルダ名のプラグインが存在しないと判断し、自動的に無効化する。管理画面にログインできたら、プラグイン一覧に GTranslate が「無効」と表示されていることを確認する。

壊れた翻訳ファイルを特定して修正する

問題の翻訳ファイルは /wp-content/languages/plugins/gtranslate-es_ES.po だ。この .po ファイルをテキストエディタで開き、誤ったフォーマット指定子を修正する。

  • 当該行を検索:msgstr "Puedes disfrutar de %1$t で始まる行を探す
  • %1$t%1$s に修正する(”t” の直後に “s” を足す)
  • ファイルを保存し、同名の .mo コンパイル済みファイルが存在する場合はいったん削除またはリネームする

.mo ファイルを削除せずに .po だけ修正しても、WordPress は既存の .mo ファイルを優先して読み込む。そのため修正が反映されず、再度エラーになるケースがある。必ず .mo ファイルを削除するか、Poedit などの専用ツールで新たにコンパイルし直す必要がある。

代替策として該当翻訳ファイルごと一時的に退避させる

.po ファイルの直接編集が難しい場合や、修正しても .mo が再生成されてエラーが戻ってしまう場合は、問題の言語ファイル一式を一時的に別フォルダへ退避させる手もある。

  • /wp-content/languages/plugins/ から gtranslate-es_ES.pogtranslate-es_ES.mo の両方を、サイト外のローカルフォルダに移動する
  • GTranslate プラグインフォルダを元の名前(gtranslate)に戻し、管理画面から再有効化する
  • 管理画面が正常に動作することを確認できたら、プラグイン作者のアップデートを待つ

これは根本解決ではないが、「とにかく今すぐ管理画面を復旧させたい」という状況では有効な暫定策になる。日本語サイトでの管理画面表示にはスペイン語翻訳ファイルは使用されないため、削除しても翻訳機能に影響は出ない。

再発を防ぐためにできること

再発を防ぐためにできること

プラグインの自動更新を一時停止して様子を見る

翻訳ファイルの自動更新は WordPress 本体の仕組みで行われ、プラグイン開発者が意図しないタイミングで新しい翻訳が配信されることがある。GTranslate のように多言語対応が複雑なプラグインは、管理画面から該当プラグインの自動更新をオフにし、公式のアップデート告知を確認してから手動更新する運用が安全だ。

エラーログを定期的にチェックする習慣をつける

今回のエラーは /wp-content/debug.log に記録されていた。WordPress のデバッグモード(wp-config.phpdefine('WP_DEBUG', true);define('WP_DEBUG_LOG', true); を記述)を有効にしておけば、管理画面が停止する前にエラーの予兆をログでキャッチできる。本番運用時は WP_DEBUG_DISPLAYfalse にして、エラーを画面に表示せずログだけに留める設定が推奨される。

よくある質問

他プラグインでも同じエラーは起きるのか

起きる。翻訳ファイルに不完全な sprintf() 指定子が混入する不具合は、どのプラグインでも発生しうる。管理画面が突然停止した場合、エラーログに “Unknown format specifier” と書かれていれば翻訳ファイルを疑うとよい。

FTP が使えない場合はどうすればいいか

契約しているレンタルサーバーの管理パネル(cPanel やコンパネ)にログインし、ファイルマネージャーを使う。GTranslate プラグインフォルダのリネーム操作はブラウザ上で完結する。

GTranslate の代わりに別の翻訳プラグインに乗り換えるべきか

このエラーは翻訳ファイルの一時的な不備であり、プラグイン自体の根本的な欠陥ではない。公式の修正が配信されれば再発リスクは下がる。すでに設定済みの翻訳データがあるなら、急いで乗り換える必要はない。

エラーが解消したあと、古い翻訳ファイルを戻す必要はあるか

退避しただけの場合は、GTranslate の次回アップデート時に正しい翻訳ファイルが再配信される。手動で戻す必要はない。削除した場合も同様に、アップデートや翻訳の再読み込みで自動的に復元される。

この記事のポイント

  • GTranslate の翻訳ファイル破損が原因で管理画面が重大エラー停止する
  • 復旧には FTP でプラグインフォルダをリネームし強制無効化する
  • 誤った sprintf 指定子を修正し .mo ファイルを削除または再生成する
  • 暫定策として問題の言語ファイルを退避させる方法も有効
  • エラーログの定期チェックと自動更新の一時停止で再発を予防できる
WP Event Manager Calendarで致命的エラーが出た時の原因と直し方

WP Event Manager Calendarで致命的エラーが出た時の原因と直し方

WP Event Manager Calendarを有効化すると「Call to undefined function get_event_manager_template()」という致命的なエラーが表示される場合、本体プラグインであるWP Event ManagerとCalendarアドオンのバージョンに互換性の問題が生じている。両方のプラグインを最新版に揃え、それでも直らなければ子テーマのfunctions.phpで関数を一時的に手動定義することで回避できる。

なぜWP Event Manager Calendarでエラーが出るのか

このエラーの根本原因は、アドオンプラグインが呼び出すget_event_manager_template()という関数が、本体のWP Event Manager側で削除されたか、名称変更されていることにある。もともとこの関数は、イベントデータの表示やカレンダー画面の生成を担うテンプレートを読み込むための重要な役割を持っていた。

Calendarアドオンがバージョン3.2.2の時点では問題なく動作していたことから、3.2.2とそれ以降の本体プラグインとの間で、関数の定義に何らかの変更が加えられたと考えられる。ところがアドオン側がその変更に追随しておらず、最新の3.4.0でもエラーが解消されていない状態だ。

WordPressでは、依存関係にあるプラグイン同士のバージョン管理はプラグイン開発者に委ねられている。片方だけ更新したり、互換性の確認を怠ったりすると、今回のように未定義の関数呼び出しによる「Fatal error」が発生し、管理画面に「このサイトで重大なエラーが発生しました」と表示される。

エラーメッセージを正確に特定してデバッグモードを有効にする方法

エラーメッセージを正確に特定してデバッグモードを有効にする方法

エラーが発生するとWordPressは「このサイトで重大なエラーが発生しました」という画面を表示し、管理画面にもアクセスできなくなるケースが多い。まずはエラーの詳細を正確に把握するため、WP_DEBUGモードを有効にしよう。

FTPクライアントやサーバーのファイルマネージャーで、WordPressインストールディレクトリにあるwp-config.phpを開く。次の記述を探し、それぞれtrueに変更する。

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

WP_DEBUG_DISPLAYfalseにすることで、エラーが画面に表示されるのを防ぎつつ、/wp-content/debug.logにログが出力される。このログファイルを確認すれば、先ほどのCall to undefined function get_event_manager_template()と、どのファイルの何行目でエラーが起きたかを正確に特定できる。

WP Event Manager本体とCalendarアドオンの互換性を確保する手順

WP Event Manager本体とCalendarアドオンの互換性を確保する手順

ここでは、エラーを解消するための具体的な手順を4つのステップに分けて示す。まずは基本となるプラグインの全更新から始め、それでも解決しない場合の暫定対応までを押さえる。

STEP 1 WP Event Manager(本体)を最新バージョンに更新する
STEP 2 WP Event Manager Calendarを最新版に更新する
STEP 3 全プラグインを無効化し、キャッシュをクリアして動作確認
STEP 4 子テーマのfunctions.phpに関数を追加して暫定対応

STEP 1からSTEP 3で環境をクリーンな状態に戻す

まず管理画面の「プラグイン」から、WP Event Manager本体が最新であることを確認する。更新可能な場合は更新を実行する。次にCalendarアドオンも同様に最新に揃える。アドオンの更新が提供されていない場合は、一度無効化と再有効化を試すとキャッシュされた古い依存関係が解消されることがある。

両方のプラグインを最新にしたら、一度すべてのプラグインを無効化してから再度必要なものだけを有効化し、ブラウザのキャッシュやサーバー側のキャッシュ(W3 Total CacheやWP Super Cacheなどを使用中の場合)もクリアする。その上で再度カレンダー機能が正常に動くかをテストする。

STEP 4で不足している関数を手動定義する

すべての更新を終えてもエラーが続く場合、WP Event Manager本体が関数の実装を完全に削除してしまっている可能性が高い。この場合の暫定対応として、子テーマのfunctions.phpに、不足している関数を手動で定義する方法がある。

次のコードは、本体プラグインの過去の実装を参考に、get_event_manager_template()関数を再定義する例だ。子テーマのfunctions.phpの末尾に追加する。

if ( ! function_exists( 'get_event_manager_template' ) ) {
    function get_event_manager_template( $template_name, $args = array(), $template_path = 'wp-event-manager', $default_path = '' ) {
        if ( $args && is_array( $args ) ) {
            extract( $args );
        }
        $located = locate_template( array( $template_path . '/' . $template_name ) );
        if ( ! $located && file_exists( WP_PLUGIN_DIR . '/wp-event-manager/templates/' . $template_name ) ) {
            $located = WP_PLUGIN_DIR . '/wp-event-manager/templates/' . $template_name;
        }
        if ( $located ) {
            include( $located );
        }
    }
}

このコードは、まず関数が存在しないかをfunction_exists()で確認し、存在しなければテンプレートファイルをlocate_template()で探して読み込むという最小限の実装だ。本来のWP Event Managerが提供していた機能のすべてを再現するものではないが、Calendarアドオンが最低限必要とする「テンプレート読み込み」の役割を補い、エラーの発生を抑える効果が期待できる。

ただし、これはあくまで緊急回避策だ。WP Event Managerの内部実装に依存しているため、将来のアップデートでさらに互換性の問題が生じる可能性もある。根本的にはプラグイン開発者による修正を待つか、別のイベント管理プラグインへの切り替えを検討する必要がある。

よくある質問

他のイベント管理プラグインに乗り換えたほうがよいのか

WP Event Managerのエコシステム内で完結したい事情がない限り、乗り換えは有効な選択肢だ。The Events CalendarやEvents Managerなどの代替プラグインは、本体とアドオンの互換性がより厳格に管理されている傾向がある。ただし乗り換えの際はイベントデータのエクスポートとインポートの手間が発生する。

無料版のWP Event Managerでもこのエラーは起こるのか

WP Event Managerには無料のコアプラグインと、有料のアドオンが存在する。Calendarアドオンが有料版でのみ提供されている場合、無料版の本体だけではエラーは発生しない。しかし無料アドオンと併用していて同じエラーが起きる場合は、やはり本体とアドオンのバージョン不一致が原因となる。

他のアドオンも同時に影響を受ける可能性はあるか

get_event_manager_template()はWP Event Managerの複数のアドオンから呼び出される共通関数だった可能性が高い。そのため、Calendar以外のアドオン(登録フォームや検索機能など)でも、同じ「Call to undefined function」エラーが発生するリスクがある。本体の更新後は、使用中のすべてのアドオンを一括で最新バージョンに揃えることが重要だ。

重要なサイトで突然このエラーが出た場合の応急措置は

まずFTPでwp-content/plugins/wp-event-manager-calendarフォルダを一時的にリネームしてCalendarアドオンを無効化し、サイトを正常表示に戻す。その間にデバッグログを確認して原因を特定し、STEP 1からSTEP 3の更新作業を進める。どうしても復旧が急がれる場合は、STEP 4の関数手動定義でエラーを抑え込む。

プラグインを最新にしても直らない場合の最終手段は

WP Event Managerのサポートフォーラムや公式ドキュメントで、同じエラーに関する最新の報告がないか確認する。開発チームが修正版をリリースするまでのつなぎとして、古い安定バージョン(今回のケースでは3.2.2)にロールバックする方法もある。WP Rollbackプラグインを使えば、管理画面から安全に旧バージョンへ戻せる。

この記事のポイント

  • エラーはWP Event Manager本体とCalendarアドオンのバージョン不一致が主因
  • 両方のプラグインを最新版に更新し、キャッシュをクリアして動作確認する
  • WP_DEBUGモードでエラーの正確な発生箇所を特定する
  • どうしても直らない場合は子テーマで関数を手動定義して暫定回避する
  • 根本解決にはプラグイン開発者の修正か代替プラグインへの移行を検討する