helis/settings-manager-bundle

提供了一种优雅的方式来定义变量并将它们注入到应用的不同部分

安装次数: 51,728

依赖者: 0

建议者: 0

安全: 0

星标: 27

关注者: 5

分支: 16

开放问题: 7

类型:symfony-bundle

4.1.0 2024-09-16 06:45 UTC

README

提供了一种优雅的方式来定义变量并将它们注入到应用的不同部分。

  • 支持 boolstringintfloatarray 作为设置值。
  • 多个提供者。
  • 用户界面。

Latest Stable Version License

跳转到

快速入门

  1. composer require helis/settings-manager-bundle

  2. 将包注册到 AppKernel.php(Symfony3)或 config/bundles.php(Symfony4)

<?php

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        return [
            new Helis\SettingsManagerBundle\HelisSettingsManagerBundle(),
        ];
    }
}
  1. 将示例配置添加到 app/config/config.yml(Symfony3)或 config/packages/settings_manager.yaml(Symfony4)
helis_settings_manager:
    settings:
        - name: foo
          description: 'foo desc'
          type: bool
          data: false
          tags:
              - 'super_switch'

        - name: baz
          description: 'master toggle for awesome new feature'
          type: string
          data: fish
          tags:
              - 'experimental'
              - 'poo'
  1. 现在,获取服务中设置的最容易的方式是通过使用 SettingsRouterAwareTrait。服务将被自动注入,通过 自动注入。然后只需请求设置
use Helis\SettingsManagerBundle\Settings\Traits\SettingsRouterAwareTrait;

class MuchAmazingService
{
    use SettingsRouterAwareTrait;

    public function doSmth()
    {
        if ($this->settingsRouter->getBool('foo')) {
            // do it
        }

        // just do it
    }
}

使用方法

要将设置放入您的服务中,您有几个选择

SettingsRouter

SettingsRouter 非常直接。它有一个主要方法,称为 $settingsRouter->get($settingName, $default = null),它返回任何类型的设置。如果设置不存在,则返回默认值。其他获取器是 get 的别名,但具有声明返回类型和适当的默认值。

缺失时抛出异常

在某些情况下,如果设置未找到,则抛出异常可能是期望的行为。为此,SettingsRoutermustGet($settingName)mustGet...($settingName) 对于每个别名获取器。

服务标签

如果您不想注入 SettingsRouter 或希望有一个更干净的服务,服务标签可以帮到您。首先,服务必须有一个设置器,可以用来注入设置值。对于布尔值,该包提供了 SwitchableTrait,它添加了 setEnabledisEnabled 方法。然后添加带有 setting(设置名称)和 method(方法名称)属性的标签。示例

AppBundle\Service\AmazingService:
    tags:
        - { name: settings_manager.setting_aware, setting: foo, method: setEnabled }

must 版本

AppBundle\Service\AmazingService:
    tags:
        - { name: settings_manager.setting_aware, setting: foo, method: setEnabled, must: true }

模型

Helis\SettingsManagerBundle\Model\SettingModel

基本设置模型。

Helis\SettingsManagerBundle\Model\DomainModel

域类似于设置组。设置不能在没有域的情况下存在。默认值为 default,它总是启用的。域只能包含一个具有相同名称的设置。具有相同名称的设置必须在不同的域中。当请求设置时,将返回优先级更高的域中的设置。

Helis\SettingsManagerBundle\Model\Type

枚举,包含设置支持的类型。值

  • STRING
  • BOOL
  • INT
  • FLOAT
  • YAML
  • CHOICE

设置提供者

设置可以从多个来源获取。目前,该包包含 4 个设置提供者。它们可以配置和排序。如果具有相同名称的设置来自 >1 个提供者,则来自优先级更高的提供者的设置将覆盖来自较低优先级提供者的设置

可以使用 用户界面 轻松地更改提供者中的设置。

设置提供者

以及额外的装饰提供者

简单设置提供者

Helis\SettingsManagerBundle\Provider\SimpleSettingsProvider

这是一个仅持有设置集合的提供者。目前,它被用于存储来自配置的设置,但可以配置更多。

为了配置额外的简单提供者,提供了一个工厂,因为提供者只能接受已去规范化对象。

配置示例

setting_provider_factory.foo:
    class: Helis\SettingsManagerBundle\Provider\Factory\SimpleSettingsProviderFactory
    arguments:
        $serializer: '@settings_manager.serializer'
        $normalizedData:
            -
                - name: foo
                  description: 'foo desc'
                  type: bool
                  domain: { name: default } 
                  data: { value: false }
                  tags: [{ name: 'super_switch' }]
    tags:
        - { name: settings_manager.provider_factory, provider: foo, priority: 10 }

DoctrineORM 设置提供者

Helis\SettingsManagerBundle\Provider\DoctrineOrmSettingsProvider

这是一个通过使用 EntityManagerInterface 读取和保存设置的提供者。

必需的库

composer require doctrine/orm

配置示例

  1. Doctrine 配置
# Symfony3, app/config/config.yml
# Symfony4, config/packages/doctrine.yaml
doctrine:
    orm:
        mappings:
            HelisSettingsManagerBundle:
                type: xml
                is_bundle: true
                dir: "Resources/config/doctrine"
                alias: HelisSettingsManagerBundle
                prefix: Helis\SettingsManagerBundle
  1. 创建设置实体
<?php
declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Helis\SettingsManagerBundle\Model\SettingModel;

#[ORM\Entity()]
#[ORM\Table(name: "setting")]
class Setting extends SettingModel
{     
     #[ORM\Id]
     #[ORM\GeneratedValue]
     #[ORM\Column(type: "integer")]
    protected int $id;
}
  1. 更新您的 doctrine 模式。

  2. 注册设置提供者

Helis\SettingsManagerBundle\Provider\DoctrineOrmSettingsProvider:
    arguments:
        $entityManager: '@doctrine.orm.default_entity_manager'
        $settingsEntityClass: 'App\Entity\Setting'
    tags:
        - { name: settings_manager.provider, provider: orm, priority: 20 }

Paseto Cookie 设置提供者

Helis\SettingsManagerBundle\Provider\PasetoCookieSettingsProvider

这是一个通过使用 cookie 启用现有设置的提供者。Cookie 已编码,因此用户无法随机启用。

必需的库

composer require paragonie/paseto

Paseto 用于加密 cookie。

配置示例

Helis\SettingsManagerBundle\Provider\PasetoCookieSettingsProvider:
    arguments:
        $serializer: '@settings_manager.serializer'
    tags:
        - { name: settings_manager.provider, provider: cookie, priority: 30 }
        - { name: kernel.event_subscriber }

非对称 Paseto Cookie 设置提供者

Helis\SettingsManagerBundle\Provider\AsymmetricPasetoCookieSettingsProvider

这是一个通过使用 cookie 启用现有设置的提供者。Cookie 使用非对称私钥和公钥进行编码,因此用户无法随机启用。

必需的库

composer require paragonie/paseto

Paseto 用于加密 cookie。

配置示例

Helis\SettingsManagerBundle\Provider\AsymmetricPasetoCookieSettingsProvider:
    arguments:
        $serializer: '@settings_manager.serializer'
    tags:
        - { name: settings_manager.provider, provider: asymmetric_cookie, priority: 40 }
        - { name: kernel.event_subscriber }

JWT Cookie 设置提供者

Helis\SettingsManagerBundle\Provider\JwtCookieSettingsProvider

这是一个通过使用 cookie 启用现有设置的提供者。Cookie 使用非对称私钥和公钥进行编码,因此用户无法随机启用。

必需的库

composer require lcobucci/jwt

JWT 用于加密 cookie。

配置示例

Helis\SettingsManagerBundle\Provider\JwtCookieSettingsProvider:
    arguments:
        $serializer: '@settings_manager.serializer'
        $publicKey: 'file://%kernel.project_dir%/config/keys/settings_cookie_public.key'
        $privateKey: 'file://%kernel.project_dir%/config/keys/settings_cookie_private.key'
    tags:
        - { name: settings_manager.provider, provider: jwt_cookie, priority: 50 }
        - { name: kernel.event_subscriber }

AWS SSM 设置提供者

Helis\SettingsManagerBundle\Provider\AwsSsmSettingsProvider

这是一个仅用于读取和更新现有 ssm 参数作为设置的提供者。

必需的库

composer require aws/aws-sdk-php

配置示例

Helis\SettingsManagerBundle\Provider\AwsSsmSettingsProvider:
    arguments:
        - '@Aws\Ssm\SsmClient'
        - '@settings_manager.serializer'
        - ['amazing_parameter_name']
    tags:
        - { name: settings_manager.provider, provider: aws_ssm }

Phpredis 装饰设置提供者

Helis\SettingsManagerBundle\Provider\DecoratingRedisSettingsProvider

此提供者用于缓存其他设置提供者,如 DoctrineORMAWS SSM。它使用 Redis 客户端,而不是 doctrine/cache 提供者symfony/cache 适配器,因为我们想利用 Redis 数据结构以简化无效化过程。

必需的扩展

pecl install redis-5.3.7

配置示例

Helis\SettingsManagerBundle\Provider\DecoratingRedisSettingsProvider:
    decorates: 'Helis\SettingsManagerBundle\Provider\DoctrineOrmSettingsProvider'
    arguments:
        $decoratingProvider: 'Helis\SettingsManagerBundle\Provider\DecoratingRedisSettingsProvider.inner'
        $redis: '@settings.cache.redis' # you need to register your own \Redis client in container
        $serializer: '@settings_manager.serializer'

Predis 装饰设置提供者

Helis\SettingsManagerBundle\Provider\DecoratingPredisSettingsProvider

phpredis 装饰设置提供者 相同。它只是用 predis 替换了 phpredis 扩展。

必需的库

composer require predis/predis

缓存装饰提供者

Helis\SettingsManagerBundle\Provider\DecoratingCacheSettingsProvider

此提供者用于缓存实现了 ModificationAwareSettingsProviderInterface 的其他设置提供者。目前支持 phpredis 装饰设置提供者predis 装饰设置提供者。它使用 Symfony PHP 文件缓存适配器。装饰提供者的任何更改都会使整个缓存失效。支持 symfony 缓存组件适配器

必需的库和扩展

composer require symfony/cache symfony/lock

配置示例

settings_manager.decorating_provider.cache:
    class: 'Helis\SettingsManagerBundle\Provider\DecoratingCacheSettingsProvider'
    decorates: 'Helis\SettingsManagerBundle\Provider\DecoratingRedisSettingsProvider'
    arguments:
        $decoratingProvider: '@settings_manager.decorating_provider.cache.inner'
        $serializer: '@settings_manager.serializer'
        $cache: '@cache.settings'
        $lockFactory: '@symfony_flock_factory'

设置提供者模拟

这是一个专门用于测试的特定提供者。当需要模拟 mustGet... 调用时很有用。

配置示例

    settings_manager.provider.mock:
        class: Helis\SettingsManagerBundle\Test\Provider\SettingsProviderMock
        tags:
            - { name: settings_manager.provider, provider: mock, priority: 9999 }

模拟

    ...

    use SettingsIntegrationTrait;

    protected function setUp()
    {
        parent::setUp();

        SettingsProviderMock::addSetting(
            (new SettingModel())
                ->setName('awesome_setting')
                ->setDomain(
                    (new DomainModel())
                        ->setName('some_domain')
                        ->setEnabled(true)
                )
        );
    }

    ...

配置参考

helis_settings_manager:
    settings:
        -
            name: foo
            description: 'foo desc'
            domain: default # Used for grouping settings.
            type: bool
            data: false
            tags: [super_switch]
    settings_router:
        treat_as_default_providers: ['config']
    profiler:
        enabled: false
    logger:
        enabled: false
        service_id: null # Psr\Log\LoggerInterface service id
    settings_files:
        # - '%kernel.root_dir%/config/extra_settings.yml'

用户界面

用户界面可以用来更改设置值,启用或禁用域名。

  1. 捆绑用户界面需要 knp-menu-bundlejsrouting-bundle

    composer require symfony/form symfony/validator symfony/translation symfony/twig-bundle symfony/asset knplabs/knp-menu-bundle friendsofsymfony/jsrouting-bundle

  2. 包含路由文件。

# <=Symfony3, app/config/routing.yml 
# >=Symfony4, config/routes/settings_manager.yaml

settings_manager:
    resource: '@HelisSettingsManagerBundle/Resources/config/routing.yaml'
    prefix: /settings

这样就完成了。现在前往 /settings 路径,您将看到设置用户界面。

Twig

还添加了Twig扩展以在您的twig模板中获取设置。就像在 SettingsRouter 中一样,第一个参数是设置名称,第二个设置默认值。

{{ setting_get('foo', false) }}

控制器

Helis\SettingsManagerBundle\Controller\Traits\SettingsControllerTrait

添加了一个方法,除非设置启用,否则拒绝访问。它使用 SettingsRouter,再次,这将通过 自动装配 注入。

public function indexAction(): Response
{
    $this->denyUnlessEnabled('index_page');
    ...
}

贡献

应该从主分支创建新功能分支。