zitec/rule-engine-bundle

安装: 5

依赖项: 0

建议者: 0

安全性: 0

星标: 2

关注者: 2

分支: 1

开放性问题: 0

类型:symfony-bundle

1.0.0 2017-07-07 13:55 UTC

This package is not auto-updated.

Last update: 2024-09-15 02:52:15 UTC


README

规则引擎是一个symfony包,允许您使用自定义参数和评估器构建复杂的条件集,以匹配您的对象和需求。它提供了一个友好的前端界面,并且可以简单集成Doctrine实体及其相应的Sonata管理员。有一个演示网站吗?

安装

您可以通过composer安装它。

 { 
   "require":{
       "zitec/rule-engine-bundle": "~1.0"
    }
  }  

用法

如何使用

上下文对象

编写一个实现RuleContextInterface的类,并添加一些方法,这些方法将返回您希望在规则中包含的参数。为了使事情更加简单,已经存在一个基本上下文类:ContextBase。它已经为current_date、current_day和current_time这三个参数提供了getter。您的自定义上下文可以扩展这个。

namespace MyBundle/RuleEngine/Context;

use Zitec/RuleEngineBundle/Service/ContextBase;

class MyFirstContext extends ContextBase
 {
    protected $dataSource;
 
    // Using a custom name will help you identify the context in built expressions.
    public function getContextObjectKey(): string
    {
        return 'my-name';
    }
    
    // The context will need a data source to read from. We will set the data source when we evaluate the expression.
    public function setMyDataSource($dataSource)
    {
        $this->dataSource = $dataSource;
    }
    
    // Added a parameter.
    public function getMyParameter(): string
    {
        return $this->dataSource->getTheData();
    }
 }

条件

对于上下文对象中的每个参数(方法),创建一个Condition对象。支持ContextBase类中的三个日期时间参数的条件服务已经在规则引擎包中定义。我们将在新的包中为新增的参数(my_parameter)添加另一个。我们可以从头开始编写条件,但扩展两个提供对单值和数组参数基本运算符支持的两个Abstract条件类会更简单。如果“my_parameter”实际上是一个数组,我们可以这样做

namespace MyBundle/RuleEngine/Conditions;

use Zitec/RuleEngineBundle/Conditions/AbstractArrayCondition;

class MyParameter extends AbstractArrayCondition
{
    // When we ask the context object for the method for this condition name, 
    // it should respond with getMyCondition, since the ContextBase does simple snake_case to getCamelCase.
    protected $name = 'my_parameter';
    // This is the name the users will see in admin pages.
    protected $label = 'My Parameter';
    // A help text displayed in the condition builder if the user selects this parameter.
    protected $description = 'Set conditions for my parameter';
    
    // Here is where we decide on the operators that will be available for this parameter.
    protected function getOperatorDefinitions(): array
    {
        $options = [
            ['key' => 'one', 'label' => 'Option one'],
            ['key' => 'two', 'label' => 'Option two'],
        ];
        
        // Details about the operator definition structure can be found in the Operator definition section.
        return [
            [
                'label'     => 'match ANY of the following',
                'name'      => $this::INTERSECTING,
                'fieldType' => 'select',
                'fieldOptions' => [
                    'multiple'  => true,
                    'options'   => $options,
                ],
            ],
            [
                'label'     => 'match NONE of the following',
                'name'      => $this::DISJOINT,
                // Details about the autocomplete feature in the Autocomplete section of this readme.
                'fieldType' => 'autocomplete',
                'fieldOptions' => [
                    'autocomplete' => 'my_autocomplete_key',
                ],
            ],
        ];
    
    }
}

规则管理器服务

现在我们有了上下文对象和匹配的定义,让我们使用RuleConditionsManager创建一个服务。我们需要将您的上下文对象作为参数传递,并将条件作为‘addSupportedCondition’调用。由于我们扩展了ContextBase类,我们可以使用规则引擎定义的日期时间条件。以下是使用上述类定义的服务的示例。

my_bundle.rule_engine.context.my_first_context:
    class: MyBundle\RuleEngine\Context\MyFirstContext
    shared: false

my_bundle.rule_engine.condition.my_parameter:
    class: MyBundle\RuleEngine\Conditions\MyParameter
    public: false
    
my_bundle.rule_engine.manager.my_object:
    class: Zitec\RuleEngineBundle\Service\RuleConditionsManager
    arguments: ['@my_bundle.rule_engine.context.my_first_context']
    calls:
        - [addSupportedCondition, ["@rule_engine.condition.current_date"]]
        - [addSupportedCondition, ["@rule_engine.condition.current_day"]]
        - [addSupportedCondition, ["@rule_engine.condition.current_time"]]
        - [addSupportedCondition, ["@my_bundle.rule_engine.condition.my_parameter"]]

表单构建

现在我们需要使用上下文和条件来渲染前端条件构建器。这可以通过向表单添加RuleEngineType表单类型并在字段选项中将规则管理器服务设置为'rule_manager'键来完成。

但在大多数情况下,您想要与规则关联的操作可能需要自己的数据。例如,我们可能决定根据我们的对象中的参数向不同的地址发送电子邮件。在这种情况下,我们可以定义一个包含电子邮件字段的doctrine实体来定义地址,并将其设置为规则实体。这样做很简单:只需在您的类中添加"implements RuleInterface",并添加"use RuleTrait"语句来实际实现接口。

class EmailAddress implements RuleInterface
{
    use RuleTrait;
    
    // Your entity's properties and getters/setters follow. 
}

更新doctrine模式并注意与Rule实体的新关系,该实体将保存EmailAddress实体的表达式。

您的规则集成实体需要与一个上下文和条件集关联,即规则条件管理器。为此,您必须向条件管理器服务声明中添加一个标签。上述服务变为

my_bundle.rule_engine.manager.my_object:
    class: Zitec\RuleEngineBundle\Service\RuleConditionsManager
    arguments: ['@my_bundle.rule_engine.context.my_first_context']
    calls:
        - [addSupportedCondition, ["@rule_engine.condition.current_date"]]
        - [addSupportedCondition, ["@rule_engine.condition.current_day"]]
        - [addSupportedCondition, ["@rule_engine.condition.current_time"]]
        - [addSupportedCondition, ["@my_bundle.rule_engine.condition.my_parameter"]]
    tags:
        - { name: rule_engine.conditions_manager, entity: "MyBundle:EmailAddress" }

接下来是管理部分。

我将假设您正在使用SonataAdmin来管理您的doctrine实体。如果是这样,这是您需要做的事情

在Admin类中,添加一个"use RuleAdminTrait"语句,并使用相关方法

class EmailAddressAdmin extends AbstractAdmin
{
    use RuleAdminTrait;

    protected function configureFormFields(FormMapper $formMapper)
    {
        // Add the rule admin, using the method from the trait:
        $this->addRuleFormElement($formMapper);
        // Add the rest of your fields.
    }

    protected function configureListFields(ListMapper $list)
    {
        // Add the columns from the rule entity. On dev environments, the generated espression will also be visible.
        $this->addRuleListColumns($list);
        // Add the rest of your columns and actions.
    }

恭喜!您现在可以看到了它的实际效果,并可以使用复杂的规则设置各种地址!

规则评估

在您的业务流程的某个地方,您将需要提取与您的对象匹配的电子邮件地址(们)。为此的代码将使用RuleEvaluator服务,可能看起来像这样

use Doctrine\ORM\EntityRepository;
use MyBundle\RuleEngine\Context\MyFirstContext;
use Zitec\RuleEngineBundle\Service\RuleEvaluator;

class RecipientChooserService
{
    /**
     * The entity repository for your EmailAddress entity
     * @var EntityRepository
     */
    protected $emailAddressRepository;

    /**
     * @var RuleEvaluator
     */
    protected $evaluator;

    /**
     * @var MyFirstContext
     */
    protected $context;

    public function __construct(
        EntityRepository $emailAddressRepository,
        RuleEvaluator $evaluator,
        MyFirstContext $context
    ) {
        $this->emailAddressRepository = $emailAddressRepository;
        $this->evaluator = $evaluator;
        $this->context = $context;
    }

    public function getRecipientAddresses($myDataSource)
    {
        // Load and filter email addresses.
        $this->context->setMyDataSource($myDataSource);
        /** @var EmailAddress[] $emailAddresses */
        $emailAddresses = $this->emailAddressRepository->findAll();

        // Determine the applicable addresses.
        $recipients = [];
        foreach ($emailAddresses as $entity) {
            if ($this->evaluator->evaluate($entity->getRule(), $this->context)) {
                $recipients[] = $entity->getEmail();
            }
        }

        return $recipients;
    }
}

就这样!完成了!

其他文档

运算符定义

操作符是一个具有以下键的数组

  • name(必填):机器名称,用于在条件中识别选定的操作符
  • label(必填):用户在管理页面中看到的文本
  • fieldType(必填):请参见下面的可能值
  • fieldOptions(可选):请参见以下详情
  • value_transform(可选):应用于从规则构建器接收的值并在生成表达式之前的回调
  • value_view_transform(可选):应用于从规则构建器接收的值并在生成规则管理视图之前的回调

字段类型和选项

  • text:基本文本输入,适用于具有自由格式值的单值参数。
  • datetime:日期选择器输入;将您的日期选择器选项添加到fieldOptions数组中的datetimepicker键。
  • interval:基本间隔定义,具有用于“从”和“到”值的文本输入。
  • datetime_interval:结合上述两种类型,就有了带有日期选择器的间隔。
  • select:一个增强的select2选择框;您可以在MyParameter条件声明中看到一个实现。
  • autocomplete:一个使用RuleEngine自动完成功能的自动完成的select2输入。

自动完成支持

为了使用自动完成字段,您需要通过实现Zitec\RuleEngineBundle\Autocomplete\AutocompleteInterface来定义一个数据源。如果您想对Doctrine实体进行自动完成,可以扩展AbstractAutocompleteEntity类

use MyBundle\Entity\MyEntity;
use Zitec\RuleEngineBundle\Autocomplete\AbstractAutocompleteEntity;

class MyEntityAutocomplete extends AbstractAutocompleteEntity
{
    protected function getEntityClass(): string
    {
        return MyEntity::class;
    }

    protected function getIdField(): string
    {
        return 'id'; // This will be the value used in the built expression
    }

    protected function getTextField(): string
    {
        return 'name'; // This will be the value displayed to the user.
    }
}

并使用“rule_engine.autocomplete.data_source”标签声明服务

my_bundle.rule_engine.autocomplete.my_autocomplete:
    class: MyBundle\RuleEngine\Autocomplete\MyEntityAutocomplete
    arguments: ["@doctrine.orm.default_entity_manager"]
    tags:
        - { name: rule_engine.autocomplete.data_source, key: my_autocomplete_key }

键的值是您必须在自动完成类型中用于fieldOptions的值。

别忘了将路由信息添加到您应用的routing.yml文件中

rule_engine:
    resource: "@ZitecRuleEngineBundle/Resources/config/routing.yml"
    prefix:   /