### Basic Porter Installation Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Installs the Porter package with a basic setup, creating the necessary Porter directory and including only the `BaseRole` class. This is a minimal installation for getting started. ```Bash # Creates Porter directory with BaseRole only php artisan porter:install ``` -------------------------------- ### Creating Roles Interactively with Porter CLI Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Guides users through the process of creating new role classes using Porter's Artisan command. This method offers an interactive setup, prompting for role name, description, and creation mode (lowest, highest, lower, higher). ```Bash # Interactive command with guided setup php artisan porter:create # The command will ask: # - Role name (auto-converted to PascalCase) # - Description # - Creation mode (lowest, highest, lower, higher) # - Target role (for lower/higher modes) # Example interaction: # What is the role name? project-manager # What is the role description? Manages development projects # Select creation mode: higher # Which role do you want to reference? Editor # ✅ Role 'ProjectManager' created successfully! ``` -------------------------------- ### Porter Installation CLI Commands Source: https://github.com/hdaklue/porter/blob/master/README.md Lists Artisan commands for installing Porter, including basic installation, installation with default roles, and forcing an overwrite of existing files. ```Bash # Basic installation (config, migrations, Porter directory) php artisan porter:install # Full installation with default roles php artisan porter:install --roles # Force overwrite existing files php artisan porter:install --roles --force ``` -------------------------------- ### Multi-Tenant Role Management Example Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Illustrates how to implement role-based access control in a multi-tenant SaaS application using Porter. It shows assigning roles at organization and project levels and includes a policy example for checking hierarchical access. ```PHP // Organization-level roles Porter::assign($user, $organization, 'admin'); Porter::assign($manager, $organization, 'manager'); // Project-level roles within organization Porter::assign($developer, $project, 'contributor'); Porter::assign($lead, $project, 'project_lead'); // Check hierarchical access if ($user->hasRoleOn($organization, 'admin')) { // Admin has access to all projects in organization // Implement business logic here } // Policy example public function update(User $user, Project $project) { // Check if user is project lead OR organization admin return $user->hasRoleOn($project, 'project_lead') || $user->hasRoleOn($project->organization, 'admin'); } ``` -------------------------------- ### Install Porter Package (Bash) Source: https://github.com/hdaklue/porter/blob/master/README.md Provides commands for installing the Hdaklue Porter package via Composer and using Artisan commands for basic or full installation with default roles. ```bash composer require hdaklue/porter ``` ```bash # Basic installation - creates Porter directory with BaseRole only php artisan porter:install ``` ```bash # Full installation - includes 6 default role classes with proper hierarchy php artisan porter:install --roles ``` -------------------------------- ### E-commerce Role Management Example Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Demonstrates the application of Porter for role management in an e-commerce platform, covering roles for store owners, managers, cashiers, catalog managers, and fulfillment staff. Includes a policy example for refund processing. ```PHP // Store management Porter::assign($storeOwner, $store, 'owner'); Porter::assign($manager, $store, 'manager'); Porter::assign($cashier, $store, 'cashier'); // Product catalog management Porter::assign($catalogManager, $catalog, 'catalog_manager'); // Order fulfillment Porter::assign($fulfillmentTeam, $warehouse, 'fulfillment_staff'); // Business logic example public function canProcessRefund(User $user, Order $order) { $store = $order->store; // Only store managers and owners can process refunds return $user->hasRoleOn($store, 'manager') || $user->hasRoleOn($store, 'owner'); } ``` -------------------------------- ### Full Porter Installation with Default Roles Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Performs a full installation of the Porter package, including the creation of 6 default role classes (Admin, Manager, Editor, Contributor, Viewer, Guest) with a properly defined hierarchy. ```Bash # Includes 6 default role classes with proper hierarchy php artisan porter:install --roles ``` -------------------------------- ### Unit Test Role Classes Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Provides examples for unit testing role classes, focusing on verifying role properties like name, level, and description, as well as testing role hierarchy comparisons. ```php use App\Porter\Admin; use PHPUnit\Framework\TestCase; class AdminRoleTest extends TestCase { public function test_admin_role_properties() { $admin = new Admin(); $this->assertEquals('admin', $admin->getName()); $this->assertEquals(10, $admin->getLevel()); $this->assertStringContains('administrator', $admin->getDescription()); } public function test_role_hierarchy() { $admin = new Admin(); $manager = new Manager(); $this->assertTrue($admin->isHigherThan($manager)); $this->assertFalse($manager->isHigherThan($admin)); } } ``` -------------------------------- ### Validate Porter Setup and Configuration Source: https://github.com/hdaklue/porter/blob/master/README.md Validates the Porter setup and configuration to ensure everything is correctly configured and ready for use. This is a diagnostic command. ```bash php artisan porter:doctor ``` -------------------------------- ### Test Role-Based Policies Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Provides examples for testing authorization policies based on user roles. It covers scenarios where an admin user can update a project and a contributor user cannot delete a project. ```php class ProjectPolicyTest extends TestCase { public function test_admin_can_update_project() { $admin = User::factory()->create(); $project = Project::factory()->create(); Porter::assign($admin, $project, 'admin'); $this->assertTrue($admin->can('update', $project)); } public function test_contributor_cannot_delete_project() { $contributor = User::factory()->create(); $project = Project::factory()->create(); Porter::assign($contributor, $project, 'contributor'); $this->assertFalse($contributor->can('delete', $project)); } } ``` -------------------------------- ### Query Role Assignments with Porter Roster Model Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Demonstrates how to query role assignments using the Porter Roster Model. It covers querying by assignable, roleable, role name, and chaining scopes for complex queries. Includes examples of auditing assignments and analyzing role distribution. ```php use Hdaklue\Porter\Models\Roster; // Query role assignments with scopes $userAssignments = Roster::forAssignable(User::class, $user->id)->get(); $projectRoles = Roster::forRoleable(Project::class, $project->id)->get(); $adminAssignments = Roster::withRoleName('admin')->get(); // Chain scopes for complex queries $recentAdminAssignments = Roster::withRoleName('admin') ->where('created_at', '>=', now()->subDays(30)) ->with(['assignable', 'roleable']) ->get(); // Audit trail functionality foreach ($assignments as $assignment) { echo "Assigned: {$assignment->description} on {$assignment->created_at}"; // Output: "User #123 has role 'admin' on Project #456 on 2024-01-15 14:30:00" } // Role assignment analytics $roleDistribution = Roster::forRoleable(Project::class, $project->id) ->selectRaw('role_key, count(*) as count') ->groupBy('role_key') ->get(); ``` -------------------------------- ### Interactive Role Creation Command Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Provides an Artisan command to interactively create new roles. The process includes guided setup, selection of creation modes (lowest, highest, lower, higher), automatic level calculation based on existing roles, and smart hierarchy management to prevent conflicts. ```Bash # Interactive command with guided setup php artisan porter:create # Choose creation mode: lowest, highest, lower, higher # Automatic level calculation based on existing roles # Smart hierarchy management prevents conflicts ``` -------------------------------- ### Role Hierarchy Comparisons and Business Logic (PHP) Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Demonstrates advanced usage of Porter for comparing role hierarchies and implementing business logic based on these comparisons, such as managing users with lower roles. ```php use App\Porter\{Admin, Manager, Editor, Contributor}; // Create role instances $admin = new Admin(); // Level 10 $manager = new Manager(); // Level 7 $editor = new Editor(); // Level 5 $contributor = new Contributor(); // Level 3 // Smart role comparisons $admin->isHigherThan($manager); // true $manager->isHigherThan($editor); // true $editor->isLowerThan($admin); // true $admin->equals(new Admin()); // true // Business logic using hierarchy public function canManageUser(User $currentUser, User $targetUser, Project $project): bool { $currentRole = Porter::getRoleOn($currentUser, $project); $targetRole = Porter::getRoleOn($targetUser, $project); // Can only manage users with lower roles return $currentRole && $targetRole && $currentRole->isHigherThan($targetRole); } ``` -------------------------------- ### Creating Roles via Porter CLI Arguments Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Demonstrates how to create role classes using the Porter Artisan command with direct command-line arguments. This allows for specifying the role name and description upfront, with prompts for mode and level calculation. ```Bash # Create specific role with description php artisan porter:create ProjectManager --description="Manages development projects" # Will prompt for creation mode and level calculation ``` -------------------------------- ### Basic Role Management in Laravel with Porter Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Demonstrates fundamental operations for assigning, checking, and removing user roles on specific entities (like projects) using the Porter facade. It also shows how to change a user's role on an entity. ```PHP use Hdaklue\Porter\Facades\Porter; // Assign role Porter::assign($user, $project, 'admin'); // Check role $isAdmin = $user->hasRoleOn($project, 'admin'); // Remove role Porter::remove($user, $project); // Change role Porter::changeRoleOn($user, $project, 'editor'); ``` -------------------------------- ### Listen to Role Assignment Events Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Illustrates how to listen to role-related events such as `RoleAssigned`, `RoleChanged`, and `RoleRemoved` to trigger actions like sending notifications or logging audit trails. ```php use Hdaklue\Porter\Events\{RoleAssigned, RoleChanged, RoleRemoved}; // Listen to role events class NotifyRoleChange { public function handle(RoleAssigned $event) { $user = $event->assignable; $entity = $event->roleable; $role = $event->role; // Send notification $user->notify(new RoleAssignedNotification($entity, $role)); // Log for audit Log::info("Role assigned", [ 'user_id' => $user->id, 'entity_type' => get_class($entity), 'entity_id' => $entity->id, 'role' => $role, ]); } } ``` -------------------------------- ### Laravel Integration Examples Source: https://github.com/hdaklue/porter/blob/master/README.md Demonstrates how Porter integrates with Laravel's authorization system, including checking roles in Policies, authorizing actions in Controllers, and using the @can directive in Blade templates. ```PHP // In your Policy public function update(User $user, Project $project) { return $user->hasRoleOn($project, 'admin'); } // In your Controller $this->authorize('update', $project); // In your Blade templates @can('update', $project) @endcan ``` -------------------------------- ### Educational System Role Assignments and Grade Access (PHP) Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Shows how to implement role-based access control in an educational system for school administration, departments, and classes. Includes a function to manage grade entry permissions. ```php // School administration Porter::assign($principal, $school, 'principal'); Porter::assign($viceP, $school, 'vice_principal'); // Department roles Porter::assign($deptHead, $department, 'department_head'); Porter::assign($teacher, $department, 'teacher'); // Class-specific assignments Porter::assign($teacher, $class, 'class_teacher'); Porter::assign($assistant, $class, 'teaching_assistant'); // Grade access control public function canEnterGrades(User $user, Class $class) { // Class teacher can always enter grades if ($user->hasRoleOn($class, 'class_teacher')) { return true; } // Department heads can enter grades for their department's classes if ($user->hasRoleOn($class->department, 'department_head')) { return true; } return false; } ``` -------------------------------- ### Example Event Listener for Role Assignment Source: https://github.com/hdaklue/porter/blob/master/docs/laravel-integration.md An example of a Laravel event listener that handles the `RoleAssigned` event from Porter. It retrieves user, target, and role information from the event and sends a notification. ```php class SendRoleAssignedNotification { public function handle(RoleAssigned $event) { $user = $event->user; $target = $event->target; $role = $event->role; // Send notification $user->notify(new RoleAssignedNotification($target, $role)); } } ``` -------------------------------- ### Dynamic Role Creation using Porter's RoleFactory Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Illustrates how to create role instances dynamically using Porter's RoleFactory. This factory can automatically scan the Porter directory for roles and provides methods to create specific roles or retrieve all available roles. ```PHP use Hdaklue\Porter\RoleFactory; // Magic factory methods - scans your Porter directory automatically $admin = RoleFactory::admin(); // Creates Admin role instance $projectManager = RoleFactory::projectManager(); // Creates ProjectManager role instance // Check if role exists before using if (RoleFactory::existsInPorterDirectory('CustomRole')) { $role = RoleFactory::customRole(); } // Get all roles from directory $allRoles = RoleFactory::allFromPorterDirectory(); ``` -------------------------------- ### Custom Role Classes with Business Logic (PHP) Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Provides an example of creating a custom role class, 'RegionalManager', extending Porter's base role functionality. It includes methods for region access and budget approval limits. ```php final class RegionalManager extends BaseRole { public function getName(): string { return 'regional_manager'; } public function getLevel(): int { return 8; } public function getRegions(): array { return ['north', 'south', 'east', 'west']; } public function canAccessRegion(string $region): bool { return in_array($region, $this->getRegions()); } public function getMaxBudgetApproval(): int { return 100000; // $100k approval limit } public function getDirectReports(): int { return 50; // Maximum 50 direct reports } } // Usage in controllers public function approveBudget(Request $request, Budget $budget) { $user = $request->user(); if (!$user->hasRoleOn($budget->company, 'regional_manager')) { abort(403, 'Insufficient permissions'); } $role = Porter::getRoleOn($user, $budget->company); // Check region access if (!$role->canAccessRegion($budget->region)) { abort(403, 'Cannot access this region'); } // Check budget limit if ($budget->amount > $role->getMaxBudgetApproval()) { abort(403, 'Budget exceeds approval limit'); } $budget->approve(); } ``` -------------------------------- ### Porter Zero-Downtime Migration Strategy Source: https://github.com/hdaklue/porter/blob/master/README.md Outlines a phased approach for migrating to Porter with zero downtime. It involves installing Porter, optionally adding traits to models, running parallel role checks, and gradually switching over. ```PHP // Phase 1: Install Porter (zero risk) composer require hdaklue/porter php artisan porter:install php artisan migrate // Just adds the `roaster` table // Phase 2: Add traits to existing models (optional) class User extends Authenticatable { use HasUlids; // Add this trait for modern ID strategy // All existing code works unchanged! } // Phase 3: Gradually migrate role checks // Old system keeps working: if ($user->hasRole('admin')) { /* existing code */ } // New Porter system runs parallel: if ($user->hasRoleOn($project, 'admin')) { /* Porter */ } // Phase 4: Switch over when ready (no rush!) ``` -------------------------------- ### Configure Environment Variables for Porter Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md This snippet shows how to define environment-specific settings for Porter using .env file variables. It covers assignment strategy, key storage, and caching configurations for both production and development environments. ```dotenv // .env PORTER_ASSIGNMENT_STRATEGY=replace # Production: replace existing roles PORTER_KEY_STORAGE=hashed # Production: hashed keys for security PORTER_CACHE_ENABLED=true # Production: enable caching PORTER_CACHE_TTL=3600 # Production: 1 hour cache # Development settings PORTER_ASSIGNMENT_STRATEGY=add # Dev: allow multiple roles for testing PORTER_KEY_STORAGE=plain # Dev: plain keys for debugging ``` -------------------------------- ### Manual Role Class Definition in Laravel Porter Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Provides an example of manually defining a role class by extending a base role class (e.g., `App\Porter\BaseRole`). This method requires explicitly defining the role's name, level, and description. ```PHP use App\Porter\BaseRole; // Your application's base role final class ProjectManager extends BaseRole { public function getName(): string { return 'project_manager'; } public function getLevel(): int { return 7; } public function getDescription(): string { return 'Manages development projects and team coordination'; } } ``` -------------------------------- ### Feature Test Role Assignments Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Demonstrates feature testing for role assignments, including verifying that a user can be assigned a role and that changing a role updates the assignment correctly. Uses `RefreshDatabase` trait for testing database interactions. ```php use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class RoleAssignmentTest extends TestCase { use RefreshDatabase; public function test_user_can_be_assigned_role() { $user = User::factory()->create(); $project = Project::factory()->create(); Porter::assign($user, $project, 'admin'); $this->assertTrue($user->hasRoleOn($project, 'admin')); $this->assertFalse($user->hasRoleOn($project, 'editor')); } public function test_role_change_updates_assignment() { $user = User::factory()->create(); $project = Project::factory()->create(); Porter::assign($user, $project, 'admin'); Porter::changeRoleOn($user, $project, 'editor'); $this->assertFalse($user->hasRoleOn($project, 'admin')); $this->assertTrue($user->hasRoleOn($project, 'editor')); } } ``` -------------------------------- ### Configure Porter Security Settings in Laravel Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md This snippet demonstrates how to integrate Porter's security configurations into a Laravel application's config file. It utilizes environment variables for assignment strategy, key storage, and automatic key generation. ```php // config/porter.php 'security' => [ 'assignment_strategy' => env('PORTER_ASSIGNMENT_STRATEGY', 'replace'), 'key_storage' => env('PORTER_KEY_STORAGE', 'hashed'), 'auto_generate_keys' => env('PORTER_AUTO_KEYS', true), ] ``` -------------------------------- ### Integrate Custom Role-Based Middleware Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Shows how to create and integrate a custom middleware (`RequireRoleOnEntity`) to enforce role-based access control on specific routes. It includes defining the middleware, registering it in the kernel, and applying it to route groups. ```php // Create custom middleware class RequireRoleOnEntity { public function handle($request, Closure $next, $role, $entityParam = null) { $user = $request->user(); $entityParam = $entityParam ?? 'project'; // Default parameter name $entity = $request->route($entityParam); if (!$user || !$entity || !$user->hasRoleOn($entity, $role)) { abort(403, "Required role: {$role}"); } return $next($request); } } // Register in Kernel.php protected $routeMiddleware = [ 'role.on' => RequireRoleOnEntity::class, ]; // Use in routes Route::middleware('role.on:admin,project')->group(function () { Route::put('/projects/{project}', [ProjectController::class, 'update']); Route::delete('/projects/{project}', [ProjectController::class, 'destroy']); }); ``` -------------------------------- ### Laravel Gates with Porter Integration Source: https://github.com/hdaklue/porter/blob/master/docs/laravel-integration.md Demonstrates how to define Laravel Gates that leverage Porter's functionality for more complex authorization scenarios. This example defines a 'manage-project-budget' gate that checks admin roles and budget approval limits. ```php // In AuthServiceProvider.php use Illuminate\Support\Facades\Gate; use Hdaklue\Porter\Facades\Porter; public function boot() { Gate::define('manage-project-budget', function (User $user, Project $project, int $amount) { if (!Porter::hasRoleOn($user, $project, 'admin')) { return false; } $role = Porter::getRoleOn($user, $project); return $role && method_exists($role, 'getMaxBudgetApproval') && $amount <= $role->getMaxBudgetApproval(); }); } ``` -------------------------------- ### PHP RBAC Core Functionality Examples Source: https://github.com/hdaklue/porter/blob/master/TEST_STATUS.md Demonstrates the usage of the Porter RBAC library in PHP, including role instantiation, factory operations, and hierarchy checks. This code confirms the core business logic is working as expected. ```PHP // All of these work perfectly: $admin = new Admin(); $role = RoleFactory::make('admin'); $manager = RoleFactory::tryMake('manager'); $exists = RoleFactory::exists('editor'); $all = RoleFactory::getAllWithKeys(); // Role hierarchy $admin->isHigherThan($editor); // true $viewer->isLowerThan($manager); // true ``` -------------------------------- ### Content Management System Role Assignments and Workflow (PHP) Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Illustrates role assignments for editorial workflows in a CMS, including roles for publications and articles. Features a function to control article publishing permissions based on user roles. ```php // Publication roles Porter::assign($editor, $publication, 'editor_in_chief'); Porter::assign($writer, $publication, 'staff_writer'); Porter::assign($freelancer, $publication, 'contributor'); // Article-specific assignments Porter::assign($author, $article, 'author'); Porter::assign($editor, $article, 'assigned_editor'); // Publishing workflow public function canPublishArticle(User $user, Article $article) { $publication = $article->publication; // Editor in chief can publish anything if ($user->hasRoleOn($publication, 'editor_in_chief')) { return true; } // Assigned editors can publish their assigned articles if ($user->hasRoleOn($article, 'assigned_editor')) { return true; } return false; } ``` -------------------------------- ### Healthcare System Role Assignments and Access Control (PHP) Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Demonstrates how to assign roles to users and patients within a healthcare system using Porter. Includes a function to check medical record access based on user roles and patient relationships. ```php // Department roles Porter::assign($doctor, $department, 'attending_physician'); Porter::assign($nurse, $department, 'head_nurse'); Porter::assign($resident, $department, 'resident'); // Patient care assignments Porter::assign($doctor, $patient, 'primary_care_physician'); Porter::assign($specialist, $patient, 'consulting_specialist'); // Medical record access control public function canViewMedicalRecord(User $user, Patient $patient) { // Primary physician always has access if ($user->hasRoleOn($patient, 'primary_care_physician')) { return true; } // Department staff can view patients in their department if ($user->hasRoleOn($patient->department, 'attending_physician') || $user->hasRoleOn($patient->department, 'head_nurse')) { return true; } return false; } ``` -------------------------------- ### Custom Blade Directive for Role Checks Source: https://github.com/hdaklue/porter/blob/master/docs/laravel-integration.md Provides an example of creating a custom Blade directive (`@hasRoleOn`) in `AppServiceProvider` to simplify Porter-specific role checks within Blade views. This enhances readability and reusability. ```php // In AppServiceProvider.php use Illuminate\Support\Facades\Blade; use Hdaklue\Porter\Facades\Porter; public function boot() { Blade::if('hasRoleOn', function ($entity, $role) { return auth()->check() && Porter::hasRoleOn(auth()->user(), $entity, $role); }); } ``` ```blade @hasRoleOn($project, 'admin')
@endhasRoleOn ``` -------------------------------- ### Integrating Porter Concerns into Laravel Models Source: https://github.com/hdaklue/porter/blob/master/docs/suggested-usage.md Shows how to integrate Porter's role management capabilities directly into your Laravel Eloquent models. This involves using traits for users who can be assigned roles and for entities that receive role assignments. ```PHP use Hdaklue\Porter\Concerns\{CanBeAssignedToEntity, ReceivesRoleAssignments}; class User extends Authenticatable { use CanBeAssignedToEntity; // Your existing User model code... } class Project extends Model { use ReceivesRoleAssignments; // Your existing Project model code... } ``` -------------------------------- ### Laravel Authorization with Porter Roles Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Shows how to use Porter roles within a Laravel application for authorization. Examples include checking roles in Policies, using the `authorize` method in Controllers, conditional rendering in Blade templates with `@can`, and authorization in Form Requests. ```PHP // In your Policy public function update(User $user, Project $project) { return $user->hasRoleOn($project, 'admin'); } // In your Controller $this->authorize('update', $project); // In your Blade templates @can('update', $project) @endcan // In your Form Requests public function authorize() { return $this->user()->hasRoleOn($this->project, 'admin'); } ``` -------------------------------- ### List All Available Roles Source: https://github.com/hdaklue/porter/blob/master/README.md Lists all the roles that are currently available within the Porter system. This command helps in understanding the existing role structure. ```bash php artisan porter:list ``` -------------------------------- ### Create Role Classes (Bash & PHP) Source: https://github.com/hdaklue/porter/blob/master/README.md Shows how to create new role classes using the Artisan command-line interface or the dynamic role factory for programmatic role creation. ```bash # Interactive role creation with guided setup php artisan porter:create ``` ```php # Or use the dynamic role factory $admin = RoleFactory::admin(); ``` -------------------------------- ### Run Complete Test Suite Source: https://github.com/hdaklue/porter/blob/master/README.md Executes the entire test suite for the Porter project using the Pest testing framework. This is crucial for verifying the stability and correctness of the application. ```bash vendor/bin/pest ``` -------------------------------- ### Porter Role Management CLI Commands Source: https://github.com/hdaklue/porter/blob/master/README.md Details Artisan commands for managing roles within Porter, specifically the `porter:create` command for interactive role creation. ```Bash # Role Creation Commands # Interactive role creation with guided setup php artisan porter:create ``` -------------------------------- ### Create Specific Role with Description Source: https://github.com/hdaklue/porter/blob/master/README.md Creates a new role with a specified name and description using the Porter CLI. This command is part of the role management features. ```bash php artisan porter:create ProjectManager --description="Manages development projects" ``` -------------------------------- ### Role Hierarchy and Comparisons Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Illustrates the role hierarchy system, allowing for intelligent comparisons between roles based on their levels. It includes methods like `isHigherThan`, `isLowerThan`, and `equals` for comparing roles, and demonstrates how to retrieve a user's role on a specific entity. ```PHP use App\Porter{Admin, ProjectManager, Developer, Viewer}; $admin = new Admin(); // Level 10 $manager = new ProjectManager(); // Level 7 $developer = new Developer(); // Level 3 $viewer = new Viewer(); // Level 1 // Intelligent role comparisons $admin->isHigherThan($manager); // true $manager->isHigherThan($developer); // true $developer->isLowerThan($admin); // true $admin->equals(new Admin()); // true // Business logic in your controllers public function canManageProject(User $user, Project $project): bool { $userRole = RoleManager::getRoleOn($user, $project); $requiredRole = new ProjectManager(); return $userRole && $userRole->isHigherThanOrEqual($requiredRole); } ``` -------------------------------- ### Run Tests with Coverage Reporting Source: https://github.com/hdaklue/porter/blob/master/README.md Runs the test suite and generates a code coverage report, indicating which parts of the codebase are covered by tests. This helps in identifying areas that need more testing. ```bash vendor/bin/pest --coverage ``` -------------------------------- ### Porter Configuration (config/porter.php) Source: https://github.com/hdaklue/porter/blob/master/README.md Defines package settings including ID strategy, database connection, directory and namespace for roles, role classes, security settings (assignment and key storage strategies), and caching options. ```PHP return [ // ID Strategy - Works with your existing models 'id_strategy' => env('PORTER_ID_STRATEGY', 'ulid'), // Database connection 'database_connection' => env('PORTER_DB_CONNECTION'), // Role Directory & Namespace Configuration 'directory' => env('PORTER_DIRECTORY', app_path('Porter')), 'namespace' => env('PORTER_NAMESPACE', 'App\\Porter'), // Your role classes (auto-populated by porter:install --roles) 'roles' => [ App\Porter\Admin::class, App\Porter\Manager::class, App\Porter\Editor::class, // ... add your custom roles here ], // Security settings 'security' => [ 'assignment_strategy' => env('PORTER_ASSIGNMENT_STRATEGY', 'replace'), // 'replace' or 'add' 'key_storage' => env('PORTER_KEY_STORAGE', 'hashed'), // 'hashed' or 'plain' 'auto_generate_keys' => env('PORTER_AUTO_KEYS', true), ], // Caching 'cache' => [ 'enabled' => env('PORTER_CACHE_ENABLED', true), 'ttl' => env('PORTER_CACHE_TTL', 3600), // 1 hour ], ]; ``` -------------------------------- ### Role Hierarchy & Comparisons (PHP) Source: https://github.com/hdaklue/porter/blob/master/README.md Illustrates how to define role hierarchies and perform intelligent comparisons between roles, including checking if one role is higher, lower, or equal to another. Also shows how to integrate these comparisons into business logic. ```php use App\Porter{Admin, ProjectManager, Developer, Viewer}; $admin = new Admin(); // Level 10 $manager = new ProjectManager(); // Level 7 $developer = new Developer(); // Level 3 $viewer = new Viewer(); // Level 1 // Intelligent role comparisons $admin->isHigherThan($manager); // true $manager->isHigherThan($developer); // true $developer->isLowerThan($admin); // true $admin->equals(new Admin()); // true // Business logic in your controllers public function canManageProject(User $user, Project $project): bool { $userRole = RoleManager::getRoleOn($user, $project); $requiredRole = new ProjectManager(); return $userRole && $userRole->isHigherThanOrEqual($requiredRole); } ``` -------------------------------- ### Porter vs. Database-Heavy RBAC Comparison Source: https://github.com/hdaklue/porter/blob/master/README.md This table highlights the architectural differences between Porter's class-based approach and traditional database-heavy RBAC solutions, focusing on role architecture, permission storage, entity context, type safety, codebase size, IDE support, and performance. ```Markdown | Feature | Database-Heavy RBAC | Porter | |---------|---------------------|--------| | **Role Architecture** | Database records | Individual PHP classes | | **Permission Storage** | Database tables | PHP class methods | | **Entity Context** | Global permissions | Entity-specific roles | | **Type Safety** | String-based | Full PHP type safety | | **Codebase Size** | Many classes/tables | Minimal architecture | | **IDE Support** | Limited | Full autocomplete | | **Performance** | Multiple DB queries | Single table, memory checks | ``` -------------------------------- ### Configurable Directory and Namespace Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Defines configuration settings for the Porter package, allowing customization of the directory where roles are stored and the namespace for these roles. These settings are typically managed via environment variables. ```PHP // config/porter.php 'directory' => env('PORTER_DIRECTORY', app_path('Porter')), 'namespace' => env('PORTER_NAMESPACE', 'App\\Porter'), ``` -------------------------------- ### Test Specific Components Source: https://github.com/hdaklue/porter/blob/master/README.md Executes tests for specific components or files within the Porter project. This allows for targeted testing of features like performance, database operations, or interactive commands. ```bash vendor/bin/pest tests/Feature/RoleValidatorTest.php ``` ```bash vendor/bin/pest tests/Feature/RoleManagerDatabaseTest.php ``` ```bash vendor/bin/pest tests/Feature/CreateRoleCommandTest.php ``` -------------------------------- ### Dynamic Role Factory with __callStatic Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Utilizes magic __callStatic methods for type-safe role instantiation. It automatically scans the Porter directory to create role instances and allows checking for role existence before use. It also provides a method to retrieve all roles from the directory. ```PHP use Hdaklue\Porter\RoleFactory; // Magic factory methods - scans your Porter directory automatically $admin = RoleFactory::admin(); // Creates Admin role instance $projectManager = RoleFactory::projectManager(); // Creates ProjectManager role instance // Check if role exists before using if (RoleFactory::existsInPorterDirectory('CustomRole')) { $role = RoleFactory::customRole(); } // Get all roles from directory $allRoles = RoleFactory::allFromPorterDirectory(); ``` -------------------------------- ### Role Assignment Service API (PHP) Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Demonstrates the `RoleManager` facade for performing core role operations like assigning, removing, and changing roles for users on projects. It also shows how to retrieve a user's role on a specific project. ```PHP use Hdaklue\Porter\Facades\Porter; // All role operations through one clean API Porter::assign($user, $project, 'admin'); Porter::remove($user, $project); Porter::changeRoleOn($user, $project, 'editor'); $role = Porter::getRoleOn($user, $project); $participants = Porter::getParticipants($project); ``` -------------------------------- ### Basic Role Operations (PHP) Source: https://github.com/hdaklue/porter/blob/master/README.md Demonstrates fundamental role management operations such as assigning roles, checking role existence, and changing roles for a user on a specific project. ```php use Hdaklue\Porter\Facades\Porter; // Basic role operations Porter::assign($user, $project, 'admin'); $isAdmin = $user->hasRoleOn($project, 'admin'); Porter::changeRoleOn($user, $project, 'editor'); ``` -------------------------------- ### Simplified Cache Strategy (PHP) Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Illustrates Porter's cache strategy, which involves caching file paths to optimize performance. The cache is cleared after each role creation to ensure data consistency. ```PHP // Simplified path-based caching private static array $classPathCache = []; // Cache only file paths, not complex data structures $classPaths[$filename] = $filePath; // Cleared after each role creation RoleValidator::clearCache(); ``` -------------------------------- ### Enhanced Roster Model Scopes (PHP) Source: https://github.com/hdaklue/porter/blob/master/README.md Demonstrates the use of scopes within the Roster model for querying role assignments based on assignable, roleable, or role name. It also highlights the availability of timestamps and human-readable descriptions for assignments. ```php use Hdaklue\Porter\Models\Roster; // Query role assignments with new scopes $userAssignments = Roster::forAssignable(User::class, $user->id)->get(); $projectRoles = Roster::forRoleable(Project::class, $project->id)->get(); $adminAssignments = Roster::withRoleName('admin')->get(); // Timestamps for audit trails $assignment = Roster::create([...]); echo "Assigned on: " . $assignment->created_at; // Human-readable descriptions foreach ($assignments as $assignment) { echo $assignment->description; // Output: "User #123 has role 'admin' on Project #456" } ``` -------------------------------- ### Porter Security Configuration (.env) Source: https://github.com/hdaklue/porter/blob/master/README.md Configures security settings for Porter, including the assignment strategy (replace or add roles) and key storage method (hashed or plain text), as well as whether to auto-generate keys. ```PHP // .env file PORTER_ASSIGNMENT_STRATEGY=replace # Default: Replaces existing roles PORTER_ASSIGNMENT_STRATEGY=add # Adds new roles alongside existing ones PORTER_KEY_STORAGE=hashed # Secure (default) - SHA256 hashed role keys PORTER_KEY_STORAGE=plain # Debug mode - Plain text role keys PORTER_AUTO_KEYS=true # Auto-generate keys from class names PORTER_AUTO_KEYS=false # Manual key definition required ``` -------------------------------- ### Custom Role Class with Business Logic (PHP) Source: https://github.com/hdaklue/porter/blob/master/README.md Shows how to create a custom role class by extending `BaseRole`, defining its name, level, and custom methods for specific business logic, such as accessing regions or setting budget approval limits. ```php final class RegionalManager extends BaseRole { public function getName(): string { return 'regional_manager'; } public function getLevel(): int { return 8; } public function getRegions(): array { return ['north', 'south', 'east', 'west']; } public function canAccessRegion(string $region): bool { return in_array($region, $this->getRegions()); } public function getMaxBudgetApproval(): int { return 100000; // $100k approval limit } } // Usage in business logic if ($user->hasRoleOn($company, 'regional_manager')) { $role = Porter::getRoleOn($user, $company); if ($role->canAccessRegion('north') && $budget <= $role->getMaxBudgetApproval()) { // Approve the budget for northern region } } ``` -------------------------------- ### Testing Porter Integrations with Laravel Source: https://github.com/hdaklue/porter/blob/master/docs/laravel-integration.md Demonstrates how to write tests for functionalities involving Porter using Laravel's testing helpers. It includes tests for an admin deleting a project and a manager being forbidden from deleting it, utilizing `RefreshDatabase` and `actingAs`. ```php class ProjectControllerTest extends TestCase { use RefreshDatabase; public function test_admin_can_delete_project() { $user = User::factory()->create(); $project = Project::factory()->create(); Porter::assign($user, $project, 'admin'); $this->actingAs($user) ->delete(route('projects.destroy', $project)) ->assertRedirect(); $this->assertDatabaseMissing('projects', ['id' => $project->id]); } public function test_manager_cannot_delete_project() { $user = User::factory()->create(); $project = Project::factory()->create(); Porter::assign($user, $project, 'manager'); $this->actingAs($user) ->delete(route('projects.destroy', $project)) ->assertForbidden(); } } ``` -------------------------------- ### Enhanced Security Options Configuration Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Configures security-related settings for the Porter package. This includes defining the assignment strategy for roles ('replace' or 'add'), the method for key storage ('hashed' or 'plain'), and whether to automatically generate keys. ```PHP // config/porter.php 'security' => [ 'assignment_strategy' => env('PORTER_ASSIGNMENT_STRATEGY', 'replace'), // 'replace' or 'add' 'key_storage' => env('PORTER_KEY_STORAGE', 'hashed'), // 'hashed' or 'plain' 'auto_generate_keys' => env('PORTER_AUTO_KEYS', true), ], ``` -------------------------------- ### Porter Single Table Architecture (roaster) Source: https://github.com/hdaklue/porter/blob/master/README.md Defines the SQL schema for the `roaster` table, which stores all role assignments for Porter. It includes columns for assignable and roleable types and IDs, role key, and timestamps, with a unique key to prevent duplicates. ```SQL -- The ENTIRE role system in one table: CREATE TABLE roaster ( id bigint PRIMARY KEY, assignable_type varchar(255), assignable_id varchar(255), roleable_type varchar(255), roleable_id varchar(255), role_key varchar(255), created_at timestamp, updated_at timestamp, -- Prevents duplicate assignments UNIQUE KEY porter_unique (assignable_type, assignable_id, roleable_type, roleable_id, role_key) ); ``` -------------------------------- ### Define Basic Roles (PHP) Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Defines `Admin` and `Editor` roles by extending the `BaseRole` class. Each role specifies its name, level, and a description, ensuring type safety and enabling role-specific methods. ```PHP final class Admin extends BaseRole { public function getName(): string { return 'admin'; } public function getLevel(): int { return 10; } public function getDescription(): string { return 'System administrator with full access'; } } final class Editor extends BaseRole { public function getName(): string { return 'editor'; } public function getLevel(): int { return 5; } public function getDescription(): string { return 'Content editor with publishing rights'; } } ``` -------------------------------- ### Laravel Contracts Integration for Roles Source: https://github.com/hdaklue/porter/blob/master/docs/core-features.md Demonstrates how roles integrate with Laravel's contract system by implementing the `RoleContract`. This ensures full type safety and adherence to Laravel conventions within the role definitions. ```PHP use Hdaklue\Porter\Contracts\RoleContract; final class Admin extends BaseRole implements RoleContract { // Full type safety with Laravel's contract system } ```