User Docs Developer Docs | |

Installer

Installer.php provides two static hooks called at specific points in the plugin lifecycle: up() on activation and down() on explicit uninstall.

File Location and Namespace

<?php

namespace PluginsMyPlugin;

class Installer
{
    public static function up(): void
    {
        // ...
    }

    public static function down(): void
    {
        // ...
    }
}

The class is not required. If Installer.php does not exist, the system skips the hook silently.

up() — Called on Activation

up() is called once during plugin activation, after migrations have run. Use it for seeding default data, creating writable directories, setting up public asset directories, and writing default settings.

Seeding Default Data

public static function up(): void
{
    $db = ConfigDatabase::connect();

    if ($db->table('mp_categories')->countAll() === 0) {
        $db->table('mp_categories')->insertBatch([
            ['name' => 'General', 'slug' => 'general', 'sort_order' => 0],
            ['name' => 'News',    'slug' => 'news',    'sort_order' => 1],
        ]);
    }
}

Always guard seed inserts with an emptiness check — up() should be idempotent.

Creating Writable Directories

$dir = WRITEPATH . 'myplugin/';
if (! is_dir($dir)) {
    mkdir($dir, 0777, true);
}

Writing Default Settings

if (setting('MyPlugin.itemsPerPage') === null) {
    setting()->set('MyPlugin.itemsPerPage', 10);
}

down() — Called on Explicit Uninstall

down() is called only when an administrator explicitly uninstalls the plugin. It is not called on deactivation.

public static function down(): void
{
    // Remove plugin settings
    $db = ConfigDatabase::connect();
    $db->table('settings')
       ->like('class', 'MyPlugin')
       ->delete();
}

Important: down() does not roll back migrations. Tables remain after uninstall. To drop tables on uninstall, do it explicitly in down() using ConfigDatabase::forge()->dropTable().

Activation vs Deactivation vs Uninstall

EventMigrations runInstaller::up()Installer::down()
ActivateYes (latest)YesNo
DeactivateNoNoNo
UninstallNoNoYes

Deactivation only sets is_active = 0 in the plugins table. No cleanup runs. Deactivate and reactivate a plugin safely without data loss.