> For the complete documentation index, see [llms.txt](https://docs.norrnext.com/norrcompetition/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.norrnext.com/norrcompetition/customisation/events/vote.md).

# Vote

Voting events allow plugins to intercept vote operations, calculate custom score weights, perform browser fingerprinting and fraud detection, enrich voter details, validate voting modal inputs, and customize client responses.

***

### `onVoteSetScore`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Vote\SetScoreEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `VoteModel::setScore()` (site)

#### Description

Allows plugins to analyze the voter's tracking data and dynamically assign custom points/weights to the vote.

```php
use NorrNext\Component\Competition\Administrator\Event\Vote\SetScoreEvent;

public function onVoteSetScore(SetScoreEvent $event): void
{
    $entryId      = $event->getEntryId();
    $trackingData = $event->getTrackingData();
    $params       = $event->getParams();
    $score        = $event->getScore(); // ['score' => 1, 'info' => []]

    // Assign bonus points based on custom algorithm
    $score['score']  = 2;
    $score['info'][] = 'Double points weekend';

    $event->setArgument('score', $score);
}
```

***

### `onVoteSetValid`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Vote\SetValidEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `VoteModel::setValid()` (site)

#### Description

Allows anti-fraud and security plugins to analyze the voter's browser fingerprint and flag fraudulent votes (`valid = 0`).

```php
use NorrNext\Component\Competition\Administrator\Event\Vote\SetValidEvent;

public function onVoteSetValid(SetValidEvent $event): void
{
    $entryId      = $event->getEntryId();
    $trackingData = $event->getTrackingData();

    // Invalidate vote if bot-like behavior is detected
    if (!empty($trackingData['is_bot'])) {
        $event->setArgument('valid', 0);
    }
}
```

***

### `onVoteBeforeSaveDetails`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Vote\BeforeSaveDetailsEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `VoteModel::saveDetails()` (site)

#### Description

Enriches the vote details record with custom geolocation (country, city) or analytics data before saving to `#__competition_vote_details`.

```php
use NorrNext\Component\Competition\Administrator\Event\Vote\BeforeSaveDetailsEvent;

public function onVoteBeforeSaveDetails(BeforeSaveDetailsEvent $event): void
{
    $table = $event->getItem(); // VoteDetailsTable object

    // Populate custom geolocation
    $table->country = 'Germany';
    $table->city    = 'Berlin';
}
```

#### Vote Details Table Properties:

* `$id` (int) — Primary key
* `$vote_id` (int) — Associated vote ID
* `$user_agent` (string) — Voter browser User-Agent
* `$language` (string) — Browser language
* `$timezone` (string) — Browser timezone
* `$platform` (string) — Operating system/device platform
* `$scr_res` (string) — Screen resolution
* `$canvas` (string) — Canvas fingerprint hash
* `$referrer` (string) — HTTP referrer URL
* `$timediff` (int) — Time in milliseconds from page visit to vote submission
* `$country` (string) — Geolocation country
* `$city` (string) — Geolocation city

***

### `onVoteAfterSaveDetails`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Vote\AfterSaveDetailsEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `VoteModel::saveDetails()` (site)

#### Description

Fired after the vote tracking details are saved to the database.

***

### `onVoteBeforeDelete`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Vote\BeforeDeleteEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `VoteModel::delete()` (site unvote or admin vote removal)
* **Cancellable:** Yes (returning `false` prevents vote deletion)

```php
use NorrNext\Component\Competition\Administrator\Event\Vote\BeforeDeleteEvent;

public function onVoteBeforeDelete(BeforeDeleteEvent $event): bool
{
    $table = $event->getItem();
    return true;
}
```

***

### `onVoteAfterDelete`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Vote\AfterDeleteEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `VoteModel::delete()`

***

### `onVoteModalContent`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Vote\VoteModalContentEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `VoteModal::getModalContent()` (site)

#### Description

Allows plugins to inject custom HTML, disclaimer checkboxes, or form fields into the interactive AJAX voting modal dialog.

```php
use NorrNext\Component\Competition\Administrator\Event\Vote\VoteModalContentEvent;

public function onVoteModalContent(VoteModalContentEvent $event): void
{
    $html = $event->getHtml();
    $html .= '<div class="uk-margin"><label><input type="checkbox" name="terms" required> I agree to voting terms</label></div>';
    
    $event->setArgument('html', $html);
}
```

***

### `onVoteModalValidate`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Vote\VoteModalValidateEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `VoteModal::validateModalSubmission()` (site)

#### Description

Validates custom inputs submitted via the vote modal dialog before allowing the vote to proceed.

```php
use NorrNext\Component\Competition\Administrator\Event\Vote\VoteModalValidateEvent;

public function onVoteModalValidate(VoteModalValidateEvent $event): void
{
    $formData = $event->getFormData();

    if (empty($formData['terms'])) {
        $event->setArgument('valid', false);
        $event->setArgument('message', 'You must accept the voting terms before casting your vote.');
    }
}
```

***

### `onVoteResponse` & `onUnvoteResponse`

* **Event Class:** `\NorrNext\Component\Competition\Administrator\Event\Controller\VoteResponseEvent`
* **Context:** `com_competition.vote`
* **Triggered In:** `ParticipantController::ajaxVote()` and `ParticipantController::ajaxUnvote()` (site)

#### Description

Allows plugins to modify the JSON response payload sent back to the browser client upon casting or revoking a vote.

```php
use NorrNext\Component\Competition\Administrator\Event\Controller\VoteResponseEvent;

public function onVoteResponse(VoteResponseEvent $event): void
{
    $response = $event->getResponse(); // Joomla\CMS\Response\JsonResponse object
    $response->message = 'Your vote was successfully recorded!';
}
```

**Arguments**\
`$context` - the context of the event, ‘com\_competition.vote’.\
`$response` - response object holding vote data, response status and response message.<br>

***

### onVoteModalContent & onVoteModalValidate

NorrCompetition allows developers to customize the vote modal dialog — for example, injecting custom disclaimers, GDPR consent checkboxes, or additional form fields, and validating user inputs before casting a vote.

* **`onVoteModalContent`** (`NorrNext\Component\Competition\Administrator\Event\Vote\VoteModalContentEvent`): Dispatched when rendering the vote confirmation modal form. Allows adding custom XML form definitions and appending custom HTML content/disclaimers.
* **`onVoteModalValidate`** (`NorrNext\Component\Competition\Administrator\Event\Vote\VoteModalValidateEvent`): Dispatched upon modal form submission to validate custom inputs (such as mandatory terms acceptance) before the vote is finalized.

{% hint style="info" %}
**Need a Custom Integration or Plugin?**\
If you need tailored voting modals, third-party verification channels, or bespoke custom plugins for NorrCompetition, you can request custom extension development at [Services for Joomla, custom plugin development](https://norrnext.com/services).
{% endhint %}
