You are here

public static function WorkflowManager::executeTransitionsOfEntity in Workflow 8

Execute a single transition for the given entity.

Implements hook_entity insert(), hook_entity_update().

When inserting an entity with workflow field, the initial Transition is saved without reference to the proper entity, since Id is not yet known. So, we cannot save Transition in the Widget, but only(?) in a hook. To keep things simple, this is done for both insert() and update().

This is referenced in from WorkflowDefaultWidget::massageFormValues().

Parameters

\Drupal\Core\Entity\EntityInterface $entity:

Overrides WorkflowManagerInterface::executeTransitionsOfEntity

1 call to WorkflowManager::executeTransitionsOfEntity()
_workflow_execute_transitions in ./workflow.module
Execute transitions. if prohibited, restore original field value.

File

src/Entity/WorkflowManager.php, line 141

Class

WorkflowManager
Manages entity type plugin definitions.

Namespace

Drupal\workflow\Entity

Code

public static function executeTransitionsOfEntity(EntityInterface $entity) {

  // Avoid this hook on workflow objects.
  if (WorkflowManager::isWorkflowEntityType($entity
    ->getEntityTypeId())) {
    return;
  }
  $user = workflow_current_user();
  foreach (workflow_get_workflow_field_names($entity) as $field_name) {

    // Transition is created in widget or WorkflowTransitionForm.

    /** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $transition */
    $transition = $entity->{$field_name}
      ->__get('workflow_transition');
    if (!$transition) {

      // We come from creating/editing an entity via entity_form, with core widget or hidden Workflow widget.
      // @todo D8: From an Edit form with hidden widget.

      /* @noinspection PhpUndefinedFieldInspection */
      if ($entity->original) {

        // Editing a Node with hidden Widget. State change not possible, so bail out.
        // $entity->{$field_name}->value = $entity->original->{$field_name}->value;
        // continue;
      }

      // Creating a Node with hidden Workflow Widget. Generate valid first transition.
      $comment = '';
      $old_sid = WorkflowManager::getPreviousStateId($entity, $field_name);
      $new_sid = $entity->{$field_name}->value;
      if (!$new_sid && ($wid = $entity->{$field_name}
        ->getSetting('workflow_type'))) {

        /** @var \Drupal\workflow\Entity\Workflow $workflow */
        $workflow = Workflow::load($wid);
        $new_sid = $workflow
          ->getFirstSid($entity, $field_name, $user);
      }
      $transition = WorkflowTransition::create([
        $old_sid,
        'field_name' => $field_name,
      ]);
      $transition
        ->setValues($new_sid, $user
        ->id(), \Drupal::time()
        ->getRequestTime(), $comment, TRUE);
    }

    // We come from Content/Comment edit page, from widget.
    // Set the just-saved entity explicitly. Not necessary for update,
    // but upon insert, the old version didn't have an ID, yet.
    $transition
      ->setTargetEntity($entity);
    if ($transition
      ->isExecuted()) {

      // Sometimes (due to Rules, or extra programming) it can happen that
      // a Transition is executed twice in a call. This check avoids that
      // situation, that generates message "Transition is executed twice".
      $executed = TRUE;
    }
    elseif ($transition
      ->isScheduled()) {

      // Returns a positive integer.
      $executed = $transition
        ->save();
    }
    elseif ($entity
      ->getEntityTypeId() == 'comment') {

      // If Transition is added via CommentForm, save Comment AND Entity.
      // Execute and check the result.
      $new_sid = $transition
        ->executeAndUpdateEntity();
      $executed = $new_sid == $transition
        ->getToSid() ? TRUE : FALSE;
    }
    else {

      // Execute and check the result.
      $new_sid = $transition
        ->execute();
      $executed = $new_sid == $transition
        ->getToSid() ? TRUE : FALSE;
    }

    // If the transition failed, revert the entity workflow status.
    // For new entities, we do nothing: it has no original.
    if (!$executed && isset($entity->original)) {
      $originalValue = $entity->original->{$field_name}->value;
      $entity->{$field_name}
        ->setValue($originalValue);
    }
  }
}