wse-1.0.x-dev/src/PublishedRevisionStorage.php

src/PublishedRevisionStorage.php
<?php

namespace Drupal\wse;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Database\Connection;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\workspaces\WorkspaceAssociationInterface;
use Drupal\workspaces\WorkspaceInformationInterface;
use Drupal\workspaces\WorkspaceInterface;
use Drupal\workspaces\WorkspaceManagerInterface;

/**
 * The published revision storage service.
 */
class PublishedRevisionStorage {

  use DependencySerializationTrait;

  /**
   * The name of the table in which data is stored.
   *
   * @var string
   */
  const TABLE = 'workspace_published_revisions';

  /**
   * Constructor.
   */
  public function __construct(
    protected readonly EntityTypeManagerInterface $entityTypeManager,
    protected readonly WorkspaceAssociationInterface $workspacesAssociation,
    protected readonly Connection $connection,
    protected readonly TimeInterface $time,
    protected readonly WorkspaceManagerInterface $workspaceManager,
    protected readonly WorkspaceInformationInterface $workspacesInformation,
  ) {}

  /**
   * Stores revision IDs about to be published from the given workspace.
   *
   * @param \Drupal\workspaces\WorkspaceInterface $workspace
   *   The workspace to collect the revision IDs from.
   */
  public function storePublishedRevisions(WorkspaceInterface $workspace) {
    $tracked_entities = $this->workspacesAssociation->getTrackedEntities($workspace->id());

    $revert_revision_ids = [];
    foreach ($tracked_entities as $entity_type_id => $tracked_entity_ids) {
      $result = $this->workspaceManager->executeOutsideWorkspace(function () use ($entity_type_id, $tracked_entity_ids) {
        $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
        return $this->entityTypeManager->getStorage($entity_type_id)
          ->getQuery()
          ->condition($entity_type->getKey('id'), $tracked_entity_ids, 'IN')
          ->accessCheck(FALSE)
          ->currentRevision()
          ->execute();
      });

      if ($result) {
        $revert_revision_ids[$entity_type_id] = $result;
      }
    }

    $this->connection->insert(static::TABLE)
      ->fields([
        'workspace_id' => $workspace->id(),
        'workspace_label' => $workspace->label(),
        'published_on' => $this->time->getCurrentTime(),
        'published_revision_ids' => Json::encode($tracked_entities),
        'revert_revision_ids' => Json::encode($revert_revision_ids),
      ])
      ->execute();
  }

  /**
   * Retrieves all the revisions that were published as part of a workspace.
   *
   * @param string $workspace_id
   *   The workspace ID.
   * @param int|null $offset
   *   The zero-based offset of the first result returned.
   * @param int|null $limit
   *   The number of results to return.
   *
   * @return array
   *   Returns a multidimensional array where the first level keys are entity
   *   type IDs and the values are an array of entity IDs keyed by revision IDs.
   */
  public function getPublishedRevisions($workspace_id, $offset = NULL, $limit = NULL) {
    $published_revisions = [];

    $result = $this->connection->select(static::TABLE, 'wpr')
      ->fields('wpr', ['published_revision_ids'])
      ->condition('workspace_id', $workspace_id)
      ->orderBy('id', 'DESC')
      ->range(0, 1)
      ->execute()
      ->fetchField();

    if ($result) {
      $published_revisions = JSON::decode($result);

      if ($offset || $limit) {
        // Flatten the multidimensional array, so we can slice it with the
        // offset and limit passed.
        $all_published_revision_ids = [];
        foreach ($published_revisions as $entity_type_id => $published_revision_ids) {
          foreach ($published_revision_ids as $revision_id => $entity_id) {
            $all_published_revision_ids[$entity_type_id . ':' . $revision_id] = $entity_id;
          }
        }

        $published_revisions = [];
        $slice = array_slice($all_published_revision_ids, $offset, $limit);
        foreach ($slice as $key => $entity_id) {
          [$entity_type_id, $revision_id] = explode(':', $key, 2);
          $published_revisions[$entity_type_id][$revision_id] = $entity_id;
        }
      }
    }

    return $published_revisions;
  }

  /**
   * Retrieves the revert revisions for a workspace.
   *
   * @param string $workspace_id
   *   The workspace ID.
   *
   * @return array
   *   Returns a multidimensional array where the first level keys are entity
   *   type IDs and the values are an array of entity IDs keyed by revision IDs.
   */
  public function getRevertRevisions($workspace_id) {
    $revert_revisions = [];

    $result = $this->connection->select(static::TABLE, 'wpr')
      ->fields('wpr', ['revert_revision_ids'])
      ->condition('workspace_id', $workspace_id)
      ->orderBy('id', 'DESC')
      ->range(0, 1)
      ->execute()
      ->fetchField();

    if ($result) {
      $revert_revisions = JSON::decode($result);
    }

    return $revert_revisions;
  }

  /**
   * Stores all current default revision IDs after the workspace was published.
   *
   * @param \Drupal\workspaces\WorkspaceInterface $workspace
   *   The workspace to save the revision snapshot for.
   */
  public function storeAllRevisions(WorkspaceInterface $workspace) {
    $all_revision_ids = [];

    foreach (array_keys($this->workspacesInformation->getSupportedEntityTypes()) as $entity_type_id) {
      $result = $this->entityTypeManager
        ->getStorage($entity_type_id)
        ->getQuery()
        ->accessCheck(FALSE)
        ->currentRevision()
        ->execute();

      if ($result) {
        $all_revision_ids[$entity_type_id] = $result;
      }
    }

    if ($all_revision_ids) {
      $record_id = $this->connection->select(static::TABLE, 'wpr')
        ->fields('wpr', ['id'])
        ->condition('workspace_id', $workspace->id())
        ->orderBy('id', 'DESC')
        ->range(0, 1)
        ->execute()
        ->fetchField();

      $this->connection->update(static::TABLE)
        ->condition('id', $record_id)
        ->fields(['all_revision_ids' => Json::encode($all_revision_ids)])
        ->execute();
    }
  }

  /**
   * Retrieves the last published workspace.
   *
   * @return string
   *   The ID of the last published workspace.
   */
  public function getLastPublishedWorkspaceId() {
    return $this->connection->select(static::TABLE, 'wpr')
      ->fields('wpr', ['workspace_id'])
      ->orderBy('published_on', 'DESC')
      ->range(0, 1)
      ->execute()
      ->fetchField();
  }

  /**
   * Deletes the published revision record for a given workspace.
   *
   * @param string $workspace_id
   *   The workspace ID.
   */
  public function deleteRecord($workspace_id) {
    $this->connection->delete(static::TABLE)
      ->condition('workspace_id', $workspace_id)
      ->execute();
  }

}

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

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