説明
Neutrope Lead Desk for Contact Form 7は、Contact Form 7のすべての送信内容を専用のデータベーステーブルへ保存し、リードとして管理するためのシンプルな WordPress 管理画面を提供します。
無料版は対象を明確に絞っています。送信内容を確実に保存し、管理画面の一覧と詳細の UI、ステータス変更、内部メモ、CSV 出力を提供します。外部サービスやトラッカーを組み込まず、無関係な画面にアップセルのバナーを表示することもありません。
バージョン0.3.0は、主にアドオンのための土台となるリリースです。文書化された汎用的な拡張ポイントを追加し、他のプラグインがこのプラグインをフォークすることなく、列やフィルター、詳細画面のパネルを追加できるようにしました。これによってプラグイン自身の動作が変わることはなく、データベースの変更も伴いません。詳しくは下記の「プラグインの拡張」を参照してください。
0.2.0以降、各エントリーには対応履歴 (Activity Timeline) も記録されます。現在のステータスだけから対応の経緯を推測するのではなく、問い合わせに対してすでに何が行われたか (いつ届いたか、誰がステータスをどの値に変更したか、いつメモが追加されたか、いつゴミ箱へ移動・復元・スパム指定されたか) を確認できます。
主な機能
- Contact Form 7のすべての送信内容を専用テーブル (
{prefix}nldcf7_entries) へ自動保存 - 送信データ全体を常に JSON として保存するため、ユーザーに入力してもらった内容を失いません
- 設定可能な候補リストを使用して、氏名、メールアドレス、電話番号、会社名のマッピング用列を自動抽出
- キーワード、ステータス、フォーム、期間による絞り込みと一括操作 (ステータス変更、ゴミ箱へ移動、スパム指定) に対応した管理画面の一覧
- ゴミ箱への移動は取り消せます。移動したエントリーはデータベースに残り、「ゴミ箱」ビューから行ごとまたは一括で復元できるため、誤操作は SQL ではなく管理画面から元に戻せます
- すべての送信フィールド、送信メタデータ、ステータス管理、チーム内メモを備えた詳細画面
- 詳細画面にエントリーごとの対応履歴を表示。受信日時、すべてのステータス変更 (どのステータスからどのステータスへ変更したか)、内部メモの操作、ゴミ箱への移動と復元、スパム状態の変更を記録し、それぞれ操作したユーザーと日時を添えて新しい順に表示、50件ずつページ送りします
- 0.2.0より前に取得したエントリーでは、対応履歴はデータベースに実際に記録されていた情報、つまり元の受信日時とこれまでの内部メモから再構成されます。アップグレード前に行われたステータス変更、ゴミ箱への移動、スパム指定はどこにも保存されていないため、作り出すことはありません。対応履歴は推測せず、その旨をそのまま表示します
- これまでのメモが引き続き正式な記録です。対応履歴はメモへリンクするだけで、置き換えや書き換え、複製は行いません
- 日付、ステータス、フォーム、スパムのフィルターに対応した CSV 出力 (UTF-8 BOM 付き、CRLF)。大規模なデータセットでは分割してストリーミング出力
- 添付ファイルのメタデータ (ファイル名、MIME タイプ、サイズ) を取得。ファイル本体は Contact Form 7の標準処理に委ねられます
- プライバシーに配慮した初期設定: IP アドレスの取得は初期設定で無効
- アンインストール時のデータ削除はオプトイン (誤って削除してもリードが消去されないよう、初期設定では無効)
- アクション / フィルターフックによる拡張に対応:
nldcf7_after_entry_saved、nldcf7_after_note_added、nldcf7_after_status_changed、nldcf7_after_entry_trashed、nldcf7_after_entry_restored、nldcf7_after_spam_changed、nldcf7_entry_data_before_insert、nldcf7_export_columns、nldcf7_export_row、nldcf7_statuses、nldcf7_event_labels、nldcf7_event_render、nldcf7_required_capability - 0.3.0以降は、さらに9つの拡張ポイントにより、アドオンがエントリー詳細画面にパネルを配置し、一覧の列やフィルターの操作部品を追加し、一覧の操作をまたいで独自のフィルター状態を保持し、エントリーの取得クエリーを絞り込めるようになりました。いずれも「プラグインの拡張」に記載しています
動作要件
- WordPress 6.0以降
- PHP 7.4以降
- Contact Form 7プラグインがインストール済みで有効化されていること
無料版の対象外となる機能
- 外部通知の送信 (Slack、Chatwork、メールダイジェスト)
- 担当者の割り当て / チームへの振り分け
- 自動フォローアップのリマインダー
- 簡易カウンターを超える分析ダッシュボードやレポート
- アップロードされたファイル本体の保存 (取得するのはメタデータのみ)
これらは将来の Pro 版で検討される可能性があります。無料版プラグインは、単体で十分に役立つよう設計されています。
プラグインの拡張
バージョン0.3.0では、アドオン開発者向けに9つの拡張ポイントを追加しました。これらは汎用的なもので、このプラグインはアドオンが何を保存するかを一切関知しません。いずれも待ち受けるものがなければ何も行わないため、アドオンを使用していないサイトの動作は0.2.0のときとまったく同じです。
nldcf7_entry_detail_main
アクション。0.3.0で追加。エントリー詳細画面で、メインカラムにあるこのプラグイン自身のカードのあと、カラムが閉じる前に発火します。
do_action( 'nldcf7_entry_detail_main', array $entry )
$entry is the entry row as stored, passed by value. The listener prints its
リスナーは、カードの外枠を含む独自のマークアップを出力し、そのエスケープにも責任を持ちます。出力はバッファリングも改変もされません。
nldcf7_entry_detail_sidebar
アクション。0.3.0で追加。サイドバーのカラムに対する、同じ取り決めのフックです。フックが2つあるため、アドオンは1つの画面の両方のカラムにコンテンツを配置できます。
do_action( 'nldcf7_entry_detail_sidebar', array $entry )
nldcf7_entry_list_columns
フィルター。0.3.0で追加。エントリー一覧に列を追加します。
apply_filters( 'nldcf7_entry_list_columns', array $columns )
独自のキーを追加した列のマップを返してください。衝突を避けるため、キーには接頭辞を付けてください。コアの列は削除も名称変更も転用もできません。フィルターの実行後、コアのキーはすべて本来のラベルに戻され、チェックボックスの列は必ず先頭に戻されます。ラベルはプレーンテキストで、出力時にエスケープされます。
nldcf7_entry_list_column_content
フィルター。0.3.0で追加。追加した列のセルを描画します。
apply_filters( 'nldcf7_entry_list_column_content', string $html, string $column_name, array $item )
独自の列については HTML を返し、それ以外については渡された値をそのまま返してください。自分の出力はエスケープしてください。プラグインは二重の防御として、その結果をさらに wp_kses_post() に通します。そのため通常の投稿マークアップは残りますが、スクリプトとイベントハンドラーは残りません。文字列以外を返した場合、セルは空で表示されます。
nldcf7_entry_list_filters
アクション。0.3.0で追加。一覧にある既存の GET フィルターフォームの内部、「絞り込み」ボタンの手前で発火します。これにより、単純な select や input を組み込みのフィルターと一緒に送信できます。
do_action( 'nldcf7_entry_list_filters', array $current_args )
$current_args is this plugin's own sanitized filter state, for reference. You
フィールド名、値、エスケープ処理は利用者側の責任です。nonce は関与しません。フィルターバーは読み取りしか行いません。
nldcf7_entry_list_carried_args
フィルター。0.3.0で追加。「すべて」と「ゴミ箱」の各ビュー、行ごとの操作、行操作や一括操作のあとのリダイレクトをまたいで、独自のフィルター状態を保持します。
apply_filters( 'nldcf7_entry_list_carried_args', array $args, array $core )
サニタイズ済みのスカラー値を独自に追加してください。プラグインはその結果をあとから再検査します。予約済みのキー (page、paged、action、action2、entry_id、_wpnonce、_wp_http_referer、view、event_page、status_view) は取り除かれ、キーは正規化され、スカラー以外は破棄され、値の長さと引数の数の両方に上限が適用されます。コア側の値が常に優先されます。クエリー文字列全体をそのまま引き継ごうとしないでください。
nldcf7_entry_query_args
フィルター。0.3.0で追加。SQL を書かずに、リポジトリーがすでに理解している引数を使ってエントリーの取得クエリーを調整します。
apply_filters( 'nldcf7_entry_query_args', array $args )
最もよく使うのは ids で、クエリーの対象を限定するエントリー ID の配列です。$args[‘context’] は呼び出し元を示し、エントリー一覧画面では list、CSV では export、それ以外では default になります。両方の呼び出し元が同じリポジトリーを共有しているため、必ず確認してください。条件を付けずに絞り込むと、CSV 出力の内容まで変わってしまいます。
nldcf7_entry_query_clauses
フィルター。0.3.0で追加。独自のテーブルを使ってエントリーの取得クエリーを絞り込みます。該当する ID を PHP に読み込むのではなく、データベース側で解決します。
apply_filters( 'nldcf7_entry_query_clauses', array $parts, array $args )
$parts has four keys:
join— JOIN 句の文字列。where— 条件文字列の配列。各文字列では%sまたは%dのプレースホルダーを使用します。prepare_args— それらのプレースホルダーに対応する値を、順番に並べたもの。distinct— 真偽値。初期値は false。
値は必ず prepare_args に入れ、条件文字列の中には書かないでください。プラグインはそれらを $wpdb->prepare() に渡します。組み立て済みの SQL 文字列を1本渡す方法は受け付けません。プレースホルダーの数と値の数が一致しない場合、その追加内容は全体が破棄されます。join の中のテーブルと列の識別子は利用者側の責任です。JOIN が1行に複数回一致する可能性がある場合は distinct を設定してください。これは行の取得クエリーと件数の取得に同時に適用されるため、一覧の合計件数とページ送りが正しく保たれます。$args['context'] はここでも有効です。
nldcf7_entry_list_items_prepared
アクション。0.3.0で追加。行が確定したあと、いずれかのセルが描画される前に、一覧のページごとに1回発火します。
do_action( 'nldcf7_entry_list_items_prepared', array $items )
$items is the current page's rows only -- never the whole result set. Use it
独自の列に必要なデータを1回のクエリーでまとめて読み込み、セルごとに問い合わせる代わりにリクエスト単位のキャッシュへ保持するために使用します。読み取り専用で戻り値はなく、ページに行がない場合は空の配列を渡して発火します。エントリー一覧画面専用で、CSV 出力中に発火することはありません。
スクリーンショット





インストール
neutrope-lead-desk-for-contact-form-7フォルダーを/wp-content/plugins/ディレクトリにアップロードするか、WordPress の「プラグイン」画面 (「プラグインのアップロード」) からインストールする。- Contact Form 7がインストール済みで有効化されていることを確認する。
- 「プラグイン」画面から Neutrope Lead Desk for Contact Form 7を有効化する。
- お問い合わせ > 設定 (Contact > Settings) で初期設定を確認する。このプラグインの画面は Contact Form 7メニューの下に表示される。特に、フィールドマッピングの候補がフォームのフィールド名と一致しているか確認する。
- いずれかの Contact Form 7フォームからテスト送信を行い、お問い合わせ > 一覧を開いて取得されたことを確認する。
FAQ
-
Contact Form 7なしで動作しますか ?
-
いいえ。このプラグインは Contact Form 7に依存しています。CF7が有効化されていない場合、送信内容は取得されず、このプラグイン自身の管理画面に警告バナーが表示されます (wp-admin の他の画面に繰り返し表示することはありません)。
-
アップロードされたファイルは保存されますか ?
-
いいえ。取得するのはメタデータ (ファイル名、MIME タイプ、ファイルサイズ) のみです。ファイル本体は Contact Form 7の標準処理に委ねられます。
-
IP アドレスは取得されますか ?
-
プライバシーに配慮して、IP アドレスの取得は初期設定で無効です。お問い合わせ > 設定 > IP 保存から有効化できます。有効にする場合は、サイトのプライバシーポリシーで IP アドレスの記録について記載してください。
-
データを CSV に出力するにはどうすればよいですか ?
-
お問い合わせ > エクスポートを開き、必要に応じてフィルター (期間、ステータス、フォーム、スパムを含める) を適用してから、ダウンロードボタンをクリックします。CSV は BOM 付きの UTF-8のため、日本語版 Excel でも文字コードを手動で変換することなく正しく開けます。
-
フィールドマッピングはどのように動作しますか ?
-
マッピング用の4つの列 (氏名、メールアドレス、電話番号、会社名) には、それぞれカンマ区切りの候補リストがあります。送信内容に存在する最初のフィールド名が採用され、その値がマッピング用の列にコピーされます。マッピングされなかったフィールドも、
raw_payload_json列に保存されます。 -
プラグインを削除すると、取得したリードは失われますか ?
-
いいえ。初期設定ではデータは保持されます。完全にアンインストールしたい場合は、先に設定 > アンインストール時にデータ削除を有効化してから、プラグインを削除してください。
-
プラグインは外部サービスにデータを送信しますか ?
-
いいえ。ご利用の WordPress の外部へは何も送信しません。外部への通信、アナリティクス、トラッキングは一切ありません。
-
必要な権限は何ですか ?
-
初期設定では、すべての管理画面で
manage_optionsが必要です。必要な権限はnldcf7_required_capabilityフィルターで変更できます。 -
CSV 出力に独自の列を追加できますか ?
-
はい。
nldcf7_export_columnsフィルターでヘッダーの列を追加または削除でき、nldcf7_export_rowで行ごとに独自の値を返せます。 -
更新前に受信したエントリーの対応履歴が短いのはなぜですか ?
-
当時実際に記録されていた情報だけから組み立てているためです。0.2.0より前のバージョンでは、各エントリーの受信日時と内部メモは保存していましたが、ステータス変更、ゴミ箱への移動と復元、スパム指定の記録は残していませんでした。これらの古い変更は復元できず、プラグインが推測で作り出すこともありません。0.2.0以降に受信したエントリーでは、発生した時点ですべての操作履歴が記録されます。
-
バグの報告や機能のリクエストはどうすればよいですか ?
-
プラグインのサポートフォーラム、またはプロジェクトの issue トラッカーで issue を登録してください。
評価
このプラグインにはレビューがありません。
貢献者と開発者
変更履歴
0.3.0
- Add: generic extension points for the entry detail screen —
nldcf7_entry_detail_mainandnldcf7_entry_detail_sidebar— so an add-on can place panels in either column without modifying this plugin. - Add: generic list extension points —
nldcf7_entry_list_columnsfor columns andnldcf7_entry_list_column_contentfor their cells. Core columns are protected: an add-on cannot remove, rename or repurpose one, and returned cell markup passes throughwp_kses_post(). - Add:
nldcf7_entry_list_filters, which places an add-on’s own controls inside the existing filter bar. - Add:
nldcf7_entry_list_carried_args, so an add-on’s own filter stays applied across the All and Trash views and after row and bulk actions. Reserved keys such as nonces, action names and entry IDs are refused, non-scalar values are dropped, and size and count are capped, so a careless listener cannot put unsafe state into a list URL. - Add:
nldcf7_entry_query_argsfor high-level query constraints, including the existingidsargument, andnldcf7_entry_query_clausesfor constraints that live in an add-on’s own table. Clauses are structured — a JOIN, conditions with placeholders, and their values kept separate — rather than a raw SQL string, and values always go through$wpdb->prepare(). - Add: optional
distincthandling for add-on joins that can match a row more than once. It is applied to the row query and the count together, so the list and its total can never disagree. - Add: query context. The entries screen and the CSV exporter share one repository, so each query now says which it is. An add-on constraint meant for the list no longer reaches CSV export unless the add-on opts in.
- Add:
nldcf7_entry_list_items_prepared, which hands an add-on the current page’s rows once, before any cell is rendered, so custom columns can load their data in a single query instead of one per cell. - Fix: the Activity preparation notice counted processing records (entries plus notes) but read as a number of inquiries. It now names the unit; the arithmetic is unchanged.
- Fix: the “history from before this plugin was updated” note no longer appears on sites that installed this version fresh and therefore have no earlier history to explain.
- No database change. The schema and database version (1.1.0) are identical to 0.2.0, no migration runs, and existing entries, notes, attachments, activity, settings, capabilities and URLs are untouched. With no add-on installed the plugin behaves exactly as 0.2.0 did.
0.2.0
- Add: an Activity Timeline (対応履歴) on the entry detail screen, showing what has already been done about an inquiry. It records the entry being received, status changes (including the previous and new status), internal-note activity, Trash and Restore, and spam-state changes — each with the user who performed it and a timestamp, newest first and paginated 50 events at a time.
- Add: a dedicated activity-event table (
{prefix}nldcf7_entry_events). The database version moves from 1.0.0 to 1.1.0; the table is created on upgrade and on fresh activation. - Add: existing entries get a historical timeline built in the background from the two things the database already recorded — each entry’s received timestamp and its existing internal notes. The backfill runs in batches, is resumable, and shows a progress notice on the plugin’s own screens while it works; you can keep using the plugin normally throughout.
- Historical status changes, trash/restore actions, and spam marking are deliberately NOT inferred. Those transitions were never stored before this release, so the timeline shows what was genuinely recorded and explains the gap rather than reconstructing a plausible-looking history that never happened.
- Your existing notes stay authoritative: the timeline links to them rather than copying or replacing them. Notes are also now rejected if their parent entry does not exist, so an orphaned note can no longer appear in a timeline that belongs to nothing.
- Fix: entry mutations are now transition-aware. Status, trash, restore, and spam changes distinguish a real transition from a no-op and from a failed write, so the timeline records a change only when the stored value actually changed. Previously a no-op update and a failed update were indistinguishable to callers.
- Fix: the entries list now keeps your keyword, status, form, date range, spam toggle, and sort order after a row or bulk action, instead of dropping you back into an unfiltered list after every single action.
- Housekeeping: resolved the remaining Plugin Check warning (
WordPress.Security.ValidatedSanitizedInput.InputNotSanitized) by restructuring how list-filter input is read, not by suppressing the check. Plugin Check reports 0 errors and 0 warnings. - No change to how submissions are captured or to what is stored for them: existing entries, notes, attachments, statuses, settings, option names, page slugs, capabilities, and existing hooks are all unchanged. Adds the actions
nldcf7_after_entry_trashed,nldcf7_after_entry_restored, andnldcf7_after_spam_changed, and the filternldcf7_event_render.
0.1.5
- Add: the entries list now has a Trash view alongside All, with a per-row “Restore” action and a “Restore” bulk action. Trashing an entry has always been a soft delete (an
is_deletedflag, never a row deletion), but until now nothing in the admin could list or restore those entries, so recovering from an accidental Trash click meant editing the database by hand. v0.1.4 deliberately removed theconfirm()gate from the row-level Trash link because that gate silently cancelled the click in browsers that suppress dialogs; this release supplies the recoverability that makes a one-click, unconfirmed Trash safe — the same trade WordPress core makes with “Move to Trash”. - The Trash view keeps the active keyword / status / form / date filters and the “Show spam” toggle when you switch views, and the All / Trash counts show how many entries are in each bucket. Restoring from the Trash view leaves you in the Trash view instead of bouncing you back to All. The Trash link stays hidden while the trash is empty, matching core list screens.
- Restore is a plain nonce-protected link with no
confirm()gate, for exactly the reason given in the v0.1.4 entry below. - No database schema change: restore simply clears the existing
is_deletedflag, and status, spam flag, notes, and attachments all survive a trash/restore round trip. Adds the nonce actionnldcf7_restore_<id>and the query varstatus_view; existing?page=nldcf7-*URLs, option names, page slugs, capabilities, and hooks are unchanged, and the Export screen’s “Include entries moved to trash” option behaves exactly as before.
0.1.4
- Fix: the row-level “Trash” link on the entries list did nothing when clicked — no confirmation, no notice, and the entry was not moved to trash. The link carried an
onclick="return confirm(...)"gate; becauseconfirm()returns false whenever the browser suppresses the dialog (Chrome’s “Prevent this page from creating additional dialogs”, embedded webviews, dialog-blocking extensions), the anchor’s navigation was cancelled and no HTTP request was ever sent. The server-side GET route was therefore never reached, which is why bulk actions — plain form posts with noconfirm()— kept working. The Trash row action is now a plain nonce-protected link, matching WordPress core’s own “Move to Trash” row action. - No database, option, page slug, capability, or hook contract changes. The GET trash route, its nonce action (
nldcf7_trash_<id>), capability check, and redirect target are unchanged.
0.1.3
- Fix: the entry detail screen did not surface flash notices after status updates or note additions. v0.1.2 had added the same per-user transient flash mechanism to the Settings page, but the detail screen still discarded notices because
NLDCF7_Entry_Detail_Page::render()did not accept the consumed transient and its view template had no notice block.render()now mirrorsNLDCF7_Settings_Page::render()and accepts an optional$notice; the detail view renders the standardnotice notice-success / notice-error is-dismissiblebanner; andNLDCF7_Admin_Menu::render_entries_route()passes the consumed transient when routing to the detail screen. - No database, option, page slug, capability, or hook contract changes.
0.1.2
- Fix: the “Settings saved.” confirmation notice did not appear after saving on the Settings page (admin menu moved under Contact Form 7 in 0.1.1 changed the form’s effective post target in some setups, suppressing the post-save redirect and notice flag). The settings form now posts to an explicit URL and the success notice is delivered via the same per-user transient flash mechanism the entries list uses, so the confirmation reliably appears on the next page render.
- No database, option, page slug, capability, or hook contract changes.
0.1.1
- Admin menu relocated: the four screens (Entries / Export / Settings / Help) now appear as submenus directly under the existing Contact Form 7 menu (“お問い合わせ” in Japanese), instead of as a standalone top-level menu.
- When Contact Form 7 is not active, no plugin submenu is registered (no broken/orphan menu is produced). The missing-dependency warning is now also shown on the Dashboard and the Plugins screen, in addition to deep-link hits to plugin pages.
- Help screen: navigation hint updated to match the new location (“Contact > Entries” / 「お問い合わせ > 一覧」).
- No database, option, page slug, or capability changes. Existing
?page=nldcf7-*URLs continue to resolve unchanged.
0.1.0
- Initial release.
- Automatic capture of Contact Form 7 submissions into a dedicated DB table.
- Raw payload stored as JSON plus mapped columns for name/email/phone/company.
- Admin list screen (search, status/form/date filtering, bulk actions).
- Detail screen with status management and internal notes.
- CSV export with date/status/form/spam filters (UTF-8 + BOM, chunked streaming).
- Attachment metadata capture.
- Privacy-friendly defaults (IP capture off).
- Opt-in data deletion on uninstall.
- Extensibility hooks for future Pro integrations.
