c14r / laravel-data-store
A flexible polymorphic key-value storage system for Laravel with namespaces, TTL support, and nested data structures
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/c14r/laravel-data-store
Requires
- php: ^8.1|^8.2|^8.3|^8.4
- illuminate/database: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^10.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpunit/phpunit: ^12.0
Suggests
- spatie/laravel-data: For seamless Data Transfer Object integration with automatic conversion
README
A flexible polymorphic key-value storage system for Laravel with namespaces, TTL support, nested data structures, and more!
Store data for Users, Teams, Organizations, or globally with an elegant, chainable API.
Features
- ๐ Polymorphic Storage - Attach data to any Eloquent model (User, Team, Organization, etc.)
- ๐ท๏ธ Namespaces - Organize data with dot-notation namespaces
- โฑ๏ธ TTL Support - Automatic expiration with time-to-live
- ๐ณ Nested Structures - Hierarchical data with dot-notation keys
- ๐ฆ Export/Import - JSON-based backup and restore
- ๐ Flexible Querying - Flat or nested data retrieval
- ๐งน Auto Cleanup - Scheduled removal of expired entries
- โจ Facade Support - Clean, expressive API
- ๐ฏ Spatie Data Integration - Seamless support for Data Transfer Objects
- ๐ Event System - Automatic event dispatching (v1.1)
- ๐๏ธ Model Trait - HasDataStore for easy model integration (v1.1)
- ๐ Query Builder - Advanced query capabilities (v1.1)
- ๐ฆ DataCollection Support - Type-safe collections with Spatie Data (v1.1)
Spatie Laravel Data Integration
DataStore has seamless integration with spatie/laravel-data for type-safe DTOs:
use Spatie\LaravelData\Data; class UserPreferences extends Data { public function __construct( public string $theme, public string $language, public int $itemsPerPage, ) {} } // Auto-converts to array when storing DataStore::set('preferences', new UserPreferences('dark', 'de', 20)); // Auto-converts to Data object when retrieving $prefs = DataStore::get('preferences', as: UserPreferences::class); echo $prefs->theme; // IDE autocomplete!
See Spatie Integration Guide for details.
Installation
Install the package via Composer:
composer require c14r/laravel-data-store
Publish and run migrations:
php artisan vendor:publish --tag="datastore-migrations"
php artisan migrate
Optionally, publish the config file:
php artisan vendor:publish --tag="datastore-config"
Quick Start
use C14r\DataStore\Facades\DataStore; use C14r\DataStore\Traits\HasDataStore; // Global storage DataStore::set('site_name', 'My Website'); // User storage (auto-detects authenticated user) DataStore::forUser()->set('theme', 'dark'); // Model trait (v1.1) class User extends Authenticatable { use HasDataStore; } $user->dataStore('preferences')->set('theme', 'dark'); $theme = $user->retrieveData('theme', 'light', 'preferences'); // Helper function (v1.1) datastore('cache')->set('key', 'value', 3600); // Query Builder (v1.1) $drafts = DataStore::query() ->forUser($user) ->keyStartsWith('draft') ->notExpired() ->get(); // Events (v1.1) Event::listen(DataStoreSet::class, function($event) { Log::info("Data set: {$event->key}"); });
Usage
Basic Operations
// Set value DataStore::set('key', 'value'); // Get value $value = DataStore::get('key'); $value = DataStore::get('missing_key', 'default'); // Check existence if (DataStore::has('key')) { // } // Delete DataStore::delete('key');
Scoping
// Global (no owner) DataStore::set('app_version', '1.0'); // For User (null = auth()->user()) DataStore::forUser()->set('theme', 'dark'); DataStore::forUser($user)->set('language', 'en'); // For any model DataStore::forTeam($team)->set('name', 'My Team'); DataStore::forGroup($group)->set('permissions', [...]); DataStore::for($organization)->set('billing', [...]);
Namespaces
// Simple namespace $settings = DataStore::inNamespace('settings'); $settings->set('items_per_page', 20); // Nested namespaces $prefs = DataStore::inNamespace('user.preferences'); // or $prefs = DataStore::inNamespace(['user', 'preferences']); // Combine with user $userSettings = DataStore::forUser()->inNamespace('settings');
Nested Keys
// Array notation DataStore::set(['config', 'app', 'name'], 'MyApp'); // Dot notation DataStore::set('config.app.version', '1.0'); // Get nested $name = DataStore::get('config.app.name'); $name = DataStore::get(['config', 'app', 'name']);
Data Retrieval
// All keys (Collection) $keys = DataStore::keys(); // All data (Collection - flat) $data = DataStore::all(); // Keys starting with prefix (Array) $keys = DataStore::keysStartingWith('user.123'); // ['user.123.name', 'user.123.email'] // Flat data starting with prefix (Collection) $data = DataStore::startingWith('user.123'); // ['user.123.name' => 'John', 'user.123.email' => 'john@example.com'] // Nested structure from prefix (Array) $user = DataStore::nestedFrom('user.123'); // ['name' => 'John', 'email' => 'john@example.com'] // Nested structure from current scope (Array) $nested = DataStore::inNamespace('config')->nested(); // ['app' => ['name' => 'MyApp', 'version' => '1.0']]
TTL (Time To Live)
// Set with TTL (in seconds) DataStore::set('session_token', 'abc123', 3600); // 1 hour // Check TTL $ttl = DataStore::ttl('session_token'); // Returns seconds left // Extend TTL DataStore::touch('session_token', 7200); // Extend to 2 hours
Bulk Operations
// Set multiple DataStore::setMany([ 'key1' => 'value1', 'key2' => 'value2', ], 3600); // Optional TTL // Get multiple $values = DataStore::getMany(['key1', 'key2']); // Delete multiple DataStore::deleteMany(['key1', 'key2']);
Counters
// Increment DataStore::increment('page_views'); DataStore::increment('page_views', 5); // Decrement DataStore::decrement('downloads', 3);
Export / Import
// Export DataStore::forUser()->export('backups/user-preferences.json'); // Import DataStore::forUser()->import('backups/user-preferences.json'); // Import without overwriting DataStore::forUser()->import('backup.json', null, false);
Configuration
The config file config/datastore.php allows you to customize:
- Default namespace
- Table name
- Default TTL
- Auto-cleanup scheduling
- Export disk and path
Artisan Commands
Cleanup Expired Entries
# Delete all expired entries php artisan datastore:cleanup # Dry run (show what would be deleted) php artisan datastore:cleanup --dry-run # Cleanup specific namespace php artisan datastore:cleanup --namespace=cache # Cleanup specific model type php artisan datastore:cleanup --type="App\Models\User"
Schedule Auto-Cleanup
In routes/console.php:
use Illuminate\Support\Facades\Schedule; Schedule::command('datastore:cleanup')->daily();
Model Relationships (Optional)
Add to your models to access data stores via relationships:
use C14r\DataStore\Models\DataStore; class User extends Authenticatable { public function dataStores() { return $this->morphMany(DataStore::class, 'storable'); } } // Usage $user->dataStores()->where('namespace', 'preferences')->get();
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Security
If you discover any security related issues, please email your-email@example.com instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.