Module Options

Static Options

Add configuration options to a module by inserting rows into module_options. A row is the option's definition: default_value is the value until someone saves another one. Saved values live in module_option_values, one row per scope (system, workspace or user); is_workspace and is_user mark an option that a workspace or a user may override.

MySQL

SET @id_module_test = (SELECT `id` FROM `modules` WHERE `ident` = 'test_module');

INSERT INTO `module_options` (`id_module`, `caption`, `name`, `type`, `default_value`, `required`)
VALUES (@id_module_test, 'Test numbers', 'number', 'number', '3', 1);

Postgres

DO $$
    DECLARE
        id_module_test integer;
    BEGIN
        SELECT id INTO id_module_test FROM modules WHERE ident = 'test_module';

        INSERT INTO module_options (id_module, caption, name, type, default_value, required)
        VALUES (id_module_test, 'Test numbers', 'number', 'number', '3', true);
    END;
$$;

Read options in your module via getOption():

use DisplayPlugin;
use plugin\Modules\IModule;

class TestModulePlugin extends DisplayPlugin implements IModule
{
    public function getNumber(): int
    {
        return (int) $this->getOption('number');
    }
}

Option Key Prefixing

ModulesManager stores workspace- and user-scope values with a scope prefix. Use the prefix when reading them back:

$apiKey = $module->getOption('workspace_api_key'); // workspace-scope
$theme  = $module->getOption('user_theme');         // user-scope
$flag   = $module->getOption('debug_mode');         // system/global — no prefix

Dynamic Field Options (IModuleOptionFieldPreparer)

When a static default is not enough — for example, populating a select field with live data — implement IModuleOptionFieldPreparer. ModuleOptionsStore checks each active module for this interface when preparing a field for display.

use core\store\field\IStoreField;
use plugin\Modules\domain\preparer\IModuleOptionFieldPreparer;
use plugin\Modules\domain\model\ModuleOptionValuesObject;

class SlackModulePlugin extends DisplayPlugin implements IModule, IModuleOptionFieldPreparer
{
    public function prepareModuleOptionField(
        ModuleOptionValuesObject $moduleOptionValuesObject,
        IStoreField $storeField
    ): void
    {
        if ($moduleOptionValuesObject->getName() !== 'notification_channel') {
            return;
        }

        $channels = $this->getFacade()->getAvailableChannels();

        $storeField->set(IStoreField::OPTION_VALUES, $channels);
    }
}

Workspace Records as Select Choices (IPrepareWorkSpaceModuleOptionListener)

A select option keeps its choices as static text in module_options.options (id:caption, one per line). When the choices are records each workspace owns, leave options empty and implement IPrepareWorkSpaceModuleOptionListener in the module's plugin. The workspace options form asks it for the choices of each option; return null for an option it does not fill.

public function onPrepareWorkSpaceModuleOptionValuesHandler(string $optionName, IWorkSpace $workSpace): ?array
{
    if ($optionName !== 'default_role') {
        return null;
    }

    return $this->getRolesCaptionsByWorkSpaceID($workSpace->getID()); // [id => caption]
}