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

Import & export

Move options between environments or ship seeded defaults through the facade (or an injected OptionsManager). options:export and options:import call the same manager, and ExportOptionsAction / ImportOptionsAction do the work underneath (see DI and actions):

use RoundlyConsulting\Options\Facades\Options;

Options::export();                   // list<OptionPayload>: every stored option, global and owned
Options::export($tenant);            // one owner's options
Options::export(globalOnly: true);   // only the global ones
Options::for($tenant)->export();     // one scope; Options::for(null)->export() = global only

$json = Options::exportJson($tenant); // the same, as a JSON array of rows

$count = Options::import($json);                                   // JSON string — upsert, returns the count
$count = Options::import([['key' => 'theme', 'value' => 'dark']]); // decoded rows (owner_type / owner_id optional)
$count = Options::import($payloads);                               // list<OptionPayload>; rows and payloads may be mixed

Payload format

exportJson() and options:export produce a JSON array of OptionPayload rows:

[
  { "key": "theme", "value": "dark", "owner_type": null, "owner_id": null },
  { "key": "theme", "value": "light", "owner_type": "App\\Models\\User", "owner_id": 5 }
]

Behaviour

  • Values travel exactly as stored — serialized, and still encrypted for encrypted options, so the target app needs the same APP_KEY to read them.
  • Import upserts on key, owner_type and owner_id, so re-importing the same file is idempotent. A forgotten option’s soft-deleted row is revived rather than duplicated.
  • Import writes rows directly: no validation, casts, events, observers or authorization.
  • import() returns the number of rows and drops the in-request memo and the persistent cache entry of every imported key, so the next read sees the imported value.
  • owner_id follows options.key_type — an int for bigint owners, a string for UUID or ULID owners. A row with only one of owner_type / owner_id is imported as global.
  • Malformed JSON, a JSON scalar, a non-array row or a row without a string key throws InvalidOptionPayload.
  • Under Options::fake(), export() and exportJson() read the in-memory store — which holds what the database would: raw strings, ciphertext for an encrypted option — and import() is recorded (assertImported()) and loaded into it.

From the command line

php artisan options:export --path=storage/options.json
php artisan options:export --owner="App\Models\User" --owner-id=5

php artisan options:import storage/options.json
php artisan options:clear-cache

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.