You are here

public function WorkflowState::deactivate in Workflow 8

Deactivate a Workflow State, moving existing content to a given State.

Parameters

int $new_sid: The state ID, to which all affected entities must be moved.

File

src/Entity/WorkflowState.php, line 243

Class

WorkflowState
Workflow configuration entity to persistently store configuration.

Namespace

Drupal\workflow\Entity

Code

public function deactivate($new_sid) {
  $current_sid = $this
    ->id();
  $force = TRUE;

  // Notify interested modules. We notify first to allow access to data before we zap it.
  // - re-parents any entity that we don't want to orphan, whilst deactivating a State.
  // - delete any lingering entity to state values.
  // \Drupal::moduleHandler()->invokeAll('workflow', ['state delete', $current_sid, $new_sid, NULL, $force]);
  // Invoke the hook.
  \Drupal::moduleHandler()
    ->invokeAll('entity_' . $this
    ->getEntityTypeId() . '_predelete', [
    $this,
    $current_sid,
    $new_sid,
  ]);

  // Re-parent any entity that we don't want to orphan, whilst deactivating a State.
  // @todo D8-port: State should not know about Transition: move this to Workflow->DeactivateState.
  if ($new_sid) {

    // A candidate for the batch API.
    // @todo Future updates should seriously consider setting this with batch.
    // Use global user, since deactivate() is a UI-only function.
    $user = \Drupal::currentUser();
    $comment = $this
      ->t('Previous state deleted');
    foreach (_workflow_info_fields() as $field_info) {
      $entity_type_id = $field_info
        ->getTargetEntityTypeId();
      $field_name = $field_info
        ->getName();
      $result = [];

      // CommentForm's are not re-parented upon Deactivate WorkflowState.
      if ($entity_type_id != 'comment') {
        $query = \Drupal::entityQuery($entity_type_id);
        $query
          ->condition($field_name, $current_sid, '=');
        $result = $query
          ->execute();
      }
      foreach ($result as $entity_id) {
        $entity = \Drupal::entityTypeManager()
          ->getStorage($entity_type_id)
          ->load($entity_id);
        $transition = WorkflowTransition::create([
          $current_sid,
          'field_name' => $field_name,
        ]);
        $transition
          ->setTargetEntity($entity);
        $transition
          ->setValues($new_sid, $user
          ->id(), \Drupal::time()
          ->getRequestTime(), $comment, TRUE);
        $transition
          ->force($force);

        // Execute Transition, invoke 'pre' and 'post' events, save new state in Field-table, save also in workflow_transition_history.
        // For Workflow Node, only {workflow_node} and {workflow_transition_history} are updated. For Field, also the Entity itself.
        // Execute transition and update the attached entity.
        $new_sid = $transition
          ->executeAndUpdateEntity($force);
      }
    }
  }

  // Delete the transitions this state is involved in.
  $workflow = Workflow::load($this
    ->getWorkflowId());

  /** @var \Drupal\workflow\Entity\WorkflowInterface $workflow */

  /** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $transition */
  foreach ($workflow
    ->getTransitionsByStateId($current_sid, '') as $transition) {
    $transition
      ->delete();
  }
  foreach ($workflow
    ->getTransitionsByStateId('', $current_sid) as $transition) {
    $transition
      ->delete();
  }

  // Delete the state. -- We don't actually delete, just deactivate.
  // This is a matter up for some debate, to delete or not to delete, since this
  // causes name conflicts for states. In the meantime, we just stick with what we know.
  // If you really want to delete the states, use workflow_cleanup module, or delete().
  $this->status = FALSE;
  $this
    ->save();

  // Clear the cache.
  self::loadMultiple([], 0, TRUE);
}