access_policy-1.0.x-dev/src/Plugin/access_policy/AccessRule/EntityFieldModerationState.php
src/Plugin/access_policy/AccessRule/EntityFieldModerationState.php
<?php namespace Drupal\access_policy\Plugin\access_policy\AccessRule; use Drupal\access_policy\LabelHelper; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; /** * Restrict content by comparing moderation states. * * @AccessRule( * id = "entity_field_moderation_state", * handlers = { * "query_alter" = "\Drupal\access_policy\AccessRuleQueryHandler\ModerationState" * } * ) */ class EntityFieldModerationState extends EntityFieldList { /** * {@inheritdoc} */ public function defaultSettings() { return [ 'value' => [], "operator" => 'or', ] + parent::defaultSettings(); } /** * {@inheritdoc} */ public function accessRuleFormSubmit(array &$form, FormStateInterface $form_state) { parent::accessRuleFormSubmit($form, $form_state); $values = $form_state->getValues(); $this->settings['value'] = array_filter($values['value']) ?? []; } /** * {@inheritdoc} */ public function accessRuleForm(array $form, FormStateInterface $form_state) { $form['message'] = [ '#type' => 'markup', '#markup' => $this->t('<strong>Warning:</strong> This does not bypass permission access. Users who can view entities with unpublished moderation states still require "view unpublished" permissions.'), ]; return parent::accessRuleForm($form, $form_state); } /** * {@inheritdoc} */ protected function valueForm(array &$form, FormStateInterface $form_state) { $form['value'] = [ '#type' => 'select', '#title' => $this->t('Value'), '#options' => $this->getAllowedValues(), '#default_value' => $this->settings['value'], '#multiple' => TRUE, ]; } /** * Get allowed field value options. * * @return array * Array of allowed values. * * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ protected function getAllowedValues() { $allowed_values = []; $workflow_storage = $this->entityTypeManager->getStorage('workflow'); foreach ($workflow_storage->loadByProperties(['type' => 'content_moderation']) as $workflow) { /** @var \Drupal\content_moderation\Plugin\WorkflowType\ContentModerationInterface $workflow_type */ $workflow_type = $workflow->getTypePlugin(); if (in_array($this->getDefinition()->getEntityType(), $workflow_type->getEntityTypes(), TRUE)) { foreach ($workflow_type->getStates() as $state_id => $state) { $workflow_string = implode('-', [$workflow->id(), $state_id]); $allowed_values[$workflow->label()][$workflow_string] = $state->label(); } } } return $allowed_values; } /** * {@inheritdoc} */ public function adminSummary() { $allowed_values = $this->getAllowedValuesFlattened(); $labels = []; $selected = $this->settings['value']; foreach ($allowed_values as $key => $label) { if (in_array($key, $selected)) { $labels[] = $label; } } return $this->getOperator() . ' ' . LabelHelper::render($labels, [ 'limit' => 2, 'empty_value' => $this->t('Unknown'), ]); } /** * Get all allowed values in a flattened associative array. * * The moderation states are grouped by workflow. This flattens that * the multi-dimensional array into flat associative array. * * @return array * Array of moderation states. */ protected function getAllowedValuesFlattened() { $allowed_values = $this->getAllowedValues(); $all_states = []; foreach ($allowed_values as $moderation_states) { foreach ($moderation_states as $name => $state) { $all_states[$name] = $state; } } return $all_states; } /** * {@inheritdoc} */ public function validateCallback(EntityInterface $entity, AccountInterface $account) { $operator = $this->getOperator(); $info = $this->operators(); $field_values = $this->getEntityValues($entity, $account); $options = $this->prepareOptions($this->getValue()); if (!empty($info[$operator]['method'])) { // If any of the field values match then return true. $valid = $this->{$info[$operator]['method']}($options, $field_values); if ($valid) { return TRUE; } } return FALSE; } /** * Prepare the options for comparison. * * @param array $value * The current computed value. * * @return array * Array of normalized options. */ public function prepareOptions(array $value) { $options = []; foreach ($value as $option) { $moderation_state = explode('-', $option)[1]; $options[] = $moderation_state; } return $options; } }