View source  
  <?php
namespace Drupal\workflow\Plugin\Action;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Action\ConfigurableActionBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\workflow\Element\WorkflowTransitionElement;
use Drupal\workflow\Entity\Workflow;
use Drupal\workflow\Entity\WorkflowTransition;
use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class WorkflowStateActionBase extends ConfigurableActionBase implements ContainerFactoryPluginInterface {
  
  public function calculateDependencies() {
    return parent::calculateDependencies() + [
      'module' => [
        'workflow',
      ],
    ];
  }
  
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition);
  }
  
  public function defaultConfiguration() {
    $configuration = parent::defaultConfiguration();
    $configuration += $this->configuration;
    $configuration += [
      'field_name' => '',
      'to_sid' => '',
      'comment' => "New state is set by a triggered Action.",
      'force' => 0,
    ];
    return $configuration;
  }
  
  protected function getTransitionForExecution(EntityInterface $entity) {
    $user = workflow_current_user();
    if (!$entity) {
      \Drupal::logger('workflow_action')
        ->notice('Unable to get current entity - entity is not defined.', []);
      return NULL;
    }
    
    $entity_id = $entity
      ->id();
    if (!$entity_id) {
      \Drupal::logger('workflow_action')
        ->notice('Unable to get current entity ID - entity is not yet saved.', []);
      return NULL;
    }
    
    $entity
      ->enforceIsNew(FALSE);
    $config = $this->configuration;
    $field_name = workflow_get_field_name($entity, $config['field_name']);
    $current_sid = workflow_node_current_state($entity, $field_name);
    if (!$current_sid) {
      \Drupal::logger('workflow_action')
        ->notice('Unable to get current workflow state of entity %id.', [
        '%id' => $entity_id,
      ]);
      return NULL;
    }
    $to_sid = isset($config['to_sid']) ? $config['to_sid'] : '';
    
    $comment_string = $this->configuration['comment'];
    $comment = $this
      ->t($comment_string, [
      '%title' => $entity
        ->label(),
      
      '%state' => workflow_get_sid_name($to_sid),
      '%user' => $user
        ->getDisplayName(),
    ]);
    $force = $this->configuration['force'];
    $transition = WorkflowTransition::create([
      $current_sid,
      'field_name' => $field_name,
    ]);
    $transition
      ->setTargetEntity($entity);
    $transition
      ->setValues($to_sid, $user
      ->id(), \Drupal::time()
      ->getRequestTime(), $comment);
    $transition
      ->force($force);
    return $transition;
  }
  
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    
    $config = $this->configuration;
    $field_name = $config['field_name'];
    $wids = workflow_get_workflow_names();
    if (empty($field_name) && count($wids) > 1) {
      $this
        ->messenger()
        ->addWarning('You have multiple workflows in the system. Please first select the field name
          and save the form. Then, revisit the form to set the correct state value.');
    }
    $wid = count($wids) ? array_keys($wids)[0] : '';
    if (!empty($field_name)) {
      $fields = _workflow_info_fields($entity = NULL, $entity_type = '', $entity_bundle = '', $field_name);
      $wid = count($fields) ? reset($fields)
        ->getSetting('workflow_type') : '';
    }
    
    
    $workflow = $wid ? Workflow::load($wid) : Workflow::create([
      'id' => 'dummy_action',
      'label' => 'dummy_action',
    ]);
    $current_state = $workflow
      ->getCreationState();
    
    $user = workflow_current_user();
    $transition = WorkflowTransition::create([
      $current_state,
      'field_name' => $field_name,
    ]);
    $transition
      ->setValues($to_sid = $config['to_sid'], $user
      ->id(), \Drupal::time()
      ->getRequestTime(), $comment = $config['comment'], $force = $config['force']);
    
    $element = [];
    
    $element['#default_value'] = $transition;
    
    $original_options = $transition
      ->getWorkflow()
      ->getSetting('options');
    $transition
      ->getWorkflow()
      ->setSetting('options', 'select');
    
    $element = WorkflowTransitionElement::transitionElement($element, $form_state, $form);
    
    $transition
      ->getWorkflow()
      ->setSetting('options', $original_options);
    
    $element['field_name']['#access'] = TRUE;
    $element['force']['#access'] = TRUE;
    $element['to_sid']['#description'] = $this
      ->t('Please select the state that should be assigned when this action runs.');
    $element['comment']['#title'] = $this
      ->t('Message');
    $element['comment']['#description'] = $this
      ->t('This message will be written
      into the workflow history log when the action runs.
      You may include the following variables: %state, %title, %user.');
    $form['workflow_transition_action_config'] = $element;
    return $form;
  }
  
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $configuration = $form_state
      ->getValue('workflow_transition_action_config');
    
    unset($configuration['workflow_transition']);
    $this->configuration = $configuration;
  }
  
  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
    $access = AccessResult::allowed();
    return $return_as_object ? $access : $access
      ->isAllowed();
  }
}