ContentModeration.php 6.81 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<?php

namespace Drupal\content_moderation\Plugin\WorkflowType;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\content_moderation\ContentModerationState;
use Drupal\workflows\Plugin\WorkflowTypeBase;
use Drupal\workflows\StateInterface;
use Drupal\workflows\WorkflowInterface;

/**
 * Attaches workflows to content entity types and their bundles.
 *
 * @WorkflowType(
 *   id = "content_moderation",
 *   label = @Translation("Content moderation"),
20 21 22 23
 *   required_states = {
 *     "draft",
 *     "published",
 *   },
24 25 26 27 28 29
 * )
 */
class ContentModeration extends WorkflowTypeBase {

  use StringTranslationTrait;

30 31 32 33 34 35 36 37 38 39 40 41 42 43
  /**
   * {@inheritdoc}
   */
  public function initializeWorkflow(WorkflowInterface $workflow) {
    $workflow
      ->addState('draft', $this->t('Draft'))
      ->setStateWeight('draft', -5)
      ->addState('published', $this->t('Published'))
      ->setStateWeight('published', 0)
      ->addTransition('create_new_draft', $this->t('Create New Draft'), ['draft', 'published'], 'draft')
      ->addTransition('publish', $this->t('Publish'), ['draft', 'published'], 'published');
    return $workflow;
  }

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
  /**
   * {@inheritdoc}
   */
  public function checkWorkflowAccess(WorkflowInterface $entity, $operation, AccountInterface $account) {
    if ($operation === 'view') {
      return AccessResult::allowedIfHasPermission($account, 'view content moderation');
    }
    return parent::checkWorkflowAccess($entity, $operation, $account);
  }

  /**
   * {@inheritdoc}
   */
  public function decorateState(StateInterface $state) {
    if (isset($this->configuration['states'][$state->id()])) {
      $state = new ContentModerationState($state, $this->configuration['states'][$state->id()]['published'], $this->configuration['states'][$state->id()]['default_revision']);
    }
    else {
      $state = new ContentModerationState($state);
    }
    return $state;
  }

  /**
   * {@inheritdoc}
   */
  public function buildStateConfigurationForm(FormStateInterface $form_state, WorkflowInterface $workflow, StateInterface $state = NULL) {
    /** @var \Drupal\content_moderation\ContentModerationState $state */
72 73
    $is_required_state = isset($state) ? in_array($state->id(), $this->getRequiredStates(), TRUE) : FALSE;

74 75 76 77 78 79
    $form = [];
    $form['published'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Published'),
      '#description' => $this->t('When content reaches this state it should be published.'),
      '#default_value' => isset($state) ? $state->isPublishedState() : FALSE,
80
      '#disabled' => $is_required_state,
81 82 83 84 85 86 87
    ];

    $form['default_revision'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Default revision'),
      '#description' => $this->t('When content reaches this state it should be made the default revision; this is implied for published states.'),
      '#default_value' => isset($state) ? $state->isDefaultRevisionState() : FALSE,
88
      '#disabled' => $is_required_state,
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
      // @todo Add form #state to force "make default" on when "published" is
      // on for a state.
      // @see https://www.drupal.org/node/2645614
    ];
    return $form;
  }

  /**
   * Gets the entity types the workflow is applied to.
   *
   * @return string[]
   *   The entity types the workflow is applied to.
   */
  public function getEntityTypes() {
    return array_keys($this->configuration['entity_types']);
  }

  /**
107
   * Gets any bundles the workflow is applied to for the given entity type.
108 109 110 111 112
   *
   * @param string $entity_type_id
   *   The entity type ID to get the bundles for.
   *
   * @return string[]
113 114
   *   The bundles of the entity type the workflow is applied to or an empty
   *   array if the entity type is not applied to the workflow.
115 116
   */
  public function getBundlesForEntityType($entity_type_id) {
117
    return isset($this->configuration['entity_types'][$entity_type_id]) ? $this->configuration['entity_types'][$entity_type_id] : [];
118 119 120 121 122
  }

  /**
   * Checks if the workflow applies to the supplied entity type and bundle.
   *
123 124 125 126 127
   * @param string $entity_type_id
   *   The entity type ID to check.
   * @param string $bundle_id
   *   The bundle ID to check.
   *
128
   * @return bool
129 130
   *   TRUE if the workflow applies to the supplied entity type ID and bundle
   *   ID. FALSE if not.
131 132
   */
  public function appliesToEntityTypeAndBundle($entity_type_id, $bundle_id) {
133
    return in_array($bundle_id, $this->getBundlesForEntityType($entity_type_id), TRUE);
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
  }

  /**
   * Removes an entity type ID / bundle ID from the workflow.
   *
   * @param string $entity_type_id
   *   The entity type ID to remove.
   * @param string $bundle_id
   *   The bundle ID to remove.
   */
  public function removeEntityTypeAndBundle($entity_type_id, $bundle_id) {
    $key = array_search($bundle_id, $this->configuration['entity_types'][$entity_type_id], TRUE);
    if ($key !== FALSE) {
      unset($this->configuration['entity_types'][$entity_type_id][$key]);
      if (empty($this->configuration['entity_types'][$entity_type_id])) {
        unset($this->configuration['entity_types'][$entity_type_id]);
      }
      else {
        $this->configuration['entity_types'][$entity_type_id] = array_values($this->configuration['entity_types'][$entity_type_id]);
      }
    }
  }

  /**
   * Add an entity type ID / bundle ID to the workflow.
   *
   * @param string $entity_type_id
161 162
   *   The entity type ID to add. It is responsibility of the caller to provide
   *   a valid entity type ID.
163
   * @param string $bundle_id
164 165
   *   The bundle ID to add. It is responsibility of the caller to provide a
   *   valid bundle ID.
166 167 168 169
   */
  public function addEntityTypeAndBundle($entity_type_id, $bundle_id) {
    if (!$this->appliesToEntityTypeAndBundle($entity_type_id, $bundle_id)) {
      $this->configuration['entity_types'][$entity_type_id][] = $bundle_id;
170 171
      sort($this->configuration['entity_types'][$entity_type_id]);
      ksort($this->configuration['entity_types']);
172 173 174 175 176 177 178 179 180
    }
  }

  /**
   * {@inheritDoc}
   */
  public function defaultConfiguration() {
    // This plugin does not store anything per transition.
    return [
181 182 183 184 185 186 187 188 189 190
      'states' => [
        'draft' => [
          'published' => FALSE,
          'default_revision' => FALSE,
        ],
        'published' => [
          'published' => TRUE,
          'default_revision' => TRUE,
        ],
      ],
191 192 193 194 195 196 197 198 199 200 201 202
      'entity_types' => [],
    ];
  }

  /**
   * @inheritDoc
   */
  public function calculateDependencies() {
    // @todo : Implement calculateDependencies() method.
    return [];
  }

203 204 205 206 207 208 209 210 211 212 213
  /**
   * {@inheritdoc}
   */
  public function getConfiguration() {
    $configuration = parent::getConfiguration();
    // Ensure that states and entity types are ordered consistently.
    ksort($configuration['states']);
    ksort($configuration['entity_types']);
    return $configuration;
  }

214
}