Defining options
Every option is a small class extending BaseOption. With no overrides, the key is the class basename, the value casts to string and the default is null:
use RoundlyConsulting\Options\BaseOption;
final class SimpleOption extends BaseOption
{
// Uses all defaults: key 'SimpleOption', cast 'string', default null.
}Override the hooks to customise it — key(), default(), castAs(), encrypted(), rules(), authorizeRead() / authorizeWrite() and the presentation methods label(), help(), section() and order():
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use RoundlyConsulting\Options\BaseOption;
final class NotificationPreferences extends BaseOption
{
public function key(): string
{
return 'notification-preferences';
}
public function default(): mixed
{
return collect(['email' => true, 'sms' => false]);
}
public function castAs(): string|CastsAttributes
{
return 'collection';
}
}The examples throughout these docs use a ThemeOption like this one:
namespace App\Options;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use RoundlyConsulting\Options\BaseOption;
final class ThemeOption extends BaseOption
{
public function key(): string
{
return 'theme';
}
public function default(): mixed
{
return 'light';
}
public function castAs(): string|CastsAttributes
{
return 'string';
}
}What you can override
| Method | Default | Purpose |
|---|---|---|
key(): string | class basename | The storage key — unique per option. |
default(): mixed | null | Returned when nothing is stored for the scope. |
castAs(): string|CastsAttributes | 'string' | How the stored value is cast on read and write. |
encrypted(): bool | false | Encrypt the value at rest. |
rules(): array|string | [] | Laravel validation rules applied on set(). |
readable(): string | title-cased key | Human name — notification-preferences becomes Notification Preferences. Used by options:list. |
label(): string | readable() | Field label in a group definition. |
help(): ?string | null | Help text under the field. |
section(): ?string | null | Section or tab a UI may group the field under. |
order(): int | 0 | Sort order within a group (ascending). |
authorizeRead(?Authenticatable, ?Model): bool | true | Read hook, enforced when authorization is enabled. |
authorizeWrite(?Authenticatable, ?Model): bool | true | Write hook, enforced when authorization is enabled. |
label(), help(), section() and order() are documented by the optional HasPresentation contract, authorizeRead() and authorizeWrite() by AuthorizesOptions. BaseOption already implements both sets, so implementing the contracts is never required.
Generating options
make:option scaffolds a class in app/Options. --key and --cast fill in the key and cast, --encrypted turns encryption on, and --enum switches to a stub that casts through EnumCast:
php artisan make:option ThemeOption --cast=string --key=theme
php artisan make:option SecretToken --encrypted
php artisan make:option StatusOption --enum="App\Enums\Status"Using an option class directly
Each option also works on its own — make() for the global scope, for() for an owner. This is shorthand, not a separate path: value(), set(), has(), forget(), reset() and remember() are final and run through the same OptionsManager as the facade, so they behave identically and Options::fake() sees them:
ThemeOption::make()->value(); // global value, or default() when unset
ThemeOption::make()->set('dark'); // global write
ThemeOption::for($user)->value(); // owner-scoped read
ThemeOption::for($user)->set('light'); // owner-scoped write
ThemeOption::for($user)->has();
ThemeOption::for($user)->forget();Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.