A practical overview for developers building custom WordPress plugins that extend the LA24Core CRM ecosystem, plus the minimum boilerplate needed to scaffold one.
What is LA24Core?
LA24Core is a modular WordPress CRM plugin. Its architecture is built around a hook-based extension system. Every major feature — menu items, CRM pages, capabilities, dashboard widgets, profile history tabs, and settings panels — is registered through WordPress filters and actions that LA24Core exposes.
You do not need to modify LA24Core source code to extend it. Create a standalone WordPress plugin, hook into the relevant filters/actions, and LA24Core picks up your additions automatically.

Prerequisites
- PHP 8.0+
- WordPress 6.0+
- LA24Core installed and activated
- Basic knowledge of WordPress hooks (actions and filters)
Extension Philosophy
LA24Core follows a **hook-first** design principle:
- All registration happens at `plugins_loaded` time via WordPress hooks
- No monkey-patching or file overrides required
- Each extension is a fully independent WordPress plugin
- Dependency check at runtime (`la24_get_option` function presence)
Architecture Overview
javascript
la24core/
├── includes/
│ ├── helpers/la24-core-functions.php ← Core utility functions
│ ├── abstracts/BaseViewController.php ← Base class for page controllers
│ ├── plugins/ ← Sub-plugin modules (ums, email, knowledge …)
│ └── LA24Core.php ← Main orchestrator
└── src/plugins/ ← React frontend entry points
Key Concepts
| Concept | How it works |
|---|---|
| Menu items | Registered via `la24_dashboard_menu_items` action + `LA24()->Menu()` singleton |
| CRM pages | Registered via `la24_endpoints` filter; each endpoint maps to a PHP controller class |
| Permissions | Registered via `la24_capability` filter; integrated with LA24Core role management UI |
| Dashboard widgets | Registered via `la24_widgets` filter; widget classes extend `\LoyalAxis\classes\services\widgets\Widget` and use a numeric ID of `900`+ for custom extensions |
| Profile history tabs | Registered via `la24_history_user_profile` filter; each tab has a controller |
| Settings panels | Registered via `la24_register_setting` filter; each panel is a settings class |
Plugin File Structure
Every LA24Core extension is a standard WordPress plugin. It registers into LA24Core by attaching callbacks to the hooks LA24Core provides. The boilerplate below is the minimum scaffolding required to build any extension.
Create a new folder inside `wp-content/plugins/`:
javascript
my-crm-extension/
├── my-crm-extension.php ← Main plugin file (WordPress header)
└── includes/
└── class-my-crm-hook.php ← Hook registration classMain Plugin File
`my-crm-extension.php`:
php
<?php
/**
* Plugin Name: My CRM Extension
* Plugin URI: https://example.com
* Description: Extends LA24Core with custom CRM features.
* Version: 1.0.0
* Author: Your Name
* Text Domain: my-crm-ext
*/
defined( 'ABSPATH' ) || exit;
define( 'MY_CRM_EXT_PATH', plugin_dir_path( __FILE__ ) );
define( 'MY_CRM_EXT_URL', plugin_dir_url( __FILE__ ) );
add_action( 'plugins_loaded', function () {
// Only load if LA24Core is active
if ( ! function_exists( 'la24_get_option' ) ) {
return;
}
require_once MY_CRM_EXT_PATH . 'includes/class-my-crm-hook.php';
new My_CRM_Hook();
} );Hook Registration Class
`includes/class-my-crm-hook.php`:
php
<?php
defined( 'ABSPATH' ) || exit;
class My_CRM_Hook {
public function __construct() {
add_action( 'la24_dashboard_menu_items', array( $this, 'register_menu_items' ) );
add_filter( 'la24_endpoints', array( $this, 'register_endpoints' ), 10 );
add_filter( 'la24_capability', array( $this, 'register_capabilities' ), 10 );
add_filter( 'la24_widgets', array( $this, 'register_widgets' ), 10 );
add_filter( 'la24_groups_permission', array( $this, 'register_permission_groups' ), 10 );
add_filter( 'la24_register_setting', array( $this, 'register_settings' ), 10 );
add_filter( 'la24_history_user_profile', array( $this, 'register_profile_history_tabs' ), 10 );
}
// Each method is implemented in the relevant guide section.
}Dependency Check
The guard `if ( ! function_exists( 'la24_get_option' ) )` ensures your plugin silently skips loading when LA24Core is absent or inactive. Without this check, fatal errors would occur on sites where LA24Core is not installed.
- `la24_get_option` is defined in `includes/helpers/la24-core-functions.php` and is available as soon as LA24Core loads.
- Always use the `plugins_loaded` action (not `init`) so that all plugins are guaranteed to have loaded before the check runs.

Quick Reference
| Goal | Hook/Function | Type |
|---|---|---|
| Add sidebar menu item | `la24_dashboard_menu_items` | Action |
| Register a CRM page | `la24_endpoints` | Filter |
| Add a permission | `la24_capability` | Filter |
| Group permissions in UI | `la24_groups_permission` | Filter |
| Add profile history tab | `la24_history_user_profile` | Filter |
| Add profile action button | `la24_render_profile_action_btn` | Filter |
| Add dashboard widget | `la24_widgets` | Filter |
| Add settings panel | `la24_register_setting` | Filter |
| Register a custom automation program | `la24_register_automation_program` | Filter |
| Check user capability | `la24_user_can( $user_id, $cap )` | Function |
| Get page URL | `la24_get_permalink_panel( $slug )` | Function |
| Read plugin option | `la24_get_option( $key, $group )` | Function |
| Save plugin option | `la24_update_option( $key, $val, $group )` | Function |