You are here

protected function PushIntent::pushReference in CMS Content Sync 2.1.x

Same name and namespace in other branches
  1. 8 src/PushIntent.php \Drupal\cms_content_sync\PushIntent::pushReference()
  2. 2.0.x src/PushIntent.php \Drupal\cms_content_sync\PushIntent::pushReference()

Parameters

\Drupal\Core\Entity\EntityInterface $entity:

bool $dependency:

bool $push_to_same_pool:

Return value

string[] The IDs of the Pools that were used

Throws

\Drupal\Core\Entity\EntityStorageException

\Drupal\cms_content_sync\Exception\SyncException

2 calls to PushIntent::pushReference()
PushIntent::addDependency in src/PushIntent.php
Push the provided entity as a dependency meaning the referenced entity is available before this entity so it can be referenced on the remote site immediately like bricks or paragraphs.
PushIntent::addReference in src/PushIntent.php
Push the provided entity as a simple reference. There is no guarantee the referenced entity will be available on the remote site as well, but if it is, it will be de-referenced. If you need the referenced entity to be available, use {

File

src/PushIntent.php, line 1241

Class

PushIntent
Class PushIntent.

Namespace

Drupal\cms_content_sync

Code

protected function pushReference($entity, $dependency, $push_to_same_pool = false) {
  try {
    $all_pools = Pool::getAll();
    $pools = $this->flow
      ->getController()
      ->getPoolsToPushTo($entity, PushIntent::PUSH_AS_DEPENDENCY, SyncIntent::ACTION_CREATE, true);
    if (isset($pools[$this->pool->id]) || $push_to_same_pool) {
      $pools = [
        $this->pool->id => $this->pool,
      ] + $pools;
    }
    $used_pools = [];
    $flows = Flow::getAll();
    $flows = [
      $this->flow->id => $this->flow,
    ] + $flows;
    $version = Flow::getEntityTypeVersion($entity
      ->getEntityTypeId(), $entity
      ->bundle());
    foreach ([
      // Prefer Flows that push AS_DEPENDENCY.
      self::PUSH_AS_DEPENDENCY,
      // But then use Flows that push AUTOMATICALLY to support that use-case as well.
      // If an AS_DEPENDENCY Flow has pushed to a specific pool before, the Flow pushing AUTOMATICALLY will not
      // be able to export to that pool again here, that's why the order matters.
      self::PUSH_AUTOMATICALLY,
      // Also push manually exported references if configured.
      self::PUSH_MANUALLY,
    ] as $reason) {
      foreach ($flows as $flow) {
        if (!$flow
          ->getController()
          ->canPushEntity($entity, $reason, SyncIntent::ACTION_CREATE)) {
          continue;
        }
        $export_pools = $flow
          ->getController()
          ->getEntityTypeConfig($entity
          ->getEntityTypeId(), $entity
          ->bundle())['export_pools'];

        // Make sure the first pool we try is the pool of the current parent
        // push operation.
        if (isset($export_pools[$this->pool->id])) {
          $export_pools = [
            $this->pool->id => $export_pools[$this->pool->id],
          ] + $export_pools;
        }
        foreach ($export_pools as $pool_id => $behavior) {
          if (in_array($pool_id, $used_pools)) {
            continue;
          }
          if (Pool::POOL_USAGE_FORBID == $behavior) {
            continue;
          }

          // If this entity was newly created, it won't have any groups to push to
          // selected, unless they're FORCED. In this case we add default sync
          // groups based on the parent entity, as you would expect.
          if ($dependency) {
            if (!isset($pools[$pool_id])) {
              continue;
            }
            $pool = $pools[$pool_id];
            $info = EntityStatus::getInfoForEntity($entity
              ->getEntityTypeId(), $entity
              ->uuid(), $flow, $pool);
            if (!$info) {
              if (!$push_to_same_pool) {
                continue;
              }
              $info = EntityStatus::create([
                'flow' => $flow->id,
                'pool' => $pool->id,
                'entity_type' => $entity
                  ->getEntityTypeId(),
                'entity_uuid' => $entity
                  ->uuid(),
                'entity_type_version' => $version,
                'flags' => 0,
              ]);
            }
            $info
              ->isPushEnabled(null, true);
            $info
              ->save();
            PushIntent::pushEntity($entity, $reason, SyncIntent::ACTION_CREATE, $flow, $pool);
          }
          else {
            $pool = $all_pools[$pool_id];
            if (Pool::POOL_USAGE_ALLOW == $behavior) {
              $info = EntityStatus::getInfoForEntity($entity
                ->getEntityTypeId(), $entity
                ->uuid(), $flow, $pool);
              if (!$info || !$info
                ->isPushEnabled()) {
                continue;
              }
            }
          }
          $info = EntityStatus::getInfoForEntity($entity
            ->getEntityTypeId(), $entity
            ->uuid(), $flow, $pool);

          // In case the handler denied pushing the entity, we simply ignore the attempt.
          if (!$info || !$info
            ->getLastPush()) {

            // Unless we are referencing our parent entity that is also being pushed right now
            // e.g. a menu item will reference it's parent node but the parent will trigger
            // the menu item push so the status entity isn't there yet.
            if (!self::isPushing($entity
              ->getEntityTypeId(), $entity
              ->uuid())) {
              continue;
            }
          }
          $used_pools[] = $pool_id;

          // If "push to same pool" is set, we can stop after pushing there.
          if ($push_to_same_pool && $pool_id === $this->pool->id) {
            return $used_pools;
          }
        }
      }
    }
  } catch (\Exception $e) {
    $this
      ->saveFailedPush(PushIntent::PUSH_FAILED_DEPENDENCY_PUSH_FAILED, $e
      ->getMessage());
    throw new SyncException(SyncException::CODE_UNEXPECTED_EXCEPTION, $e);
  }
  return $used_pools;
}