### 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')