dive-be/laravel-feature-flags

此包已弃用且不再维护。没有建议的替代包。

在您的 Laravel 应用中处理功能标志

1.1 2022-02-11 16:15 UTC

This package is auto-updated.

Last update: 2023-02-04 14:42:36 UTC


README

请使用更好的替代方案

此包解决了什么问题?

"功能标志是一种软件开发流程,用于在不部署代码的情况下远程启用或禁用功能。新功能可以部署而不使其对用户可见。功能标志有助于解耦部署和发布,让您管理功能的整个生命周期。"(来源:https://launchdarkly.com/blog/what-are-feature-flags)

安装

您可以通过 composer 安装此包

composer require dive-be/laravel-feature-flags

一旦 composer 完成,您必须发布配置和迁移

php artisan feature:install

这是已发布配置文件的內容

return [

    /**
     * The name of the cache key that will be used to cache your app's features.
     */
    'cache_key' => 'feature_flags',

    /**
     * The feature model that will be used to retrieve your app's features.
     */
    'feature_model' => Dive\FeatureFlags\Models\Feature::class,
];

如果您不需要多语言支持,您现在就可以开始了。

多语言支持

此包使用 Spatie 的优秀 Laravel 可翻译包 提供一流的多语言支持。

composer require spatie/laravel-translatable

接下来,转到配置文件并将 feature_model 更改为

Dive\FeatureFlags\Models\TranslatableFeature::class

最后,找到迁移并取消注释注释,并删除其前面的所有内容。它应该如下所示

// ...
$table->json('message')->nullable();
$table->timestamp('disabled_at')->nullable();
// ...

使用方法

有关您可用的完整列表,请参阅 功能合约 以获取详尽列表。

设置您的应用初始功能

可以在常规 Laravel 种子中进行(初始)功能的播种。

php artisan make:seeder FeaturesTableSeeder

以下是一个示例

use Dive\FeatureFlags\Models\Feature;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class FeaturesTableSeeder extends Seeder
{
    public function run()
    {
        DB::table('features')->upsert([
            [
                'description' => 'Registrations that come through our partnerships',
                'label' => 'Public registrations',
                'message' => 'The registration period has ended. Thanks for participating in our programme.',
                'name' => 'registrations',
                'scope' => Feature::getDefaultScope(),
            ],
            [
                'description' => 'Display the App version on the homepage',
                'label' => 'Application version',
                'message' => 'Version is hidden',
                'name' => 'version',
                'scope' => Feature::getDefaultScope(),
            ],
        ], ['scope', 'name'], ['description', 'label', 'message']);
    }
}

解析管理器

此包提供了从 IoC 容器中解析 Feature 实例的每一种可能方式。我们为您做好了准备!

外观

use Dive\FeatureFlags\Facades\Feature;

Feature::find('dashboard');

或者使用别名(特别有助于 Blade 视图)

use Feature;

Feature::disabled('dashboard');

辅助函数

feature('dashboard');
feature_disabled('dashboard');
feature_enabled('dashboard');
feature_verify('dashboard');

依赖注入

use Dive\FeatureFlags\Contracts\Feature;

public function index(Feature $feature)
{
    $feature->verify('dashboard');

    return view('layouts.dashboard');
}

服务定位

app('feature')->find('dashboard');

范围

此包允许您定义一个自定义范围,并将其与功能(不要与 Laravel 的全局范围混淆)一起使用。特别适用于您需要为应用程序的不同部分使用相同名称时。此包的大部分函数和方法都接受一个额外的 $scope 参数。

请参阅功能合约以获取完整列表。

更改默认通配符作用域

如果您希望使用除默认的星号(*)以外的不同作用域来创建和检查/验证功能,您可以在AppServiceProviderboot方法中更改此设置。

use Dive\FeatureFlags\Models\Feature;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Feature::setDefaultScope('my-wonderful-app');
    }
}

种子

有关如何设置功能的作用域,请参阅上面的种子部分

Blade指令 🗡

@disabled

您可以使用@disabled指令根据功能的当前状态有条件地在视图中显示内容。使用此指令首先将使功能的message属性自动成为块内作用域变量。示例

@disabled('registrations')
    <div class="alert warning">
        {{ $message }} <!-- Automatically injected -->
    </div>
@enabled
    <div class="alert info">
        Welcome to our public registrations.
    </div>
@enddisabled

@enabled

您还可以使用@enabled指令执行与上面相同的事情。但是,使用此指令首先时,$message变量将不可用@disabled块内。

@enabled('registrations')
    <div class="alert info">text</div>
@disabled
    <div>$message is not available here</div>
@endenabled

@can(not)

此包还注册了自己在Laravel的Gate上。访客不需要认证即可使用它。

@can('feature', 'dashboard')
    <a href="/dashboard" target="_blank">View Dashboard</a>
@else
    <small>Dashboard is currently disabled</small>
@endcan

保护应用程序的部分 💂🏼

有多种方法可以防止用户访问应用程序中禁用的部分。

如果功能未启用,将抛出FeatureDisabledException

路由中间件

Route::get('registrations', [RegistrationsController::class, 'index'])->middleware('feature:registrations');

使用 'verify' 手动检查

控制器示例

假设您典型的控制器

class RegistrationsController extends Controller
{
    public function __construct(Feature $feature)
    {
        $feature->verify('registrations');
    }
    
    public function index()
    {
        return view('registrations.index');
    }
}

Livewire示例

这在无法真正使用路由中间件的环境中特别有用,例如Livewire操作

use Dive\FeatureFlags\Facades\Feature;
use Dive\Wishlist\Facades\Wishlist;

class HeartButton extends Component
{
    public function add($id)
    {
        Feature::verify('wishlist');
        
        Wishlist::add($id);
    }

    public function render()
    {
        return view('livewire.heart-button');
    }
}

PS:别忘了检查我们的愿望单包哦😉

访问门

此包还注册了自己在Laravel的Gate上,提供您通过它们检查功能状态的能力。这意味着您可以执行如下操作

Route::get(...)->middleware('can:feature,dashboard');
Gate::authorize('feature', 'dashboard');

然而,有一个关键的区别。Laravel的Gate将抛出AccessDeniedHttpException,而包自身的检查将抛出FeatureDisabledException(它扩展了前者异常类)。因此,如果您需要知道异常的类型,强烈建议您不要使用门。

Artisan命令 🧑‍🎨

切换功能的开关

由于功能是通过Feature Eloquent模型管理的,因此您当然可以使用像Laravel Nova这样的解决方案来完成此操作。

然而,在本地开发时,您可能希望轻松地打开/关闭某个功能。您可以使用以下命令来完成此操作

php artisan feature:toggle {name} {scope?}

显示所有功能的列表

使用以下命令显示所有功能和它们对应状态的表格

php artisan feature:list

可用选项:compactdisabledenabledscope

清除缓存

功能被永久缓存以加快后续检查。如果您不使用Eloquent来更新或修改记录,您必须手动重置缓存

php artisan feature:clear

注意:通过Eloquent创建/更新功能时,缓存清除会自动为您完成。

测试

composer test

变更日志

请参阅CHANGELOG以获取有关最近更改的更多信息。

贡献

请参阅CONTRIBUTING以获取详细信息。

安全

如果您发现任何安全相关的问题,请通过电子邮件oss@dive.be联系,而不是使用问题跟踪器。

鸣谢

许可

MIT 许可证(MIT)。请参阅许可文件以获取更多信息。