Contents

Hooks reference - Plugixa CRM

Every hook is prefixed plugixa_crm_. Add listeners from a small plugin or your theme’s functions.php.

Lifecycle

Action Fires
plugixa_crm_loaded The plugin has booted and the container is built
plugixa_crm_activated On activation
plugixa_crm_deactivated On deactivation
plugixa_crm_uninstall On uninstall, before anything is removed
plugixa_crm_register_rest_routes With the namespace and the container, so your own routes can join it
plugixa_crm_enqueue_assets When the app’s assets are enqueued
plugixa_crm_admin_submenus To add a submenu under the CRM’s menu item

Records

do_action( 'plugixa_crm_entity_created',  $entity, $id, $data );
do_action( 'plugixa_crm_entity_updated',  $entity, $id, $data, $old );
do_action( 'plugixa_crm_entity_deleted',  $entity, $id );
do_action( 'plugixa_crm_entity_restored', $entity, $id );
do_action( 'plugixa_crm_entity_purged',   $entity, $id );
do_action( 'plugixa_crm_entity_assigned', $entity, $id, $user_id );
do_action( 'plugixa_crm_entity_field_changed', $entity, $id, $field, $to, $from );

These fire on every write, from the database layer. Two shipped features were built entirely on them without touching a single write path: the activity stream listens to three, the audit log to five. That is the argument for firing events before anybody consumes them.

The matching filters run before the write:

Filter Purpose
plugixa_crm_before_insert Change the data about to be inserted
plugixa_crm_before_update Change the data about to be updated
plugixa_crm_load_record Change a record as it is loaded
plugixa_crm_filter_output Change what an endpoint returns
plugixa_crm_entity_types Register an entity, with its fields
plugixa_crm_filterable_fields What a list may be narrowed by
plugixa_crm_record_names Human names for records in messages
plugixa_crm_record_writers Register a generic writer, which is what makes an entity importable

Plus plugixa_crm_before_delete, plugixa_crm_before_purge, plugixa_crm_records_merged and plugixa_crm_merge_references.

Permissions

Hook Kind Purpose
plugixa_crm_user_can filter The single permission decision, handed the record
plugixa_crm_capabilities filter The capability map
plugixa_crm_user_team_ids filter Which teams somebody is on
plugixa_crm_access_granted / _revoked action CRM access changed

plugixa_crm_user_can is the one to know. Every permission decision in the plugin runs through it, and it is handed the record, not just the action - which is what makes own and team scopes expressible at all.

Keep any listener on it cheap. It is called constantly.

Sales

Hook Kind Fires
plugixa_crm_stage_changed action A deal moved stage: the id, the stage, and what it came from
plugixa_crm_lead_converted action A lead became an account, contact and opportunity
plugixa_crm_roll_up_account filter How figures roll up to an account

plugixa_crm_stage_changed is the one most integrations want. Reconstructing “a deal was won” from the generic update action would mean every consumer re-deriving what a stage change even is.

Activities and reminders

Hook Kind Purpose
plugixa_crm_activity_completed action A task, call or meeting was completed
plugixa_crm_set_reminders action A module announces it saved something with reminders
plugixa_crm_reminders_for / _reminder_targets filter Which records a reminder can be set on
plugixa_crm_notify action Put something in somebody’s inbox

plugixa_crm_notify is a public door: anything can notify somebody without knowing the notifications module exists.

Email

Hook Kind Purpose
plugixa_crm_email_sent / _received action After a message goes or arrives
plugixa_crm_before_send_mail action Before a message leaves
plugixa_crm_case_opened_by_email action Email-to-case opened one
plugixa_crm_mailbox_client filter Supply your own mailbox transport

Portal and lead capture

Hook Kind Purpose
plugixa_crm_portal_case_opened action A customer opened a case
plugixa_crm_portal_reply action A customer replied
plugixa_crm_portal_profile_updated action A customer corrected their details
plugixa_crm_portal_self_enrolled action Somebody was matched by self-enrolment
plugixa_crm_lead_capture_confirmed action A double opt-in was confirmed
plugixa_crm_public_request_captcha filter Add a challenge to a public request

Integrations and outbound requests

Hook Kind Purpose
plugixa_crm_integrations filter Register a connector
plugixa_crm_integration_handlers filter What a connector can do
plugixa_crm_integration_switched action One was enabled or disabled
plugixa_crm_outbound_destination_allowed filter Whether an address may be reached
plugixa_crm_webhook_destination_allowed filter The same question for webhooks
plugixa_crm_webhook_drain_seconds filter How long a drain run may take
plugixa_crm_form_submission_processed action A contact-form submission was handled
plugixa_crm_woo_order_synced action A WooCommerce order reached the CRM
plugixa_crm_sms_received action An inbound text arrived

Be careful with the two _destination_allowed filters. They are the guard that refuses private and reserved addresses, and returning true from one is how a webhook reaches your own internal network.

Reporting, search and the client

Hook Kind Purpose
plugixa_crm_report_sources filter Add a source to the report builder
plugixa_crm_dashboard_stats filter Change the dashboard figures
plugixa_crm_search_providers filter Add something to global search
plugixa_crm_streamed_entities filter Which entities have a stream
plugixa_crm_stream_status_fields filter Which field changes the stream reports
plugixa_crm_admin_config filter What the admin bundle is given
plugixa_crm_bootstrap_payload filter What /bootstrap returns

Documents, PDF and export

Hook Kind Purpose
plugixa_crm_pdf_engine filter Replace the PDF engine
plugixa_crm_pdf_data filter Change what a template is given
plugixa_crm_pdf_fonts filter Register a font
plugixa_crm_export_columns / _export_rows filter Change what an export contains

Settings, modules and data

Hook Kind Purpose
plugixa_crm_modules filter Register a module of your own
plugixa_crm_sanitize_settings filter Validate your own setting
plugixa_crm_settings_saved action After a save
plugixa_crm_examples filter Contribute example content
plugixa_crm_personal_data_tables filter Where personal data lives, for erasure
plugixa_crm_personal_data_erased action After an erasure
plugixa_crm_audit_retention_days filter How long the audit log is kept
plugixa_crm_currency_rate filter Supply a rate from your own source

plugixa_crm_examples is worth noting: the example content is contributed through it, which is why the seeder can seed twenty-four records across four modules while naming none of them. An add-on contributes its own the same way.

Front end

Hook Kind Purpose
plugixa_crm_is_app_page filter Whether this page carries the app
plugixa_crm_app_page_keep_styles filter Stylesheets to keep through the style strip
plugixa_crm_client_ip filter How the visitor’s address is determined behind a proxy
plugixa_crm_dev_bar filter Whether the development bar is drawn

Example

Open a case when a deal is won:

add_action(
    'plugixa_crm_stage_changed',
    function ( int $id, array $stage ): void {
        if ( 'won' !== ( $stage['type'] ?? '' ) ) {
            return;
        }
        my_open_onboarding_case( $id );
    },
    10,
    2
);

Troubleshooting

Symptom Usual cause
A listener never fires Register it on plugins_loaded or later, and check the argument count.
A filter has no effect Another listener runs later. Raise the priority number.
plugixa_crm_user_can is called constantly It is. Every permission decision goes through it. Keep it cheap.
A webhook reaches an internal address Something is returning true from a _destination_allowed filter.
An entity has no CRUD routes Register it through plugixa_crm_entity_types.
An entity cannot be imported It also needs a writer, through plugixa_crm_record_writers.
A Pro hook does nothing Its connector is absent. The hook fires; nothing listens.

What to do next

Quick Links