diff --git a/core/modules/quickedit/quickedit.module b/core/modules/quickedit/quickedit.module index d569de2503..9c8a5637fa 100644 --- a/core/modules/quickedit/quickedit.module +++ b/core/modules/quickedit/quickedit.module @@ -193,5 +193,6 @@ function _quickedit_entity_is_latest_revision(ContentEntityInterface $entity) { ->sort($entity_definition->getKey('revision'), 'DESC') ->range(0, 1) ->execute(); - return $entity->getLoadedRevisionId() == array_keys($revision_ids)[0]; + $array_keys = array_keys($revision_ids); + return $entity->getLoadedRevisionId() == reset(array_keys($array_keys)); } diff --git a/core/modules/workspace/src/WorkspaceListBuilder.php b/core/modules/workspace/src/WorkspaceListBuilder.php index d16e238b8d..db7a35c9d6 100644 --- a/core/modules/workspace/src/WorkspaceListBuilder.php +++ b/core/modules/workspace/src/WorkspaceListBuilder.php @@ -79,7 +79,7 @@ public function getDefaultOperations(EntityInterface $entity) { /** @var \Drupal\workspace\Entity\WorkspaceInterface $entity */ $operations = parent::getDefaultOperations($entity); if (isset($operations['edit'])) { - $operations['edit']['query']['destination'] = $entity->toUrl('collection'); + $operations['edit']['query']['destination'] = $entity->toUrl('collection')->toString(); } $active_workspace = $this->workspaceManager->getActiveWorkspace(); @@ -87,7 +87,7 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['activate'] = [ 'title' => $this->t('Set Active'), 'weight' => 20, - 'url' => $entity->toUrl('activate-form', ['query' => ['destination' => $entity->toUrl('collection')]]), + 'url' => $entity->toUrl('activate-form', ['query' => ['destination' => $entity->toUrl('collection')->toString()]]), ]; } @@ -95,7 +95,7 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['deployment'] = [ 'title' => $this->t('Deploy content'), 'weight' => 20, - 'url' => $entity->toUrl('deployment-form', ['query' => ['destination' => $entity->toUrl('collection')]]), + 'url' => $entity->toUrl('deployment-form', ['query' => ['destination' => $entity->toUrl('collection')->toString()]]), ]; } diff --git a/core/modules/workspace/workspace.module b/core/modules/workspace/workspace.module index 5683157088..e4b2ebd2a5 100644 --- a/core/modules/workspace/workspace.module +++ b/core/modules/workspace/workspace.module @@ -40,13 +40,15 @@ function workspace_help($route_name, RouteMatchInterface $route_match) { */ function workspace_entity_base_field_info(EntityTypeInterface $entity_type) { if (\Drupal::service('workspace.manager')->entityTypeCanBelongToWorkspaces($entity_type)) { - return ['workspace' => BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Workspace')) - ->setDescription(t('The Workspace of this piece of content.')) - ->setComputed(TRUE) - ->setClass(WorkspaceFieldItemList::class) - ->setSetting('target_type', 'workspace') - ->setTranslatable(TRUE)]; + return [ + 'workspace' => BaseFieldDefinition::create('entity_reference') + ->setLabel(t('Workspace')) + ->setDescription(t('The Workspace of this piece of content.')) + ->setComputed(TRUE) + ->setClass(WorkspaceFieldItemList::class) + ->setSetting('target_type', 'workspace') + ->setTranslatable(TRUE) + ]; } } @@ -58,16 +60,22 @@ function workspace_query_entity_query_alter(AlterableInterface $query) { $workspace_manager = \Drupal::service('workspace.manager'); $active_workspace = $workspace_manager->getActiveWorkspace(); $default_workspace_id = \Drupal::getContainer()->getParameter('workspace.default'); + // Don't alter any entity queries if the active workspace is the default + // workspace (ie. live). if ($active_workspace == $default_workspace_id) { return; } + // Only alter if the entity type can belong to a workspace, being revisionable + // and publishable. $entity_type = \Drupal::entityTypeManager()->getDefinition($query->getMetaData('entity_type')); if (!empty($entity_type) && $workspace_manager->entityTypeCanBelongToWorkspaces($entity_type)) { $entity_type_id = $entity_type->id(); $entity_type_id_key = $entity_type->getKey('id'); + // Join the Content Workspace entity's field revision table. $query->leftJoin('content_workspace_field_revision', 'cwfr', 'base_table.' . $entity_type_id_key . ' = cwfr.content_entity_id'); $query->condition('cwfr.content_entity_type_id', $entity_type_id); + // Only return entities for the active or default workspace. $query->condition('cwfr.workspace', [$active_workspace, $default_workspace_id], 'IN'); } } @@ -80,15 +88,20 @@ function workspace_views_query_alter(ViewExecutable $view, QueryPluginBase $quer $workspace_manager = \Drupal::service('workspace.manager'); $active_workspace = $workspace_manager->getActiveWorkspace(); $default_workspace_id = \Drupal::getContainer()->getParameter('workspace.default'); + // Don't alter any views if the active workspace is the default workspace + // (ie. live). if ($active_workspace == $default_workspace_id) { return; } + // Don't alter any views if the entity type can't belong to a workspace, + // being revisionable and publishable. $entity_type = $view->getBaseEntityType(); if (empty($entity_type) || !$workspace_manager->entityTypeCanBelongToWorkspaces($entity_type)) { return; } + // Join the view to the Content Workspace entity's field revision table. $configuration = [ 'table' => 'content_workspace_field_revision', 'field' => 'content_entity_id', @@ -101,9 +114,14 @@ function workspace_views_query_alter(ViewExecutable $view, QueryPluginBase $quer ->createInstance('standard', $configuration); /** @var \Drupal\views\Plugin\views\query\Sql $query */ $query->addRelationship('cwrf', $join, 'content_workspace_field_revision'); + // Return entities in the active workspace, the default workspace, or if the + // workspace value is set to NULL. $query->setWhereGroup('OR', 'workspace'); $query->addWhere('workspace', 'cwrf.workspace', [$active_workspace, $default_workspace_id], 'IN'); $query->addWhere('workspace', 'cwrf.workspace', NULL, 'IS'); + // If there is already a condition for publishing status, replace it with an + // 'OR' condition, based on the publishing status in the workspace and the + // general publishing status of the entity. foreach ($query->where as $where_id => $where) { foreach ($where['conditions'] as $condition_id => $condition) { if ($condition['field'] == $entity_type->getDataTable() . '.' . $entity_type->getKey('published')) { @@ -116,6 +134,8 @@ function workspace_views_query_alter(ViewExecutable $view, QueryPluginBase $quer } } + // Add a group_by option for all displays so only one result is returned per + // entity. foreach ($view->displayHandlers->getInstanceIds() as $display_id) { $view->displayHandlers->get($display_id)->setOption('group_by', TRUE); } @@ -127,16 +147,22 @@ function workspace_views_query_alter(ViewExecutable $view, QueryPluginBase $quer function workspace_entity_load(array &$entities, $entity_type_id) { /** @var \Drupal\workspace\WorkspaceManagerInterface $workspace_manager */ $workspace_manager = \Drupal::service('workspace.manager'); + // Don't alter the loaded entity if the entity type can't belong to a + // workspace. if (!$workspace_manager->entityTypeCanBelongToWorkspaces(\Drupal::entityTypeManager()->getDefinition($entity_type_id))) { return; } + // Don't alter the loaded entity if the active workspace is the default + // workspace. $active_workspace = $workspace_manager->getActiveWorkspace(); $default_workspace_id = \Drupal::getContainer()->getParameter('workspace.default'); if ($active_workspace == $default_workspace_id) { return; } + // Find the latest content workspace entity for an entity within the active or + // default workspaces. $keys = array_keys($entities); $results = \Drupal::entityTypeManager() ->getStorage('content_workspace') @@ -154,12 +180,16 @@ function workspace_entity_load(array &$entities, $entity_type_id) { ->getStorage('content_workspace') ->loadRevision($revision_id); $entity = $entities[$content_workspace->get('content_entity_id')->value]; + // If the latest revision is not the same as the loaded entity, replace it + // with the latest revision. if ($content_workspace->get('content_entity_revision_id')->value != $entity->getRevisionId()) { $new_entity = \Drupal::entityTypeManager() ->getStorage($entity_type_id) ->loadRevision($content_workspace->get('content_entity_revision_id')->value); $entities[$entity->id()] = $new_entity; } + // Update the entity's publishing status based on the publishing status + // within the workspace. $content_workspace->isPublished() ? $entities[$entity->id()]->setPublished() : $entities[$entity->id()]->setUnpublished(); } } @@ -287,9 +317,9 @@ function workspace_page_bottom(array &$page_bottom) { /** @var \Drupal\workspace\Entity\WorkspaceInterface $active_workspace */ $active_workspace = \Drupal::service('workspace.manager') ->getActiveWorkspace(TRUE); - $control_block = t('Current workspace:

@active_workspace

Manage workspaces', ['@active_workspace' => $active_workspace->label(), - '@collection_url' => Url::fromRoute('entity.workspace.collection') - ->toString() + $control_block = t('Current workspace:

@active_workspace

Manage workspaces', [ + '@active_workspace' => $active_workspace->label(), + '@collection_url' => Url::fromRoute('entity.workspace.collection')->toString() ]); $deploy_form = \Drupal::formBuilder() ->getForm(DeploymentForm::class, $active_workspace);