92. 条件插件condition plugins

条件插件在块实体配置中被用到(在默认安装下,系统也只有该处用到),用来指定块在什么条件下才显示,见管理后台:管理》结构》区块布局》点击某个块的配置,每一种类型的条件由一个插件负责,这些插件由条件插件管理器来管理:

服务idplugin.manager.condition

类:Drupal\Core\Condition\ConditionManager

获取方式:\Drupal::service('plugin.manager.condition');

插件定义的修改钩子:condition_info

插件存放目录:src/Plugin/Condition

释文类:\Drupal\Core\Condition\Annotation\Condition

 

系统默认提供了5个条件插件:

语言条件:

控制在某种语言界面下,是否满足需求,类如下:

Drupal\language\Plugin\Condition\Language

 

内容类型条件:

控制是在哪些内容类型下条件是否满足,类如下:

\Drupal\node\Plugin\Condition\NodeType

 

页面条件:

依据路径判断是否满足条件,类如下:

\Drupal\system\Plugin\Condition\RequestPath

 

角色条件:

依据角色判断是否满足条件,类如下:

\Drupal\user\Plugin\Condition\UserRole

 

当前主题条件:

只在当前主题下才满足条件,类如下:

\Drupal\system\Plugin\Condition\CurrentThemeCondition

 

自定义条件插件:

在模块的src/Plugin/Condition目录下定义一个类,实现以下接口:

\Drupal\Core\Condition\ConditionInterface

系统很贴心的提供了条件插件的默认基类:

\Drupal\Core\Condition\ConditionPluginBase

只需要继承她即可,清除缓存启用

可参见系统定义的插件示例,以下提供了一个自定义的示例。

 

自定义示例:

这里提供一个示例,用于在指定的星期才显示块,没有指定的那一天不显示,如果没有配置,将视为显示,这里假设模块名为“yunke”,在目录yunke/src/Plugin/Condition建立一个类,文件名:Week.php,内容如下:

<?php

namespace Drupal\yunke\Plugin\Condition;

use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * 提供一个星期条件
 *
 * @Condition(
 *   id = "week",
 *   label = @Translation("week"),
 * )
 */
class Week extends ConditionPluginBase
{

    /**
     * {@inheritdoc}
     */
    public function buildConfigurationForm(array $form, FormStateInterface $form_state)
    {
        $options = [
            1 => 'Monday',
            2 => 'Tuesday',
            3 => 'Wednesday',
            4 => 'Thursday',
            5 => 'Friday',
            6 => 'Saturday',
            0 => 'Sunday',
        ];
        $form['week'] = [
            '#type'          => 'checkboxes',
            '#title'         => '在以下时间显示',
            '#default_value' => $this->configuration['week'],
            '#options'       => $options,
            '#description'   => '如果没有选择,相当于全部选中',
        ];
        return parent::buildConfigurationForm($form, $form_state);
    }

    /**
     * {@inheritdoc}
     */
    public function defaultConfiguration()
    {
        return [
                'week' => [],
            ] + parent::defaultConfiguration();
    }

    /**
     * {@inheritdoc}
     */
    public function submitConfigurationForm(array &$form, FormStateInterface $form_state)
    {
        $this->configuration['week'] = array_filter($form_state->getValue('week'));
        parent::submitConfigurationForm($form, $form_state);
    }

    /**
     * {@inheritdoc}
     */
    public function summary()
    {
        $days = $this->configuration['week'];
        if (count($days) > 1) {
            $days = implode(', ', $days);
        } else {
            $days = reset($days);
        }
        if (!empty($this->configuration['negate'])) {
            return $this->t('在星期 @week 将不显示', ['@week' => $days]);
        } else {
            return $this->t('在星期 @week 显示', ['@week' => $days]);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function evaluate()
    {
        $week=date("w");
        if (empty($this->configuration['week']) && !$this->isNegated()) {
            return TRUE;
        }
        return in_array($week, $this->configuration['week']);
    }

    /**
     * {@inheritdoc}
     */
    public function getCacheContexts()
    {
        $contexts = parent::getCacheContexts();
        $contexts[]='week';
        //此处应定义一个关于星期的上下文,以便让缓存正常工作
        return $contexts;
    }

}

该类需要一个自定义的上下文,在目录yunke\src\CacheContext建立类:

文件名:WeekCacheContext.php 内容如下:

<?php

namespace Drupal\yunke\CacheContext;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\Context\CacheContextInterface;

/**
 * 定义一个星期缓存上下文
 *
 * 上下文 ID: 'week'.
 */
class WeekCacheContext implements CacheContextInterface {
    
  /**
   * {@inheritdoc}
   */
  public static function getLabel() {
    return t('Week');
  }

  /**
   * {@inheritdoc}
   */
  public function getContext() {
    return date("w");
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata() {
    return new CacheableMetadata();
  }

}

然后在服务定义文件:yunke/yunke.services.yml中添加以下内容:

  cache_context.week:
    class: \Drupal\yunke\CacheContext\WeekCacheContext
    tags:
      - { name: cache.context }

清除缓存,然后到块配置页面就能看到我们自定义的条件了

 

条件解析特征:

系统提供了一个条件解析特征:

\Drupal\Core\Condition\ConditionAccessResolverTrait

这被用来判断有多个条件时,最终条件是否能够满足,只有一个方法:

resolveConditions($conditions, $condition_logic)

参数$conditions是由条件插件对象构成的数组,$condition_logic代表级联条件的关键词,andor之一,

该方法返回一个布尔值,代表条件是否得到满足,true为所有条件满足。

 

补充:

条件插件的上下文映射数组来自:

\Drupal\Core\Condition\ConditionPluginBase::buildConfigurationForm

在表单内部以值类型被保存

 

 

 

本书共97小节:

评论 (写第一个评论)