Guides

BricksMembers Documentation

Find everything you need to set up, customize, and get the most out of BricksMembers — from quick-start guides to advanced features.

Extensions Registry and Event-Based Extensibility

Pascal Basel
modified at February 8, 2026

BricksMembers provides a comprehensive event-based extensibility system. Extensions react to events but cannot override core access decisions. This preserves system integrity while enabling powerful integrations.

Core Principle: React, Don’t Decide

Extensions can respond to access changes but cannot bypass core access logic. This means:

  • Send email on access_granted
  • Sync CRM on access_revoked
  • Add bonus access on payment_completed (via separate API call)
  • Queue background jobs on access_scheduled

Available Events

Each event carries an \BaselMedia\BricksMembers\Core\Event object with:

  • User ID – The affected user
  • Resource Type – ‘level’ or ‘post’
  • Resource ID – Level or post ID
  • Reason – Why this happened (e.g., ‘scheduled_expiration’)
  • Trigger – What caused it (admin, webhook, woocommerce, cron, api)
  • Timestamp – When it occurred
  • Correlation ID – UUID for tracing related events
  • Context – Additional data specific to the event

Event Types

EventDescription
access_grantedUser gained access to a level or post
access_revokedUser lost access to a level or post
access_scheduledAccess change scheduled for the future (e.g., expiration)
access_expiredScheduled access expired (fires before revocation)
access_rebuiltAccess state was recalculated (progress rebuild, cache sync)
progress_completedUser completed a lesson/post
progress_incompletedUser marked content incomplete
content_unlockedDrip content became available

Subscribe to Events (Recommended)

Use \BaselMedia\BricksMembers\Utilities\ExtensionRegistry::subscribe() to listen for specific event types. Add these use statements at the top of your file:

use BaselMedia\BricksMembers\Utilities\ExtensionRegistry;
use BaselMedia\BricksMembers\Core\Event;

// Subscribe to access_granted events
ExtensionRegistry::subscribe(
    Event::ACCESS_GRANTED,
    function( Event $event ): void {
        // Send welcome email when level access is granted
        if ( $event->get_resource_type() === 'level' ) {
            $user_id  = $event->get_user_id();
            $level_id = $event->get_resource_id();
            $reason   = $event->get_reason();
            $trigger  = $event->get_trigger();
            
            // Log with correlation ID for tracing
            error_log( sprintf(
                '[%s] User %d granted level %d via %s: %s',
                $event->get_correlation_id(),
                $user_id,
                $level_id,
                $trigger,
                $reason
            ) );
            
            send_welcome_email( $user_id, $level_id );
        }
    }
);

// Subscribe to access_expired events
// Note: access_expired fires BEFORE the actual revocation.
// The sequence is: access_expired -> access_revoked (brm_event_access_revoked)
ExtensionRegistry::subscribe(
    Event::ACCESS_EXPIRED,
    function( Event $event ): void {
        // Send expiration-specific notification
        notify_user_access_expired(
            $event->get_user_id(),
            $event->get_resource_id()
        );
    }
);

// Subscribe to ALL events for logging/auditing
ExtensionRegistry::subscribe_all(
    function( Event $event ): void {
        log_to_audit_system( $event->to_array() );
    }
);

Event Context Management

When triggering access changes from your code, set the event context:

use BaselMedia\BricksMembers\Core\Event;

// Option 1: Set context manually
brm_set_event_context( Event::TRIGGER_WEBHOOK, 'payment_received' );
brm_add_user_level( $user_id, $level_id );
brm_clear_event_context();

// Option 2: Use the helper wrapper
brm_with_event_context(
    Event::TRIGGER_API,
    'external_system_sync',
    function() use ( $user_id, $level_id ) {
        brm_add_user_level( $user_id, $level_id );
    }
);

Register Settings Sections

Extensions can register settings sections to add admin UI:

use BaselMedia\BricksMembers\Utilities\ExtensionRegistry;

ExtensionRegistry::register_settings_section(
    'my_extension',
    array(
        'title'       => __( 'My Extension', 'brm' ),
        'description' => __( 'Additional settings for My Extension.', 'brm' ),
        'callback'    => 'my_extension_render_settings',
    )
);

Extension Guidelines

  • React, don’t decide – Extensions cannot override core access logic.
  • Use services for mutations; avoid direct DB writes.
  • Use \BaselMedia\BricksMembers\Services\CoreDataService for read-only access.
  • Set event context when triggering access changes from external sources.
  • Use correlation IDs to trace related events across systems.
  • Route cache invalidation through \BaselMedia\BricksMembers\Core\MutationContract.

See docs/api/actions.md for the full actions reference.

Create

Start Building with BricksMembers

Create, sell, and manage your content without limits. BricksMembers gives you everything you need to build membership and LMS sites directly in Bricks Builder — fast and frustration-free.

Join the membership & LMS revolution now!

Get Started
Still have questions? We're here to help!