NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Options for Laravel

The Options facade

RoundlyConsulting\Options\Facades\Options is the recommended entry point. It proxies the OptionsManager singleton, and every method takes an option class-string or a registered key, plus an optional owner model (omit it, or pass null, for a global option):

use RoundlyConsulting\Options\Facades\Options;

// Flat verbs: a class-string or a registered key, plus an optional owner
Options::get(ThemeOption::class, $user);
Options::set(ThemeOption::class, 'dark', $user);
Options::many([ThemeOption::class, LocaleOption::class], $user);
Options::all($user);
Options::export($team);
Options::import($json);

// Handles
Options::for($user)->set(ThemeOption::class, 'light');         // PendingOptions — one owner
Options::option(ThemeOption::class)->default();                // OptionContext — one option
Options::key('theme')->set('dark');                            // OptionContext by registered key
Options::group(AppearanceSettings::class)->for($user)->all();  // PendingGroup — a settings screen

// Registry, observers, access control, config bridge, cache
Options::register(['theme' => ThemeOption::class]);
Options::observe(ThemeOption::class, RecompileThemeListener::class);
Options::withoutAuthorization(fn () => Options::set(MaintenanceModeOption::class, true));
Options::overrides('app.name', AppNameOption::class);
Options::flushCache();

Every method

MethodReturnsWhat it does
get($option, $owner = null)mixedThe typed value, or default() when nothing is stored.
set($option, $value, $owner = null)voidValidate, cast and persist a value.
has($option, $owner = null)boolWhether a value is stored for the scope.
forget($option, $owner = null) / reset(…)voidDelete the stored value; reset() is an alias.
remember($option, Closure $callback, $owner = null)mixedThe stored value, or compute, store and return it.
resolve($option, $owner = null)OptionInterfaceThe option instance bound to the owner.
many(array $options, $owner = null)arraySeveral values at once, keyed by what you passed.
setMany(array $values, $owner = null)voidSeveral writes, all or nothing: every value is authorized and validated first, then written in one transaction.
all($owner = null)CollectionEvery stored value of the scope, raw key => value, one query. With access control on, leaves out what the user may not read.
export($owner = null, bool $globalOnly = false)list<OptionPayload>Stored options as raw payloads — one owner, everything, or only the global ones.
exportJson($owner = null, bool $globalOnly = false)stringexport() as a JSON array of rows.
import(array|string $payload)intUpsert from JSON, decoded rows or OptionPayloads; returns the count.
for(?Model $owner)PendingOptionsOwner-bound handle; for(null) is the global scope.
option($option) / key($key)OptionContextA single-option handle, by class-string or registered key.
group($group, $owner = null)PendingGroupA settings group: all(), set(), definition(), options().
register(array $options) / registered()void / arrayAdd key => class mappings at runtime; read the registry.
resolveClass($option)class-stringTurn a key or class into the option class-string.
observe($option, $callback)voidAttach a targeted observer (closure or invokable class).
forgetObservers($option) / flushObservers()voidDrop one option’s observers, or all of them.
actingAs(?Authenticatable $user, Closure $callback)mixedRun a callback authorized as that user.
withoutAuthorization(Closure $callback)mixedRun a callback with access control bypassed.
overrides($configKey, $option)voidMap a config() key to an option, applied immediately.
configOverrides() / applyConfigOverrides()array / voidThe active config-bridge map; re-apply every mapping now.
flushCache()voidFlush the in-request memo and the persistent cache, on any store.
fake()OptionsFakeFacade only: swap in the recording in-memory fake (see Testing).

The assert*() methods listed in the facade’s docblock exist only after Options::fake() — see Testing.

One manager behind every path

The facade, the for() / option() / key() / group() handles, option instances, the HasOptions trait and the options() helper all funnel into the same OptionsManager methods. Pick whichever reads best — they validate, cast, cache, authorize and fire events identically:

// One OptionsManager behind every spelling — identical behaviour, all visible to Options::fake()
Options::set(ThemeOption::class, 'dark', $user);      // the facade
Options::for($user)->set(ThemeOption::class, 'dark'); // a handle
ThemeOption::for($user)->set('dark');                 // an option instance
$user->option(ThemeOption::class)->set('dark');       // the HasOptions trait
options()->set(ThemeOption::class, 'dark', $user);    // the helper

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 crypto

By 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.