Memory Wiki

Untitled Session

2026-05-28 03:52 UTC · 35 messages · cli

You2026-05-28 03:55 UTC
Create the automation engine PHP files for the Profe CRM WordPress plugin at /var/www/html/wp-content/plugins/profe-crm/includes/. These handle the automation funnels, triggers, actions, segment builder, and runner. Files to create: 1. class-automation.php 2. class-automation-step.php 3. class-automation-runner.php 4. class-triggers.php 5. class-actions.php 6. class-segment-builder.php
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"total_count": 8, "files": ["/var/www/html/wp-content/plugins/profe-crm/includes/class-activity.php", "/var/www/html/wp-content/plugins/profe-crm/includes/class-contact-meta.php", "/var/www/html/wp-content/plugins/profe-crm/includes/class-contact.php", "/var/www/html/wp-content/plugins/profe-crm/in...
Tool2026-05-28 03:55 UTC
{"total_count": 9, "files": ["/var/www/html/wp-content/plugins/profe-crm/includes/class-activity.php", "/var/www/html/wp-content/plugins/profe-crm/includes/class-contact-meta.php", "/var/www/html/wp-content/plugins/profe-crm/includes/class-contact.php", "/var/www/html/wp-content/plugins/profe-crm/in...
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * Main plugin class. Singleton bootstrap that initializes all components.\n 4| */\n 5|\n 6|defined('ABSPATH') || exit;\n 7|\n 8|class Profe_CRM {\n 9|\n 10| private static $instance = null;\n 11|\n 12| /** @var Pro...
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * Database schema for Profe CRM.\n 4| * Creates all custom tables on activation.\n 5| * All tables use the wp_ prefix via $wpdb->prefix.\n 6| */\n 7|\n 8|defined('ABSPATH') || exit;\n 9|\n 10|class Profe_CRM_Database {\n 11...
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * LabelRelation model for Profe CRM.\n 4| * Manages the polymorphic wp_profe_crm_label_relations pivot table.\n 5| */\n 6|\n 7|defined('ABSPATH') || exit;\n 8|\n 9|class Profe_CRM_Label_Relation {\n 10|\n 11| /**\n 12...
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * ContactNotes model for Profe CRM.\n 4| * Manages the wp_profe_crm_contact_notes table.\n 5| */\n 6|\n 7|defined('ABSPATH') || exit;\n 8|\n 9|class Profe_CRM_Contact_Notes {\n 10|\n 11| /**\n 12| * Add a note to ...
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * ContactMeta model for Profe CRM.\n 4| * Manages the wp_profe_crm_contact_meta table.\n 5| */\n 6|\n 7|defined('ABSPATH') || exit;\n 8|\n 9|class Profe_CRM_Contact_Meta {\n 10|\n 11| /**\n 12| * Get a single meta...
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * Contact model for Profe CRM.\n 4| * Manages the wp_profe_crm_contacts table with CRUD, search, label, activity, and meta helpers.\n 5| */\n 6|\n 7|defined('ABSPATH') || exit;\n 8|\n 9|class Profe_CRM_Contact {\n 10|\n 11|...
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * Activity model for Profe CRM.\n 4| * Manages the wp_profe_crm_activities table (engagement event log).\n 5| */\n 6|\n 7|defined('ABSPATH') || exit;\n 8|\n 9|class Profe_CRM_Activity {\n 10|\n 11| /**\n 12| * Tra...
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * Label model for Profe CRM.\n 4| * Manages the wp_profe_crm_labels table.\n 5| */\n 6|\n 7|defined('ABSPATH') || exit;\n 8|\n 9|class Profe_CRM_Label {\n 10|\n 11| /**\n 12| * Get a label by primary key.\n 13|...
Tool2026-05-28 03:55 UTC
{"content": " 1|<?php\n 2|/**\n 3| * Plugin Name: Profe CRM\n 4| * Description: Member relationship management for the Profe community platform.\n 5| * Contact management, labels, segmentation, automation funnels,\n 6| * activity tracking, and REST A...
Donna2026-05-28 03:55 UTC
Now I have a complete picture of the codebase. Let me create all 6 files.
Tool2026-05-28 03:55 UTC
{"bytes_written": 16738, "dirs_created": true, "lint": {"status": "skipped", "message": "No linter for .php files"}}
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"bytes_written": 10896, "dirs_created": true, "lint": {"status": "skipped", "message": "No linter for .php files"}}
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"bytes_written": 7673, "dirs_created": true, "lint": {"status": "skipped", "message": "No linter for .php files"}}
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"bytes_written": 15860, "dirs_created": true, "lint": {"status": "skipped", "message": "No linter for .php files"}}
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"bytes_written": 27109, "dirs_created": true, "lint": {"status": "skipped", "message": "No linter for .php files"}}
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"bytes_written": 33932, "dirs_created": true, "lint": {"status": "skipped", "message": "No linter for .php files"}}
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"output": "-rw-r--r-- 1 root root 15860 May 28 03:53 class-actions.php\n-rw-r--r-- 1 root root 27109 May 28 03:54 class-automation-runner.php\n-rw-r--r-- 1 root root 10896 May 28 03:53 class-automation-step.php\n-rw-r--r-- 1 root root 16738 May 28 03:52 class-automation.php\n-rw-r--r-- 1 root root ...
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"output": "=== class-automation.php ===\nNo syntax errors detected in class-automation.php\n=== class-automation-step.php ===\nNo syntax errors detected in class-automation-step.php\n=== class-automation-runner.php ===\nNo syntax errors detected in class-automation-runner.php\n=== class-triggers.ph...
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"total_count": 13, "matches": [{"path": "/var/www/html/wp-content/plugins/profe-crm/includes/class-label-relation.php", "line": 9, "content": "class Profe_CRM_Label_Relation {"}, {"path": "/var/www/html/wp-content/plugins/profe-crm/includes/class-contact.php", "line": 9, "content": "class Profe_CRM...
Donna2026-05-28 03:55 UTC
Tool2026-05-28 03:55 UTC
{"total_count": 6, "matches": [{"path": "/var/www/html/wp-content/plugins/profe-crm/profe-crm.php", "line": 34, "content": "require_once PROFE_CRM_PLUGIN_DIR . 'includes/class-automation.php';"}, {"path": "/var/www/html/wp-content/plugins/profe-crm/profe-crm.php", "line": 35, "content": "require_onc...
Donna2026-05-28 03:55 UTC
All 6 files are created, pass PHP syntax validation, and the autoloader in `profe-crm.php` already references them correctly. Here's the summary: --- ## Summary ### Files Created **1. `/var/www/html/wp-content/plugins/profe-crm/includes/class-automation.php`** (16.7 KB) - **Class:** `Profe_CRM_Automation` - **CRUD:** `get()`, `create()`, `update()`, `delete()`, `get_all()`, `count()`, `count_by_status()` - **Step management:** `get_steps()`, `add_step()`, `update_step()`, `remove_step()`, `reorder_steps()` - **Stats:** `get_run_count()`, `get_completed_count()`, `get_active_contacts()` - All serialized fields (conditions, settings) handle `maybe_serialize()/maybe_unserialize()` **2. `/var/www/html/wp-content/plugins/profe-crm/includes/class-automation-step.php`** (10.9 KB) - **Class:** `Profe_CRM_Automation_Step` - **CRUD:** `get()`, `create()`, `update()`, `delete()` - **Validation:** `is_valid_action()` (9 valid actions), `is_valid_benchmark()` (3 valid benchmarks) - **Schema provider:** `get_action_settings_schema()` returns field definitions for all action types **3. `/var/www/html/wp-content/plugins/profe-crm/includes/class-automation-runner.php`** (27.1 KB) - **Class:** `Profe_CRM_Automation_Runner` - Core execution engine with full pipeline: - `start_automation()` — creates run entries, processes first step - `process_step()` — dispatches actions/benchmarks/wait steps - `process_next_step()` / `advance_to_next_step()` — walks the step chain - `process_delayed_steps()` — cron handler that processes `status='waiting'` runs whose delay has elapsed - `cancel_automation()` / `complete_automation()` - `get_contact_automations()` - Benchmark listeners wired via `profe_crm_label_applied`, `profe_crm_label_removed`, `profe_crm_activity_recorded` hooks - Fallback direct execution (`execute_action_direct()`) if the Actions registry isn't available yet - Uses `class_exists()` guards throughout **4. `/var/www/html/wp-content/plugins/profe-crm/includes/class-triggers.php`** (7.7 KB) - **Class:** `Profe_CRM_Triggers` - Registry pattern: `register()`, `get_registered()`, `get_trigger()`, `fire()` - 9 default triggers registered: `user_registered`, `contact_label_applied`, `contact_label_removed`, `studio_joined`, `studio_left`, `reputation_threshold`, `activity_occurred`, `contact_meta_updated`, `user_logged_in` - `fire()` queries all ACTIVE automations matching the trigger name and starts them via the Runner - Includes basic condition evaluation framework **5. `/var/www/html/wp-content/plugins/profe-crm/includes/class-actions.php`** (15.9 KB) - **Class:** `Profe_CRM_Actions` - Registry + executor pattern: `register()`, `get_registered()`, `get_action()`, `execute()` - 9 default actions with settings schemas: `apply_label`, `remove_label`, `send_notification`, `add_note`, `change_status`, `http_webhook`, `update_meta`, `remove_from_automation`, `wait` - Each action has a dedicated private executor method: - `apply_label`/`remove_label` → `Profe_CRM_Label_Relation::attach/detach()` - `send_notification` → `bp_notifications_add_notification()` with fallback to ContactNotes - `add_note` → `Profe_CRM_Contact_Notes::add()` (returns note_id as string) - `change_status` → direct `$wpdb->update()` on contacts table - `http_webhook` → `wp_remote_post()` with contact data payload - `update_meta` → `Profe_CRM_Contact_Meta::set()` - Extensible via `profe_crm_execute_action` filter **6. `/var/www/html/wp-content/plugins/profe-crm/includes/class-segment-builder.php`** (33.9 KB) - **Class:** `Profe_CRM_Segment_Builder` - 5-layer filter query engine using EXISTS subqueries (no cartesian joins): - **General** — contact field filters with operators: `=`, `!=`, `>`, `<`, `>=`, `<=`, `LIKE`, `NOT LIKE`, `IN`, `NOT IN`, `BETWEEN`, `IS NULL`, `IS NOT NULL` - **Labels** — `in` (any), `not_in` (none), `in_all` (has all), `not_in_all` (missing at least one) - **Custom Fields** (meta) — `=`, `!=`, `LIKE`, `NOT LIKE`, `IN`, `NOT IN`, `EXISTS`, `NOT EXISTS` - **Activities** — `in_last_days`, `before_date`, `after_date`, `never`, `count_gt`, `count_lt` - **Automation** — `entered`, `not_entered`, `completed`, `active`, `cancelled` - `query()` returns contact IDs, `count()` returns integer - Segment CRUD: `save_segment()`, `get_segment()`, `get_segments()`, `update_segment()`, `delete_segment()` - `query_segment()` loads a saved segment, decodes filters JSON, and runs the query - Automatic unique slug generation, JSON encoding/decoding for filters ### Key Design Decisions - All classes follow existing plugin conventions (no namespaces, `Profe_CRM_` prefix, `$wpdb->global`, `current_time('mysql')`) - All user input goes through `$wpdb->prepare()` — no raw SQL with concatenated values - `class_exists()` guards protect against missing model classes during early initialization - The Runner lazy-loads references to Triggers/Actions from the main CRM instance via `init` hook - Benchmark automations use WordPress action hooks to advance waiting runs when conditions are met