delivery-8.x-1.x-dev/src/DeliveryService.php

src/DeliveryService.php
<?php

namespace Drupal\delivery;

use Drupal\conflict\ConflictResolver\ConflictResolverManager;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemList;
use Drupal\delivery\Entity\DeliveryItem;
use Drupal\workspaces\WorkspaceAssociationInterface;
use Drupal\workspaces\WorkspaceInterface;
use Drupal\delivery\Plugin\views\traits\EntityDeliveryStatusTrait;
use Drupal\workspaces\WorkspaceManagerInterface;

/**
 * Class DeliveryService
 *
 * @package Drupal\delivery
 */
class DeliveryService {

  use EntityDeliveryStatusTrait;

  /**
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * @var \Drupal\workspaces\WorkspaceManagerInterface
   */
  protected $workspaceManager;

  /**
   * @var \Drupal\Core\Entity\EntityRepositoryInterface
   */
  protected $entityRepository;

  /**
   * @var \Drupal\conflict\ConflictResolver\ConflictResolverManager
   */
  protected $conflictResolverManager;

  /**
   * @var \Drupal\workspaces\WorkspaceAssociationInterface
   */
  protected $workspaceAssociation;

  /**
   * DeliveryService constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * @param \Drupal\workspaces\WorkspaceManagerInterface $workspaceManager
   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entityRepository
   * @param \Drupal\conflict\ConflictResolver\ConflictResolverManager $conflictResolverManager
   * @param \Drupal\workspaces\WorkspaceAssociationInterface $workspaceAssociation
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    WorkspaceManagerInterface $workspaceManager,
    EntityRepositoryInterface $entityRepository,
    ConflictResolverManager $conflictResolverManager,
    WorkspaceAssociationInterface $workspaceAssociation
  ) {
    $this->entityTypeManager = $entity_type_manager;
    $this->workspaceManager = $workspaceManager;
    $this->entityRepository = $entityRepository;
    $this->conflictResolverManager = $conflictResolverManager;
    $this->workspaceAssociation = $workspaceAssociation;
  }

  /**
   * Forwards a delivery using a delivery entity and a workspace target ID.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   * @param $target_ids
   * @param int $source_id
   *
   * @return \Drupal\delivery\DeliveryInterface
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function forwardDelivery(DeliveryInterface $delivery, $target_ids, $source_id = 0) {
    $forwarded = $delivery->createDuplicate();
    // Re-set the title.
    $title = $delivery->label();
    $forwarded->set('label', 'FWD: ' . $title);

    // Re-set the source workspace.
    $currentWorkspace = $this->workspaceManager->getActiveWorkspace();
    $forwarded->source = ['target_id' => $currentWorkspace->id()];

    // Re-set the target workspace.
    $forwarded->workspaces = array_values(array_map(function ($id) {
      return ['target_id' => $id];
    }, array_filter($target_ids)));

    $forwarded->items = [];

    foreach ($delivery->items as $item) {
      /** @var DeliveryItem $deliveryItem */
      $deliveryItem = $item->entity;
      // Skip delivery items that don't target the current workspace.
      if ($deliveryItem->getTargetWorkspace() !== $currentWorkspace->id()) {
        continue;
      }
      foreach (array_filter($target_ids) as $target) {
        $forwarded->items[] = DeliveryItem::create([
          'source_workspace' => $deliveryItem->getTargetWorkspace(),
          'target_workspace' => $target,
          'entity_type' => $deliveryItem->getTargetType(),
          'entity_id' => $deliveryItem->getTargetId(),
          'source_revision' => $deliveryItem->getResultRevision(),
        ]);
      }
    }

    $forwarded->save();
    return $forwarded;
  }

  /**
   * Returns an array of possible target workspaces, keyed by workspace IDs.
   *
   * @return array
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getTargetWorkspaces() {
    $list = [];
    $currentWorkspace = $this->workspaceManager->getActiveWorkspace();

    $workspaces = $this->entityTypeManager->getStorage('workspace')
      ->loadMultiple();

    foreach ($workspaces as $workspace) {
      $list[$workspace->id()] = $workspace->label();
    }
    return $list;
  }

  /**
   * Checks if there are conflicts.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return bool
   *
   * @todo Properly implement this once the workspace index work is complete.
   */
  public function deliveryHasConflicts(DeliveryInterface $delivery) {
    $currentWorkspace = $this->workspaceManager->getActiveWorkspace();

    $pages = [0];
    foreach ($delivery->nodes as $item) {
      $pages[] = $item->target_revision_id;
    }

    $media = [0];
    foreach ($delivery->media as $item) {
      $media[] = $item->target_revision_id;
    }

    $pages = views_get_view_result('workspace_status_pages', 'delivery_status', implode('+', $pages), $delivery->source->target_id, $currentWorkspace->id());
    $media = views_get_view_result('workspace_status_media', 'delivery_status', implode('+', $media), $delivery->source->target_id, $currentWorkspace->id());

    $pages = array_filter($pages, function ($row) {
      return $row->entity_delivery_status === EntityDeliveryStatusTrait::$CONFLICT;
    });

    $media = array_filter($media, function ($row) {
      return $row->entity_delivery_status === EntityDeliveryStatusTrait::$CONFLICT;
    });

    return $pages || $media;
  }

  /**
   * Checks if a delivery has pending changes.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return bool
   *
   * @todo Properly implement this once the workspace index work is complete.
   */
  public function deliveryHasPendingChanges(DeliveryInterface $delivery) {
    $currentWorkspace = $this->workspaceManager->getActiveWorkspace();
    $delivered = TRUE;

    foreach ($delivery->items as $item) {
      if ($item->entity->target_workspace->value === $currentWorkspace->id()) {
        $delivered = $delivered && $item->entity->resolution->value;
      }
    }
    return !$delivered;
  }

  /**
   * Checks if the delivery has any kind of changes (conflict, pending changes,
   * outdated content).
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   * @param \Drupal\workspaces\WorkspaceInterface $targetWorkspace | NULL
   *
   * @return bool.
   *
   * @todo Properly implement this once the workspace index work is complete.
   */
  public function deliveryHasChanges(DeliveryInterface $delivery, WorkspaceInterface $targetWorkspace = NULL) {
    $currentWorkspace = $this->workspaceManager->getActiveWorkspace();

    $pages = [0];
    foreach ($delivery->nodes as $item) {
      $pages[] = $item->target_revision_id;
    }

    $media = [0];
    foreach ($delivery->media as $item) {
      $media[] = $item->target_revision_id;
    }

    $pages = views_get_view_result('workspace_status_pages', 'delivery_status', implode('+', $pages), $delivery->source->target_id, !empty($targetWorkspace) ? $targetWorkspace->id() : $currentWorkspace->id());
    $media = views_get_view_result('workspace_status_media', 'delivery_status', implode('+', $media), $delivery->source->target_id, !empty($targetWorkspace) ? $targetWorkspace->id() : $currentWorkspace->id());

    $pages = array_filter($pages, function ($row) {
      return $row->entity_delivery_status !== EntityDeliveryStatusTrait::$NOT_APPLICABLE && $row->entity_delivery_status !== EntityDeliveryStatusTrait::$IDENTICAL;
    });

    $media = array_filter($media, function ($row) {
      return $row->entity_delivery_status !== EntityDeliveryStatusTrait::$NOT_APPLICABLE && $row->entity_delivery_status !== EntityDeliveryStatusTrait::$IDENTICAL;
    });

    return $pages || $media;
  }

  /**
   * Returns an array of modified entity IDs.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return array
   */
  public function getModifiedEntities(DeliveryInterface $delivery) {
    $currentWorkspace = $this->workspaceManager->getActiveWorkspace();

    $pages = [0];
    foreach ($delivery->nodes as $item) {
      $pages[] = $item->target_revision_id;
    }

    $media = [0];
    foreach ($delivery->media as $item) {
      $media[] = $item->target_revision_id;
    }

    $pages = views_get_view_result('workspace_status_pages', 'delivery_status', implode('+', $pages), $delivery->source->target_id, $currentWorkspace->id());
    $media = views_get_view_result('workspace_status_media', 'delivery_status', implode('+', $media), $delivery->source->target_id, $currentWorkspace->id());

    $pages = array_filter($pages, function ($row) {
      return $row->entity_delivery_status === EntityDeliveryStatusTrait::$MODIFIED;
    });

    $media = array_filter($media, function ($row) {
      return $row->entity_delivery_status === EntityDeliveryStatusTrait::$MODIFIED;
    });

    $entities = [
      'node' => [],
      'media' => [],
    ];
    foreach ($pages as $page) {
      $entities['node'][$page->_entity->id()] = $page->_entity->id();
    }
    foreach ($media as $medium) {
      $entities['media'][$medium->_entity->id()] = $medium->_entity->id();
    }
    return $entities;
  }

  /**
   * Returns true if a delivery can be safely forwarded, otherwise false.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return bool
   */
  public function canForwardDelivery(DeliveryInterface $delivery) {
    $targets = $this->getDeliveryTargets($delivery);
    if (!in_array($this->workspaceManager->getActiveWorkspace()
      ->id(), $targets)) {
      return FALSE;
    }

    if ($this->deliveryHasPendingChanges($delivery)) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * Get an array of node IDs and node revision IDs.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return array
   */
  public function getNodeIDsFromDelivery(DeliveryInterface $delivery) {
    $nodes = $delivery->get('nodes');
    if (!$nodes instanceof EntityReferenceRevisionsFieldItemList) {
      return [];
    }
    return $nodes->getValue() ?: [];
  }

  /**
   * Get an array of media IDs and media revision IDs.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return array
   */
  public function getMediaIDsFromDelivery(DeliveryInterface $delivery) {
    $media = $delivery->get('media');
    if (!$media instanceof EntityReferenceRevisionsFieldItemList) {
      return [];
    }
    return $media->getValue() ?: [];
  }

  /**
   * Pulls all updates from a delivery into the current workspace.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   * @param \Drupal\workspaces\WorkspaceInterface $workspace
   *
   * @return array
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function pullChangesFromDeliveryToWorkspace(DeliveryInterface $delivery, WorkspaceInterface $workspace) {
    $skipped = 0;
    foreach ($delivery->items as $item) {
      /** @var DeliveryItem $deliveryItem */
      $deliveryItem = $item->entity;
      if (isset($deliveryItem->resolution->value)) {
        continue;
      }
      if ($deliveryItem->getTargetWorkspace() !== $workspace->id()) {
        continue;
      }

      if ($this->deliverItemHasConflicts($deliveryItem)) {
        $skipped++;
        continue;
      }

      $this->acceptDeliveryItem($deliveryItem);
    }
    return $skipped;
  }

  /**
   * @param $entityType
   *
   * @return \Drupal\Core\Entity\ContentEntityStorageInterface
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function getContentEntityStorage($entityType) {
    return $this->entityTypeManager->getStorage($entityType);
  }

  public function deliverItemHasConflicts($deliveryItem) {

    /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
    $storage = $this->entityTypeManager->getStorage($deliveryItem->getTargetType());
    /** @var \Drupal\Core\Entity\ContentEntityInterface $sourceEntity */
    $sourceEntity = $storage->loadRevision($deliveryItem->getSourceRevision());

    /** @var \Drupal\Core\Entity\ContentEntityInterface $targetEntity */
    $targetEntity = $storage->loadRevision($this->getActiveRevision($deliveryItem));

    /** @var \Drupal\revision_tree\EntityRevisionTreeHandlerInterface $revisionTreeHandler */
    $revisionTreeHandler = $this->entityTypeManager->getHandler($sourceEntity->getEntityTypeId(), 'revision_tree');
    $parentEntityRevision = $revisionTreeHandler
      ->getLowestCommonAncestorId($sourceEntity->getRevisionId(), $targetEntity->getRevisionId(), $deliveryItem->getTargetId());

    // If the target is a ascendant, there are no conflicts.
    if ($parentEntityRevision === $targetEntity->getRevisionId()) {
      return FALSE;
    }

    /** @var \Drupal\Core\Entity\ContentEntityInterface $parentEntity */
    $parentEntity = $storage->loadRevision($parentEntityRevision);

    // If there is no common ancestor it means that the entity has not been
    // modified in any parent workspace, so no conflict possible.
    if (!$parentEntity) {
      return FALSE;
    }

    $hasConflicts = FALSE;

    if ($sourceEntity->isTranslatable()) {
      foreach ($sourceEntity->getTranslationLanguages() as $language) {
        $languageId = $language->getId();
        if (!$targetEntity->hasTranslation($languageId)) {
          continue;
        }
        if (!$parentEntity->hasTranslation($languageId)) {
          continue;
        }

        $sourceTranslation = $sourceEntity->getTranslation($languageId);
        $parentTranslation = $parentEntity->getTranslation($languageId);
        $targetTranslation = $targetEntity->getTranslation($languageId);

        $conflicts = $this->conflictResolverManager->getConflicts(
          $targetTranslation,
          $sourceTranslation,
          $parentTranslation
        );
        $hasConflicts = $hasConflicts || count($conflicts) > 0;
      }
    }
    return $hasConflicts;
  }

  /**
   * Force push a delivery item.
   *
   * Resolve a merge conflict preferring the source version of an entity.
   *
   * @param \Drupal\delivery\Entity\DeliveryItem $deliveryItem
   *   The delivery item to force push.
   */
  public function acceptDeliveryItem(DeliveryItem $deliveryItem, $state = 'draft') {
    $entityType = $this->entityTypeManager->getDefinition($deliveryItem->getTargetType());
    $storage = $this->getContentEntityStorage($deliveryItem->getTargetType());
    /** @var \Drupal\Core\Entity\ContentEntityInterface $source */
    $source = $storage->loadRevision($deliveryItem->getSourceRevision());

    $activeRevisionId = $this->getActiveRevision($deliveryItem);

    $revisionParentField = $entityType->getRevisionMetadataKey('revision_parent');
    $revisionMergeParentField = $entityType->getRevisionMetadataKey('revision_merge_parent');
    $revisionField = $entityType->getKey('revision');

    // Pretend that the source revision is a default revision, so languages
    // are not merged
    $is_default = $source->isDefaultRevision();
    $source->isDefaultRevision(TRUE);
    /** @var ContentEntityInterface $result */
    $result = $storage->createRevision($source);
    $source->isDefaultRevision($is_default);

    $result->{$revisionMergeParentField}->target_revision_id = $deliveryItem->getSourceRevision();
    $result->{$revisionParentField}->target_revision_id = $activeRevisionId;
    $result->workspace = $deliveryItem->getTargetWorkspace();
    $result->setSyncing(TRUE);

    if ($result->hasField('moderation_state')) {
      $result->set('moderation_state', $state);
    }

    $this->workspaceManager->executeInWorkspace($deliveryItem->getTargetWorkspace(), function () use ($result) {
      $result->save();
    });

    $deliveryItem->resolution = DeliveryItem::RESOLUTION_SOURCE;
    $deliveryItem->result_revision = $result->{$revisionField};
    $deliveryItem->save();
  }

  /**
   * Force decline the delivery item.
   *
   * Resolve a merge conflict preferring the target version of an entity.
   *
   * @param \Drupal\delivery\Entity\DeliveryItem $deliveryItem
   */
  public function declineDeliveryItem(DeliveryItem $deliveryItem) {
    $entityType = $this->entityTypeManager->getDefinition($deliveryItem->getTargetType());
    $storage = $this->getContentEntityStorage($deliveryItem->getTargetType());

    $activeRevisionId = $this->getActiveRevision($deliveryItem);

    $revisionParentField = $entityType->getRevisionMetadataKey('revision_parent');
    $revisionMergeParentField = $entityType->getRevisionMetadataKey('revision_merge_parent');
    $revisionField = $entityType->getKey('revision');

    $source = $storage->loadRevision($deliveryItem->getSourceRevision());

    // Pretend that the source revision is a default revision, so languages
    // are not merged
    $is_default = $source->isDefaultRevision();
    $source->isDefaultRevision(TRUE);
    /** @var ContentEntityInterface $result */
    $result = $storage->createRevision($source);
    $source->isDefaultRevision($is_default);

    $result->{$revisionMergeParentField}->target_revision_id = $deliveryItem->getSourceRevision();
    $result->{$revisionParentField}->target_revision_id = $activeRevisionId;
    $result->workspace = $deliveryItem->getTargetWorkspace();
    $result->setSyncing(TRUE);
    $this->workspaceManager->executeInWorkspace($deliveryItem->getTargetWorkspace(), function () use ($result) {
      $result->save();
    });

    $deliveryItem->resolution = DeliveryItem::RESOLUTION_TARGET;
    $deliveryItem->result_revision = $result->{$revisionField};
    $deliveryItem->save();
  }

  public function mergeDeliveryItem(DeliveryItem $deliveryItem, ContentEntityInterface $result) {
    $entityType = $this->entityTypeManager->getDefinition($deliveryItem->getTargetType());
    $storage = $this->getContentEntityStorage($deliveryItem->getTargetType());

    $revisionParentField = $entityType->getRevisionMetadataKey('revision_parent');
    $revisionMergeParentField = $entityType->getRevisionMetadataKey('revision_merge_parent');
    $revisionField = $entityType->getKey('revision');

    $target = $this->getActiveRevision($deliveryItem);

    $source = $storage->loadRevision($deliveryItem->getSourceRevision());

    // Pretend that the source revision is a default revision, so languages
    // are not merged
    $is_default = $source->isDefaultRevision();
    $source->isDefaultRevision(TRUE);
    /** @var ContentEntityInterface $result */
    $result = $storage->createRevision($source);
    $source->isDefaultRevision($is_default);

    $result->{$revisionMergeParentField}->target_revision_id = $deliveryItem->getSourceRevision();
    $result->{$revisionParentField}->target_revision_id = $target;
    $result->workspace = $deliveryItem->getTargetWorkspace();
    $result->setSyncing(TRUE);
    $this->workspaceManager->executeInWorkspace($deliveryItem->getTargetWorkspace(), function () use ($result) {
      $result->save();
    });

    // TODO: Properly detect left/right/merge/identical states.
    $deliveryItem->resolution = DeliveryItem::RESOLUTION_MERGE;
    $deliveryItem->result_revision = $result->{$revisionField};
    $deliveryItem->save();
  }

  public function getActiveRevision(DeliveryItem $deliveryItem) {
    $storage = $this->getContentEntityStorage($deliveryItem->getTargetType());
    $targets = $this->workspaceAssociation->getTrackedEntities($deliveryItem->getTargetWorkspace(), $deliveryItem->getTargetType(), [$deliveryItem->getTargetId()]);

    // If the entity is not yet tracked at all, just use the highest live revision.
    if (empty($targets)) {
      $live_revisions = array_keys($storage->getQuery()->allRevisions()
        ->notExists('workspace')
        ->condition($storage->getEntityType()->getKey('id'), $deliveryItem->getTargetId())->execute());
      return array_pop($live_revisions);
    }
    else {
      $targets = array_keys($targets[$deliveryItem->getTargetType()]);
      $target = array_pop($targets);
    }
    return $target;
  }

  protected function getWorkspaceHierarchy($workspaceId) {
    $workspace = $this->getContentEntityStorage('workspace')->load($workspaceId);
    $context = [$workspace->id()];
    while ($workspace = $workspace->parent->entity) {
      $context[] = $workspace->id();
    }
    $context[] = NULL;
    return $context;
  }

  /**
   * Returns the current workspace id along with descendent ids
   *
   * @return array
   */
  public function getCurrentWorkspaceIdWithDescendentIds() {
    $current_workspace_id = $this->getActiveWorkspace()->id();
    // Retrieve descendents of current workspace id
    $descendent_ids = $this->getWorkspaceDescendentIds($current_workspace_id);
    // Return current workspace id along with descendent ids
    return array_merge([$current_workspace_id], $descendent_ids);
  }

  /**
   * Returns the descendent workspace ids for a given workspace id
   * @param $workspaceId
   *
   * @return array
   */
  public function getWorkspaceDescendentIds($workspaceId) {
    /** @var \Drupal\workspaces\WorkspaceStorage $workspace_storage */
    $workspace_storage = $this->entityTypeManager->getStorage('workspace');
    // Get the workspace hierarchy
    $workspace_tree = $workspace_storage->loadTree();
    // Return descendents of given workspace id
    return (isset($workspace_tree[$workspaceId])) ? $workspace_tree[$workspaceId]->_descendants : [];
  }

  /**
   * Helper method to return the current active workspace.
   *
   * @return \Drupal\workspaces\WorkspaceInterface
   */
  public function getActiveWorkspace() {
    return $this->workspaceManager->getActiveWorkspace();
  }

  /**
   * Returns an array of workspace IDs referenced by a given delivery.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return array
   */
  public function getTargetWorkspacesFromDelivery(DeliveryInterface $delivery) {
    $workspaces = $delivery->get('workspaces');
    if (!$workspaces instanceof EntityReferenceFieldItemList) {
      return [];
    }
    $targets = $workspaces->getValue();
    return array_column($targets, 'target_id');
  }

  /**
   * Get the delivery target workspace IDs.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return array
   */
  public function getDeliveryTargets(DeliveryInterface $delivery) {
    $targets = [];
    foreach ($delivery->workspaces as $item) {
      $targets[] = $item->target_id;
    }
    return $targets;
  }

  /**
   * Returns true if a delivery can be pulled into the active workspace.
   *
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return bool
   */
  public function canPullDelivery(DeliveryInterface $delivery) {
    // Ensure we're not trying to pull changes to an inappropriate workspace.
    $targets = $this->getTargetWorkspacesFromDelivery($delivery);
    if (!in_array($this->getActiveWorkspace()->id(), $targets)) {
      return FALSE;
    }
    // Ensure there are pending changes.
    if (!$this->deliveryHasPendingChanges($delivery)) {
      return FALSE;
    }
    // Ensure no conflicts.
    if ($this->deliveryHasConflicts($delivery)) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * Returns an array containing an entity, conflict and update count.
   *
   * @param \Drupal\workspaces\WorkspaceInterface $workspace
   * @param \Drupal\delivery\DeliveryInterface $delivery
   *
   * @return array
   */
  public function getDeliveryDataByWorkspace(WorkspaceInterface $workspace, DeliveryInterface $delivery) {
    $entities = 0;
    $entities += $delivery->get('nodes')->count();
    $entities += $delivery->get('media')->count();
    $updates = 0;
    $conflicts = 0;

    $pages = [0];
    foreach ($delivery->nodes as $item) {
      $pages[] = $item->target_revision_id;
    }

    $pages = views_get_view_result('workspace_status_pages', 'embed', implode('+', $pages), $delivery->source->target_id, $workspace->id());
    foreach ($pages as $page) {
      $status = $page->status_value;
      if ($status == static::$CONFLICT) {
        $conflicts++;
      }
      if ($status == static::$MODIFIED) {
        $updates++;
      }
    }

    $media = [0];
    foreach ($delivery->media as $item) {
      $media[] = $item->target_revision_id;
    }

    $media = views_get_view_result('workspace_status_media', 'embed', implode('+', $media), $delivery->source->target_id, $workspace->id());
    foreach ($media as $medium) {
      $status = $medium->status_value;
      if ($status == static::$CONFLICT) {
        $conflicts++;
      }
      if ($status == static::$MODIFIED) {
        $updates++;
      }
    }

    return [
      'entities' => $entities,
      'conflicts' => $conflicts,
      'updates' => $updates,
    ];
  }

  /**
   * Returns true if the entity passed belongs the the current / active workspace
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *
   * @return bool
   */
  public function getEntityInheritedFlag(ContentEntityInterface $entity) {
    $entity_workspace = $entity->get('workspace')->target_id;
    $current_workspace = $this->workspaceManager->getActiveWorkspace()->id();

    return $entity_workspace === $current_workspace;
  }
}

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

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