Contact Form 7 + Flamingo の送信データ格納先を変更しようとした話
2025-09-07
WordPress でお問い合わせフォームを利用する際、Contact Form 7(CF7)と Flamingo を組み合わせて使うのが定番ですが、デフォルトでは送信データの保存場所がworpdressのデータベースの wp_postsテーブル と wp_postmeta テーブルに格納されます。
今回は、これらの格納先を wp_custom_flamingo_posts , wp_custom_flamingo_metaという独自のテーブルに変更しようと試みた話をまとめます。
目次
カスタムプラグイン作成:Custom Flamingo Mod
Flamingo のデータ保存処理を変更するため、独自の WordPress プラグイン「Custom Flamingo Mod」を作成しました。
プラグインの基本構成
/wp-content/plugins/custom-flamingo-mod/
└── custom-flamingo-mod.php
試みたこと
送信データの格納先テーブルの変更
wp_posts と wp_postmeta ではなく、wp_custom_flamingo_posts, wp_custom_flamingo_meta に格納するように変更。
// プラグイン有効化時に独自テーブル作成
function create_custom_flamingo_table() {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_flamingo_messages';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
post_id bigint(20) unsigned NOT NULL DEFAULT 0,
post_author bigint(20) unsigned NOT NULL DEFAULT 0,
post_date datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
post_date_gmt datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
post_content longtext COLLATE utf8mb4_unicode_ci NOT NULL,
post_title text COLLATE utf8mb4_unicode_ci NOT NULL,
post_excerpt text COLLATE utf8mb4_unicode_ci NOT NULL,
post_status varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'publish',
comment_status varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'open',
ping_status varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'open',
post_password varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
post_name varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
to_ping text COLLATE utf8mb4_unicode_ci NOT NULL,
pinged text COLLATE utf8mb4_unicode_ci NOT NULL,
post_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
post_modified_gmt datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
post_content_filtered longtext COLLATE utf8mb4_unicode_ci NOT NULL,
post_parent bigint(20) unsigned NOT NULL DEFAULT 0,
guid varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
menu_order int(11) NOT NULL DEFAULT 0,
post_type varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'flamingo_message',
post_mime_type varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
comment_count bigint(20) NOT NULL DEFAULT 0,
PRIMARY KEY (ID),
KEY post_name (post_name),
KEY post_parent (post_parent),
KEY post_author (post_author),
KEY post_type (post_type)
) $charset_collate;";
$table_name = $wpdb->prefix . 'custom_flamingo_meta';
$charset_collate = $wpdb->get_charset_collate();
$sql_meta = "CREATE TABLE IF NOT EXISTS $table_name (
meta_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
post_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
meta_key VARCHAR(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
meta_value LONGTEXT COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (meta_id),
KEY post_id (post_id),
KEY meta_key (meta_key)
) ENGINE=InnoDB $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
dbDelta($sql_meta);
}
register_activation_hook(__FILE__, 'create_custom_flamingo_table');
投稿データの格納テーブルの変更方法
wp_insert_post のフックを利用し、post_type を検証することで wp_custom_flamingo_posts に保存することに成功。
//格納テーブルを独自テーブルへ変更
function copy_flamingo_data_to_custom_table($post_id, $post, $update) {
error_log("post_id: " . $post_id);
// `flamingo_inbound` のデータだけ処理する
if ($post->post_type === 'flamingo_inbound') {
$existing_value = get_option('flamingo_custom_id', '');
// 新しいデータを結合(例: "_new_data" を追加)
$new_value = $existing_value . ',' . $post_id;
// 更新
update_option('flamingo_custom_id', $new_value, 'yes');
// ログ出力(確認用)
error_log("Updated flamingo_custom_id: " . $new_value);
global $wpdb;
$table_name = $wpdb->prefix . 'custom_flamingo_messages';
$data = array(
'ID' => NULL, // AUTO_INCREMENT
'post_id' => $post_id,
'post_author' => $post->post_author,
'post_date' => $post->post_date,
'post_date_gmt' => $post->post_date_gmt,
'post_content' => $post->post_content,
'post_title' => $post->post_title,
'post_excerpt' => $post->post_excerpt,
'post_status' => $post->post_status,
'comment_status' => $post->comment_status,
'ping_status' => $post->ping_status,
'post_password' => $post->post_password,
'post_name' => $post->post_name,
'to_ping' => $post->to_ping,
'pinged' => $post->pinged,
'post_modified' => $post->post_modified,
'post_modified_gmt' => $post->post_modified_gmt,
'post_content_filtered' => $post->post_content_filtered,
'post_parent' => $post->post_parent,
'guid' => $post->guid,
'menu_order' => $post->menu_order,
'post_type' => 'flamingo_inbound', // カスタムテーブル用のタイプ
'post_mime_type' => $post->post_mime_type,
'comment_count' => $post->comment_count,
);
// データを挿入
$result = $wpdb->insert($table_name, $data);
// `wp_posts` から削除(必要なら)
wp_delete_post($post_id, true);
return $post_id;
} elseif ($post->post_type === 'flamingo_contact') {
$existing_value = get_option('flamingo_custom_id', '');
// 新しいデータを結合(例: "_new_data" を追加)
$new_value = $existing_value . ',' . $post_id;
// 更新
update_option('flamingo_custom_id', $new_value, 'yes');
// ログ出力(確認用)
error_log("Updated flamingo_custom_id: " . $new_value);
global $wpdb;
$table_name = $wpdb->prefix . 'custom_flamingo_messages';
$data = array(
'ID' => NULL,
'post_id' => $post_id,
'post_type' => 'flamingo_contact',
'post_status' => 'publish',
'post_title' => $post->post_title,
'post_name' => $post->post_name,
'post_content' => $post->post_content,
);
// データを挿入
$result = $wpdb->insert($table_name, $data);
// `wp_posts` から削除(必要なら)
wp_delete_post($post_id, true);
return $post_id;
} else {
return;
}
}
add_action('wp_insert_post', 'copy_flamingo_data_to_custom_table', 10, 3);
メタデータの保存先の変更
update_post_meta のフックを利用し、wp_options に格納した post_id をもとに Flamingo の投稿かどうかを判定しようと試みた。
//メタデータの保存先を独自メタデータ用テーブルへ変更
function redirect_flamingo_meta_update( $null, $object_id, $meta_key, $meta_value ) {
error_log("redirect_flamingo_meta_update");
$post_type = 'post';
if( 'post' === $post_type){
$flamingo_custom_id = get_option('flamingo_custom_id', '');
error_log("Hook triggered - flamingo_custom_id: {$flamingo_custom_id}, object_id: {$object_id}, meta_key: {$meta_key}, meta_value: {$meta_value}");
if (strpos($flamingo_custom_id, $object_id) !== false) {
global $wpdb;
$custom_table = $wpdb->prefix . 'custom_flamingo_meta';
error_log("Saving to custom table - post_id: {$object_id}, meta_key: {$meta_key}, meta_value: {$meta_value}");
// カスタムテーブルにデータを保存
$wpdb->replace(
$custom_table,
[
'post_id' => $object_id,
'meta_key' => $meta_key,
'meta_value' => $meta_value
]
);
error_log("Data saved successfully!");
// `false` を返すと `update_post_meta()` の保存をスキップできる
return false;
}
}
return $null;
}
add_action( 'update_post_meta', 'redirect_flamingo_meta_update', 10, 4 );
問題発生:update_post_meta のフックが引っかからない?
作り始めたころは update_post_meta のフックが正常に動作していたはずなのに、なぜか途中から反応しなくなりました。
「なぜ?」と悩みながら、update_metadaに変えたりなど、デバッグを続けましたが、どうしても update_post_meta のフックが発火せず、今のところ原因を特定できていません。
考察:Flamingo は WordPress のお作法に従った保存方法をしている?
Flamingo のデータ保存方法を改めて見直してみると、WordPress の標準的なデータ管理の流れに沿っているように思えます。
当初は「テーブルを分けた方が DB を直接見たときに確認しやすいのでは?」と考えていましたが、データベースを直接確認するときは、wp_posts テーブルで SELECT * FROM `wp_posts` WHERE `post_type` LIKE 'flamingo%’ で切り分ければ十分かもしれません。
さらに、WordPress の標準的なデータ管理の流れを活用することで、例えば LiteSpeed Cache などのデータベース最適化機能を利用し、不要になった(孤立した)postmeta 情報を自動削除できるという利点があります。独自のテーブルでデータを管理してしまうと、こうした WordPress 標準機能の恩恵を受けることができません。そのため、あえてテーブルを分ける必要はないかもしれません。
ただし、wp_postmeta には、1件の問い合わせから名前やメールアドレス、問い合わせ内容などのデータが個別に格納されるため、レコード数が増える仕様になっています。大量の問い合わせを受けるサイトでは、これがボトルネックになる可能性がありそうです。
結論:テーブル分割の必要性は?
カスタムテーブルを作成してみたものの、WordPress の標準機能を活かしたデータ管理の方が実用的かもしれません。
ただ、wp_postmeta 方式はデータの増加によりパフォーマンスに影響を与える可能性があるため、大量の問い合わせが来るようなサイトは最適な保存方法を考える必要がありそうです。
気が向けば今後も検証を続ける予定です。
サーバ&テクノロジContact Form 7,DB最適化,Flamingo,LiteSpeed Cache,update_post_meta,wordpress,WordPress最適化,wp_insert_post,wp_postmeta,wp_posts,カスタムテーブル,カスタムプラグイン,データベース,フック,問い合わせフォーム
Posted by 納戸 工房
関連記事

QUIC.cloud を有効化するまでの実録(自宅 WordPress+OpenLiteSpeed/WireGuard公開)
LiteSpeed Cache の CDN(QUIC.cloud)を自宅 Wor ...

【Google AdSense】審査を通過したサイト改善ポイントまとめ
Google AdSense 審査に合格した際の最終的な編集ポイントと、審査通過 ...

RSSフィードの改善:RSS Validatorでの警告解消とMySQLによる属性削除
以前の記事では W3C Feed Validator を使って WordPres ...

WordPressのLiteSpeed CacheプラグインでCloudflareを有効にする方法
WordPressのパフォーマンスを向上させるために、Cloudflareを利用 ...

WordPress(Luxeritas + SyntaxHighlighter Evolved)でRSSフィードが壊れた原因と対処法
このブログは WordPress に Luxeritas テーマを使って運営して ...







ディスカッション
コメント一覧
まだ、コメントがありません