概要
MW WP Form でラジオボタンの送信値を日本語に変換してメールに反映させようとしたところ、mwform_value フックを使っても値が変換されないという問題にハマった。
結論から言うと、原因は post_raw="true" という属性だった。この属性があると MW WP Form の内部処理がスキップされ、フックに値が渡らなくなる。公式ドキュメントにも明記されていない罠なので、同じ症状で詰まっている人の参考になれば。
環境
| 項目 | バージョン |
|---|---|
| WordPress | 6.x |
| PHP | 8.x |
| MW WP Form | 5.1.0 |
| テーマ | Emanon Premium(子テーマ) |
前提:本来の動作
MW WP Form のラジオボタンは children にこう書く。
[mwform_radio name="category" children="option_a : 選択肢A, option_b : 選択肢B"]
value : ラベル の形式で書けば、通常はメールにはラベル(選択肢A)が届く設計になっている。
ではなぜ英字のまま届いたのか。それが post_raw="true" の問題だった。
やりたかったこと
ラジオボタンのvalue値は英字(option_a, option_b など)で管理しているが、メールには日本語(選択肢A, 選択肢B など)で届いてほしい。フォームのショートコードはこう書いていた。
[mwform_radio name="category" children="option_a : 選択肢A, option_b : 選択肢B" post_raw="true"]
最初に試したこと(NG)
mwform_validation_values フィルターで値を書き換えようとした。
add_filter( 'mwform_validation_values_mw-wp-form-116', function( $values, $Data ) {
$label_map = [
'option_a' => '選択肢A',
'option_b' => '選択肢B',
];
if ( isset( $values['category'] ) ) {
$values['category'] = $label_map[$values['category']] ?? $values['category'];
}
return $values;
}, 10, 2 );
結果:メールには依然として英字のまま届いた。
mwform_validation_values はバリデーション処理用のフックで、メールテンプレートへの差し込みには影響しない。フック自体は動いているが、使う場所が違った。
原因の切り分け
次に mwform_value フックを試したが、やはり変換されなかった。本当にフックが呼ばれているのかを確認するため、セッションに値を保存して検証した。
なぜセッションを使ったか:フォーム送信は画面遷移を伴うため、var_dump や echo を直接書いても確認できない。ログが見られない共有サーバー環境だったこともあり、セッションに保存して送信後のページで出力する方法をとった。
// フックの中でセッションに保存
add_filter( 'mwform_value_mw-wp-form-116', function ( $value, $name ) {
if ( $name === 'category' ) {
$_SESSION['debug_category'] = 'フック呼ばれた: ' . print_r( $value, true );
}
return $value;
}, 10, 2 );
// wp_footer で画面に出力
add_action( 'wp_footer', function () {
echo '<pre style="background:yellow;padding:10px;">';
echo 'SESSION: ' . print_r( $_SESSION['debug_category'] ?? 'なし', true );
echo '</pre>';
});
結果は SESSION: フック呼ばれた: で、フックは呼ばれているが値が空だった。
真の原因:post_raw="true" の罠
post_raw="true" がある場合とない場合で、MW WP Form の内部処理フローが変わる。
// 通常(post_raw なし)
$_POST → MW WP Form 内部整形処理 → mwform_value フック → メール差し込み
// post_raw="true" あり
$_POST → メール差し込み(整形処理・フックをスキップ)
MW WP Form は通常、受け取った値を内部のデータオブジェクトに格納して管理する。mwform_value フックはそのデータオブジェクトから値を取り出すタイミングで発火する。
post_raw="true" を付けると、この整形処理を完全にスキップして $_POST の値をそのままメールに渡す。その結果、children に書いたラベル変換も行われず、フックにも値が渡らなくなる。
つまり post_raw="true" がある限り、どんなフックを書いても整形後の値がフックに渡らない。MW WP Form は送信値を一度データクラスにラップして管理しているが、post_raw="true" はそのラップ処理を通さない。
解決策
ケース①:post_raw が不要なら外すだけでいい
実は children="value : ラベル" の形式で書いている場合、post_raw="true" を外すだけでメールにはラベルが届く。MW WP Form の本来の設計がラベル変換を行うためで、フックすら不要なケースもある。post_raw="true" を使う場合はサニタイズ処理を自前で担保する必要がある。
[mwform_radio name="category" children="option_a : 選択肢A, option_b : 選択肢B, option_c : 選択肢C"]
まずはこれだけ試してほしい。
ケース②:value値で制御したい場合はフックで変換する
DBへの保存や外部連携で英字のvalue値が必要、あるいはラベルとは別の日本語表記をメールに使いたいといった場合は、mwform_value フックで変換する。
add_filter( 'mwform_value_mw-wp-form-116', function ( $value, $name ) {
if ( $name !== 'category' ) {
return $value;
}
$label_map = [
'option_a' => '選択肢A',
'option_b' => '選択肢B',
'option_c' => '選択肢C',
];
if ( is_array( $value ) ) {
$converted = array_map( fn($v) => $label_map[$v] ?? $v, $value );
return implode( '、', $converted );
}
return $label_map[$value] ?? $value;
}, 10, 2 );
post_raw="true" をあえて使うケース
post_raw="true" は罠ではなく、意図して使う場面もある。
- 外部APIやDBと連携するためにvalue値をそのまま渡したいとき
- MW WP Form の整形処理に干渉させたくない特殊な加工を自前でやるとき
ただし「MW WP Form のデータ管理レイヤーを無効化するスイッチ」であることを理解したうえで使う必要がある。フックが一切効かなくなるため、変換処理が必要な場面では使わないのが原則だ。
まとめ
-
mwform_validation_valuesはバリデーション用で、メール差し込みには使えない -
children="value : ラベル"形式ならpost_raw="true"を外すだけでラベルが届く - メール差し込み値をコードで制御したい場合は
mwform_valueフックを使う -
post_raw="true"を使うと MW WP Form の整形処理がスキップされる - デバッグはセッション+
wp_footerでの出力が、画面遷移があるフォームには有効
MW WP Form は「値を整形して扱う設計」のプラグインである。
post_raw="true" はその設計思想を無効化するスイッチだ。
MW WP Form でフックが効かないときは、まず post_raw="true" を疑え。