gksh / transistor
Laravel integration for gksh/bitmask
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/gksh/transistor
Requires
- php: ^8.2
- gksh/bitmask: ^1.0
- illuminate/contracts: ^11.0|^12.0
- illuminate/database: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
- laravel/prompts: ^0.1|^0.2|^0.3
Requires (Dev)
- laravel/pint: ^1.18
- orchestra/testbench: ^9.0|^10.0
- pestphp/pest: ^3.0|^4.0
- phpstan/phpstan: ^2.0
README
Transistor
Laravel integration for gksh/bitmask - providing Eloquent casting, query scopes, validation, Blade directives, and migration macros for working with bitmask flags.
Installation
composer require gksh/transistor
The service provider is auto-discovered by Laravel.
Quick Start
// 1. Generate a bitmask enum php artisan make:bitmask-flags Permission // 2. Add migration macro Schema::create('users', function (Blueprint $table) { $table->id(); $table->bitmask('permissions'); }); // 3. Configure your model use Gksh\Transistor\Casts\BitmaskCast; use Gksh\Transistor\Concerns\HasBitmaskScopes; class User extends Model { use HasBitmaskScopes; protected function casts(): array { return [ 'permissions' => BitmaskCast::class, ]; } } // 4. Use it $user->permissions = $user->permissions ->set(Permission::Read) ->set(Permission::Write); User::whereHasBitmaskFlag('permissions', Permission::Admin)->get();
Artisan Commands
make:bitmask-flags
Generate a bitmask flags enum interactively:
php artisan make:bitmask-flags php artisan make:bitmask-flags Permission
Creates an enum in app/Enums with bit-shifted values:
namespace App\Enums; enum Permission: int { case Read = 1 << 0; // 1 case Write = 1 << 1; // 2 case Delete = 1 << 2; // 4 case Admin = 1 << 3; // 8 }
bitmask:inspect
Display bitmask flags as a lookup table:
php artisan bitmask:inspect "App\Enums\Permission"
php artisan bitmask:inspect Permission 13
+--------+---------+-----------------+
| Case | Decimal | Binary |
+--------+---------+-----------------+
| Read | 1 | 0 0 0 0 0 0 0 1 |
| Write | 2 | 0 0 0 0 0 0 1 0 |
| Delete | 4 | 0 0 0 0 0 1 0 0 |
| Admin | 8 | 0 0 0 0 1 0 0 0 |
+--------+---------+-----------------+
| Value | 13 | 0 0 0 0 1 1 0 1 |
+--------+---------+-----------------+
When a value is provided, active bits are highlighted in green. Heavily inspired by https://laracasts.com/series/lukes-larabits/episodes/18.
Eloquent Cast
Cast database integers to Bitmask objects:
use Gksh\Transistor\Casts\BitmaskCast; protected function casts(): array { return [ 'permissions' => BitmaskCast::class, // 32-bit (default) 'settings' => BitmaskCast::class.':tiny', // 8-bit (0-255) 'features' => BitmaskCast::class.':small', // 16-bit (0-65,535) 'options' => BitmaskCast::class.':medium', // 24-bit (0-16,777,215) ]; }
The cast returns a Gksh\Bitmask\Bitmask object with methods like set(), unset(), toggle(), has(), and value().
Query Scopes
Add the HasBitmaskScopes trait to your model:
use Gksh\Transistor\Concerns\HasBitmaskScopes; class User extends Model { use HasBitmaskScopes; }
Available Scopes
// Filter where flag IS set User::whereHasBitmaskFlag('permissions', Permission::Read)->get(); // Filter where ALL flags are set User::whereHasAllBitmaskFlags('permissions', [Permission::Read, Permission::Write])->get(); // Filter where ANY flag is set User::whereHasAnyBitmaskFlag('permissions', [Permission::Write, Permission::Admin])->get(); // Filter where flag is NOT set User::whereDoesntHaveBitmaskFlag('permissions', Permission::Admin)->get(); // Filter where NONE of the flags are set User::whereDoesntHaveAnyBitmaskFlag('permissions', [Permission::Read, Permission::Write])->get();
Scopes can be chained:
User::whereHasBitmaskFlag('permissions', Permission::Read) ->whereDoesntHaveBitmaskFlag('permissions', Permission::Admin) ->get();
Migration Macros
Create bitmask columns with the appropriate integer size:
Schema::create('users', function (Blueprint $table) { $table->id(); $table->bitmask('permissions'); // unsigned integer (32-bit) $table->tinyBitmask('settings'); // unsigned tinyInteger (8-bit) $table->smallBitmask('features'); // unsigned smallInteger (16-bit) $table->mediumBitmask('options'); // unsigned mediumInteger (24-bit) });
All macros set a default value of 0.
Validation
As a Rule Object
use Gksh\Transistor\Rules\ValidBitmask; $validated = $request->validate([ 'permissions' => ['required', new ValidBitmask()], 'role_flags' => ['required', new ValidBitmask(Permission::class)], ]);
As a String Rule
$validated = $request->validate([ 'permissions' => 'required|bitmask', 'role_flags' => 'required|bitmask:App\Enums\Permission', ]);
When an enum class is provided, the rule ensures the value doesn't exceed the maximum possible combination of all flags.
Blade Directives
@hasBitmaskFlag($user->permissions, Permission::Admin) <span>Administrator</span> @endif @hasAnyBitmaskFlag($user->permissions, [Permission::Write, Permission::Admin]) <button>Edit</button> @endif @hasAllBitmaskFlags($user->permissions, [Permission::Read, Permission::Write]) <span>Full Access</span> @endif
Requirements
- PHP 8.2+
- Laravel 11.x or 12.x
License
MIT