PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.5
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.5
2.4.5 2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 All 69 releases
← All changes | app/Modules/MCP/Support/CustomerMetaEnricher.php +12 -26 2.3.1 → 2.4.5 View file →
@@ -4,15 +4,11 @@
4 4
5 5 use FluentSupport\App\Modules\PermissionManager;
6 6
7 7 /**
8 - * Resolves an optional, integration-provided one-line meta string per customer
9 - * for MCP list surfaces (e.g. "Paying · 8,016 sent/30d · domain verified").
10 - *
11 - * Fluent Support generates nothing here — it only exposes a batch filter that
12 - * integrations (FluentCRM/FluentCart/etc.) may hook. The string can carry
13 - * billing/CRM PII, so resolution is gated on the fst_sensitive_data capability,
14 - * the same boundary AdminSensitivePolicy uses for customer data.
8 + * Optional one-line customer summary for MCP lists, supplied by integrations
9 + * through a batch filter. It can carry billing/CRM PII, so it's gated on
10 + * fst_sensitive_data like AdminSensitivePolicy.
15 11 */
16 12 class CustomerMetaEnricher
17 13 {
18 14 const MAX_LEN = 120;
@@ -17,14 +13,10 @@
17 13 {
18 14 const MAX_LEN = 120;
19 15
20 16 /**
21 - * Build a [customer_id => meta line] map for the customers on one list page.
17 + * [customer_id => line] for one list page. One filter call per page.
22 18 *
23 - * Fires the filter ONCE per page (never per row) and returns [] for agents
24 - * without fst_sensitive_data, so the integration round-trip is skipped and
25 - * no PII leaks by default.
26 - *
27 19 * @param iterable $tickets The page of Ticket models (customer eager-loaded).
28 20 * @param array $context Extra context passed to the filter (e.g. agent_id).
29 21 * @return array<int,string>
30 22 */
@@ -52,20 +44,15 @@
52 44 *
53 45 * Inject a short, plain-text status line per customer for MCP list
54 46 * surfaces, e.g. "Paying · 8,016 sent/30d · domain verified".
55 47 *
56 - * CONTRACT — read before hooking:
57 - * • BATCH ONLY. Fired ONCE per page with a deduplicated array of
58 - * customer IDs. Do ALL work in a single query (WHERE customer_id
59 - * IN (...)). DO NOT query per customer in a loop — that reintroduces
60 - * N+1 and shows up in list latency. The loaded Customer models are
61 - * passed so you can read email/user_id without an extra DB hit.
62 - * • CHEAP. Runs on every list render. No remote HTTP calls. Cache
63 - * anything expensive yourself (transient / object cache).
64 - * • PLAIN STRING. The return value is sanitized to plain text: tags
65 - * stripped, control chars removed, capped at 120 chars. HTML,
66 - * markdown, arrays, objects and unknown keys are DISCARDED.
67 - * • ADDITIVE. Merge into the incoming map; preserve existing keys.
48 + * Contract:
49 + * - Batch: fired once per page. Use one query for all IDs, not one per customer.
50 + * Loaded Customer models are passed to save a lookup.
51 + * - Cheap: runs on every list render. No remote calls; cache anything expensive.
52 + * - Plain text: tags and control chars are stripped and values capped at 120 chars.
53 + * Non-scalar values and unknown IDs are dropped.
54 + * - Additive: merge into the incoming map, keep existing keys.
68 55 *
69 56 * @param array<int,string> $lines Default []. Merge, don't overwrite.
70 57 * @param int[] $customerIds Deduped customer IDs on this page.
71 58 * @param array $customers [customer_id => loaded Customer model].
@@ -101,15 +88,14 @@
101 88
102 89 foreach ($raw as $id => $value) {
103 90 $id = (int) $id;
104 91
105 - // Drop keys not on this page and non-scalar (array/object) values.
106 92 if (!isset($allowed[$id]) || !is_scalar($value)) {
107 93 continue;
108 94 }
109 95
110 96 $value = wp_strip_all_tags((string) $value, true);
111 - $value = preg_replace('/[\x00-\x1F\x7F]+/u', ' ', $value); // strip control chars
97 + $value = preg_replace('/[\x00-\x1F\x7F]+/u', ' ', $value);
112 98 $value = trim(preg_replace('/\s+/u', ' ', $value));
113 99
114 100 if ($value === '') {
115 101 continue;