View source
<?php
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\workspaces\Entity\Workspace;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;
function multiversion_module_implements_alter(&$implementations, $hook) {
if ($hook == 'entity_type_alter') {
$group = $implementations['multiversion'];
unset($implementations['multiversion']);
$implementations = [
'multiversion' => $group,
] + $implementations;
}
if ($hook == 'field_info_alter') {
$group = $implementations['multiversion'];
unset($implementations['multiversion']);
$implementations['multiversion'] = $group;
}
}
function multiversion_entity_type_alter(array &$entity_types) {
$manager = \Drupal::service('multiversion.manager');
foreach ($entity_types as $entity_type) {
if ($manager
->allowToAlter($entity_type)) {
$entity_keys = $entity_type
->getKeys();
if (empty($entity_keys['published'])) {
$entity_keys['published'] = 'status';
$entity_type
->set('entity_keys', $entity_keys);
}
if (!$entity_type
->isRevisionable()) {
$entity_keys['revision'] = 'revision_id';
$entity_type
->set('entity_keys', $entity_keys);
if ($entity_type
->getRevisionTable() === null) {
$entity_type
->set('revision_table', $entity_type
->id() . '_revision');
}
if ($entity_type
->getRevisionDataTable() === null) {
$entity_type
->set('revision_data_table', $entity_type
->id() . '_field_revision');
}
}
$namespace = 'Drupal\\multiversion\\Entity\\Storage\\Sql';
$original_storage_class = $entity_type
->getHandlerClass('storage');
$entity_type
->setHandlerClass('original_storage', $original_storage_class);
switch ($entity_type
->id()) {
case 'node':
$entity_type
->setHandlerClass('storage', "{$namespace}\\NodeStorage");
break;
case 'taxonomy_term':
$entity_type
->setHandlerClass('storage', "{$namespace}\\TermStorage");
break;
case 'comment':
$entity_type
->setHandlerClass('storage', "{$namespace}\\CommentStorage");
break;
case 'menu_link_content':
$entity_type
->setClass('Drupal\\multiversion\\Entity\\MenuLinkContent');
$entity_type
->setHandlerClass('storage', "{$namespace}\\MenuLinkContentStorage");
break;
case 'file':
$entity_type
->setClass('Drupal\\multiversion\\Entity\\File');
$entity_type
->setHandlerClass('storage', "{$namespace}\\FileStorage");
break;
case 'media':
$entity_type
->setHandlerClass('storage', "{$namespace}\\MediaStorage");
break;
case 'shortcut':
$entity_type
->setClass('Drupal\\multiversion\\Entity\\Shortcut');
if (in_array($original_storage_class, [
NULL,
'Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage',
])) {
$entity_type
->setHandlerClass('storage', "{$namespace}\\ContentEntityStorage");
}
break;
case 'entity_test':
$entity_type
->setClass('Drupal\\multiversion\\Entity\\EntityTest');
if (in_array($original_storage_class, [
NULL,
'Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage',
])) {
$entity_type
->setHandlerClass('storage', "{$namespace}\\ContentEntityStorage");
}
break;
case 'entity_test_mul':
$entity_type
->setClass('Drupal\\multiversion\\Entity\\EntityTestMul');
if (in_array($original_storage_class, [
NULL,
'Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage',
])) {
$entity_type
->setHandlerClass('storage', "{$namespace}\\ContentEntityStorage");
}
break;
case 'entity_test_rev':
$entity_type
->setClass('Drupal\\multiversion\\Entity\\EntityTestRev');
if (in_array($original_storage_class, [
NULL,
'Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage',
])) {
$entity_type
->setHandlerClass('storage', "{$namespace}\\ContentEntityStorage");
}
break;
case 'entity_test_mulrev':
$entity_type
->setClass('Drupal\\multiversion\\Entity\\EntityTestMulRev');
if (in_array($original_storage_class, [
NULL,
'Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage',
])) {
$entity_type
->setHandlerClass('storage', "{$namespace}\\ContentEntityStorage");
}
break;
default:
$storage_class = $entity_type
->getHandlerClass('storage');
if (in_array($storage_class, [
NULL,
'Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage',
])) {
$entity_type
->setHandlerClass('storage', "{$namespace}\\ContentEntityStorage");
}
break;
}
}
}
if (isset($entity_types['block_content']) && $manager
->allowToAlter($entity_types['block_content'])) {
$entity_types['block']
->setHandlerClass('storage', 'Drupal\\multiversion\\Entity\\Storage\\Sql\\BlockStorage');
}
}
function multiversion_entity_base_field_info(EntityTypeInterface $entity_type) {
$manager = \Drupal::service('multiversion.manager');
if ($manager
->allowToAlter($entity_type)) {
$fields = [];
$published_key = $entity_type
->getKey('published') ?: 'status';
if (empty($fields[$published_key])) {
$fields[$published_key] = BaseFieldDefinition::create('boolean')
->setName($published_key)
->setTargetEntityTypeId($entity_type
->id())
->setTargetBundle(NULL)
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating the published state.'))
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDefaultValue(TRUE);
}
$fields['_deleted'] = BaseFieldDefinition::create('boolean')
->setName('_deleted')
->setTargetEntityTypeId($entity_type
->id())
->setTargetBundle(NULL)
->setLabel(t('Deleted flag'))
->setDescription(t('Indicates if the entity is flagged as deleted or not.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setDefaultValue(FALSE)
->setCardinality(1);
$fields['_rev'] = BaseFieldDefinition::create('revision_token')
->setName('_rev')
->setTargetEntityTypeId($entity_type
->id())
->setTargetBundle(NULL)
->setLabel(t('Revision token'))
->setDescription(t('The token for this entity revision.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setCardinality(1)
->setReadOnly(TRUE);
return $fields;
}
}
function multiversion_data_type_info_alter(&$info) {
$info['entity_reference']['class'] = '\\Drupal\\multiversion\\EntityReference';
}
function multiversion_field_info_alter(&$info) {
$info['entity_reference']['class'] = '\\Drupal\\multiversion\\EntityReferenceItem';
$info['file']['class'] = '\\Drupal\\multiversion\\FileItem';
$info['image']['class'] = '\\Drupal\\multiversion\\ImageItem';
if (isset($info['entity_reference_revisions'])) {
$info['entity_reference_revisions']['class'] = '\\Drupal\\multiversion\\EntityReferenceRevisionsItem';
}
}
function multiversion_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
$manager = \Drupal::service('multiversion.manager');
if ($manager
->allowToAlter($entity_type)) {
$exclude_fields = [
$entity_type
->getKey('id'),
$entity_type
->getKey('revision') ?: 'revision_id',
$entity_type
->getKey('uuid'),
$entity_type
->getKey('bundle'),
'_deleted',
'_rev',
];
foreach ($fields as $key => $field) {
if (!in_array($key, $exclude_fields)) {
$field
->setRevisionable(TRUE);
}
}
}
}
function multiversion_views_post_execute(ViewExecutable $view) {
$base_field = $view->storage
->get('base_field');
$table_info = $view->query
->getEntityTableInfo();
$content_type_info = array_column($table_info, 'entity_type');
if (is_array($view->result) && ($content_type = reset($content_type_info))) {
$manager = \Drupal::service('multiversion.manager');
$storage = \Drupal::entityTypeManager()
->getStorage($content_type);
if ($manager
->allowToAlter($storage
->getEntityType())) {
$ids = [];
foreach ($view->result as $index => $row) {
if (empty($row->_entity) && !empty($row->{$base_field})) {
$ids[$index] = $row->{$base_field};
}
}
$entities = $storage
->loadMultipleDeleted($ids);
foreach ($view->result as $index => $row) {
if (empty($row->_entity) && !empty($row->{$base_field}) && isset($entities[$row->{$base_field}])) {
$view->result[$index]->_entity = $entities[$row->{$base_field}];
}
elseif (empty($row->_entity)) {
unset($view->result[$index]);
}
}
}
}
}
function multiversion_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
$views_ids = [
'content',
'frontpage',
'comments_recent',
'content_recent',
'taxonomy_term',
'glossary',
'archive',
'block_content',
];
if (in_array($view
->id(), $views_ids)) {
$manager = \Drupal::service('multiversion.manager');
$entity_type = $view
->getBaseEntityType();
if (!$manager
->isEnabledEntityType($entity_type)) {
return;
}
$base_table = $view->storage
->get('base_table');
$view->query->where[1]['conditions'][] = [
'field' => $base_table . '._deleted',
'value' => FALSE,
'operator' => '=',
];
}
}
function multiversion_query_entity_query_alter(AlterableInterface $query) {
$entity_type_id = $query
->getMetaData('entity_type');
$entity_type = \Drupal::entityTypeManager()
->getDefinition($entity_type_id);
if ($entity_type_id && \Drupal::service('multiversion.manager')
->isEnabledEntityType($entity_type)) {
$revision_key = $entity_type
->getKey('revision');
$data_table = $entity_type
->getDataTable();
if ($data_table) {
if (!in_array($data_table, array_column($query
->getTables(), 'table'))) {
$query
->join($data_table, NULL, 'base_table.' . $revision_key . '=' . $data_table . '.' . $revision_key);
}
}
}
}
function multiversion_query_taxonomy_term_access_alter(AlterableInterface $query) {
$active_workspace = \Drupal::service('workspaces.manager')
->getActiveWorkspace();
if (!$active_workspace
->isDefaultWorkspace() && !$query
->hasTag('entity_query_taxonomy_term')) {
$workspace_association_table = 'workspace_association';
$query
->leftJoin($workspace_association_table, $workspace_association_table, "%alias.target_entity_type_id = 'taxonomy_term' AND %alias.target_entity_id = t.tid");
$query
->condition($query
->orConditionGroup()
->condition("{$workspace_association_table}.workspace", $active_workspace
->id())
->condition("{$workspace_association_table}.workspace", NULL, 'IS'));
}
}
function multiversion_form_node_type_edit_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
unset($form['workflow']['options']['#options']['revision']);
}
function multiversion_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
if (isset($form['revision']['#group']) && $form['revision']['#group'] == 'revision_information') {
$form['revision']['#default_value'] = TRUE;
$form['revision']['#disabled'] = TRUE;
}
}
function multiversion_prepare_file_destination($destination) {
$dirname = \Drupal::service('file_system')
->dirname($destination);
return file_prepare_directory($dirname, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY);
}
function multiversion_menu_links_discovered_alter(&$links) {
if (\Drupal::moduleHandler()
->moduleExists('menu_link_content')) {
$storage = \Drupal::entityTypeManager()
->getStorage('menu_link_content');
if (\Drupal::service('multiversion.manager')
->isEnabledEntityType($storage
->getEntityType())) {
$workspaces = Workspace::loadMultiple();
foreach ($workspaces as $workspace_id => $workspace) {
$storage
->useWorkspace($workspace_id);
$menu_link_content_entities = $storage
->loadMultiple();
$new_ids = [];
$links_to_purge = [];
foreach ($menu_link_content_entities as $menu_link_content) {
$uuid = $menu_link_content
->uuid();
$old_id = "menu_link_content:{$uuid}";
$new_id = "{$old_id}:" . $menu_link_content
->id();
if (isset($links[$old_id])) {
$links_to_purge[] = $old_id;
unset($links[$old_id]);
}
$new_ids[$old_id] = $new_id;
if (!isset($links[$new_id])) {
$links[$new_id] = $menu_link_content
->getPluginDefinition();
}
$links[$new_id]['class'] = 'Drupal\\multiversion\\Plugin\\Menu\\MenuLinkContent';
}
if ($links_to_purge) {
\Drupal::service('menu.tree_storage')
->purgeMultiple($links_to_purge);
}
foreach ($links as $id => $link) {
if (!empty($link['parent']) && in_array($link['parent'], array_keys($new_ids))) {
$links[$id]['parent'] = $new_ids[$link['parent']];
}
}
$storage
->useWorkspace(NULL);
}
}
}
}
function multiversion_modules_installed($modules) {
$entity_type_manager = \Drupal::entityTypeManager();
$supported_entity_types = \Drupal::configFactory()
->getEditable('multiversion.settings')
->get('supported_entity_types');
$supported_entity_types = $supported_entity_types ?: [];
$entities_to_enable = [];
foreach ($supported_entity_types as $entity_type_id) {
$entity_type = $entity_type_manager
->getDefinition($entity_type_id, FALSE);
if (!empty($entity_type) && in_array($entity_type
->getProvider(), $modules)) {
$entities_to_enable[$entity_type_id] = $entity_type;
}
}
if (!empty($entities_to_enable)) {
\Drupal::service('multiversion.manager')
->enableEntityTypes($entities_to_enable);
}
}