Plugin settings
Declare plugin settings in signals.yaml, use the generated admin form, and read values via Signals::setting() with encrypted leave-blank semantics.
Declaration → form → read path
- Declare keys in
signals.yamlsettings[](key,type,labelrequired; see Manifest). - Install seeds defaults into the settings group via
PluginSettingsManager. - Admin UI embeds Livewire
PluginSettingsForm, generated from the manifest schema, on the Plugins page (/admin/settings/plugins). - Read at runtime with
Signals::setting()orPluginContext::setting()/PluginBase::setting().
Signals::setting(string $package, string $key, mixed $default = null): mixed
// PluginBase
protected function setting(string $key, mixed $default = null): mixed
// PluginContext (hooks)
public function setting(string $key, mixed $default = null): mixed
Values are decrypted (when encrypted) and type-cast by PluginSettingsManager.
Storage group naming
plugin_ + package with "/" and "-" → "_"
Examples:
| Package | Group |
|---|---|
acme/example |
plugin_acme_example |
signals/xero-sync |
plugin_signals_xero_sync |
Persisted as settings()->set($group.'.'.$key, …). Encrypted keys use SettingsService type encrypted.
Setting types
Manifest-allowed types: string, integer, boolean, enum, json.
| Field | Notes |
|---|---|
options |
Required non-empty list when type: enum |
default |
Optional; seeded on install |
rules |
List of Laravel validation rule strings for the generated form |
encrypted |
Stored encrypted; blank/masked save keeps prior value |
Encrypted semantics
When encrypted: true:
- Stored via the same Crypt path as other platform secrets.
- On save,
shouldKeepEncryptedkeeps the prior value when the submitted value isnull,'', or the masked placeholder (ChannelConfigMasker::FULL_MASK). - Audits / UI show a mask, not the secret.
Xero example (client_secret):
- key: client_secret
type: string
label: Xero Client Secret
encrypted: true
Dual registration path
| Path | Purpose |
|---|---|
Manifest → PluginSettingsManager |
Plugin-private config + generated Plugins UI form (preferred; Xero uses this) |
$registrar->setting(SettingsDefinition $definition) |
Also register into global SettingsRegistry |
setting(SettingsDefinition) is manifest-gated: every key in SettingsDefinition::defaults() must appear in settings[].key. Prefer the manifest-only path unless you intentionally surface keys in the core settings catalogue.
Contract: Settings Registry.
Xero read example
$direction = (string) Signals::setting('signals/xero-sync', 'sync_direction', 'push');
Inside a hook:
$direction = (string) $context->setting('sync_direction', 'push');