View source
<?php
namespace Drupal\config_entity_revisions;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\diff\DiffEntityComparison;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\Serializer\Serializer;
use Drupal\Core\Database\Connection;
abstract class ConfigEntityRevisionsControllerBase extends ControllerBase implements ConfigEntityRevisionsControllerInterface {
protected $renderer;
protected $config;
protected $entityComparison;
protected $serialiser;
protected $container;
protected $dateFormatter;
protected $connection;
public function __construct(ContainerInterface $container, DateFormatterInterface $date_formatter, RendererInterface $renderer, ImmutableConfig $config, DiffEntityComparison $entity_comparison, EntityTypeManager $entity_type_manager, AccountProxyInterface $current_user, Serializer $serialiser, Connection $connection) {
$this->container = $container;
$this->dateFormatter = $date_formatter;
$this->renderer = $renderer;
$this->config = $config;
$this->entityComparison = $entity_comparison;
$this->entityTypeManager = $entity_type_manager;
$this->currentUser = $current_user;
$this->serialiser = $serialiser;
$this->connection = $connection;
}
public static function create(ContainerInterface $container) {
return new static($container, $container
->get('date.formatter'), $container
->get('renderer'), $container
->get('config.factory')
->get('diff.settings'), $container
->get('diff.entity_comparison'), $container
->get('entity_type.manager'), $container
->get('current_user'), $container
->get('serializer'), $container
->get('database'));
}
public function createInitialRevision(ConfigEntityRevisionsInterface $config_entity) {
$contentID = $config_entity
->getContentEntityID();
if ($contentID) {
return NULL;
}
$originalEntity = $config_entity
->configEntityStorage()
->load($config_entity
->id());
$source = $originalEntity ? $originalEntity : $config_entity;
$bundle_type = $config_entity
->getEntityTypeId() . "_revisions";
$user_id = $this->container
->get('current_user')
->id();
$request_time = $this->container
->get('datetime.time')
->getRequestTime();
$contentEntity = $config_entity
->contentEntityStorage()
->create([
'form' => $source
->get('uuid'),
'configuration' => $this->serialiser
->serialize($source, 'json'),
'type' => $bundle_type,
]);
$contentEntity
->setNewRevision(TRUE);
$contentEntity->revision_log = 'Original revision';
$contentEntity
->setRevisionCreationTime($request_time);
$contentEntity
->setRevisionUserId($user_id);
$contentEntity->moderation_state->value = 'draft';
$contentEntity
->save();
$contentID = $contentEntity
->id();
$config_entity
->setContentEntityID($contentID);
$config_entity
->save();
return $contentEntity;
}
public function createUpdateRevision(ConfigEntityRevisionsInterface $config_entity) {
$revisionsEntity = NULL;
$previous_state = FALSE;
if (!empty($config_entity
->getRevisionId())) {
$revisionsEntity = $config_entity
->contentEntityStorage()
->loadRevision($config_entity
->getRevisionID());
$previous_state = $revisionsEntity->moderation_state->value;
}
else {
$contentID = $config_entity
->getContentEntityID();
if (is_null($contentID)) {
return;
}
$revisionsEntity = $config_entity
->contentEntityStorage()
->load($contentID);
}
$revisionsEntity
->set('configuration', $this->serialiser
->serialize($config_entity, 'json'));
$revisionsEntity
->setRevisionUserId($this->currentUser
->id());
$revisionsEntity
->setRevisionCreationTime($this->container
->get('datetime.time')
->getRequestTime());
$new_message = $config_entity
->get('revision_log_message')[0]['value'];
$new_revision = $config_entity
->get('revision');
$moderation_state = is_null($config_entity
->get('moderation_state')) ? null : $config_entity
->get('moderation_state')[0]['value'];
$published = NULL;
if (!is_null($moderation_state)) {
$published = $moderation_state == 'published';
}
if (is_null($moderation_state) && is_null($new_revision)) {
$new_revision = FALSE;
}
if (!is_null($new_message)) {
$revisionsEntity
->setRevisionLogMessage($config_entity
->get('revision_log_message')[0]['value']);
}
$revisionsEntity
->setNewRevision($new_revision);
if (!is_null($moderation_state)) {
$revisionsEntity->moderation_state = $moderation_state;
}
if (!is_null($published)) {
if ($published) {
$revisionsEntity
->setPublished();
}
else {
$revisionsEntity
->setUnpublished();
}
$revisionsEntity
->isDefaultRevision($published);
}
$revisionsEntity
->save();
if (($previous_state == 'published') !== $published) {
$this
->resetDefaultRevision($revisionsEntity);
}
}
public function resetDefaultRevision(ContentEntityInterface $content_entity) {
$content_entity_id = $content_entity
->id();
$revisions = $this->connection
->select("config_entity_revisions_revision", 'c')
->fields('c', [
'revision',
'revision_default',
'published',
])
->condition('id', $content_entity_id)
->orderBy('revision', 'DESC')
->execute()
->fetchAllAssoc('revision');
$first_published = NULL;
$first_revision = NULL;
$remove_default = [];
foreach ($revisions as $revision) {
if (!$first_revision) {
$first_revision = $revision;
}
if ($revision->published && !$first_published) {
$first_published = $revision;
}
if ($revision->revision_default) {
$remove_default[$revision->revision] = 1;
}
}
$default_revision = $first_published ?: $first_revision;
if ($default_revision) {
unset($remove_default[$default_revision->revision]);
}
if (!empty($remove_default)) {
$this->connection
->update("config_entity_revisions_revision")
->condition('revision', array_keys($remove_default), 'IN')
->fields([
'revision_default' => 0,
])
->execute();
}
if ($default_revision) {
if (!$default_revision->revision_default) {
$this->connection
->update("config_entity_revisions_revision")
->condition('revision', $default_revision->revision)
->fields([
'revision_default' => 1,
])
->execute();
}
$this->connection
->update("config_entity_revisions")
->condition('id', $content_entity_id)
->fields([
'revision' => $default_revision->revision,
])
->execute();
}
}
public function getRevisionIds($content_entity_id) {
$revisions = $this->connection
->select("config_entity_revisions_revision", 'c')
->fields('c', [
'revision',
])
->condition('id', $content_entity_id)
->execute()
->fetchCol();
return $revisions;
}
public function deleteRevision($revision) {
$was_default = $revision
->isDefaultRevision();
$revisions = $this
->getRevisionIds($revision
->id());
if ($was_default) {
$this->connection
->update("config_entity_revisions_revision")
->condition('id', $revision
->id())
->fields([
'revision_default' => 0,
])
->execute();
$revision_to_use = $revisions[0] == $this->revision
->getRevisionId() ? $revisions[1] : $revisions[0];
$new_default = $this->configEntityRevisionsStorage
->loadRevision($revision_to_use);
$new_default
->enforceIsNew(FALSE);
$new_default
->isDefaultRevision(TRUE);
$new_default
->save();
}
$this->entityTypeManager
->getStorage('config_entity_revisions')
->deleteRevision($revision
->getRevisionId());
}
public function deleteRevisions(ConfigEntityRevisionsInterface $config_entity) {
$contentEntity = $config_entity
->getContentEntity();
if ($contentEntity) {
$config_entity
->contentEntityStorage()
->delete([
$contentEntity,
]);
}
}
public function loadConfigEntityRevision($revision = NULL, $entity = '') {
$config_entity_name = $this
->config_entity_name();
if (!$entity) {
try {
$match = \Drupal::service('router')
->matchRequest(\Drupal::request());
} catch (\Exception $exception) {
$match = [];
}
$entity = isset($match[$config_entity_name]) ? $match[$config_entity_name] : NULL;
}
if (is_string($entity)) {
$entity = $this->entityTypeManager
->getStorage($config_entity_name)
->load($entity);
}
if ($revision) {
$revisionsEntity = $this->entityTypeManager
->getStorage('config_entity_revisions')
->loadRevision($revision);
$entity = \Drupal::getContainer()
->get('serializer')
->deserialize($revisionsEntity
->get('configuration')->value, get_class($entity), 'json');
$entity
->set('settingsOriginal', $entity
->get('settings'));
$entity
->set('enforceIsNew', FALSE);
$entity
->updateLoadedRevisionId($revisionsEntity
->getRevisionId());
}
return $entity;
}
}