access_policy-1.0.x-dev/src/Plugin/access_policy/AccessRule/AccessRuleBase.php
src/Plugin/access_policy/AccessRule/AccessRuleBase.php
<?php namespace Drupal\access_policy\Plugin\access_policy\AccessRule; use Drupal\access_policy\Plugin\access_policy\AccessPolicyHandlerInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\PluginBase; use Drupal\Core\Session\AccountInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Class AccessRuleBase. * * This abstract class provides the generic access rule configuration form and * validation. */ abstract class AccessRuleBase extends PluginBase implements AccessRulePluginInterface, AccessPolicyHandlerInterface { use AccessRulePluginTrait { buildSettingsForm as traitBuildSettingsForm; } /** * The actual values that will be compared against. * * @var mixed */ protected $value = NULL; /** * Contains the operator which is used for validation. * * @var string */ protected $operator = '='; /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->configuration = $configuration; $settings = $configuration['settings'] ?? []; $this->setSettings($settings); } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, ); } /** * {@inheritdoc} */ abstract public function isApplicable(EntityInterface $entity); /** * {@inheritdoc} */ abstract public function validate(EntityInterface $entity, AccountInterface $account); /** * {@inheritdoc} */ public function getCacheContexts() { return ['user.permissions']; } /** * {@inheritdoc} */ public function buildSettingsForm(array $form, FormStateInterface $form_state) { $form = $this->traitBuildSettingsForm($form, $form_state); return $form; } /** * {@inheritdoc} */ public function accessRuleForm(array $form, FormStateInterface $form_state) { if ($this->showOperator()) { $this->operatorForm($form, $form_state); } if ($this->showArgumentForm()) { $this->argumentValueForm($form, $form_state); } else { $this->valueForm($form, $form_state); $this->hideValueFormWithStates($form, $form_state); } return $form; } /** * Optionally hide the value form with states as defined by the operators. * * Depending on which operator is chosen, you may not want to show the value * form. * * @param array $form * The current form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state. */ protected function hideValueFormWithStates(array &$form, FormStateInterface $form_state) { $hide_value = FALSE; foreach ($this->operators() as $operator) { if (!empty($operator['hide_value'])) { $hide_value = TRUE; break; } } if ($hide_value) { $fields = []; foreach ($this->operators() as $key => $operator) { if (!empty($operator['hide_value'])) { $fields[] = ['value' => $key]; } } $form['value']['#states'] = [ 'invisible' => [ 'select[name="operator"]' => $fields, ], ]; } } /** * Show the operator form if options exist. * * @param array $form * The form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. */ protected function operatorForm(array &$form, FormStateInterface $form_state) { $options = $this->getOperatorOptions(); if (!empty($options)) { $form['operator'] = [ '#type' => 'select', '#title' => $this->t('Operator'), '#options' => $this->getOperatorOptions(), '#default_value' => $this->getOperator(), ]; } } /** * Build the argument value form. * * @param array $form * The form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. */ protected function argumentValueForm(array &$form, FormStateInterface $form_state) { $form['value'] = [ '#tree' => TRUE, ]; $argument = $this->getArgument(); $argument_settings = $argument->valueForm([], $form_state); foreach ($argument_settings as $name => $element) { $form['value'][$name] = $element; } } /** * Build the value form. * * @param array $form * The form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. */ protected function valueForm(array &$form, FormStateInterface $form_state) { $form['value'] = []; } /** * Create array of operator options. * * @return array * Array of operators. */ public function getOperatorOptions() { $options = []; $operators = $this->operators(); foreach ($operators as $op => $item) { $options[$op] = $item['title']; } return $options; } /** * Array of operators. * * @return array * The array of operators. */ public function operators() { return []; } /** * {@inheritdoc} */ public function accessRuleFormValidate(array &$form, FormStateInterface $form_state) { } /** * {@inheritdoc} */ public function accessRuleFormSubmit(array &$form, FormStateInterface $form_state) { $this->operatorSubmit($form, $form_state); $this->valueSubmit($form, $form_state); $values = $form_state->getValues(); if (isset($values['operator'])) { $this->settings['operator'] = $values['operator']; } // Saving the settings from which we retrieve the value, not necessarily // the actual value. if (isset($values['value'])) { $this->settings['value'] = $values['value']; } } /** * Perform any changes to the submitted values. */ protected function operatorSubmit($form, FormStateInterface $form_state) { } /** * Perform any changes to the submitted values. */ protected function valueSubmit($form, FormStateInterface $form_state) { } /** * Return the actual value that is being validated against. * * This can be static values or computed values such as from a field. * * @return mixed * The current actual values. */ public function getValue() { if (!isset($this->value)) { if ($this->definition->getArgument()) { $this->value = $this->getArgument()->getValue(); } else { if (isset($this->settings['value'])) { $value = $this->settings['value']; if (!is_array($value)) { $value = [$value]; } $this->value = $value; } } } return $this->value; } /** * Set the computed value. * * @param mixed $value * The computed value. */ public function setValue($value) { $this->value = $value; } /** * Get the current operator. * * The operator can be set in multiple places, either in the data definition, * the settings or in the class itself. If the operator is set in the data * definition then it can't be changed. * * @return string * The current operator. */ public function getOperator() { if ($this->definition->getOperator()) { $this->operator = $this->definition->getOperator(); } elseif (isset($this->settings['operator'])) { $this->operator = $this->settings['operator']; } return $this->operator; } /** * Show the operator. * * If the operator is defined in the data definition then it can't be changed * and therefore should not be shown. * * @return bool * TRUE if the operator should be shown; FALSE otherwise. */ protected function showOperator() { if ($this->definition->getOperator()) { return FALSE; } return TRUE; } /** * Show the argument form instead of the value form. * * If the argument is defined in the data definition then we show that * form instead of the value form. * * @return bool * TRUE if the argument form should be shown; FALSE otherwise. */ protected function showArgumentForm() { if ($this->definition->getArgument()) { return TRUE; } return FALSE; } /** * {@inheritdoc} */ public function adminLabel() { if ($this->adminSummary() && empty($this->getDefinition()->getSetting('admin_label'))) { return $this->getDefinition()->getLabel() . ' (' . $this->adminSummary() . ')'; } return $this->getDefinition()->getLabel(); } /** * {@inheritdoc} */ public function adminSummary() { } }