Contact Form 7 v5.4.1でフィルターフックを使うとエラーが出る現象

WordPressのプラグイン「Contact Form 7」の話。
エラーメッセージの位置を変えたくて[参考サイト](http://wpcj.net/1130)を元にフィルターフックを使用したが、なぜかエラーになってハマってしまった。

こちらの問題かと色々試行錯誤してみたが解決せず。
調べてみると他でも同じ現象があって、[サポートの方でも上がっている](https://wordpress.org/support/topic/contact-form-7-invalid-json/)ようだけど、2021年6月18日現在では解消していない。

**使用したフィルターフック**
・wpcf7_ajax_json_echo
・wpcf7_feedback_response

**特定のバージョンのみで発生する模様**
・Contact Form 7　v5.4.1

**エラーの内容**
ローティングアイコンが消えず、以下のJSエラーが出る。

``` js
{code: "invalid_json", message: "The response is not a valid JSON response."}@ index.js?ver=5.4:1
```

## 解決方法
Contact Form 7 をv5.3.2にダウングレードした。
過去バージョンは以下ページの最下部のプルダウンからバージョン選んでダウンロード可能。
https://ja.wordpress.org/plugins/contact-form-7/advanced/

これで動くようになった。
注意点として参照する配列キーが変わっているので注意。
`invalids`（v5.2以前） → `invalid_fields`(v5.3以降)

``` function.php
function wpcf7_custom_item_error_position( $items, $result ) {
  $class = 'wpcf7-custom-item-error';
  $names = array('name','tel');

  if ( isset( $items['invalid_fields'] ) ) {
      foreach ( $items['invalid_fields'] as $k => $v ) {
          $orig = $v['into'];
          $name = substr( $orig, strrpos($orig, ".") + 1 );
          if ( in_array( $name, $names ) ) {
              $items['invalid_fields'][$k]['into'] = ".{$class}.{$name}";
          }
      }
  }
  return $items;
}
add_filter( 'wpcf7_feedback_response', 'wpcf7_custom_item_error_position', 10, 2 );
```
とても素晴らしいプラグインなので今後のアップデートに期待。

## 2022年6月3日追記　Contact Form 7 v5.5.6.1でwpcf7_feedback_responseを正しく機能させる方法。さらにConditional Fields for Contact Form 7 v2.1.5を併用してもwpcf7_feedback_responseを正しく機能させる方法
@mechanajira さんご指摘ありがとうございました。

Contact Form 7 は`v5.3.2以降は仕様が変わってPHPのコードはそのままで問題ありませんが、「Contact Form 7の方のタグを変更する」必要があります。`
phpの`$v['into']`で指定した HTML エレメントの下層には、`wpcf7-form-control` クラスを持つエレメントが必要、ということです。
フォームコントロールに クラスを追加することで、例えばエラーのあるテキストフィールドの枠を赤くするなどのカスタマイズを可能にするための物です。

というわけで、Contact Form 7のタグを
```html
<span class="wpcf7-custom-item-error name tel">
    <span class="wpcf7-form-control"></span>
</span>
```
`エラーメッセージの表示位置の <span> の中にさらに <span> で wpcf7-form-control クラスを持った要素を追加してやる必要があります。`

ただし、このままだと、今まで`name`か`tel`のどちらかのエラーメッセージ１つだけが表示されていたものが、この変更で両方表示されるようになります。
必ず一方のみがエラーになるのであればphpは変更の必要がありませんが、両方エラーになった時、エラーを1つだけ表示したい場合はphpの変更も必要になります。
又、Conditional Fields for Contact Form 7 v2.1.5を併用した場合さらに、考慮が必要になります。
`$orig`の末尾に、Conditional Fields for Contact Form 7が`:not(.wpcf7cf-disabled)`という要素を追加します。
Conditional Fields for Contact Form 7を併用しようが、しまいが、どちらでも動作するようにするためには、具体的には以下のように修正します。

``` function.php
function wpcf7_custom_item_error_position( $items, $result ) {
  $class = 'wpcf7-custom-item-error';
  $names = array('name','tel');
  $processed_messeage = false;

  if ( isset( $items['invalid_fields'] ) ) {
      foreach ( $items['invalid_fields'] as $k => $v ) {
		  $orig = $v['into'];
		  $name = substr($orig, 0, strcspn($orig,':'));
		  $name = substr( $name, strrpos($name, ".") + 1 );
          if ( in_array( $name, $names ) ) {
			if ($name == 'name' || $name == 'tel') {
				if ($processed_messeage == true) {
					unset($items['invalid_fields'][$k]);
					continue;
				} else {
					$processed_messeage = true;
				}
			}
              $items['invalid_fields'][$k]['into'] = ".{$class}.{$name}";
          }
      }
      $items['invalid_fields'] = array_values($items['invalid_fields']);
  }
  return $items;
}
add_filter( 'wpcf7_feedback_response', 'wpcf7_custom_item_error_position', 10, 2 );
```

これで、
WordPress：5.9.3（最新版）
PHP：7.4.25
Contact Form 7：5.5.6.1（最新版）
Conditional Fields for Contact Form 7：2.1.5（最新版）使用、未使用でも問題なし
で問題なく動作します。

### その他参考サイト
https://dezanari.com/contactform7-error-position/
https://nldot.info/i-want-to-change-the-validation-message-display-position-in-copipable-contact-form-7/
http://wpcj.net/1130