SIGNALS Documentation
API Reference

Settings Registry

Contract for registering settings groups, their defaults, validation rules, and type metadata.

Overview

App\Services\SettingsRegistry is the registry of settings-group definitions that drives SettingsService, SettingsController, and the current settings UI.

Each registry entry is a SettingsDefinition object. Core binds the registry as a singleton in SettingsServiceProvider and registers the framework's shipped settings groups there.

Public surface

Method Purpose
register() Register one SettingsDefinition instance
registerMany() Register multiple definitions atomically
get() Return a definition for one group or null
all() Return the keyed definition map
has() Check whether a group exists
defaults() Return the group's default values or []
types() Return the group's type declarations or []
rules() Return the group's validation rules or []

Accepted definition shape

The accepted registration value is a concrete subclass of App\Settings\SettingsDefinition.

The contract requires:

  • group(): string
  • defaults(): array
  • rules(): array

The base SettingsDefinition also offers optional extension points:

  • types(): array for non-string storage such as boolean, integer, json, or encrypted
  • guard(array $input, SettingsService $settings): void for write-time invariants after validation passes

The registry key is the group's group() string, such as email, security, api, or pricing.

Identity, collisions, and lookup behavior

Only one definition may be registered per group.

  • register() throws InvalidArgumentException when the group already exists
  • registerMany() performs duplicate checks before mutating state, so collisions leave the registry unchanged

Lookup behavior is intentionally forgiving:

  • get($group) returns the definition object or null
  • defaults($group), types($group), and rules($group) return [] for unknown groups

Grouping, ordering, and current core registrations

This registry is group-oriented rather than category-oriented. It does not expose a secondary grouping API.

all() returns an associative map keyed by group name. The current registration order comes directly from SettingsServiceProvider.

The current core singleton registers nineteen settings groups:

  • action-log
  • api
  • availability
  • company
  • email
  • finance
  • preferences
  • integrations
  • invoices
  • localisation
  • maintenance
  • notifications
  • rentals
  • pricing
  • scheduling
  • security
  • sso
  • stock_checks
  • tax

Representative examples:

Group Current purpose Example type behavior
email Mail transport and sender configuration smtp_password is encrypted
security Password and login policies integer and boolean fields
api API-facing operational settings mixed validation rules and defaults

Runtime consumption

Current framework consumers read the registry in three different ways:

  1. SettingsService falls back to registry defaults when a value is not stored in the database
  2. SettingsController resolves rules(), types(), and guard() when reading or updating a group through the API
  3. settings pages and configuration services use get(), defaults(), and types() to drive UI and runtime behavior

Updating settings through the API currently dispatches the settings.updated webhook event after the controller persists and masks the response payload.

Worked example

This is the current registration shape for one definition object:

$registry->register(new EmailSettings);

That single object contributes all of the following group-level contract data:

  • group() returns email
  • defaults() provides fallback values such as mailer => log
  • rules() defines per-key validation
  • types() marks keys such as smtp_password as encrypted

With that definition registered:

  • defaults('email') returns the default email settings
  • types('email') exposes storage metadata for masking and persistence
  • rules('email') gives SettingsController the validation schema for partial updates