Agent Skills by ALSEL
汎用ソフトウェア開発⭐ リポ 11品質スコア 80/100

fluentcrm-overview

FluentCRM拡張機能開発向けのスキルです。Free/Pro分割構成(FluentCRM = ファネルベース; FluentCampaign Pro = 統合機能・高度なアクション/ベンチマーク)、プラグインパスと定数、ブートストラップ順序(fluentcrm_loaded → fluentcrm_addons_loaded → fluent_crm/after_init)、モデル層(Subscriber、Funnel、FunnelSequence、FunnelSubscriber、FunnelMetric)、グローバルヘルパー(FluentCrmApi、fluentCrmDb、FunnelHelper)、コンタクトライフサイクルフック(fluent_crm/contact_created、_updated、_email_changed、_custom_data_updated)、スマートコード拡張フィルター(fluent_crm/extended_smart_codes)、適切な拡張コントラクトを選択するための判定マトリックスをカバーしています。新しいFluentCRM統合をスキャフォールディングする場合、拡張するコントラクトを選択する場合、または機能の配置場所を確認する場合に使用します。

description の原文を見る

Orient skill for FluentCRM extension development. Covers the Free / Pro split (FluentCRM = funnel chassis; FluentCampaign Pro = integrations + advanced actions / benchmarks), plugin paths and constants, the bootstrap order (fluentcrm_loaded → fluentcrm_addons_loaded → fluent_crm/after_init), the model layer (Subscriber, Funnel, FunnelSequence, FunnelSubscriber, FunnelMetric), the global helpers (FluentCrmApi, fluentCrmDb, FunnelHelper), the contact lifecycle hooks (fluent_crm/contact_created, _updated, _email_changed, _custom_data_updated), the smart-code extension filter (fluent_crm/extended_smart_codes), and a decision matrix for picking the right extension contract. Use when scaffolding a new FluentCRM integration, choosing which contract to extend, or asking where things live. Triggers on FluentCrmApi, fluentCrmDb, FunnelHelper, fluent_crm/contact_, fluent_crm/extended_smart_codes, FLUENTCRM, FLUENTCAMPAIGN.

SKILL.md 本文

FluentCRM: 開発者向けガイド

FluentCRM拡張機能を新しく始める際、またはどの契約を拡張すべきかまだ決まっていない場合は、まずこのスキルを選びましょう。これは概要層です。個別の拡張ポイントについての詳細は教えず、ファイルマップを示して、さらに詳しい専門スキル(fluentcrm-funnel-triggerfluentcrm-funnel-actionfluentcrm-funnel-benchmarkfluentcrm-rest-options)へ導きます。

プラグインの識別情報

フィールドソース
スラッグfluent-crmヘッダー
バージョン2.9.87fluent-crm.php:6
Pro スラッグfluentcampaign-proヘッダー
Pro バージョン2.9.86fluentcampaign-pro.php
ブートコンスタントFLUENTCRM ('fluentcrm')fluent-crm.php:20
Pro コンスタントFLUENTCAMPAIGN_PLUGIN_VERSIONfluentcampaign-pro.php
パスコンスタント (Free)FLUENTCRM_PLUGIN_PATHfluent-crm.php:22
パスコンスタント (Pro)FLUENTCAMPAIGN_PLUGIN_PATHfluentcampaign-pro.php:20
最小 PHP バージョン (検証済み)7.4composer.json

アクティベーション検出class_exists('FluentCRM') でテストしないでください(そのようなクラスは存在しません)。以下を使用します:

public static function isFluentCRMActive(): bool {
    return defined('FLUENTCRM');
}

public static function isFluentCRMProActive(): bool {
    return defined('FLUENTCAMPAIGN_PLUGIN_VERSION')
        && version_compare(FLUENTCAMPAIGN_PLUGIN_VERSION, '2.8.0', '>=');
}

2.8.0 の下限は、BaseTrigger / BaseAction ライフサイクルの安定性ポイントです。コードがモデルAPIのみを使用する場合は削除できます。)

他のプラグイン向けアクティベーション検出の標準(読み込み順序の罠)

トリガー / アクション / ベンチマークは fluentcrm_loaded:5 に登録され、これは FluentCRM 自身の plugins_loaded:10 コールバックから発火します。登録機能内のすべての依存関係チェックは、その時点で実行され — ファイル読み込み時に宣言されたシンボルのみが 保証されます。WordPress は plugins_loaded:10 コールバックをプラグイン登録順序で実行し(インストール間で非決定的)、別のプラグインの plugins_loaded コールバック内部で設定されたシンボルはレースコンディションの危険があります。

安全 (ファイル読み込み時に宣言 — トップレベルスコープ、条件付き require なし):

プラグイン使用方法理由
WooCommerceclass_exists('WooCommerce')woocommerce.php はファイルスコープで class-woocommerce.php をインクルードします
FluentCampaign Prodefined('FLUENTCAMPAIGN_PLUGIN_VERSION')fluentcampaign-pro.php はファイルスコープで fluentcampaign_boot.php を require し、その中でコンスタントを define() します
WC Membershipsclass_exists('WC_Memberships_Loader')トップレベルのローダークラス、WC_Memberships 自体は init_plugin() 内で読み込まれレースコンディションの危険があります
LW LMSclass_exists('LightweightPlugins\\LMS\\Plugin')オートローダーはファイルスコープで登録されます
Jet Engineclass_exists('Jet_Engine')トップレベルのクラス宣言

非安全 (依存関係自体のコールバック内で宣言 — 登録時に使用しないでください):

// 間違い — wc_memberships() 関数は Memberships の
// plugins_loaded:10 コールバック内で宣言されます。登録機能が
// Memberships のコールバックより前に実行された場合、
// function_exists は false を返し、アクションはエディターから
// サイレントに除外されます。
return function_exists('wc_memberships');

// 正解 — WC_Memberships_Loader はファイルスコープにあります。
return class_exists('WC_Memberships_Loader');

依存関係のメインオブジェクトが初期化後にのみ存在する場合は、テスト対象となるトップレベルのローダー/登録機能を見つけてください(すべての形式の整ったプラグインは1つ持っています)。

Free vs Pro 一覧

機能Free (FluentCRM)Pro (FluentCampaign)
連絡先、リスト、タグ、セグメントありあり
メールキャンペーン、シーケンス、テンプレートありあり
フォーム、オプトインありあり
ファネル トリガー (BaseTrigger)あり — 任意のプラグインから登録可能あり — 多数の組み込み (Tutor、LearnDash、LifterLMS、EDD、WishlistMember、AffiliateWP、Woo Subscriptions)
ファネル アクション (BaseAction)あり — 任意のプラグインから登録可能あり — 多数の組み込み (高度な Woo、シーケンス追加/削除、カスタムフィールド更新)
ファネル ベンチマーク (BaseBenchMark)あり — 任意のプラグインから登録可能あり — 追加の組み込み
条件分岐 / A-B テストノードいいえあり
企業モジュールありあり
Webhook 受信/送信ありあり
SMTP / メールドライバーレイヤーFree は WP mail / Fluent SMTP を使用Pro は高度なレポート機能を追加

4つの拡張契約(トリガー、アクション、ベンチマーク、スマートコード)は すべて Free に含まれます。Pro は主に組み込み統合 + UI機能です。Free を拡張するコンパニオンプラグインは Pro に対しても自動的に機能します。

ブートストラップ順序

plugins_loaded:10           ← プラグインがブートストラップをインスタンス化
        ↓
fluentcrm_loaded            ← boot/app.php:41 から do_action('fluentcrm_loaded')
                              トリガー / アクション / ベンチマークをここに登録 (priority < 10)
                              FluentCampaign Pro の IntegrationHandler もここで実行
        ↓
fluentcrm_addons_loaded     ← boot/app.php:42 から do_action('fluentcrm_addons_loaded')
                              FunnelHandler::handle が実行 (actions.php:76)
                                 → fluentcrm_funnel_settings オプションを読み込み
                                 → 保存されたトリガー名ごとに:
                                     $argNum = apply_filters('fluentcrm_funnel_arg_num_'.$name, 1)
                                     add_action($name, ..., 10, $argNum)   ← ロック
        ↓
init:1000                   ← boot/app.php:44-46 から do_action('fluent_crm/after_init')
                              argNum フィルターには遅すぎる
        ↓
... ランタイムイベントが発火 ...

唯一のタイミング規則 — すべてのトリガー / アクション / ベンチマークを fluentcrm_loaded 優先度 < 10 で登録します。fluent_crm/after_init または init にフックすると、マルチ引数が静かに削除されます。説明は fluentcrm-funnel-trigger を参照してください。

ファイルマップ

fluent-crm/
├── fluent-crm.php                   ← ヘッダー + ブートストラップエントリ
├── boot/
│   ├── app.php                      ← フレームワーク初期化、fluentcrm_loaded / addons_loaded ディスパッチ
│   └── …
├── app/
│   ├── Api/
│   │   ├── Classes/Extender.php     ← 公開API面 (スマートコード拡張機能、連絡先API)
│   │   └── Classes/Contact.php      ← fluentCrmApi('contacts') バックエンド
│   ├── Functions/helpers.php        ← FluentCrmApi()、fluentCrmDb()、fluentCrmTimestamp() など
│   ├── Hooks/
│   │   ├── actions.php              ← 組み込み `add_action` 登録
│   │   ├── filters.php
│   │   └── Handlers/                ← Funnel、Subscriber、Campaign など のハンドラー
│   ├── Http/Controllers/            ← REST エンドポイント (FunnelController、OptionsController など)
│   ├── Models/                      ← Subscriber、Funnel、FunnelSequence など
│   ├── Services/
│   │   ├── Funnel/
│   │   │   ├── BaseTrigger.php
│   │   │   ├── BaseAction.php
│   │   │   ├── BaseBenchMark.php
│   │   │   ├── FunnelProcessor.php
│   │   │   └── FunnelHelper.php
│   │   ├── Helper.php
│   │   └── Libs/Parser/             ← スマートコードパーサー
│   └── Views/
└── ...

fluentcampaign-pro/
├── fluentcampaign-pro.php
└── app/
    ├── Hooks/Handlers/IntegrationHandler.php   ← initFunnelActions / initBenchmarks / initTriggers
    └── Services/Integrations/
        ├── TutorLms/CourseEnrollTrigger.php    ← 標準的なトリガー参照
        ├── TutorLms/AddToCourseAction.php      ← 標準的なアクション参照
        ├── WooCommerce/                        ← 深い Woo 統合
        ├── LearnDash/, LifterLms/, EDD/, AffiliateWP/, WishlistMember/
        └── …

使用するモデル

モデルクラス注記
SubscriberFluentCrm\App\Models\Subscriberコア連絡先。getWpUserId()tagslistsemailstatus
FunnelFluentCrm\App\Models\Funnel自動化。status{published, draft, archived}
FunnelSequenceFluentCrm\App\Models\FunnelSequenceファネル内の手順。action_name がブロックにキー付け。type{action, benchmark, conditional}
FunnelSubscriberFluentCrm\App\Models\FunnelSubscriber結合:連絡先 <-> ファネル。現在のシーケンス位置を追跡
FunnelMetricFluentCrm\App\Models\FunnelMetricステップごとの監査行。status{pending, complete, skipped, failed}
TagFluentCrm\App\Models\TagSubscriberPivot 経由で Subscriber と多対多の関係
ListsFluentCrm\App\Models\Lists同じ
WebhookFluentCrm\App\Models\Webhookインバウンド webhook 受信機

ステータス文字列の標準は 'complete''completed' ではありません — 詳細は fluentcrm-funnel-action を参照してください。

グローバルヘルパー

// API面 — 直接モデル書き込みより推奨
FluentCrmApi('contacts')->createOrUpdate($data);
FluentCrmApi('contacts')->getContact($emailOrId);

// データベースクエリビルダー — Eloquent をバイパスしてraw クエリ実行
fluentCrmDb()->table('fc_subscribers')->where('email', $email)->first();

// FunnelHelper — コンパニオンプラグインから最も使用される単一のユーティリティ
FunnelHelper::prepareUserData($wpUserId);             // $subscriberData スケルトンを構築
FunnelHelper::getSubscriber($emailOrUserId);          // Subscriber モデルを解決
FunnelHelper::ifAlreadyInFunnel($funnelId, $subId);   // 重複排除ガード
FunnelHelper::removeSubscribersFromFunnel($funnelId, $subIds);  // リスタートヘルパー
FunnelHelper::getUpdateOptions();                     // 標準的な「存在する場合」ラジオオプション
FunnelHelper::changeFunnelSubSequenceStatus($funnelSubId, $sequenceId, 'complete');
FunnelHelper::maybeExplodeFullName($subscriberData);  // "John Doe" → 名/姓に分割
FunnelHelper::createWpUserFromSubscriber($subscriber, $sendWelcomeEmail);

FluentCrmApifluentCrmDbFluentCrm (サービスコンテナ) はすべて helpers.php で定義されています。

連絡先ライフサイクルフック

連絡先の状態が変わるたびに、レガシーアンダースコア名アクション 新しいスラッシュ名アクション(2.8で導入)の両方が発火します。新しいコードではスラッシュ版をフックします。アンダースコア版は非推奨ですが、後方互換性のためにまだ発火します:

最新フックレガシーエイリアス (非推奨)引数ソース
fluent_crm/contact_createdfluentcrm_contact_created$subscriberSubscriber.php:970-971, 1145-1146
fluent_crm/contact_updatedfluentcrm_contact_updated$subscriber, $dirtyFieldsSubscriber.php:1006-1007, 1148
fluent_crm/contact_email_changed(エイリアスなし)$subscriber, $oldEmailSubscriber.php:1095
fluent_crm/contact_custom_data_updatedfluentcrm_contact_custom_data_updated$newValues, $subscriber, $updateValuesSubscriber.php:669-670

ファネルに依存せずに購読者の状態に反応する必要があるときに便利です。たとえば、連絡先データを外部CRMにミラーリングします。

スマートコード拡張

{{my_plugin.foo}} のようなカスタムテンプレートタグは、fluent_crm/extended_smart_codes フィルター経由で登録されます (Helper.php:329Extender.php:108)。Extender API:

FluentCrmApi('extender')->addSmartCode(
    'my_plugin',                                    // 名前空間キー
    __('My Plugin Tokens', 'my-plugin'),            // グループタイトル
    [
        'my_plugin.contact_score' => 'Contact Score',
        'my_plugin.last_purchase' => 'Last Purchase Date',
    ],
    function ($code, $valueKey, $defaultValue, $subscriber) {
        // $subscriber に対して $valueKey を解決します。文字列を返します。
        if ($valueKey === 'contact_score') {
            return (string) get_user_meta($subscriber->user_id, 'my_score', true);
        }
        return $defaultValue;
    }
);

スマートコードはメール レンダー時に評価され、「カスタムフィールドの更新」などのアクション用の動的フィールドトークン内でも評価されます。不明なコードのフォールバックは apply_filters('fluentcrm_smartcode_fallback', $matches[0], $subscriber) です — レガシーな {{tag}} 形式に便利です。

ファネルレイヤーアーキテクチャ

                ┌──────────────────────────────────────────┐
                │  トリガーが発火 (実際の WP アクション)   │
                │  例: lw_lms_after_grant、tutor_after_    │
                │      enrolled、woocommerce_new_order      │
                └────────────────────┬─────────────────────┘
                                     │
                ┌────────────────────▼─────────────────────┐
                │  FunnelHandler::mapTriggers              │
                │  (FunnelHandler.php:105-141)             │
                │  - マッチする trigger_name を持つ         │
                │    公開ファネルを検索                     │
                │  - fluentcrm_funnel_start_* をディスパッチ│
                │  - マッチする action_name を持つ           │
                │    公開 BENCHMARK シーケンスを検索        │
                │  - fluentcrm_funnel_benchmark_           │
                │    start_* をディスパッチ                 │
                └────────┬──────────────────────┬──────────┘
                         │                      │
              ┌──────────▼──────────┐  ┌────────▼──────────┐
              │ BaseTrigger::handle │  │ BaseBenchMark::    │
              │  → startFunnelSequ- │  │  handle            │
              │    ence (新規実行)  │  │  → startFunnelFrom │
              │                     │  │    SequencePoint   │
              │                     │  │    (再開)          │
              └──────────┬──────────┘  └────────┬──────────┘
                         │                      │
                    ┌────▼──────────────────────▼────┐
                    │ FunnelProcessor::processSequence│
                    │ (シーケンスステップをループ)    │
                    │  - シーケンスタイプ 'action'   │
                    │      → fluentcrm_funnel_       │
                    │        sequence_handle_*       │
                    │      → BaseAction::handle()    │
                    │  - シーケンスタイプ 'benchmark'│
                    │      → 待機                    │
                    │  - シーケンスタイプ 'conditional'│
                    │      → 分岐 (Pro)              │
                    └─────────────────────────────────┘

決定マトリックス — 適切な契約を選択

やりたいこと拡張する
X が発生したときに自動化を開始するトリガーfluentcrm-funnel-trigger
シーケンスステップで連絡先の作業を実行するアクションfluentcrm-funnel-action
X が発生するまでファネルを一時停止してから再開するベンチマークfluentcrm-funnel-benchmark
上記のいずれかにマルチセレクトピッカーフィールドを追加するREST オプションフィルターfluentcrm-rest-options
{{my_code.foo}} テンプレートタグを追加するスマートコード拡張機能 — 上記の「スマートコード拡張」を参照
ファネルなしで連絡先の状態に反応する連絡先ライフサイクルフック — 上記の表を参照
カスタム REST エンドポイントを追加するWP REST API — FluentCRM に特別なラッパーはありません。register_rest_route を使用します
カスタム連絡先フィールドを追加するFluentCRM 管理画面 → 設定 → 連絡先カスタムフィールド。コードパスなし。

重要なルール

  • トリガー / アクション / ベンチマーク登録に対して必ず fluentcrm_loaded 優先度 < 10 をフックしてください。 最も一般的なタイミングの罠です。
  • アクションとベンチマークの getBlock() に必ず 'settings' をシードしてください。 getBlockFields()['fields'] キーごとに1つのキーです。これなしだとエディターが空のパネルをレンダリングし、JS コンソールが TypeError: Cannot read properties of undefined をスローします。トリガーはこの罠を持っていません(デフォルトは抽象 getFunnelSettingsDefaults() / getFunnelConditionDefaults() メソッドから来ます)。
  • ステータス文字列の標準は 'complete' (not 'completed')です。すべての changeFunnelSubSequenceStatus$funnelMetric->status に適用されます。
  • ->user_id ではなく getWpUserId() を使用します。 Subscriber インスタンスから WP ユーザーを読み取るときです。
  • FluentCrmApi('contacts')->createOrUpdate() を使用します。 コンパニオンコードで直接 Subscriber モデルをインスタンス化するのではなく。API は リスト/タグアタッチメント、ダブルオプトイン処理、ライフサイクルフック発火をカプセル化します。
  • 2.8.0 で Pro バージョン検出をピンします。 最新のライフサイクルに依存する場合です。古い Pro リリースは安定した BaseAction セマンティクスより前のものです。
  • fluentcrm_funnel_start_* を直接キャッチしないでください。 常に BaseTrigger を経由します。FluentCRM は今後そのフックの周りに検証を追加する可能性があり、BaseTrigger を迂回することは prepareEditorDetails (__force_run_actions インジェクションなど) を逃すことを意味します。
  • プラグインの存在検出はファイル読み込み時のシンボルを使用する必要があります。 class_exists('TopLevelClassFromMainFile') または defined('CONST_NAME')。別のプラグインの plugins_loaded コールバック内で宣言されたシンボルに対して function_exists() を使用することは決してしないでください — 非決定的なロード順序によって、チェックが一部のインストールでパスし他でフェイルします。上記の「アクティベーション検出標準」でプラグインごとの標準リストを参照してください。

一般的な間違い

  • アンダースコア vs スラッシュフック変種を混同する — 両方は今日発火しますが、fluentcrm_* は非推奨化トラック上にあります。新しい統合は fluent_crm/* をフックすべきです。
  • プラグイン検出に class_exists('FluentCRM') に頼る。そのようなクラスはありません。defined('FLUENTCRM') を使用します。
  • トリガー / アクションをブートストラップ時にインスタンス化する plugins_loaded 上で fluentcrm_loaded 間接化なし。FluentCRM がまだ plugins_loaded 時点でロードされていない可能性があります。それでさえ、BaseTrigger::register() が FluentCRM 自身のブート前に実行されるため、フィルターターゲットは完全に配線されていない環境です。
  • Subscriber::find() のような内部モデルメソッドを FluentCRM の外部から呼び出す。安定していますが、モデルの動作はマイナーバージョン間で変わります。読み取りには FluentCrmApi('contacts')->getContact() を優先します。
  • 依存関係認識型登録をゲートするのに function_exists('helper_fn') を使用する。古典的なロード順序レース — 依存関係がまず読み込まれるインストールで機能し、2番目に読み込まれるインストール上で静かに破断します。症状:トリガー / アクションがあるサイトのエディターに表示され、他では表示されない、エラーなし。常に「アクティベーション検出標準」に記載されているファイルスコープクラス/コンスタント標準を使用します。
  • **実際には Pro を

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
Lonsdale201
リポジトリ
Lonsdale201/wp-agent-skills
ライセンス
MIT
最終更新
2026/5/9

Source: https://github.com/Lonsdale201/wp-agent-skills / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: Lonsdale201 · Lonsdale201/wp-agent-skills · ライセンス: MIT