| Install | |
|---|---|
composer require justustheis/registry |
|
| Latest Version: | v0.0.2-alpha |
Laravel Registry is a powerful and flexible key–value store designed for managing application settings in Laravel. It offers a unified API with support for per-model scoping, optional encryption, caching, and a modern web interface. The package also supports overriding Laravel configuration values at runtime using registry entries — enabling dynamic, environment-specific configuration.

composer require justustheis/registry
php artisan vendor:publish --provider="JustusTheis\Registry\RegistryServiceProvider" --tag="config"
php artisan migrate
Add the authorization gate to your AppServiceProvider:
use Illuminate\Support\Facades\Gate;
public function boot()
{
Gate::define('access-registry', function ($user) {
return $user->isAdmin(); // Customize this logic
});
}
Important: Before accessing the registry frontend, you must configure authorization using Laravel Gates. By default, the registry requires users to pass the access-registry gate to access the web interface.
Add this to your AppServiceProvider boot method:
use Illuminate\Support\Facades\Gate;
public function boot()
{
// Define who can access the registry frontend
Gate::define('access-registry', function ($user) {
return $user->isAdmin(); // Adjust this logic as needed
});
}
You can customize the gate name in the configuration:
// config/registry.php
'authorization' => [
'enabled' => true,
'gate' => 'access-registry', // Change this to your preferred gate name
],
To disable authorization entirely (not recommended for production):
'authorization' => [
'enabled' => false,
],
The configuration file config/registry.php provides extensive customization options:
'cache' => [
'driver' => env('REGISTRY_CACHE_DRIVER', 'redis'),
'ttl' => env('REGISTRY_CACHE_TTL', 86400), // 24 hours
],
'user_model' => App\Models\User::class,
'user_name_column' => 'name', // For "updated by" tracking
'models' => [
'User' => App\Models\User::class,
'Product' => App\Models\Product::class,
// Add your models here for hierarchical key parsing
],
'auto_cast_types' => env('REGISTRY_AUTO_CAST_TYPES', true),
'cast_rules' => [
'boolean_true_values' => ['true', 'yes', 'on'],
'boolean_false_values' => ['false', 'no', 'off'],
'null_values' => ['null'],
'numeric_detection' => true,
'array_detection' => true,
'object_detection' => true,
],
'override' => [
'production' => [
'app.name' => 'app.name', // Maps config('app.name') to registry('app.name')
],
'local' => [
'mail.default' => 'mail.driver',
],
],
use JustusTheis\Registry\Facades\Registry;
// Store a value
Registry::key('app.theme')->value('dark')->set();
// Retrieve a value
$theme = Registry::key('app.theme')->default('light')->get();
// Fluent API
$value = Registry::key('user.preferences')
->default(['notifications' => true])
->encrypt()
->set(['notifications' => false, 'theme' => 'dark']);
// Simple get/set operations
registry_set('app.debug', true);
$debug = registry_get('app.debug', false);
// Delete a key
registry_delete('app.debug');
// Flexible registry() helper
$value = registry('app.name', 'Default App Name');
$registry = registry(); // Returns Registry instance
// String values
Registry::key('app.name')->value('My Application')->set();
// Numeric values
Registry::key('app.version')->value(1.5)->set();
// Boolean values
Registry::key('app.debug')->value(true)->set();
// Arrays and Objects
Registry::key('user.preferences')->value([
'theme' => 'dark',
'notifications' => true,
'sidebar_collapsed' => false
])->set();
Use the HasRegistry trait to scope registry entries to specific models:
use JustusTheis\Registry\Traits\HasRegistry;
class User extends Model
{
use HasRegistry;
}
$user = User::find(1);
// Set user-specific settings
$user->registry()->key('preferences.theme')->value('dark')->set();
// Get user-specific settings
$theme = $user->registry()->key('preferences.theme')->default('light')->get();
// Using helper functions with model scoping
registry_set('notifications.email', true, $user);
$emailNotifications = registry_get('notifications.email', false, $user);
// Access all registry entries for a model
$entries = $user->registryEntries;
// Check if user has specific settings
if ($user->registry()->key('preferences.theme')->exists()) {
// User has custom theme
}
The package includes a complete Vue 3 + Inertia.js frontend that provides a Windows Registry Editor-like interface.
npm install
php artisan vendor:publish --provider="JustusTheis\Registry\RegistryServiceProvider" --tag="registry-assets"
Ensure you have an Inertia.js app template. The package includes one you can copy:
cp vendor/justustheis/registry/resources/views/app.blade.php resources/views/app.blade.php
# Development
npm run dev
# Production
npm run build
Visit /registry in your browser (after setting up the authorization gate).
Encrypt sensitive data automatically:
// Encrypt a single value
Registry::key('api.secret')->value('sensitive-data')->encrypt()->set();
// Retrieve encrypted value (automatically decrypted)
$secret = Registry::key('api.secret')->get();
// Using helpers
registry_set('database.password', 'secret123', null, true); // true = encrypt
$password = registry_get('database.password', null, null, true);
Organize settings in tree structures:
// Create hierarchical structure
Registry::key('app.mail.driver')->value('smtp')->set();
Registry::key('app.mail.host')->value('smtp.gmail.com')->set();
Registry::key('app.mail.port')->value(587)->set();
// Work with parent/child relationships
$mailConfig = Registry::key('app.mail.driver');
$parent = $mailConfig->parent(); // Returns 'app.mail' registry
$children = $mailConfig->children(); // Collection of child registries
// Get hierarchical key for display
echo $mailConfig->getHierarchicalKey(); // "app.mail.driver"
Registry entries are automatically cached for performance:
// Cache configuration in config/registry.php
'cache' => [
'driver' => 'redis', // or 'memcached', 'file', etc.
'ttl' => 86400, // 24 hours
],
Override Laravel config values dynamically:
// In config/registry.php
'override' => [
'production' => [
'app.name' => 'app.name', // config('app.name') will check registry first
],
],
// Set override value
Registry::key('app.name')->value('Production App')->set();
// Now config('app.name') returns 'Production App'
echo config('app.name'); // "Production App"
Automatically delete registry entries when parent models are deleted:
// In config/registry.php
'cascade_on_delete' => true,
'cascade_on_soft_delete' => false,
// Explicit type setting
Registry::key('count')->value(42)->type('integer')->set();
Registry::key('data')->value($array)->type('array')->set();
// Automatic type detection (default)
Registry::key('auto')->value('123')->set(); // Stored as integer 123
Registry::key('auto')->value('true')->set(); // Stored as boolean true
Registry::key(string $key): selfSet the registry key for the operation.
Registry::value(mixed $value): selfSet the value to be stored.
Registry::default(mixed $default): selfSet the default value if key doesn't exist.
Registry::for(Model $model): selfScope the registry to a specific model.
Registry::encrypt(): selfMark the value for encryption.
Registry::type(string $type): selfExplicitly set the value type.
get(?string $key = null, mixed $default = null): mixedRetrieve a value from the registry.
set(?string $key = null, mixed $value = null): mixedStore a value in the registry.
delete(?string $key = null): boolDelete a key from the registry.
exists(?string $key = null): boolCheck if a key exists in the registry.
rename(string $newKey, bool $renameChildren = true): selfRename a registry key and optionally its children.
parent(): ?selfGet the parent registry instance.
children(): CollectionGet all direct child registry instances.
class User extends Model
{
use HasRegistry;
}
// Set user preferences
$user = User::find(1);
$user->registry()->key('preferences')->value([
'theme' => 'dark',
'language' => 'en',
'notifications' => [
'email' => true,
'push' => false,
'sms' => false
]
])->set();
// Get specific preference
$theme = $user->registry()->key('preferences.theme')->default('light')->get();
// Update single preference
$user->registry()->key('preferences.language')->value('es')->set();
// Environment-specific settings
if (app()->environment('production')) {
Registry::key('app.debug')->value(false)->set();
Registry::key('cache.default')->value('redis')->set();
} else {
Registry::key('app.debug')->value(true)->set();
Registry::key('cache.default')->value('file')->set();
}
// API configuration with encryption
Registry::key('services.stripe.secret')
->value('sk_test_...')
->encrypt()
->set();
// Global feature flags
Registry::key('features.new_dashboard')->value(true)->set();
Registry::key('features.beta_search')->value(false)->set();
// User-specific feature overrides
$user->registry()->key('features.beta_search')->value(true)->set();
// Check feature availability
function hasFeature($feature, $user = null) {
if ($user && $user->registry()->key("features.{$feature}")->exists()) {
return $user->registry()->key("features.{$feature}")->get();
}
return registry_get("features.{$feature}", false);
}
Run the test suite:
# Run all tests
vendor/bin/phpunit
# Run with coverage
vendor/bin/phpunit --coverage-html coverage/
# Run specific test categories
vendor/bin/phpunit --filter RegistryCache
vendor/bin/phpunit --filter RegistryEncryption
vendor/bin/phpunit --filter RegistryScope
The package doesn't include specific Artisan commands, but you can interact with it using Tinker:
php artisan tinker
# Try some commands
Registry::key('test')->value('Hello World')->set()
Registry::key('test')->get()
registry('test', 'Default Value')
This package is open-sourced software licensed under the MIT license.
Please see CONTRIBUTING.md for details.
If you discover any security vulnerabilities or bugs, please report them via GitHub Issues.
For support, please create an issue on GitHub or contact the maintainer at justus@sharma-theis.com.