flow-1.0.0-beta8/flow.module

flow.module
<?php

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\RevisionableInterface;
use Drupal\flow\Entity\EntitySaveHandler;
use Drupal\flow\Flow;
use Drupal\flow\FlowTaskQueue;

/**
 * @file
 * Flow module file.
 */

/**
 * Implements hook_entity_create().
 */
function flow_entity_create(EntityInterface $entity) {
  Flow::service()->apply($entity, 'create');
}

/**
 * Implements hook_entity_presave().
 */
function flow_entity_presave(EntityInterface $entity) {
  Flow::service()->apply($entity, 'save');
  _flow_save_new_referenced_entities($entity);
}

/**
 * Implements hook_entity_predelete().
 */
function flow_entity_predelete(EntityInterface $entity) {
  Flow::service()->apply($entity, 'delete');
}

/**
 * Implements hook_entity_insert().
 */
function flow_entity_insert(EntityInterface $entity) {
  _flow_update_task_stack($entity);
  _flow_cleanup_save_stack($entity);
  _flow_process_after_task($entity, 'create');
  _flow_process_after_task($entity, 'save');
}

/**
 * Implements hook_entity_update().
 */
function flow_entity_update(EntityInterface $entity) {
  _flow_update_task_stack($entity);
  _flow_cleanup_save_stack($entity);
  _flow_process_after_task($entity, 'save');
}

/**
 * Implements hook_entity_delete().
 */
function flow_entity_delete(EntityInterface $entity) {
  _flow_process_after_task($entity, 'delete');
}

/**
 * Processes Flow tasks that are to be executed after task completion.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The Flow-related entity.
 * @param string $task_mode
 *   The completed task mode.
 */
function _flow_process_after_task(EntityInterface $entity, string $task_mode): void {
  if (!($entity instanceof ContentEntityInterface)) {
    // Flow only takes care of content entities.
    return;
  }

  $flow_is_active = Flow::isActive();
  Flow::setActive(\Drupal::getContainer()->getParameter('flow.allow_nested_flow'));
  try {
    if (!isset(Flow::$stack[$task_mode])) {
      Flow::$stack[$task_mode] = [];
    }
    $stack = &Flow::$stack[$task_mode];
    array_push($stack, $entity);
    FlowTaskQueue::service()->process($entity, $task_mode, TRUE);
    $entity_needs_save = FALSE;
    if (!empty(Flow::$save)) {
      /** @var \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository */
      $entity_repository = \Drupal::service('entity.repository');
      $loaded = $entity->uuid() ? $entity_repository->loadEntityByUuid($entity->getEntityTypeId(), $entity->uuid()) : NULL;
      $entity_needs_save = $loaded && $task_mode !== 'delete' && (in_array($entity, Flow::$save, TRUE) || array_filter(Flow::$save, function ($stacked) use ($entity) {return $entity->uuid() && ($stacked->uuid() === $entity->uuid());}));
      EntitySaveHandler::service()->ensureSave(Flow::$save);
    }
    array_pop($stack);
    if ($entity_needs_save) {
      Flow::setActive(FALSE);
      if ($entity instanceof RevisionableInterface) {
        $entity->updateLoadedRevisionId();
        $entity->setNewRevision(FALSE);
      }
      $entity->save();
    }
  }
  finally {
    Flow::setActive($flow_is_active);
  }
}

/**
 * Updates the Flow task stack using the given entity.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The Flow-related entity.
 */
function _flow_update_task_stack(EntityInterface $entity) {
  if ($uuid = $entity->uuid()) {
    foreach (Flow::$stack as &$stack) {
      foreach ($stack as $i => $stacked) {
        if (($stacked !== $entity) && ($uuid === $stacked->uuid())) {
          $stack[$i] = $entity;
        }
      }
    }
  }
}

/**
 * Removes the given entity from the save stack.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The Flow-related entity.
 */
function _flow_cleanup_save_stack(EntityInterface $entity) {
  if (!empty(Flow::$save)) {
    foreach (Flow::$save as $i => $stacked) {
      if (($stacked === $entity) || ($entity->uuid() && ($entity->uuid() === $stacked->uuid()))) {
        unset(Flow::$save[$i]);
      }
    }
  }
}

/**
 * Saves referenced entities which are new and not saved yet.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The Flow-related entity.
 */
function _flow_save_new_referenced_entities(EntityInterface $entity) {
  foreach ($entity->referencedEntities() as $referenced) {
    // Besides the check for whether the entity is new, also make sure not to
    // run into an infinite loop by checking for non-existence of a
    // back-reference. This scenario would then also lead to a fatal error,
    // but at least it won't run into a loop that blocks even more resources.
    if ($referenced->isNew() && ($entity !== $referenced) && !in_array($entity, $referenced->referencedEntities(), TRUE)) {
      $flow_is_active = Flow::isActive();
      Flow::setActive(FALSE);
      try {
        $referenced->save();
      }
      finally {
        Flow::setActive($flow_is_active);
      }
      _flow_cleanup_save_stack($referenced);
    }
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc