salesrender/plugin-component-settings

SalesRender plugin settings model

Installs: 1 022

Dependents: 1

Suggesters: 0

Security: 0

Stars: 0

Watchers: 2

Forks: 0

Open Issues: 0

pkg:composer/salesrender/plugin-component-settings

0.2.15 2023-12-27 17:41 UTC

This package is auto-updated.

Last update: 2026-02-13 20:58:57 UTC


README

Settings model for the SalesRender plugin ecosystem. Provides per-plugin-instance settings storage based on plugin-component-db and plugin-component-form. Each plugin instance has exactly one Settings record (singleton per plugin) that holds serialized form data (FormData). Includes an integrity guard to verify that settings are properly filled before allowing critical operations.

Installation

composer require salesrender/plugin-component-settings

Requirements

Requirement Version
PHP >= 7.4.0
ext-json *
salesrender/plugin-component-db ^0.3.0
salesrender/plugin-component-form ^0.10.0 | ^0.11.0

Key classes

Settings

The main model class. Declared as final -- it is not intended for subclassing.

Namespace: SalesRender\Plugin\Components\Settings

Extends: SalesRender\Plugin\Components\Db\Model

Implements: SalesRender\Plugin\Components\Db\SinglePluginModelInterface

Method Signature Description
getData getData(): FormData Returns the stored FormData instance (dot-notation accessor for form field values)
setData setData(FormData $data): void Replaces the stored form data
find static find(): Settings Loads the settings for the current plugin instance (by Connector::getReference()->getId()). Returns a new empty Settings if none exist
getForm static getForm(array $context = []): Form Returns the configured settings Form. Throws RuntimeException if setForm() was not called
setForm static setForm(Form|callable $form): void Configures the settings form. Accepts a Form instance or a callable that returns one (lazy loading)
guardIntegrity static guardIntegrity(): void Validates current settings data against the form. Throws IntegritySettingsException (HTTP 424) if data is empty or incomplete
schema static schema(): array Database schema: single data column of type TEXT

Inherited from Model: save(), delete(), getId(), findById(), findByCondition(), addOnSaveHandler(), removeOnSaveHandler(), tableName(), freeUpMemory().

IntegritySettingsException

Thrown by guardIntegrity() when settings validation fails.

Namespace: SalesRender\Plugin\Components\Settings\Exceptions

Extends: \Exception

  • HTTP status code: 424 (Failed Dependency)
  • Default message: "Settings data empty or incomplete"

FormData

Provided by salesrender/plugin-component-form. Extends Adbar\Dot -- a dot-notation array accessor. Used to store and retrieve individual setting values.

Namespace: SalesRender\Plugin\Components\Form

Key methods (from Adbar\Dot):

  • get(string $key, $default = null) -- get a value by dot-notation key
  • set(string $key, $value) -- set a value
  • has(string $key): bool -- check if a key exists
  • toArray(): array -- convert to plain array

Usage

1. Configure the settings form in bootstrap.php

Every plugin must register a settings form during bootstrap. The form defines the fields that appear on the plugin settings page.

From plugin-logistic-cdek:

use SalesRender\Plugin\Components\Settings\Settings;
use SalesRender\Plugin\Instance\Logistic\Settings\SettingsForm;

// Using a callable for lazy loading (recommended)
Settings::setForm(fn() => new SettingsForm());

From plugin-pbx-example:

use SalesRender\Plugin\Components\Settings\Settings;
use SalesRender\Plugin\Instance\Pbx\Forms\SettingsForm;

Settings::setForm(fn() => new SettingsForm());

2. Define a SettingsForm class

The form class extends Form from plugin-component-form and defines the field groups and their validation.

From plugin-logistic-example:

use SalesRender\Plugin\Components\Form\FieldDefinitions\PasswordDefinition;
use SalesRender\Plugin\Components\Form\FieldDefinitions\StringDefinition;
use SalesRender\Plugin\Components\Form\FieldGroup;
use SalesRender\Plugin\Components\Form\Form;
use SalesRender\Plugin\Components\Translations\Translator;

class SettingsForm extends Form
{
    public function __construct()
    {
        parent::__construct(
            Translator::get('settings', 'Settings'),
            null,
            [
                'main' => new FieldGroup(
                    Translator::get('settings', 'Main settings'),
                    null,
                    [
                        'login' => new StringDefinition(
                            Translator::get('settings', 'Login'),
                            null,
                            function () { return []; }
                        ),
                        'password' => new PasswordDefinition(
                            Translator::get('settings', 'Password'),
                            null,
                            function () { return []; }
                        ),
                    ]
                ),
            ],
            Translator::get('settings', 'Save'),
        );
    }
}

3. Read settings values in plugin code

The most common pattern is Settings::find()->getData(), then access individual values with dot notation.

From plugin-logistic-cdek:

use SalesRender\Plugin\Components\Settings\Settings;

$settings = Settings::find()->getData();
$login = $settings->get('main.login');
$password = $settings->get('main.password');

From plugin-chat-eskiz:

use SalesRender\Plugin\Components\Settings\Settings;

$settings = Settings::find()->getData();
$token = $settings->get('main.token');

4. Guard integrity before critical operations

Use guardIntegrity() to ensure settings are valid before performing operations that depend on them. If settings are not filled, an IntegritySettingsException is thrown with HTTP code 424.

From plugin-macros-example:

use SalesRender\Plugin\Components\Settings\Settings;

class ExampleHandler implements BatchHandlerInterface
{
    public function __invoke(Process $process, Batch $batch)
    {
        Settings::guardIntegrity();
        $fields = Settings::find()->getData()->get('group_1.fields');
        // proceed with processing...
    }
}

From plugin-logistic-example (inside form value provider):

use SalesRender\Plugin\Components\Settings\Settings;

$values = new CallableValues(function () {
    Settings::guardIntegrity();
    $data = Settings::find()->getData();
    $senders = [];
    for ($i = 1; $i <= 3; $i++) {
        if ($data->get("sender_{$i}.use", false)) {
            $senders[$i] = [
                'title' => $data->get("sender_{$i}.name"),
                'group' => 'Sender',
            ];
        }
    }
    return $senders;
});

5. Register save handlers

Use addOnSaveHandler() (inherited from Model) to execute logic whenever settings are saved. This is useful for triggering side effects like syncing configuration to external services.

From plugin-pbx-example:

use SalesRender\Plugin\Components\Settings\Settings;

Settings::addOnSaveHandler(function (Settings $settings) {
    $builder = new ConfigBuilder($settings);
    $sender = new ConfigSender($builder);
    $sender();
});

From plugin-core-logistic (named handler):

use SalesRender\Plugin\Components\Settings\Settings;

Settings::addOnSaveHandler(function (Settings $settings) {
    if (LogisticHelper::isFulfillment()) {
        $handler = FulfillmentContainer::getBindingHandler();
        $handler($settings)->sync();
    }
}, 'ffSync');

How it works with plugin-core

The plugin-core framework provides built-in HTTP routes for settings management via SettingsHandler:

Route Method Description
/forms/settings GET Returns the settings form definition (calls Settings::getForm())
/data/settings GET Returns the current settings data (calls Settings::find()->getData())
/data/settings PUT Saves new settings data (validates against the form, then calls setData() + save())

These routes are registered automatically by the core framework. Plugin developers only need to configure the form via Settings::setForm() in bootstrap.php.

API reference

Database schema

The Settings table has a single data column. The id, companyId, pluginAlias, and pluginId columns are managed automatically by Model and SinglePluginModelInterface.

Column Type Description
id (auto) Plugin instance ID (= Connector::getReference()->getId())
companyId (auto) Company ID from plugin reference
pluginAlias (auto) Plugin alias from plugin reference
pluginId (auto) Plugin ID from plugin reference
data TEXT JSON-serialized FormData

Data serialization

  • On write (beforeWrite): FormData is serialized to JSON via json_encode()
  • On read (afterRead): JSON is deserialized back to FormData via new FormData(json_decode($data, true))

Singleton behavior

Settings implements SinglePluginModelInterface. This means:

  • There is exactly one Settings record per plugin instance (identified by pluginId)
  • Settings::find() returns the record for the current plugin context, or a new empty Settings if none exists
  • The id field is automatically set to Connector::getReference()->getId()

Dependencies

Package Purpose
salesrender/plugin-component-db Database ORM: Model, SinglePluginModelInterface, Connector
salesrender/plugin-component-form Form, FormData (dot-notation data container based on adbario/php-dot-notation)

See also