mud-qadm/policy-discovery 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mud-qadm/policy-discovery

最新稳定版本:v1.0.0

Composer 安装命令:

composer require mud-qadm/policy-discovery

包简介

Laravel package for recursive policy auto discovery supporting modular architecture

README 文档

README

Latest Version on Packagist Total Downloads PHP Version Laravel Version License

Automatically discover and register Laravel policies recursively – even in deeply nested directories or modular domain structures.

📋 Table of Contents

🔥 The Problem

Laravel's native policy auto-discovery works perfectly for flat directory structures:

app/Policies/
├── UserPolicy.php
├── PostPolicy.php
└── CommentPolicy.php

But real-world applications often grow beyond that. When you organise policies by domain or module:

app/
└── Policies/
    ├── Settings/
    │   ├── RolePolicy.php
    │   └── PermissionPolicy.php
    ├── HR/
    │   └── EmployeePolicy.php
    └── Finance/
        └── InvoicePolicy.php

Laravel does not recursively scan subdirectories. This forces you to manually register every policy using Gate::policy() – a tedious and error-prone process.

💡 Solution

This package recursively scans any number of policy directories, automatically maps policies to their corresponding models, and registers them with Laravel's Gate – without any manual intervention.

  • ✅ Recursively discovers policies in nested folders
  • ✅ Maps policies to models using naming conventions or explicit annotations
  • ✅ Works with Laravel's package auto-discovery
  • ✅ Includes file-based caching for production performance
  • ✅ Provides artisan commands for inspection and cache management

✨ Features

Feature Description
Recursive discovery Finds policies in any subdirectory under configured paths
Automatic model mapping Infers model from policy name or uses @model annotation
Modular support Perfect for DDD, modules, or domain-driven structures
Zero configuration Drop-in installation, works out of the box
Performance caching File-based cache to avoid filesystem scanning on every request
CLI tools List, validate, warmup, clear, rebuild, and optimise caches
Export mappings Export discovered policy–model mappings to JSON
Diagnostics Statistics and validation commands to ensure correct setup
Automatic policy detection Newly created policies are discovered automatically without manual registration

🧰 Requirements

  • PHP 8.1 or higher
  • Laravel 10.x, or higher

📦 Installation

Install via Composer:

composer require mud-qadm/policy-discovery

Laravel will automatically register the package's service provider thanks to Laravel's package discovery.

To publish the configuration file:

php artisan vendor:publish --tag=policy-discovery-config

This will create config/policy-discovery.php where you can customise directories, caching behaviour, and naming conventions.

⚙️ Configuration

After publishing, you can modify the following options in config/policy-discovery.php:

return [

    /*
    |--------------------------------------------------------------------------
    | Policy Base Directory
    |--------------------------------------------------------------------------
    | Root directory where all policy classes are located.
    */
    'policy_directory' => app_path('Policies'),

    /*
    |--------------------------------------------------------------------------
    | Policy Namespace
    |--------------------------------------------------------------------------
    | Base namespace used to resolve policy classes.
    */
    'policy_namespace' => 'App\\Policies',

    /*
    |--------------------------------------------------------------------------
    | Model Directories
    |--------------------------------------------------------------------------
    | Directories used for automatic model resolution when mapping policies.
    */
    'model_directories' => [
        app_path('Models'),
    ],

    /*
    |--------------------------------------------------------------------------
    | Recursive Scanning
    |--------------------------------------------------------------------------
    | When enabled, policies inside nested directories will be discovered.
    */
    'recursive' => true,

    /*
    |--------------------------------------------------------------------------
    | Cache Enabled
    |--------------------------------------------------------------------------
    | Enable or disable caching of discovered policy mappings.
    */
    'cache_enabled' => env('POLICY_DISCOVERY_CACHE', true),

    /*
    |--------------------------------------------------------------------------
    | Cache File Path
    |--------------------------------------------------------------------------
    | File used to store cached policy-model mappings.
    */
    'cache_file' => storage_path('policy-discovery/mapping.json'),

];

🚀 Usage

Once installed, simply place your policy files anywhere under the configured directories.

Example

Policy file: app/Policies/Settings/RolePolicy.php

<?php

namespace App\Policies\Settings;

use App\Models\Settings\Role;
use App\Models\User;

class RolePolicy
{
    public function viewAny(User $user): bool { /* ... */ }
    public function view(User $user, Role $role): bool { /* ... */ }
    public function update(User $user, Role $role): bool { /* ... */ }
    public function delete(User $user, Role $role): bool { /* ... */ }
}

The package will automatically:

  1. Discover RolePolicy recursively.
  2. Map it to App\Models\Settings\Role (using convention: RolePolicyRole model).
  3. Register it with Laravel's Gate.

You can now use Laravel's authorisation methods as usual:

$user->can('view', $role);
Gate::allows('update', $role);

No additional service provider code or manual Gate::policy() calls are needed.

🛠️ Artisan Commands

Command Description
php artisan policy-discovery:list Display all discovered policy–model mappings
php artisan policy-discovery:check Validate that mapped models and policies exist and are loadable
php artisan policy-discovery:warmup Generate the cache without clearing existing cache
php artisan policy-discovery:clear-cache Delete the cached policy mappings
php artisan policy-discovery:rebuild Clear and regenerate the cache
php artisan policy-discovery:optimize Optimise the cached mapping structure (e.g., sort, deduplicate)
php artisan policy-discovery:stats Show statistics (total policies, models, directories scanned, cache age)
php artisan policy-discovery:export Export all discovered mappings as JSON (useful for debugging or CI)

⚙️ How It Works

  1. Scanning – On the first request (or when the cache is empty), the package recursively scans the configured directories for PHP files ending with *Policy.php.

  2. Model Resolution – For each discovered policy, the package determines the target model using the following strategies (in order):

    • PHP Attributes using #[PolicyFor(...)]
    • DocBlock annotations using @model
    • Naming conventions (RolePolicyRole)

🎯 Explicit Policy Mapping (Attributes)

You can explicitly define which model a policy belongs to using PHP Attributes:

use MudQadm\PolicyDiscovery\Attributes\PolicyFor;

#[PolicyFor(User::class)]
class UserPolicy
{
    //
}

This is especially useful when the policy name does not directly match the model name or when working with custom domain structures.

  1. Registration – Each discovered policy–model pair is automatically registered with Laravel's Gate using Gate::policy().

  2. Caching – Discovered mappings are cached to avoid unnecessary filesystem scans and improve performance.

  3. Automatic Refresh – When a new policy is generated using:

php artisan make:policy

the package automatically refreshes its mappings, ensuring the newly created policy is available without requiring manual cache rebuilds.

You can customise the discovery paths, namespaces, and mapping behaviour through the configuration file.

🧠 Caching & Performance

  • Policy mappings are cached to minimise filesystem operations.
  • Cache is automatically invalidated when policy files are added, removed, or modified.
  • Newly generated policies are detected automatically and included in the mapping cache.
  • In production, you may run php artisan policy-discovery:warmup after deployment to pre-build the cache.
  • Run php artisan policy-discovery:optimize to optimise the cached mapping structure.

⚠️ Policy Discovery automatically keeps its cache in sync with policy changes, so manual cache rebuilding is rarely required.

🔍 Troubleshooting

Issue Solution
Policy not discovered Ensure the file name ends with Policy.php, verify the configured discovery paths, and run php artisan policy-discovery:check.
Model mapped incorrectly Use the #[PolicyFor(...)] attribute or add an @model annotation.
Cache appears outdated Run php artisan policy-discovery:rebuild and verify cache directory permissions.
Performance issues during development Disable caching or clear the cache frequently while iterating.

For additional help, open an issue on GitHub.

📄 License

The MIT License (MIT). See the LICENSE file for details.

Created & maintained by Ahmed Sabry Hagrs

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-11

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固