For the complete documentation index, see llms.txt. This page is also available as Markdown.

Events

NorrCompetition 3.0+ is built from the ground up using the modern Joomla 5 Event Dispatcher architecture. All component actions dispatch strongly typed event classes derived from \NorrNext\Component\Competition\Administrator\Event\NcEvent (for immutable events) or \NorrNext\Component\Competition\Administrator\Event\NcMutableEvent (for mutable events).

Third-party extensions and plugins can subscribe to these events to intercept lifecycles, validate actions, modify queries, mutate data, or integrate external systems (e.g., payment gateways, CRM, SMS/OTP channels, AI moderation).


🏛️ Architecture Overview

Plugin Group

Custom plugins created specifically for NorrCompetition should use the competition plugin group (plugins/competition/myplugin/), although standard Joomla content plugins (plugins/content/) and system plugins (plugins/system/) can also subscribe to NorrCompetition events.

Subscribing to Events (SubscriberInterface)

In Joomla 5, plugins implement \Joomla\Event\SubscriberInterface and map event names to method callbacks in getSubscribedEvents():

<?php

namespace MyCompany\Plugin\Competition\MyCustomRules\Extension;

\defined('_JEXEC') or die;

use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\SubscriberInterface;
use NorrNext\Component\Competition\Administrator\Event\Participant\AllowedVotesEvent;
use NorrNext\Component\Competition\Administrator\Event\Model\BeforeSaveEvent;

final class MyCustomRules extends CMSPlugin implements SubscriberInterface
{
    /**
     * Maps subscribed event names or classes to handler methods.
     *
     * @return array<string, string>
     */
    public static function getSubscribedEvents(): array
    {
        return [
            'onParticipantAllowedCompetitionVotes' => 'onParticipantAllowedCompetitionVotes',
            'onParticipantBeforeSave'              => 'onParticipantBeforeSave',
        ];
    }

    public function onParticipantAllowedCompetitionVotes(AllowedVotesEvent $event): void
    {
        $context       = $event->getContext();
        $participantId = $event->getParticipantId();
        
        // Grant additional votes for VIP users
        $event->setArgument('allowedVotes', 5);
    }

    public function onParticipantBeforeSave(BeforeSaveEvent $event): bool
    {
        $context = $event->getContext();
        $table   = $event->getItem();
        $isNew   = $event->getIsNew();

        // Returning false cancels the save operation and rolls back the transaction
        return true;
    }
}

🎯 Event Types & Lifecycle

NorrCompetition uses three types of typed events:

  1. Immutable Events (NcEvent): Read-only notification events fired after an action completes (e.g., status changes, notifications, display preparation).

  2. Mutable Events (NcMutableEvent): Events where listeners can update properties (e.g., modifying redirect URLs, updating allowed vote quotas, altering tracking data, setting OTP channels).

  3. Cancellable Events (ResultAwareInterface): Events that gate critical operations (BeforeSave, BeforeDelete, BeforeTransactionCommit). If any listener returns false, the operation is aborted and the active database transaction is rolled back.


📚 Event Categories

Explore the available events by area:

  • Content — Form preparation and content plugin rendering events on entry views.

  • Contest — Contest lifecycle, display, save, delete, state, and automated status change events.

  • Entry — Participant entry lifecycle, approval workflows, voting frequency gates, vote limits, and state transitions.

  • Entry Form & Submission — Entry submission form lifecycle, custom field loading, and redirect handling.

  • Custom Fields — Field lifecycle, saving, state changes, and deletion events.

  • Voting — Vote submission, unvoting, score calculation, browser fingerprinting/analytics, and modal dialog validation.

  • Other & Ecosystem — Open Graph metadata, ACL overrides, OTP verification channels, image moderation, Flysystem remote storage, and points gating.

Last updated