You are here

public function BulkDocs::save in Replication 8

Same name and namespace in other branches
  1. 8.2 src/BulkDocs/BulkDocs.php \Drupal\replication\BulkDocs\BulkDocs::save()

Return value

\Drupal\replication\BulkDocs\BulkDocsInterface

Overrides BulkDocsInterface::save

File

src/BulkDocs/BulkDocs.php, line 136

Class

BulkDocs

Namespace

Drupal\replication\BulkDocs

Code

public function save() {

  // Writing a bulk of documents can potentially take a lot of time, so we
  // aquire a lock to ensure the integrity of the operation.
  do {

    // Check if the operation may be available.
    if ($this->lock
      ->lockMayBeAvailable('bulk_docs')) {

      // The operation may be available, so break the wait and continue if we
      // successfully can acquire a lock.
      if ($this->lock
        ->acquire('bulk_docs')) {
        break;
      }
    }
    $this->logger
      ->critical('Lock exists on bulk operation. Waiting.');
  } while ($this->lock
    ->wait('bulk_docs', 3000));
  $inital_workspace = $this->workspaceManager
    ->getActiveWorkspace();
  $this->workspaceManager
    ->setActiveWorkspace($this->workspace);

  // Temporarily disable the maintenance of the {comment_entity_statistics} table.
  $this->state
    ->set('comment.maintain_entity_statistics', FALSE);
  foreach ($this->entities as $entity) {
    $uuid = $entity
      ->uuid();
    $rev = $entity->_rev->value;
    try {

      // Check if the revision being posted already exists.
      $record = $this->revIndex
        ->useWorkspace($this->workspace
        ->id())
        ->get("{$uuid}:{$rev}");
      if ($record) {
        if (!$this->newEdits && !$record['is_stub']) {
          $this->result[] = [
            'error' => 'Conflict',
            'reason' => 'Document update conflict.',
            'id' => $uuid,
            'rev' => $rev,
          ];
          continue;
        }
      }

      // In cases where a stub was created earlier in the same bulk operation
      // it may already exists. This means we need to ensure the local ID
      // mapping is correct.
      $entity_type = $this->entityTypeManager
        ->getDefinition($entity
        ->getEntityTypeId());
      $id_key = $entity_type
        ->getKey('id');
      if ($record = $this->uuidIndex
        ->useWorkspace($this->workspace
        ->id())
        ->get($entity
        ->uuid())) {
        $entity->{$id_key}->value = $record['entity_id'];
        $entity
          ->enforceIsNew(FALSE);
      }
      else {
        $entity
          ->enforceIsNew(TRUE);
        $entity->{$id_key}->value = NULL;
      }
      $entity->workspace->target_id = $this->workspace
        ->id();
      $entity->_rev->new_edit = $this->newEdits;
      $this->entityTypeManager
        ->getStorage($entity
        ->getEntityTypeId())
        ->useWorkspace($this->workspace
        ->id());
      if ($entity
        ->save()) {
        $this->result[] = [
          'id' => $uuid,
          'ok' => TRUE,
          'rev' => $entity->_rev->value,
        ];
        if ($this->config
          ->get('verbose_logging')) {
          $this->logger
            ->info($entity_type
            ->getLabel() . ' ' . $entity
            ->label() . ' saved in workspace ' . $this->workspace
            ->label());
        }
      }
    } catch (\Throwable $e) {
      $message = $e
        ->getMessage();
      $this->result[] = [
        'error' => $message,
        'reason' => 'Exception',
        'id' => $uuid,
        'rev' => $entity->_rev->value,
      ];
      $arguments = Error::decodeException($e) + [
        '%uuid' => $uuid,
      ];
      $this->logger
        ->error('%type: @message in %function (line %line of %file). The error occurred while saving the entity with the UUID: %uuid.', $arguments);
    }
  }

  // Enable the the maintenance of entity statistics for comments.
  $this->state
    ->set('comment.maintain_entity_statistics', TRUE);

  // Switch back to the initial workspace.
  $this->workspaceManager
    ->setActiveWorkspace($inital_workspace);
  $this->lock
    ->release('bulk_docs');
  return $this;
}