PluginInterface

Every Plugin.php must implement AppInterfacesPluginInterface. This contract is how Pubvana communicates with your plugin during boot, menu rendering, route loading, and CSRF configuration.

Interface Definition

<?php
// app/Interfaces/PluginInterface.php

namespace AppInterfaces;

interface PluginInterface
{
    public function getName(): string;
    public function getSlug(): string;
    public function getVersion(): string;
    public function getMenuItems(): array;
    public function getCsrfExemptions(): array;
    public function getPublicRoutes(): array;
    public function register(): void;
}

Method Reference

getName(): string

Returns the human-readable plugin name. Displayed in the admin panel plugin list.

public function getName(): string
{
    return 'Pubvana Docs';
}

getSlug(): string

Returns the plugin's folder name. Used as URL prefix, settings namespace, and DB identifier. Must match the actual folder name under plugins/.

public function getSlug(): string
{
    return 'pvdocs';
}

Rules: lowercase, no spaces, no hyphens. Use letters and numbers only.

getVersion(): string

Returns the current version string. Must match the version field in plugin_info.json. Used by the update checker to detect available upgrades.

public function getVersion(): string
{
    return '1.1.0';
}

getMenuItems(): array

Returns the admin sidebar menu entry for this plugin. PluginManager merges these into the admin navigation. Return an empty array [] if your plugin has no admin UI.

Return structure:

public function getMenuItems(): array
{
    return [
        'label'    => 'Pubvana Docs',
        'icon'     => 'fas fa-book',
        'children' => [
            [
                'label'   => 'Dashboard',
                'url'     => '/pvdocs/admin',
                'nav_key' => 'pvdocs_dashboard',
            ],
            [
                'label'   => 'Versions',
                'url'     => '/pvdocs/admin/versions',
                'nav_key' => 'pvdocs_versions',
            ],
            [
                'label'   => 'Articles',
                'url'     => '/pvdocs/admin/articles',
                'nav_key' => 'pvdocs_articles',
            ],
        ],
    ];
}

Key fields:

  • label (string) — display text for the menu item
  • icon (string) — FontAwesome 6 icon class (e.g., fas fa-book, fas fa-store)
  • children (array) — array of child menu items; each has label, url, and nav_key
  • nav_key (string) — unique key used to highlight the active sidebar item; must be globally unique across all plugins

If the plugin has only one admin page and no sub-navigation, use a flat structure (omit children and add url and nav_key directly to the top-level array).

getCsrfExemptions(): array

Returns an array of route patterns that should be exempt from CSRF verification. Used for endpoints that receive external POST requests — webhooks from payment gateways, external APIs calling back, etc.

public function getCsrfExemptions(): array
{
    return [
        'dstore/webhooks/stripe',
        'dstore/webhooks/*',
    ];
}

Patterns use CI4's route wildcard syntax. These are injected into the CI4 CSRF filter's except list during PluginManager::boot(). Do not use this to exempt your own admin forms — those should use CSRF tokens normally.

Return [] if your plugin has no external webhook endpoints.

getPublicRoutes(): array

Returns an array of public-facing route labels and URLs for this plugin. Used to populate the admin panel's "Public Routes" listing (Appearance or similar admin section). This is informational only — it does not define the actual routes (those go in Config/Routes.php).

public function getPublicRoutes(): array
{
    return [
        ['label' => 'User Docs', 'url' => '/pvdocs/user'],
        ['label' => 'Dev Docs',  'url' => '/pvdocs/dev'],
    ];
}

Return [] if your plugin has no public-facing URLs.

register(): void

Called during PluginManager::boot() on every request, after the namespace is registered and before routes are loaded. Use this for:

  • Registering CI4 event listeners
  • Initialising third-party SDKs that must load early
  • Overriding CI4 services for this plugin's scope
  • Setting up anything that must happen before controllers run
public function register(): void
{
    // Example: register a CI4 event listener
    CodeIgniterEventsEvents::on('post_published', function ($post) {
        service('mypluginService')->onPostPublished($post);
    });
}

For most simple plugins, register() is empty. Do not perform database queries or heavy work here — it runs on every request.

New in 2.3.6 — If your plugin implements the Email Provider interface and declares "core" capability, register it here: service('emailProvider')->register($this->getSlug(), new MyEmailProvider()); — see Email Provider.

Complete Example (PvDocs Plugin)

<?php

namespace PluginsPvDocs;

use AppInterfacesPluginInterface;

class Plugin implements PluginInterface
{
    public function getName(): string { return 'Pubvana Docs'; }
    public function getSlug(): string { return 'pvdocs'; }
    public function getVersion(): string { return '1.1.0'; }

    public function getMenuItems(): array
    {
        return [
            'label'    => 'Pubvana Docs',
            'icon'     => 'fas fa-book',
            'children' => [
                ['label' => 'Dashboard', 'url' => '/pvdocs/admin',          'nav_key' => 'pvdocs_dashboard'],
                ['label' => 'Versions',  'url' => '/pvdocs/admin/versions', 'nav_key' => 'pvdocs_versions'],
                ['label' => 'Articles',  'url' => '/pvdocs/admin/articles', 'nav_key' => 'pvdocs_articles'],
            ],
        ];
    }

    public function getPublicRoutes(): array
    {
        return [
            ['label' => 'User Docs', 'url' => '/pvdocs/user'],
            ['label' => 'Dev Docs',  'url' => '/pvdocs/dev'],
        ];
    }

    public function getCsrfExemptions(): array { return []; }

    public function register(): void { }
}