Rubyと筋肉とギターとわたし

筋トレが仕事です

【wordpress】contact form 7でinternal server errorが発生するときの対処法

お久しぶりです、もてぃです。

前回記事を書いてから半年以上が経過し、もうあと2ヶ月で今年も終わってしまいますね。時間の流れは残酷です。

今回はグループ会社のwordpressを新サーバーに移行した際に起きたエラーの解決方法を書いていきます。

新・旧サーバーについて

旧サーバー

諸事上によりphp, kusanagiを吹き飛ばしてしまったのでうる覚えです。

新サーバー

いずれもwebサーバーはapacheを使用しています(本当はnginxを使いたいが普段管理している人が使えないため)

contact form 7で起きたエラー

送信時に何も起きなかったので開発者コンソールを確認しました。それが以下。

error

さらに中を見てみる

error dev tool

全く意味不明。

なのでサーバーにsshしてログを確認します。

ログを確認する

centos stream 9のkusanagiで構築したサーバーの設定ファイルの場所は少し特殊です。

例えばapachephp-fpmの場所は /etc/opt/kusanagi配下に作成されます(/etc配下ではないです)。

ログも同じく変わった場所にあり、 /var/opt/kusanagi/log 配下にあります。今回対象のログは /var/opt/kusanagi/log/php-fpm/error.log を見ればOK。

ログの中身が以下。

NOTICE: PHP message: PHP Warning:  Attempt to read property "post_parent" on null in /home/kusanagi/hogehoge/DocumentRoot/wp/wp-content/plugins/code-snippets/php/snippet-ops.php(581) : eval()'d code on line 3
NOTICE: PHP message: PHP Fatal error:  Uncaught TypeError: implode(): Argument #2 ($array) must be of type ?array, string given in /home/kusanagi/hogehoge/DocumentRoot/wp/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin.php:849
Stack trace:
#0 /home/kusanagi/hogehoge/DocumentRoot/wp/wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin.php(849): implode()
#1 /home/kusanagi/hogehoge/DocumentRoot/wp/wp-content/plugins/contact-form-7-to-database-extension/CFDBIntegrationContactForm7.php(55): CF7DBPlugin->saveFormData()
#2 /home/kusanagi/hogehoge/DocumentRoot/wp/wp-includes/class-wp-hook.php(309): CFDBIntegrationContactForm7->saveFormData()
#3 /home/kusanagi/hogehoge/DocumentRoot/wp/wp-includes/class-wp-hook.php(331): WP_Hook->apply_filters()
#4 /home/kusanagi/hogehoge/DocumentRoot/wp/wp-includes/plugin.php(522): WP_Hook->do_action()
#5 /home/kusanagi/hogehoge/DocumentRoot/wp/wp-content/plugins/contact-form-7/includes/submission.php(616): do_...

CF7DBPlugin.phpの849行目を修正すればよさそう。でも可能ならプラグインの中身はさわりたくないなぁ…ということで検索。

同じ人いたけど、ちがうっぽい。

wordpress.org

どうしたものか。。

php implode()の確認

そもそものエラー内容の implode()関数がどういうふうに使われるか確認してみる。

リファレンス

www.php.net

implode(string $separator, array $array): string

Rubyでいう Array#join みたいな挙動。

今の環境がphp8なので

implode(array $array, string $separator): string

の挙動が削除されているとのこと。

contact form 7 DBの該当箇所を修正する必要があるなこれ。

該当ファイル

 843             foreach ($cf7->posted_data as $name => $value) {
 844                 $nameClean = stripslashes($name);
 845                 if ($this->fieldMatches($nameClean, $noSaveFields)) {
 846                     continue; // Don't save in DB
 847                 }
 848 
 849                 $value = is_array($value) ? implode($value, ', ') : $value; // ここ!!!!
 850                 $valueClean = stripslashes($value);
 851 
 852                 // Check if this is a file upload field
 853                 $didSaveFile = false;
 854                 if ($cf7->uploaded_files && isset($cf7->uploaded_files[$nameClean])) {
 855                     $foundUploadFiles[] = $nameClean;
 856                     $filePath = $cf7->uploaded_files[$nameClean];
 857                     if ($filePath) {
 858                         $content = file_get_contents($filePath);
 859                         $didSaveFile = $wpdb->query($wpdb->prepare($parametrizedFileQuery,
 860                             $time,
 861                             $title,
 862                             $nameClean,
 863                             $valueClean,
 864                             $order++,
 865                             $content));
 866                         if (!$didSaveFile) {
 867                             $this->getErrorLog()->log("CFDB Error: could not save uploaded file, field=$nameClean, file=$filePath");
 868                         }
 869                     }
 870                 }
 871                 if (!$didSaveFile) {
 872                     $wpdb->query($wpdb->prepare($parametrizedQuery,
 873                         $time,
 874                         $title,
 875                         $nameClean,
 876                         $valueClean,
 877                         $order++));
 878                 }
 879             }

修正したのがこれ

$value = is_array($value) ? implode(', ', $value) : $value;

これでおk。

phpの再起動 & 送信確認

$ sudo systemctl restart php-fpm.service

うまくいきましたー。

結論

wordpressプラグインはクソ。

メンテできないなら使うな。

あと、アプデするならちゃんとプラグインも整理しましょうね!反省!