Save Big: Bundle all Skunk products and save up to 57%

Docs/Developers/Hooks & Filters

SkunkCRM Hooks and Filters Reference

SkunkCRM provides a comprehensive set of WordPress action and filter hooks to extend and customize your CRM functionality. This reference provides complete documentation for developers who want to extend SkunkCRM.

Overview

All SkunkCRM hooks use the skunkcrm_ prefix to follow WordPress naming conventions. The hooks are strategically placed throughout the plugin to provide maximum extensibility while maintaining performance and security.

Plugin Lifecycle Hooks

These hooks fire during plugin initialization, activation, and deactivation.

Action Hooks

skunkcrm_before_init

Fires before SkunkCRM initialization begins.

functions.phpphp
1do_action('skunkcrm_before_init');

Parameters: None

Since: 1.8.0

Example:

functions.phpphp
1add_action('skunkcrm_before_init', function() {
2    // Initialize your custom SkunkCRM extensions
3    MyCustomSkunkExtension::init();
4});

skunkcrm_after_init

Fires after SkunkCRM initialization is complete.

functions.phpphp
1do_action('skunkcrm_after_init');

Parameters: None

Since: 1.8.0

skunkcrm_before_activation

Fires before plugin activation begins.

functions.phpphp
1do_action('skunkcrm_before_activation');

Parameters: None

Since: 1.8.0

skunkcrm_after_activation

Fires after plugin activation is complete.

functions.phpphp
1do_action('skunkcrm_after_activation');

Parameters: None

Since: 1.8.0

skunkcrm_before_deactivation

Fires before plugin deactivation begins.

functions.phpphp
1do_action('skunkcrm_before_deactivation');

Parameters: None

Since: 1.8.0

skunkcrm_after_deactivation

Fires after plugin deactivation is complete.

functions.phpphp
1do_action('skunkcrm_after_deactivation');

Parameters: None

Since: 1.8.0

Contact Management Hooks

These hooks provide extensibility for contact CRUD operations.

Action Hooks

skunkcrm_before_contact_create

Fires before a contact is created.

functions.phpphp
1do_action('skunkcrm_before_contact_create', $data);

Parameters:

  • $data (array) The sanitized contact data that will be inserted

Since: 1.8.0

Example:

functions.phpphp
1add_action('skunkcrm_before_contact_create', function($data) {
2    // Log contact creation attempts
3    error_log('Creating contact: ' . $data['name']);
4    
5    // Send notification to admin
6    wp_mail('admin@example.com', 'New Contact', 'Contact ' . $data['name'] . ' is being created');
7});

skunkcrm_after_contact_create

Fires after a contact is successfully created.

functions.phpphp
1do_action('skunkcrm_after_contact_create', $contact_id, $data);

Parameters:

  • $contact_id (int) The ID of the newly created contact
  • $data (array) The contact data that was inserted

Since: 1.8.0

Example:

functions.phpphp
1add_action('skunkcrm_after_contact_create', function($contact_id, $data) {
2    // Automatically assign new contacts to default user
3    update_contact_meta($contact_id, 'assigned_to', 1);
4    
5    // Trigger welcome email automation
6    MyEmailSystem::send_welcome_email($contact_id);
7});

skunkcrm_before_contact_update

Fires before a contact is updated.

functions.phpphp
1do_action('skunkcrm_before_contact_update', $contact_id, $data, $old_data);

Parameters:

  • $contact_id (int) The ID of the contact being updated
  • $data (array) The new contact data
  • $old_data (array) The existing contact data before update

Since: 1.8.0

skunkcrm_after_contact_update

Fires after a contact is successfully updated.

functions.phpphp
1do_action('skunkcrm_after_contact_update', $contact_id, $data, $old_data);

Parameters:

  • $contact_id (int) The ID of the updated contact
  • $data (array) The new contact data
  • $old_data (array) The previous contact data

Since: 1.8.0

skunkcrm_before_contact_delete

Fires before a contact is deleted.

functions.phpphp
1do_action('skunkcrm_before_contact_delete', $contact_id, $contact_data);

Parameters:

  • $contact_id (int) The ID of the contact being deleted
  • $contact_data (array) The contact data before deletion

Since: 1.8.0

skunkcrm_after_contact_delete

Fires after a contact is successfully deleted.

functions.phpphp
1do_action('skunkcrm_after_contact_delete', $contact_id, $contact_data);

Parameters:

  • $contact_id (int) The ID of the deleted contact
  • $contact_data (array) The contact data that was deleted

Since: 1.8.0

skunkcrm_before_contact_status_change

Fires before a contact's status is changed.

functions.phpphp
1do_action('skunkcrm_before_contact_status_change', $contact_id, $old_status, $new_status);

Parameters:

  • $contact_id (int) The ID of the contact
  • $old_status (string) The previous status
  • $new_status (string) The new status

Since: 1.8.0

skunkcrm_after_contact_status_change

Fires after a contact's status is successfully changed.

functions.phpphp
1do_action('skunkcrm_after_contact_status_change', $contact_id, $old_status, $new_status);

Parameters:

  • $contact_id (int) The ID of the contact
  • $old_status (string) The previous status
  • $new_status (string) The new status

Since: 1.8.0

Filter Hooks

skunkcrm_contact_data_before_save

Filters contact data before saving to database.

functions.phpphp
1$data = apply_filters('skunkcrm_contact_data_before_save', $data, $contact_id);

Parameters:

  • $data (array) The contact data
  • $contact_id (int|null) The contact ID (null for new contacts)

Return: (array) Modified contact data

Since: 1.8.0

Example:

functions.phpphp
1add_filter('skunkcrm_contact_data_before_save', function($data, $contact_id) {
2    // Auto-capitalize names
3    if (isset($data['name'])) {
4        $data['name'] = ucwords(strtolower($data['name']));
5    }
6    
7    // Auto-format phone numbers
8    if (isset($data['phone']) && !empty($data['phone'])) {
9        $data['phone'] = format_phone_number($data['phone']);
10    }
11    
12    // Add timestamp for tracking
13    if (is_null($contact_id)) {
14        $data['lead_source'] = 'website_' . date('Y-m-d');
15    }
16    
17    return $data;
18}, 10, 2);

skunkcrm_contact_status_options

Filters the available contact status options.

functions.phpphp
1$statuses = apply_filters('skunkcrm_contact_status_options', $statuses);

Parameters:

  • $statuses (array) Array of status key-value pairs

Return: (array) Modified status options

Since: 1.8.0

Example:

functions.phpphp
1add_filter('skunkcrm_contact_status_options', function($statuses) {
2    // Add custom statuses
3    $statuses['vip'] = 'VIP Customer';
4    $statuses['partner'] = 'Business Partner';
5    
6    // Remove unused status
7    unset($statuses['unqualified']);
8    
9    return $statuses;
10});

skunkcrm_contacts_query_args

Filters query arguments before retrieving contacts.

functions.phpphp
1$args = apply_filters('skunkcrm_contacts_query_args', $args);

Parameters:

  • $args (array) Query arguments

Return: (array) Modified query arguments

Since: 1.8.0

Example:

functions.phpphp
1add_filter('skunkcrm_contacts_query_args', function($args) {
2    // Only show contacts assigned to current user by default
3    if (!isset($args['assigned_to']) && !current_user_can('manage_options')) {
4        $args['assigned_to'] = get_current_user_id();
5    }
6    
7    return $args;
8});

skunkcrm_contacts_search_results

Filters contact search results before returning.

functions.phpphp
1$results = apply_filters('skunkcrm_contacts_search_results', $results, $search_term, $args);

Parameters:

  • $results (array) Search results
  • $search_term (string) The search term used
  • $args (array) Search arguments

Return: (array) Modified search results

Since: 1.8.0

API Hooks

These hooks provide extensibility for the REST API endpoints.

Action Hooks

skunkcrm_before_api_init

Fires before REST API routes are registered.

functions.phpphp
1do_action('skunkcrm_before_api_init');

Parameters: None

Since: 1.8.0

skunkcrm_before_api_request

Fires before processing any API request.

functions.phpphp
1do_action('skunkcrm_before_api_request', $request, $endpoint);

Parameters:

  • $request (WP_REST_Request) The REST request object
  • $endpoint (string) The endpoint being accessed

Since: 1.8.0

Example:

functions.phpphp
1add_action('skunkcrm_before_api_request', function($request, $endpoint) {
2    // Log all API requests
3    $user_id = get_current_user_id();
4    $ip = $request->get_header('X-Forwarded-For') ?: $_SERVER['REMOTE_ADDR'];
5    
6    error_log("SkunkCRM API: User {$user_id} from {$ip} accessing {$endpoint}");
7    
8    // Rate limiting check
9    if (is_user_over_rate_limit($user_id, $endpoint)) {
10        wp_die('Rate limit exceeded', 429);
11    }
12}, 10, 2);

skunkcrm_after_api_request

Fires after successful API request processing.

functions.phpphp
1do_action('skunkcrm_after_api_request', $response, $request, $endpoint);

Parameters:

  • $response (WP_REST_Response) The API response
  • $request (WP_REST_Request) The REST request object
  • $endpoint (string) The endpoint that was accessed

Since: 1.8.0

skunkcrm_api_error

Fires when API request encounters an error.

functions.phpphp
1do_action('skunkcrm_api_error', $error, $request, $endpoint);

Parameters:

  • $error (WP_Error) The error object
  • $request (WP_REST_Request) The REST request object
  • $endpoint (string) The endpoint that encountered the error

Since: 1.8.0

Filter Hooks

skunkcrm_api_response_data

Filters response data before creating response.

functions.phpphp
1$data = apply_filters('skunkcrm_api_response_data', $data, $request, $endpoint);

Parameters:

  • $data (mixed) The response data
  • $request (WP_REST_Request) The REST request object
  • $endpoint (string) The endpoint being accessed

Return: (mixed) Modified response data

Since: 1.8.0

Example:

functions.phpphp
1add_filter('skunkcrm_api_response_data', function($data, $request, $endpoint) {
2    if ($endpoint === 'get_contacts') {
3        // Add custom fields to contact data
4        foreach ($data as &$contact) {
5            $contact['custom_score'] = calculate_lead_score($contact['id']);
6            $contact['last_interaction'] = get_last_interaction_date($contact['id']);
7        }
8    }
9    
10    return $data;
11}, 10, 3);

skunkcrm_api_permission_check

Filters basic API permission result.

functions.phpphp
1$has_permission = apply_filters('skunkcrm_api_permission_check', $has_permission, $request);

Parameters:

  • $has_permission (bool) Current permission result
  • $request (WP_REST_Request) The REST request object

Return: (bool) Modified permission result

Since: 1.8.0

Database Hooks

These hooks provide extensibility for database operations.

Action Hooks

skunkcrm_before_table_creation

Fires before any database table creation begins.

functions.phpphp
1do_action('skunkcrm_before_table_creation');

Parameters: None

Since: 1.8.0

skunkcrm_after_table_creation

Fires after all database tables are created.

functions.phpphp
1do_action('skunkcrm_after_table_creation');

Parameters: None

Since: 1.8.0

skunkcrm_before_table_creation_individual

Fires before each individual table creation.

functions.phpphp
1do_action('skunkcrm_before_table_creation_individual', $table_name, $sql);

Parameters:

  • $table_name (string) Name of the table being created
  • $sql (string) SQL statement for table creation

Since: 1.8.0

skunkcrm_after_table_creation_individual

Fires after each individual table creation.

functions.phpphp
1do_action('skunkcrm_after_table_creation_individual', $table_name, $result);

Parameters:

  • $table_name (string) Name of the table that was created
  • $result (bool|null) Result of the table creation

Since: 1.8.0

Filter Hooks

skunkcrm_table_creation_sql

General filter for any table creation SQL.

functions.phpphp
1$sql = apply_filters('skunkcrm_table_creation_sql', $sql, $table_name);

Parameters:

  • $sql (string) The SQL statement
  • $table_name (string) Name of the table

Return: (string) Modified SQL statement

Since: 1.8.0

Example:

functions.phpphp
1add_filter('skunkcrm_table_creation_sql', function($sql, $table_name) {
2    if ($table_name === 'skunk_contacts') {
3        // Add custom column to contacts table
4        $sql = str_replace(
5            'created_at datetime DEFAULT CURRENT_TIMESTAMP,',
6            'created_at datetime DEFAULT CURRENT_TIMESTAMP,
7             custom_score int(11) DEFAULT 0,',
8            $sql
9        );
10    }
11    
12    return $sql;
13}, 10, 2);

skunkcrm_database_charset_collate

Filters charset and collation settings.

functions.phpphp
1$charset_collate = apply_filters('skunkcrm_database_charset_collate', $charset_collate);

Parameters:

  • $charset_collate (string) Charset and collation string

Return: (string) Modified charset and collation

Since: 1.8.0

Automation Hooks

These hooks provide extensibility for the automation system.

Action Hooks

skunkcrm_before_automation_execute

Fires before an automation is executed.

functions.phpphp
1do_action('skunkcrm_before_automation_execute', $automation_id, $contact_id, $trigger_data);

Parameters:

  • $automation_id (int) The automation ID
  • $contact_id (int) The contact ID triggering the automation
  • $trigger_data (array) Data about what triggered the automation

Since: 1.8.0

skunkcrm_after_automation_execute

Fires after an automation is executed.

functions.phpphp
1do_action('skunkcrm_after_automation_execute', $automation_id, $contact_id, $result, $trigger_data);

Parameters:

  • $automation_id (int) The automation ID
  • $contact_id (int) The contact ID that triggered the automation
  • $result (array) The execution result
  • $trigger_data (array) Data about what triggered the automation

Since: 1.8.0

skunkcrm_before_automation_email

Fires before sending an automation email.

functions.phpphp
1do_action('skunkcrm_before_automation_email', $contact_id, $email_config, $automation_id);

Parameters:

  • $contact_id (int) The contact ID
  • $email_config (array) Email configuration
  • $automation_id (int) The automation ID

Since: 1.8.0

skunkcrm_after_automation_email

Fires after sending an automation email.

functions.phpphp
1do_action('skunkcrm_after_automation_email', $contact_id, $email_result, $email_config, $automation_id);

Parameters:

  • $contact_id (int) The contact ID
  • $email_result (bool) Whether the email was sent successfully
  • $email_config (array) Email configuration
  • $automation_id (int) The automation ID

Since: 1.8.0

Filter Hooks

skunkcrm_automation_email_content

Filters email content before processing.

functions.phpphp
1$content = apply_filters('skunkcrm_automation_email_content', $content, $contact, $template, $automation_id);

Parameters:

  • $content (string) Email content
  • $contact (array) Contact data
  • $template (string) Email template
  • $automation_id (int) The automation ID

Return: (string) Modified email content

Since: 1.8.0

Example:

functions.phpphp
1add_filter('skunkcrm_automation_email_content', function($content, $contact, $template, $automation_id) {
2    // Add personalization
3    $content = str_replace('{first_name}', get_first_name($contact['name']), $content);
4    $content = str_replace('{company}', $contact['company'], $content);
5    
6    // Add dynamic content based on contact status
7    if ($contact['status'] === 'customer') {
8        $content .= "\n\nAs a valued customer, here's your special offer: [CUSTOMER_OFFER]";
9    }
10    
11    return $content;
12}, 10, 4);

skunkcrm_should_execute_automation

Controls whether an automation should execute.

functions.phpphp
1$should_execute = apply_filters('skunkcrm_should_execute_automation', true, $automation_id, $contact_id, $trigger_data);

Parameters:

  • $should_execute (bool) Whether to execute the automation
  • $automation_id (int) The automation ID
  • $contact_id (int) The contact ID
  • $trigger_data (array) Trigger data

Return: (bool) Whether the automation should execute

Since: 1.8.0

Examples

Complete Contact Lifecycle Tracking

functions.phpphp
1// Track complete contact lifecycle
2class ContactLifecycleTracker {
3    
4    public function __construct() {
5        add_action('skunkcrm_after_contact_create', [$this, 'track_contact_created']);
6        add_action('skunkcrm_after_contact_update', [$this, 'track_contact_updated'], 10, 3);
7        add_action('skunkcrm_after_contact_status_change', [$this, 'track_status_change'], 10, 3);
8        add_action('skunkcrm_before_contact_delete', [$this, 'track_contact_deleted'], 10, 2);
9    }
10    
11    public function track_contact_created($contact_id, $data) {
12        $this->log_event('contact_created', $contact_id, [
13            'name' => $data['name'],
14            'email' => $data['email'],
15            'initial_status' => $data['status']
16        ]);
17    }
18    
19    public function track_contact_updated($contact_id, $new_data, $old_data) {
20        $changes = array_diff_assoc($new_data, $old_data);
21        if (!empty($changes)) {
22            $this->log_event('contact_updated', $contact_id, [
23                'changes' => $changes,
24                'previous_data' => $old_data
25            ]);
26        }
27    }
28    
29    public function track_status_change($contact_id, $old_status, $new_status) {
30        $this->log_event('status_changed', $contact_id, [
31            'from' => $old_status,
32            'to' => $new_status,
33            'timestamp' => current_time('mysql')
34        ]);
35        
36        // Trigger different actions based on status
37        if ($new_status === 'customer') {
38            $this->trigger_customer_onboarding($contact_id);
39        }
40    }
41    
42    public function track_contact_deleted($contact_id, $contact_data) {
43        $this->log_event('contact_deleted', $contact_id, [
44            'final_data' => $contact_data,
45            'deleted_by' => get_current_user_id()
46        ]);
47    }
48    
49    private function log_event($event, $contact_id, $data) {
50        // Log to custom table or external service
51        error_log("SkunkCRM Event: {$event} for contact {$contact_id}: " . json_encode($data));
52    }
53    
54    private function trigger_customer_onboarding($contact_id) {
55        // Custom onboarding logic
56        do_action('company_customer_onboarding', $contact_id);
57    }
58}
59
60new ContactLifecycleTracker();

Custom API Response Enhancement

functions.phpphp
1// Add custom data to all API responses
2add_filter('skunkcrm_api_response_data', function($data, $request, $endpoint) {
3    // Add metadata to all responses
4    if (is_array($data) && $endpoint === 'get_contacts') {
5        foreach ($data as &$contact) {
6            // Add calculated fields
7            $contact['days_since_created'] = calculate_days_since_created($contact['created_at']);
8            $contact['interaction_count'] = get_contact_interaction_count($contact['id']);
9            $contact['last_activity'] = get_last_activity_date($contact['id']);
10            $contact['lead_score'] = calculate_lead_score($contact);
11            
12            // Add permissions for current user
13            $contact['permissions'] = [
14                'can_edit' => current_user_can('edit_contact', $contact['id']),
15                'can_delete' => current_user_can('delete_contact', $contact['id'])
16            ];
17        }
18    }
19    
20    return $data;
21}, 10, 3);
22
23function calculate_lead_score($contact) {
24    $score = 0;
25    
26    // Email provided
27    if (!empty($contact['email'])) $score += 20;
28    
29    // Phone provided
30    if (!empty($contact['phone'])) $score += 15;
31    
32    // Company provided
33    if (!empty($contact['company'])) $score += 10;
34    
35    // Status-based scoring
36    $status_scores = [
37        'lead' => 50,
38        'warm-lead' => 30,
39        'cold-lead' => 10,
40        'customer' => 100
41    ];
42    $score += $status_scores[$contact['status']] ?? 0;
43    
44    return $score;
45}

Advanced Automation Extension

functions.phpphp
1// Extend automation system with custom actions and conditions
2class AdvancedAutomationExtensions {
3    
4    public function __construct() {
5        add_filter('skunkcrm_automation_action_types', [$this, 'add_custom_actions']);
6        add_filter('skunkcrm_automation_condition_types', [$this, 'add_custom_conditions']);
7        add_filter('skunkcrm_custom_action_type', [$this, 'handle_custom_action'], 10, 4);
8        add_filter('skunkcrm_custom_condition_type', [$this, 'handle_custom_condition'], 10, 3);
9        add_filter('skunkcrm_automation_email_content', [$this, 'enhance_email_content'], 10, 4);
10    }
11    
12    public function add_custom_actions($actions) {
13        $actions['create_task'] = 'Create Task';
14        $actions['send_slack'] = 'Send Slack Message';
15        $actions['webhook_post'] = 'Send Webhook';
16        return $actions;
17    }
18    
19    public function add_custom_conditions($conditions) {
20        $conditions['lead_score_above'] = 'Lead Score Above';
21        $conditions['days_since_contact'] = 'Days Since Last Contact';
22        return $conditions;
23    }
24    
25    public function handle_custom_action($result, $action_type, $config, $contact) {
26        switch ($action_type) {
27            case 'create_task':
28                return $this->create_task_action($config, $contact);
29            case 'send_slack':
30                return $this->send_slack_action($config, $contact);
31            case 'webhook_post':
32                return $this->webhook_post_action($config, $contact);
33        }
34        return $result;
35    }
36    
37    public function handle_custom_condition($result, $condition_type, $config, $contact) {
38        switch ($condition_type) {
39            case 'lead_score_above':
40                return calculate_lead_score($contact) > intval($config['value']);
41            case 'days_since_contact':
42                $last_contact = get_last_contact_date($contact['id']);
43                $days_diff = (time() - strtotime($last_contact)) / DAY_IN_SECONDS;
44                return $days_diff > intval($config['days']);
45        }
46        return $result;
47    }
48    
49    private function create_task_action($config, $contact) {
50        // Create task in your task management system
51        $task_data = [
52            'title' => str_replace('{contact_name}', $contact['name'], $config['title']),
53            'description' => str_replace('{contact_name}', $contact['name'], $config['description']),
54            'contact_id' => $contact['id'],
55            'due_date' => date('Y-m-d', strtotime($config['due_in_days'] . ' days')),
56            'assigned_to' => $config['assigned_to'] ?? get_current_user_id()
57        ];
58        
59        return wp_insert_post([
60            'post_type' => 'task',
61            'post_title' => $task_data['title'],
62            'post_content' => $task_data['description'],
63            'post_status' => 'publish',
64            'meta_input' => $task_data
65        ]);
66    }
67    
68    private function send_slack_action($config, $contact) {
69        $webhook_url = $config['webhook_url'];
70        $message = str_replace('{contact_name}', $contact['name'], $config['message']);
71        
72        $payload = [
73            'text' => $message,
74            'channel' => $config['channel'] ?? '#general',
75            'username' => 'SkunkCRM'
76        ];
77        
78        return wp_remote_post($webhook_url, [
79            'body' => json_encode($payload),
80            'headers' => ['Content-Type' => 'application/json']
81        ]);
82    }
83    
84    public function enhance_email_content($content, $contact, $template, $automation_id) {
85        // Add dynamic content based on contact data
86        $replacements = [
87            '{contact_score}' => calculate_lead_score($contact),
88            '{days_as_contact}' => calculate_days_since_created($contact['created_at']),
89            '{last_interaction}' => get_last_interaction_summary($contact['id']),
90            '{recommended_action}' => get_recommended_next_action($contact)
91        ];
92        
93        return str_replace(array_keys($replacements), array_values($replacements), $content);
94    }
95}
96
97new AdvancedAutomationExtensions();

This documentation covers the most commonly used hooks. For a complete list of all available hooks, see the source code documentation in each class file.

Was this page helpful?