| Install | |
|---|---|
composer require sindyko/aliaser |
|
| Latest Version: | v0.1.2 |
| PHP: | ^8.1 |
Elegant alias management for Laravel Eloquent models, Livewire forms, DTOs, collections, and enums. Replace long class names with short, memorable aliases throughout your application and Livewire snapshots.
Entity::user(1)Entity::user(1) instead of User::find(1)aliaser:install, aliaser:list, aliaser:helpmodelsMap(), formsMap(), etc.Note: Livewire features require Livewire 3.x. See Livewire Compatibility for details.
composer require sindyko/aliaser
Install configuration:
php artisan aliaser:install
In your AppServiceProvider::boot():
use App\Models\{User, Post, Comment};
use App\Livewire\Forms\{PostForm, UserForm};
use App\DTOs\{UserFilterDTO, ProductDTO};
use App\Enums\{UserStatus, PostStatus};
public function boot(): void
{
// Models (auto-syncs with morph map)
modelsMap([
'user' => User::class,
'post' => Post::class,
'comment' => Comment::class,
]);
// Livewire Forms
formsMap([
'postForm' => PostForm::class,
'userForm' => UserForm::class,
]);
// DTOs & Value Objects
objectsMap([
'userFilter' => UserFilterDTO::class,
'productDto' => ProductDTO::class,
'money' => Money::class,
]);
// Enums
enumsMap([
'userStatus' => UserStatus::class,
'postStatus' => PostStatus::class,
]);
// Custom Collections
collectionsMap([
'userCollection' => UserCollection::class,
]);
}
use Sindyko\Aliaser\Facades\Entity;
// Query builder
$users = Entity::user()->where('active', true)->get();
// Find by ID
$user = Entity::user(1);
// Find with specific columns
$user = Entity::user(1, ['id', 'name', 'email']);
// Find multiple
$users = Entity::user([1, 2, 3]);
// Static methods work too!
Entity::user()->all();
Entity::user()->create(['name' => 'John']);
Entity::user()->isSoftDeletable();
The Entity facade provides elegant access to your models:
// No arguments → ModelProxy (query builder)
Entity::user()->latest()->paginate(10);
// Single ID → find()
$user = Entity::user(1); // User or null
// Array of IDs → findMany()
$users = Entity::user([1, 2, 3]); // Collection
// With columns
$user = Entity::user(1, ['id', 'name']);
$users = Entity::user([1, 2, 3], ['name', 'email']);
ModelProxy automatically handles both static and query builder methods:
$user = Entity::user();
// Static methods (cached via Reflection)
$user->all();
$user->create([...]);
$user->destroy([1, 2, 3]);
$user->isSoftDeletable();
$user->isPrunable();
// Query builder methods
$user->where('active', true)->get();
$user->with('posts')->paginate();
$user->orderBy('created_at')->first();
// Get FQCN
$proxy->class(); // 'App\Models\User'
// or use
$user = Entity::user()->all();
$user = Entity::user()->create([...]);
$user = Entity::user()->destroy([1, 2, 3]);
$user = Entity::user()->isSoftDeletable();
$user = Entity::user()->isPrunable();
Model aliases automatically sync with Eloquent morph map:
// Database before
commentable_type: 'App\Models\Post'
commentable_id: 1
// Database after (with Aliaser)
commentable_type: 'post'
commentable_id: 1
// Usage
$comment->commentable_type; // 'post'
Aliaser automatically reduces Livewire snapshot size:
class ShowUser extends Component
{
public User $user;
}
Snapshot comparison:
{
"user": [
"mdl",
{
"...": "..."
},
{
"class": "App\\Models\\User"
}
]
}
{
"user": [
"mdl-alias",
{
"...": "..."
},
{
"class": "user"
}
]
}
class EditPost extends Component
{
public PostForm $form;
}
Snapshot:
{
"class": "App\\Livewire\\Forms\\PostForm"
}
{
"class": "postForm"
}
class PostsList extends Component
{
public Collection $posts; // Eloquent Collection
}
Snapshot:
{
"posts": [
"elcln",
[
"..."
],
{
"class": "Illuminate\\Database\\Eloquent\\Collection",
"modelClass": "App\\Models\\Post"
}
]
}
{
"posts": [
"elcln-alias",
[
"..."
],
{
"class": "elqn_clctn",
"modelClass": "post"
}
]
}
Built-in collection aliases:
lrvl_clctn → Illuminate\Support\Collectionelqn_clctn → Illuminate\Database\Eloquent\Collectionclass UserProfile extends Component
{
public UserStatus $status;
}
Snapshot:
{
"class": "App\\Enums\\UserStatus"
}
{
"class": "userStatus"
}
class ProductFilter extends Component
{
public Money $price;
public UserFilterDTO $filters;
}
Snapshot:
{
"price": [
"obj",
{
"...": "..."
},
{
"class": "App\\ValueObjects\\Money"
}
],
"filters": [
"obj",
{
"...": "..."
},
{
"class": "App\\DTOs\\UserFilterDTO"
}
]
}
{
"price": [
"obj-alias",
{
"...": "..."
},
{
"class": "money"
}
],
"filters": [
"obj-alias",
{
"...": "..."
},
{
"class": "userFilter"
}
]
}
ObjectAliasSynth features:
toArray() methodfill() method# List all registered aliases
php artisan aliaser:list
# Filter by type
php artisan aliaser:list --models
php artisan aliaser:list --forms
php artisan aliaser:list --objects
php artisan aliaser:list --collections
php artisan aliaser:list --enums
# JSON output
php artisan aliaser:list --json
# General help
php artisan aliaser:help
# Topic-specific help
php artisan aliaser:help models
php artisan aliaser:help forms
php artisan aliaser:help objects
php artisan aliaser:help collections
php artisan aliaser:help enums
php artisan aliaser:help livewire
use Sindyko\Aliaser\Registers\ModelRegistry;
// Register single alias
ModelRegistry::register('admin', Admin::class);
// Bulk registration
ModelRegistry::map([
'product' => Product::class,
'order' => Order::class,
]);
// Check if exists
if (ModelRegistry::has('user')) {
$class = ModelRegistry::find('user'); // 'App\Models\User'
}
// Get alias for class
$alias = ModelRegistry::aliasForClass(User::class); // 'user'
// Get all registered
$map = ModelRegistry::getMap(); // ['user' => 'App\Models\User', ...]
// Remove alias
ModelRegistry::forget('user');
// Clear all
ModelRegistry::clear();
// Enable globally
ModelRegistry::allowOverwrite(true);
ModelRegistry::register('user', Admin::class); // OK
// Or per registration
ModelRegistry::register('user', Admin::class, $overwrite = true);
use Sindyko\Aliaser\Support\ModelProxy;
$proxy = new ModelProxy(User::class);
$users = $proxy->where('active', true)->get();
$user = $proxy->find(1);
$proxy->create(['name' => 'Jane']);
// Clear static methods cache (useful in tests)
ModelProxy::clearStaticMethodsCache();
// All helper functions support overwrite parameter
modelsMap([...], $overwrite = false);
formsMap([...], $overwrite = false);
objectsMap([...], $overwrite = false);
collectionsMap([...], $overwrite = false);
enumsMap([...], $overwrite = false);
// config/aliaser.php
return [
/*
|--------------------------------------------------------------------------
| Morph Map Sync
|--------------------------------------------------------------------------
|
| Automatically sync model aliases with Relation::enforceMorphMap().
|
| Benefits:
| - Short type names in polymorphic relations (e.g., 'post' instead of FQCN)
| - Alias-based Livewire snapshots via getMorphClass()
|
| If disabled, you'll need to manually call Relation::enforceMorphMap()
| in your AppServiceProvider if you need polymorphic relations.
|
*/
'use_morph_map' => env('ALIASER_USE_MORPH_MAP', true),
/*
|--------------------------------------------------------------------------
| Allow Alias Overwrite
|--------------------------------------------------------------------------
|
| When enabled, registering the same alias twice will overwrite
| the previous registration instead of throwing an exception.
|
| Not recommended for production.
|
*/
'allow_overwrite' => env('ALIASER_ALLOW_OVERWRITE', false),
];
All registries extend AbstractAliasRegistry:
Features:
aliasForClass()6 custom synthesizers for different types:
| Synthesizer | Key | Handles |
|---|---|---|
ModelAliasSynth |
mdl-alias |
Eloquent models |
FormAliasSynth |
frm-alias |
Livewire forms |
ObjectAliasSynth |
obj-alias |
DTOs, Value Objects |
CollectionAliasSynth |
clctn-alias |
Custom collections |
EloquentCollectionAliasSynth |
elcln-alias |
Eloquent collections |
EnumAliasSynth |
enm-alias |
Enums |
Only registered if Livewire is installed!
Static Method Caching:
// ModelProxy caches Reflection results
Entity::user()->isSoftDeletable(); // ~1μs (first call - Reflection)
Entity::user()->isSoftDeletable(); // ~0.3μs (cached - 70% faster)
Memory usage:
# 1. Multiple Models in Controller
// Before
use App\Models\User;
use App\Models\Post;
use App\Models\Comment;
use App\Models\Category;
use App\Models\Tag;
public function dashboard()
{
return [
'users' => User::latest()->take(5)->get(),
'posts' => Post::published()->take(10)->get(),
'comments' => Comment::pending()->count(),
'categories' => Category::withCount('posts')->get(),
'tags' => Tag::popular()->get(),
];
}
// After
use Entity;
public function dashboard()
{
return [
'users' => Entity::user()->latest()->take(5)->get(),
'posts' => Entity::post()->published()->take(10)->get(),
'comments' => Entity::comment()->pending()->count(),
'categories' => Entity::category()->withCount('posts')->get(),
'tags' => Entity::tag()->popular()->get(),
];
}
# 2. Dynamic Model Access
// Before - switch/if or class map
public function getStats(string \$modelType)
{
$modelClass = match($modelType) {
'user' => \App\Models\User::class,
'post' => \App\Models\Post::class,
'comment' => \App\Models\Comment::class,
};
return $modelClass::count();
}
// After - direct access
public function getStats(string $modelType)
{
return Entity::$modelType()->count();
}
### 3. API Resources / Services
// Before
use App\Models\{User, Post, Comment, Like, Follow, Notification};
class UserService
{
public function getUserData(int $userId)
{
return [
'user' => User::findOrFail($userId),
'posts' => Post::where('user_id', $userId)->get(),
'comments' => Comment::where('user_id', $userId)->get(),
'likes' => Like::where('user_id', \$userId)->count(),
'followers' => Follow::where('following_id', $userId)->count(),
'notifications' => Notification::where('user_id', $userId)->unread()->get(),
];
}
}
// After
use Entity;
class UserService
{
public function getUserData(int $userId)
{
return [
'user' => Entity::user($userId),
'posts' => Entity::post()->where('user_id', \$userId)->get(),
'comments' => Entity::comment()->where('user_id', \$userId)->get(),
'likes' => Entity::like()->where('user_id', \$userId)->count(),
'followers' => Entity::follow()->where('following_id', \$userId)->count(),
'notifications' => Entity::notification()->where('user_id', \$userId)->unread()->get(),
];
}
}
// Move model without database migration
// Old: App\Models\User
// New: App\Domain\Users\User
// Just update the alias registration
modelsMap(['user' => \App\Domain\Users\User::class]);
// Database morph map still uses 'user' - no migration needed!
<!-- Component with 10 models in state -->
<!-- Without Aliaser: 2.3 KB HTML -->
<!-- With Aliaser: 1.1 KB HTML (52% reduction!) -->
<!-- Faster initial page load -->
<!-- Less bandwidth usage -->
{
"user": [
"mdl",
{
"...": "..."
},
{
"class": "App\\Domain\\Users\\Models\\User"
}
],
"settings": [
"obj",
{
"...": "..."
},
{
"class": "App\\Settings\\UserSettings"
}
]
}
{
"user": [
"mdl-alias",
{
"...": "..."
},
{
"class": "user"
}
],
"settings": [
"obj-alias",
{
"...": "..."
},
{
"class": "userSettings"
}
]
}
Attackers can't easily determine:
Please see CHANGELOG for more information.
Contributions are welcome! Please feel free to submit a Pull Request.
If you discover any security issues, please email mail@sindyko.ru instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.
Current Status:
Note: Livewire 2.x support is planned for a future release. Currently, if you have Livewire 2.x installed, Livewire-specific features (snapshot optimization) will be automatically disabled, but all other features will work normally.
Even without Livewire 3.x (or without Livewire at all), you can use:
Entity::user()->where('active', true)->get()aliaser:list, aliaser:help, etc.Only Livewire snapshot optimization requires Livewire 3.x.
If you're using Livewire 2.x and want full Aliaser integration:
Yes! Core features like Entity facade, morph map integration, and registries work perfectly without Livewire. Only snapshot optimization requires Livewire 3.x.
Yes, but with limited functionality. Aliaser will automatically detect Livewire 2.x and disable Livewire-specific features. The Entity facade, registries, and morph map integration will work normally. Livewire 2.x support is planned for future releases.
Livewire 3 introduced a new synthesizer architecture that Aliaser uses for snapshot optimization. Livewire 2 has a different internal structure. We're working on backward compatibility and plan to support Livewire 2.x in an upcoming release.
Made with ❤️ for the Laravel community