diff --git a/core/modules/workspace/src/Access/WorkspaceViewCheck.php b/core/modules/workspace/src/Access/WorkspaceViewCheck.php index 8d45be1df1..54f5943681 100644 --- a/core/modules/workspace/src/Access/WorkspaceViewCheck.php +++ b/core/modules/workspace/src/Access/WorkspaceViewCheck.php @@ -3,11 +3,13 @@ namespace Drupal\workspace\Access; use Drupal\Core\Access\AccessResult; -use Drupal\Core\Access\AccessResultInterface; use Drupal\Core\Routing\Access\AccessInterface; use Drupal\Core\Session\AccountInterface; use Drupal\workspace\Entity\WorkspaceInterface; +/** + * Class WorkspaceViewCheck + */ class WorkspaceViewCheck implements AccessInterface { /** @@ -15,15 +17,16 @@ class WorkspaceViewCheck implements AccessInterface { * * "View" in practice implies "is allowed to make active". * - * @param WorkspaceInterface $workspace + * @param \Drupal\workspace\Entity\WorkspaceInterface $workspace * The workspace to view. - * @param AccountInterface $account + * @param \Drupal\Core\Session\AccountInterface $account * The user account to check. * - * @return AccessResultInterface + * @return \Drupal\Core\Access\AccessResultInterface * The access result. */ public function access(WorkspaceInterface $workspace, AccountInterface $account) { return AccessResult::allowedIf($workspace->access('view', $account))->addCacheableDependency($workspace); } + } diff --git a/core/modules/workspace/src/Changes/Changes.php b/core/modules/workspace/src/Changes/Changes.php index 958e913d53..3ec177dd5a 100644 --- a/core/modules/workspace/src/Changes/Changes.php +++ b/core/modules/workspace/src/Changes/Changes.php @@ -47,7 +47,7 @@ class Changes implements ChangesInterface { /** * @param \Drupal\workspace\Entity\WorkspaceInterface $workspace * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * @param \Drupal\Workspace\Index\SequenceIndexInterface + * @param \Drupal\Workspace\Index\SequenceIndexInterface $sequence_index */ public function __construct(WorkspaceInterface $workspace, EntityTypeManagerInterface $entity_type_manager, SequenceIndexInterface $sequence_index) { $this->workspaceId = $workspace->id(); @@ -130,4 +130,4 @@ public function getLongpoll() { return $change; } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/Changes/ChangesFactory.php b/core/modules/workspace/src/Changes/ChangesFactory.php index de1da503f2..7787723dd7 100644 --- a/core/modules/workspace/src/Changes/ChangesFactory.php +++ b/core/modules/workspace/src/Changes/ChangesFactory.php @@ -1,4 +1,5 @@ instances[$workspace->id()]; } -} \ No newline at end of file + +} diff --git a/core/modules/workspace/src/Changes/ChangesFactoryInterface.php b/core/modules/workspace/src/Changes/ChangesFactoryInterface.php index 58dce7c059..d885469b46 100644 --- a/core/modules/workspace/src/Changes/ChangesFactoryInterface.php +++ b/core/modules/workspace/src/Changes/ChangesFactoryInterface.php @@ -18,4 +18,4 @@ */ public function get(WorkspaceInterface $workspace); -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/Changes/ChangesInterface.php b/core/modules/workspace/src/Changes/ChangesInterface.php index edd489ca19..4ddb356c8b 100644 --- a/core/modules/workspace/src/Changes/ChangesInterface.php +++ b/core/modules/workspace/src/Changes/ChangesInterface.php @@ -39,4 +39,4 @@ public function getNormal(); */ public function getLongpoll(); -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/Controller/DeploymentController.php b/core/modules/workspace/src/Controller/DeploymentController.php index d0743a5d1d..67d5cdaf29 100644 --- a/core/modules/workspace/src/Controller/DeploymentController.php +++ b/core/modules/workspace/src/Controller/DeploymentController.php @@ -7,10 +7,9 @@ use Drupal\Core\Form\FormBuilderInterface; use Drupal\workspace\Entity\Workspace; use Drupal\workspace\Form\DeploymentForm; -use Drupal\workspace\Form\WorkspaceSwitcherForm; +use Drupal\workspace\UpstreamManager; use Drupal\workspace\WorkspaceManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\Response; /** * Class DeploymentController @@ -28,14 +27,21 @@ class DeploymentController extends ControllerBase implements ContainerInjectionI protected $formBuilder; /** + * @var \Drupal\workspace\UpstreamManager + */ + protected $upstreamManager; + + /** * DeploymentController constructor. * * @param \Drupal\workspace\WorkspaceManagerInterface $workspace_manager * @param \Drupal\Core\Form\FormBuilderInterface $form_builder + * @param \Drupal\workspace\UpstreamManager */ - public function __construct(WorkspaceManagerInterface $workspace_manager, FormBuilderInterface $form_builder) { + public function __construct(WorkspaceManagerInterface $workspace_manager, FormBuilderInterface $form_builder, UpstreamManager $upstream_manager) { $this->workspaceManager = $workspace_manager; $this->formBuilder = $form_builder; + $this->upstreamManager = $upstream_manager; } /** @@ -44,32 +50,34 @@ public function __construct(WorkspaceManagerInterface $workspace_manager, FormBu public static function create(ContainerInterface $container) { return new static( $container->get('workspace.manager'), - $container->get('form_builder') + $container->get('form_builder'), + $container->get('workspace.upstream_manager') ); } /** * @return array */ - public function workspaces() { - $active_workspace_id = $this->workspaceManager->getActiveWorkspace(); - $workspaces = Workspace::loadMultiple(); - $active_workspace = $workspaces[$active_workspace_id]; - unset($workspaces[$active_workspace_id]); - return $this->formBuilder->getForm(DeploymentForm::class, $active_workspace); + public function workspaces($workspace = NULL) { + $active_workspace = Workspace::load($workspace); + $form = $this->formBuilder->getForm(DeploymentForm::class, $active_workspace); + return [ - '#theme' => 'workspace_deployment', - '#active_workspace' => $active_workspace, - '#workspaces' => $workspaces, - '#deploy' => $deploy, - '#attached' => [ - 'library' => [ - 'workspace/drupal.workspace.deployment', - ], - ], - '#cache' => [ - 'contexts' => ['workspace'], + '#type' => 'details', + '#title' => $this->t('Deploy content'), + '#open' => TRUE, + 'from' => [ + '#prefix' => '

', + '#markup' => $this->t('Update %from from %to or deploy to %to.', [ + '%from' => $active_workspace->label(), + '%to' => $this->upstreamManager + ->createInstance($active_workspace->get('upstream')->value) + ->getLabel() + ]), + '#suffix' => '

', ], + 'form' => $form, ]; } -} \ No newline at end of file + +} diff --git a/core/modules/workspace/src/Entity/ContentWorkspace.php b/core/modules/workspace/src/Entity/ContentWorkspace.php index 63573e307f..4702225336 100644 --- a/core/modules/workspace/src/Entity/ContentWorkspace.php +++ b/core/modules/workspace/src/Entity/ContentWorkspace.php @@ -40,7 +40,7 @@ * } * ) */ -class ContentWorkspace extends ContentEntityBase implements ContentWorkspaceInterface { +class ContentWorkspace extends ContentEntityBase implements ContentWorkspaceInterface { use EntityPublishedTrait; @@ -121,7 +121,7 @@ public function setOwner(UserInterface $account) { /** * Creates or updates an entity's workspace whilst saving that entity. * - * @param \Drupal\content_moderation\Entity\ContentWorkspace $content_workspace + * @param \Drupal\workspace\Entity\ContentWorkspace $content_workspace * The content moderation entity content entity to create or save. * * @internal @@ -141,7 +141,7 @@ public static function updateOrCreateFromEntity(ContentWorkspace $content_worksp * An array of default values. */ public static function getCurrentUserId() { - return array(\Drupal::currentUser()->id()); + return [\Drupal::currentUser()->id()]; } /** diff --git a/core/modules/workspace/src/Entity/ReplicationLog.php b/core/modules/workspace/src/Entity/ReplicationLog.php index 0af516af8c..f1415e7553 100644 --- a/core/modules/workspace/src/Entity/ReplicationLog.php +++ b/core/modules/workspace/src/Entity/ReplicationLog.php @@ -2,7 +2,6 @@ namespace Drupal\workspace\Entity; -use Drupal\Core\Entity\Entity; use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; @@ -137,4 +136,5 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { return $fields; } + } diff --git a/core/modules/workspace/src/Entity/Workspace.php b/core/modules/workspace/src/Entity/Workspace.php index a108262ec4..8251c59d4a 100644 --- a/core/modules/workspace/src/Entity/Workspace.php +++ b/core/modules/workspace/src/Entity/Workspace.php @@ -45,8 +45,10 @@ * "add-form" = "/admin/structure/workspace/add", * "edit-form" = "/admin/structure/workspace/{workspace}/edit", * "activate-form" = "/admin/structure/workspace/{workspace}/activate", + * "deployment-form" = "/admin/structure/workspace/{workspace}/deployment", * "collection" = "/admin/structure/workspace", * }, + * field_ui_base_route = "entity.workspace.collection", * ) */ class Workspace extends ContentEntityBase implements WorkspaceInterface { diff --git a/core/modules/workspace/src/EntityAccess.php b/core/modules/workspace/src/EntityAccess.php index a6641d2a89..4482894826 100644 --- a/core/modules/workspace/src/EntityAccess.php +++ b/core/modules/workspace/src/EntityAccess.php @@ -75,7 +75,6 @@ public static function create(ContainerInterface $container) { * @return AccessResult */ public function entityAccess(EntityInterface $entity, $operation, AccountInterface $account) { - // Workspaces themselves are handled by another hook. Ignore them here. if ($entity->getEntityTypeId() == 'workspace') { return AccessResult::neutral(); @@ -179,7 +178,7 @@ public function workspaceAccess(WorkspaceInterface $workspace, $operation, Accou * Hook bridge; * * @see hook_create_access(); - * @see hook_ENTITY_TYPE_create_access(). + * @see hook_ENTITY_TYPE_create_access() * * @param \Drupal\Core\Session\AccountInterface $account * @param array $context diff --git a/core/modules/workspace/src/Form/DeploymentForm.php b/core/modules/workspace/src/Form/DeploymentForm.php index c43ed5f2fe..0889f5c537 100644 --- a/core/modules/workspace/src/Form/DeploymentForm.php +++ b/core/modules/workspace/src/Form/DeploymentForm.php @@ -2,13 +2,10 @@ namespace Drupal\workspace\Form; -use Drupal\Core\Ajax\AjaxResponse; -use Drupal\Core\Ajax\ReplaceCommand; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\workspace\Entity\Workspace; use Drupal\workspace\Entity\WorkspaceInterface; -use Drupal\workspace\Replication\ReplicationManager; /** * Class DeploymentForm @@ -36,18 +33,48 @@ public function buildForm(array $form, FormStateInterface $form_state, Workspace '#value' => $workspace->id(), ]; - $form['submit'] = [ + $form['update'] = [ '#type' => 'submit', - '#value' => 'Deploy to ' . $upstream_plugin->getLabel(), + '#value' => $this->t('Update'), + '#submit' => [[$this, 'updateHandler']], + ]; + + $form['deploy'] = [ + '#type' => 'submit', + '#value' => $this->t('Deploy to %upstream', ['%upstream' => $upstream_plugin->getLabel()]), + '#submit' => [[$this, 'deployHandler']], + '#attributes' => [ + 'class' => ['primary', 'button--primary'], + ], ]; return $form; } /** - * @inheritDoc + * @param array $form + * @param \Drupal\Core\Form\FormStateInterface $form_state */ - public function submitForm(array &$form, FormStateInterface $form_state) { + public function updateHandler(array &$form, FormStateInterface $form_state) { + $workspace = Workspace::load($form_state->getValue('workspace_id')); + $upstream_manager = \Drupal::service('workspace.upstream_manager'); + try { + \Drupal::service('workspace.replication_manager')->replicate( + $upstream_manager->createInstance($workspace->get('upstream')->value), + $upstream_manager->createInstance('workspace:' . $workspace->id()) + ); + drupal_set_message('Update successful.'); + } + catch (\Exception $e) { + drupal_set_message('Deployment error', 'error'); + } + } + + /** + * @param array $form + * @param \Drupal\Core\Form\FormStateInterface $form_state + */ + public function deployHandler(array &$form, FormStateInterface $form_state) { $workspace = Workspace::load($form_state->getValue('workspace_id')); $upstream_manager = \Drupal::service('workspace.upstream_manager'); try { @@ -60,7 +87,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) { catch (\Exception $e) { drupal_set_message('Deployment error', 'error'); } + } + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + // Submission handled in custom handlers. } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/Form/WorkspaceActivateForm.php b/core/modules/workspace/src/Form/WorkspaceActivateForm.php index c2234c2cc9..1ccdda6150 100644 --- a/core/modules/workspace/src/Form/WorkspaceActivateForm.php +++ b/core/modules/workspace/src/Form/WorkspaceActivateForm.php @@ -38,7 +38,7 @@ public function buildForm(array $form, FormStateInterface $form_state, Workspace '#value' => 'Activate', ]; - $form['#title'] = $this->t('Activate workspace %label', array('%label' => $workspace->label())); + $form['#title'] = $this->t('Activate workspace %label', ['%label' => $workspace->label()]); return $form; } diff --git a/core/modules/workspace/src/Form/WorkspaceActivateFormBase.php b/core/modules/workspace/src/Form/WorkspaceActivateFormBase.php index dba7776af8..619359be01 100644 --- a/core/modules/workspace/src/Form/WorkspaceActivateFormBase.php +++ b/core/modules/workspace/src/Form/WorkspaceActivateFormBase.php @@ -5,7 +5,6 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; -use Drupal\workspace\Entity\WorkspaceInterface; use Drupal\workspace\WorkspaceManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -54,7 +53,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { } // Ensure the workspace by that id exists. - /** @var WorkspaceInterface $workspace */ + /** @var \Drupal\workspace\Entity\WorkspaceInterface $workspace */ $workspace = $this->entityTypeManager->getStorage('workspace')->load($id); if (!$workspace) { $form_state->setErrorByName('workspace_id', 'This workspace no longer exists.'); @@ -66,17 +65,17 @@ public function validateForm(array &$form, FormStateInterface $form_state) { */ public function submitForm(array &$form, FormStateInterface $form_state) { $id = $form_state->getValue('workspace_id'); - /** @var WorkspaceInterface $workspace */ + /** @var \Drupal\workspace\Entity\WorkspaceInterface $workspace */ $workspace = $this->entityTypeManager->getStorage('workspace')->load($id); try { $this->workspaceManager->setActiveWorkspace($workspace); $form_state->setRedirect(''); } - catch(\Exception $e) { + catch (\Exception $e) { watchdog_exception('Workspace', $e); drupal_set_message($e->getMessage(), 'error'); } } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/Index/SequenceIndex.php b/core/modules/workspace/src/Index/SequenceIndex.php index 49d5bf5839..4dab7fb882 100644 --- a/core/modules/workspace/src/Index/SequenceIndex.php +++ b/core/modules/workspace/src/Index/SequenceIndex.php @@ -53,7 +53,7 @@ public function useWorkspace($id) { * {@inheritdoc} */ public function add(ContentEntityInterface $entity) { - $workspace_id = null; + $workspace_id = NULL; $record = $this->buildRecord($entity); if ($entity->getEntityType()->get('workspace') === FALSE) { $workspace_id = 0; @@ -87,7 +87,7 @@ public function getLastSequenceId() { * @param $workspace_id * @return \Drupal\key_value\KeyValueStore\KeyValueStoreSortedSetInterface */ - protected function sortedSetStore($workspace_id = null) { + protected function sortedSetStore($workspace_id = NULL) { if (!$workspace_id) { $workspace_id = $this->workspaceId ?: $this->workspaceManager->getActiveWorkspace()->id(); } @@ -108,4 +108,4 @@ protected function buildRecord(ContentEntityInterface $entity) { ]; } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/Index/SequenceIndexInterface.php b/core/modules/workspace/src/Index/SequenceIndexInterface.php index 1518a02beb..6055960e40 100644 --- a/core/modules/workspace/src/Index/SequenceIndexInterface.php +++ b/core/modules/workspace/src/Index/SequenceIndexInterface.php @@ -23,7 +23,7 @@ public function add(ContentEntityInterface $entity); /** * @param float $start * @param float $stop - * @param boolean $inclusive + * @param bool $inclusive * * @return array */ @@ -34,4 +34,4 @@ public function getRange($start, $stop = NULL, $inclusive = TRUE); */ public function getLastSequenceId(); -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/KeyValueStore/DatabaseStorageSortedSet.php b/core/modules/workspace/src/KeyValueStore/DatabaseStorageSortedSet.php index a517ee47d9..0c6d875dfe 100644 --- a/core/modules/workspace/src/KeyValueStore/DatabaseStorageSortedSet.php +++ b/core/modules/workspace/src/KeyValueStore/DatabaseStorageSortedSet.php @@ -54,7 +54,7 @@ class DatabaseStorageSortedSet implements KeyValueStoreSortedSetInterface { * @param string (optional) $table * The name of the SQL table to use, defaults to key_value_sorted. */ - public function __construct($collection, SerializationInterface $serializer, Connection $connection, $table = 'key_value_sorted') { + public function __construct($collection, SerializationInterface $serializer, Connection $connection, $table = 'key_value_sorted') { $this->collection = $collection; $this->serializer = $serializer; $this->connection = $connection; @@ -87,7 +87,7 @@ public function addMultiple(array $pairs) { ->condition('value', $encoded_value) ->execute(); } - catch(\Exception $e) { + catch (\Exception $e) { // If there was an exception, try to create the table. if (!$try_again = $this->ensureTableExists()) { // If the exception happened for other reason than the missing @@ -139,7 +139,7 @@ public function getRange($start, $stop = NULL) { } return $values; } - catch(\Exception $e) { + catch (\Exception $e) { $this->catchException($e); } } @@ -153,7 +153,7 @@ public function getMaxKey() { ':collection' => $this->collection ])->fetchField(); } - catch(\Exception $e) { + catch (\Exception $e) { $this->catchException($e); } } @@ -167,7 +167,7 @@ public function getMinKey() { ':collection' => $this->collection ])->fetchField(); } - catch(\Exception $e) { + catch (\Exception $e) { $this->catchException($e); } } @@ -183,7 +183,7 @@ protected function ensureTableExists() { if (!$database_schema->tableExists($this->table)) { $database_schema->createTable($this->table, $this->schemaDefinition()); return TRUE; - } + } } // If the table already exists, then attempting to recreate it will throw an // exception. In this case just catch the exception and do nothing. @@ -246,4 +246,5 @@ protected function schemaDefinition() { ], ]; } + } diff --git a/core/modules/workspace/src/KeyValueStore/KeyValueDatabaseSortedSetFactory.php b/core/modules/workspace/src/KeyValueStore/KeyValueDatabaseSortedSetFactory.php index 363d5aa49d..b85d288bb1 100644 --- a/core/modules/workspace/src/KeyValueStore/KeyValueDatabaseSortedSetFactory.php +++ b/core/modules/workspace/src/KeyValueStore/KeyValueDatabaseSortedSetFactory.php @@ -32,7 +32,7 @@ class KeyValueDatabaseSortedSetFactory implements KeyValueSortedSetFactoryInterf * @param \Drupal\Core\Database\Connection $connection * The Connection object containing the key-value tables. */ - function __construct(SerializationInterface $serializer, Connection $connection) { + public function __construct(SerializationInterface $serializer, Connection $connection) { $this->serializer = $serializer; $this->connection = $connection; } @@ -43,4 +43,5 @@ function __construct(SerializationInterface $serializer, Connection $connection) public function get($collection) { return new DatabaseStorageSortedSet($collection, $this->serializer, $this->connection); } + } diff --git a/core/modules/workspace/src/Negotiator/WorkspaceNegotiatorInterface.php b/core/modules/workspace/src/Negotiator/WorkspaceNegotiatorInterface.php index eb969342c5..e5df71ee67 100644 --- a/core/modules/workspace/src/Negotiator/WorkspaceNegotiatorInterface.php +++ b/core/modules/workspace/src/Negotiator/WorkspaceNegotiatorInterface.php @@ -24,7 +24,7 @@ public function setWorkspaceManager(WorkspaceManagerInterface $entity_manager); /** * @param \Symfony\Component\HttpFoundation\Request $request - * @return boolean + * @return bool */ public function applies(Request $request); @@ -36,7 +36,7 @@ public function getWorkspaceId(Request $request); /** * @param \Drupal\workspace\Entity\WorkspaceInterface $workspace - * @return boolean + * @return bool */ public function persist(WorkspaceInterface $workspace); diff --git a/core/modules/workspace/src/ParamConverter/EntityRevisionConverter.php b/core/modules/workspace/src/ParamConverter/EntityRevisionConverter.php index b118a0f87e..25f9d79097 100644 --- a/core/modules/workspace/src/ParamConverter/EntityRevisionConverter.php +++ b/core/modules/workspace/src/ParamConverter/EntityRevisionConverter.php @@ -41,7 +41,7 @@ public function convert($value, $definition, $name, array $defaults) { // If the entity type is translatable, ensure we return the proper // translation object for the current context. if ($entity instanceof EntityInterface && $entity instanceof TranslatableInterface) { - $entity = $this->entityManager->getTranslationFromContext($entity, NULL, array('operation' => 'entity_upcast')); + $entity = $this->entityManager->getTranslationFromContext($entity, NULL, ['operation' => 'entity_upcast']); } return $entity; } @@ -92,4 +92,4 @@ protected function getEntityTypeFromDefaults($definition, $name, array $defaults return $entity_type_id; } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/Plugin/Derivative/Workspace.php b/core/modules/workspace/src/Plugin/Derivative/Workspace.php index 7cbefc0866..2d8c46b735 100644 --- a/core/modules/workspace/src/Plugin/Derivative/Workspace.php +++ b/core/modules/workspace/src/Plugin/Derivative/Workspace.php @@ -44,4 +44,5 @@ public function getDerivativeDefinitions($base_plugin_definition) { } return $this->derivatives; } + } diff --git a/core/modules/workspace/src/Plugin/Field/FieldType/ReplicationHistoryItem.php b/core/modules/workspace/src/Plugin/Field/FieldType/ReplicationHistoryItem.php index 11c693b9d5..4c96eccb99 100644 --- a/core/modules/workspace/src/Plugin/Field/FieldType/ReplicationHistoryItem.php +++ b/core/modules/workspace/src/Plugin/Field/FieldType/ReplicationHistoryItem.php @@ -90,66 +90,66 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'doc_write_failures' => array( + return [ + 'columns' => [ + 'doc_write_failures' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, - ), - 'docs_read' => array( + ], + 'docs_read' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, - ), - 'docs_written' => array( + ], + 'docs_written' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, - ), - 'end_last_seq' => array( + ], + 'end_last_seq' => [ 'type' => 'int', 'size' => 'big', 'not null' => FALSE, - ), - 'end_time' => array( + ], + 'end_time' => [ 'type' => 'varchar', 'length' => 50, 'not null' => FALSE, - ), - 'missing_checked' => array( + ], + 'missing_checked' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, - ), - 'missing_found' => array( + ], + 'missing_found' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, - ), - 'recorded_seq' => array( + ], + 'recorded_seq' => [ 'type' => 'int', 'size' => 'big', 'not null' => FALSE, 'default' => 0, - ), - 'session_id' => array( + ], + 'session_id' => [ 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, - ), - 'start_last_seq' => array( + ], + 'start_last_seq' => [ 'type' => 'int', 'size' => 'big', 'not null' => FALSE, - ), - 'start_time' => array( + ], + 'start_time' => [ 'type' => 'varchar', 'length' => 50, 'not null' => FALSE, - ), - ), - ); + ], + ], + ]; } } diff --git a/core/modules/workspace/src/Replication/DefaultReplicator.php b/core/modules/workspace/src/Replication/DefaultReplicator.php index 069ad461e9..43f15bf9f7 100644 --- a/core/modules/workspace/src/Replication/DefaultReplicator.php +++ b/core/modules/workspace/src/Replication/DefaultReplicator.php @@ -4,10 +4,8 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\workspace\Changes\ChangesFactoryInterface; -use Drupal\workspace\Entity\ContentWorkspace; use Drupal\workspace\Entity\ReplicationLog; use Drupal\workspace\Entity\Workspace; -use Drupal\workspace\Entity\WorkspaceInterface; use Drupal\workspace\Index\SequenceIndexInterface; use Drupal\workspace\UpstreamInterface; use Drupal\workspace\WorkspaceManagerInterface; @@ -78,7 +76,7 @@ public function replicate(UpstreamInterface $source, UpstreamInterface $target) $target = Workspace::load($target_id); $replication_id = \md5($source->id() . $target->id()); $start_time = new \DateTime(); - $sessionId = \md5((\microtime(true) * 1000000)); + $sessionId = \md5((\microtime(TRUE) * 1000000)); $replication_log = ReplicationLog::loadOrCreate($replication_id); $current_active = $this->workspaceManager->getActiveWorkspace(TRUE); @@ -150,4 +148,4 @@ public function replicate(UpstreamInterface $source, UpstreamInterface $target) return $replication_log; } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/Replication/ReplicationManager.php b/core/modules/workspace/src/Replication/ReplicationManager.php index 0f343e5011..85b7d5f8b0 100644 --- a/core/modules/workspace/src/Replication/ReplicationManager.php +++ b/core/modules/workspace/src/Replication/ReplicationManager.php @@ -8,6 +8,9 @@ */ class ReplicationManager { + /** + * @var array + */ protected $replicators = []; /** @@ -20,6 +23,7 @@ public function addReplicator(ReplicationInterface $replicator, $priority) { /** * @param \Drupal\workspace\UpstreamInterface $source * @param \Drupal\workspace\UpstreamInterface $target + * * @return mixed */ public function replicate(UpstreamInterface $source, UpstreamInterface $target) { @@ -31,4 +35,5 @@ public function replicate(UpstreamInterface $source, UpstreamInterface $target) } } } + } diff --git a/core/modules/workspace/src/UpstreamInterface.php b/core/modules/workspace/src/UpstreamInterface.php index 71b39879f2..f0ab1539e4 100644 --- a/core/modules/workspace/src/UpstreamInterface.php +++ b/core/modules/workspace/src/UpstreamInterface.php @@ -2,7 +2,6 @@ namespace Drupal\workspace; -use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Component\Plugin\PluginInspectionInterface; /** @@ -17,4 +16,5 @@ * The of the upstream. */ public function getLabel(); + } diff --git a/core/modules/workspace/src/UpstreamManager.php b/core/modules/workspace/src/UpstreamManager.php index 1ba0c7238f..afdbc02f04 100644 --- a/core/modules/workspace/src/UpstreamManager.php +++ b/core/modules/workspace/src/UpstreamManager.php @@ -1,4 +1,5 @@ alterInfo('workspace_upstream_info'); $this->setCacheBackend($cache_backend, 'workspace_upstream'); } -} \ No newline at end of file + +} diff --git a/core/modules/workspace/src/WorkspaceCacheContext.php b/core/modules/workspace/src/WorkspaceCacheContext.php index 531407e5ae..bc44b412c4 100644 --- a/core/modules/workspace/src/WorkspaceCacheContext.php +++ b/core/modules/workspace/src/WorkspaceCacheContext.php @@ -50,4 +50,4 @@ public function getCacheableMetadata($type = NULL) { return new CacheableMetadata(); } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/WorkspaceListBuilder.php b/core/modules/workspace/src/WorkspaceListBuilder.php index e4ca51be04..0132894696 100644 --- a/core/modules/workspace/src/WorkspaceListBuilder.php +++ b/core/modules/workspace/src/WorkspaceListBuilder.php @@ -6,8 +6,6 @@ use Drupal\Core\Entity\EntityListBuilder; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\workspace\Entity\WorkspaceInterface; -use Drupal\workspace\Entity\WorkspaceTypeInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -62,7 +60,7 @@ public function buildHeader() { * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { - /** @var WorkspaceInterface $entity */ + /** @var \Drupal\workspace\Entity\WorkspaceInterface $entity */ $row['label'] = $entity->label() . ' (' . $entity->getMachineName() . ')'; $row['owner'] = $entity->getOwner()->getDisplayname(); $active_workspace = $this->workspaceManager->getActiveWorkspace(); @@ -74,7 +72,7 @@ public function buildRow(EntityInterface $entity) { * {@inheritdoc} */ public function getDefaultOperations(EntityInterface $entity) { - /** @var WorkspaceInterface $entity */ + /** @var \Drupal\workspace\Entity\WorkspaceInterface $entity */ $operations = parent::getDefaultOperations($entity); if (isset($operations['edit'])) { $operations['edit']['query']['destination'] = $entity->url('collection'); @@ -82,14 +80,22 @@ public function getDefaultOperations(EntityInterface $entity) { $active_workspace = $this->workspaceManager->getActiveWorkspace(); if ($entity->id() != $active_workspace) { - $operations['activate'] =[ + $operations['activate'] = [ 'title' => $this->t('Set Active'), 'weight' => 20, 'url' => $entity->urlInfo('activate-form', ['query' => ['destination' => $entity->url('collection')]]), ]; } + if ('workspace:' . $entity->id() != $entity->get('upstream')->value) { + $operations['deployment'] = [ + 'title' => $this->t('Deploy content'), + 'weight' => 20, + 'url' => $entity->urlInfo('deployment-form', ['query' => ['destination' => $entity->url('collection')]]), + ]; + } + return $operations; } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/WorkspaceManagerInterface.php b/core/modules/workspace/src/WorkspaceManagerInterface.php index 3e2c1a6997..5c408a4a99 100644 --- a/core/modules/workspace/src/WorkspaceManagerInterface.php +++ b/core/modules/workspace/src/WorkspaceManagerInterface.php @@ -15,14 +15,14 @@ /** * @param \Drupal\Core\Entity\EntityInterface $entity * - * @return boolean + * @return bool */ public function entityCanBelongToWorkspaces(EntityInterface $entity); /** * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * - * @return boolean + * @return bool */ public function entityTypeCanBelongToWorkspaces(EntityTypeInterface $entity_type); @@ -79,4 +79,5 @@ public function setActiveWorkspace(WorkspaceInterface $workspace); * The entity to update or create from. */ public function updateOrCreateFromEntity(EntityInterface $entity); + } diff --git a/core/modules/workspace/src/WorkspacePointerInterface.php b/core/modules/workspace/src/WorkspacePointerInterface.php index 5b95d74ea0..5c66ba9022 100644 --- a/core/modules/workspace/src/WorkspacePointerInterface.php +++ b/core/modules/workspace/src/WorkspacePointerInterface.php @@ -1,6 +1,5 @@ setParameter('renderer.config', $renderer_config); } -} \ No newline at end of file +} diff --git a/core/modules/workspace/src/WorkspaceTypeListBuilder.php b/core/modules/workspace/src/WorkspaceTypeListBuilder.php deleted file mode 100644 index 5da8dd9910..0000000000 --- a/core/modules/workspace/src/WorkspaceTypeListBuilder.php +++ /dev/null @@ -1,28 +0,0 @@ -t('Workspace type'); - $header['id'] = $this->t('Machine name'); - return $header + parent::buildHeader(); - } - /** - * {@inheritdoc} - */ - public function buildRow(EntityInterface $entity) { - $row['label'] = $entity->label(); - $row['id'] = $entity->id(); - - return $row + parent::buildRow($entity); - } -} \ No newline at end of file diff --git a/core/modules/workspace/templates/workspace-deployment.html.twig b/core/modules/workspace/templates/workspace-deployment.html.twig deleted file mode 100644 index ab75d5d061..0000000000 --- a/core/modules/workspace/templates/workspace-deployment.html.twig +++ /dev/null @@ -1,31 +0,0 @@ -{# -/** - * @file - * Default theme implementation for deployment. - * - * @see template_preprocess_workspace_deployment() - * - * @ingroup themeable - */ -#} - -
- - - {% for workspace in workspaces %} -
- -
- {% endfor %} -
- -
-
\ No newline at end of file diff --git a/core/modules/workspace/tests/src/Functional/ReplicationTest.php b/core/modules/workspace/tests/src/Functional/ReplicationTest.php index 308568136d..3fc26c63b0 100644 --- a/core/modules/workspace/tests/src/Functional/ReplicationTest.php +++ b/core/modules/workspace/tests/src/Functional/ReplicationTest.php @@ -112,4 +112,5 @@ public function testNodeReplication() { $this->assertEquals($live->id(), $this->getOneEntityByLabel('node', 'Test node')->workspace->target_id); $this->assertEquals($live->id(), $this->getOneEntityByLabel('node', 'Test stage node')->workspace->target_id); } -} \ No newline at end of file + +} diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceBypassTest.php b/core/modules/workspace/tests/src/Functional/WorkspaceBypassTest.php index 0c9888c7e5..644d25dfb8 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceBypassTest.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceBypassTest.php @@ -11,7 +11,6 @@ * @group workspace * @runTestsInSeparateProcesses * @preserveGlobalState disabled - * */ class WorkspaceBypassTest extends BrowserTestBase { use WorkspaceTestUtilities; @@ -131,8 +130,6 @@ public function testBypassOwnWorkspace() { $this->drupalGet('/node/' . $ditka_bears_node_id . '/edit'); $session = $this->getSession(); $this->assertEquals(403, $session->getStatusCode()); - } - } diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceEntityTest.php b/core/modules/workspace/tests/src/Functional/WorkspaceEntityTest.php index 826de5162f..946aa39695 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceEntityTest.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceEntityTest.php @@ -2,9 +2,8 @@ namespace Drupal\Tests\workspace\Functional; -use Drupal\node\Entity\Node; use Drupal\simpletest\BlockCreationTrait; -use \Drupal\Tests\BrowserTestBase; +use Drupal\Tests\BrowserTestBase; /** * Tests creating and loading entities in workspaces. @@ -12,7 +11,6 @@ * @group workspace * @runTestsInSeparateProcesses * @preserveGlobalState disabled - * */ class WorkspaceEntityTest extends BrowserTestBase { use WorkspaceTestUtilities; @@ -154,4 +152,5 @@ public function nodeEntityTestCases() { ['dev'], ]; } + } diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceIndividualPermissionsTest.php b/core/modules/workspace/tests/src/Functional/WorkspaceIndividualPermissionsTest.php index 3704a2aba3..9bf4a0c75e 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceIndividualPermissionsTest.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceIndividualPermissionsTest.php @@ -13,7 +13,7 @@ * * @preserveGlobalState disabled */ -class WorkspaceIndividualPermissionsTest extends BrowserTestBase { +class WorkspaceIndividualPermissionsTest extends BrowserTestBase { use WorkspaceTestUtilities; diff --git a/core/modules/workspace/tests/src/Functional/WorkspacePermissionsTest.php b/core/modules/workspace/tests/src/Functional/WorkspacePermissionsTest.php index 0b52aca923..f70a8872ad 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspacePermissionsTest.php +++ b/core/modules/workspace/tests/src/Functional/WorkspacePermissionsTest.php @@ -2,10 +2,7 @@ namespace Drupal\Tests\workspace\Functional; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\workspace\Entity\WorkspaceInterface; -use Drupal\simpletest\BrowserTestBase; - +use Drupal\Tests\BrowserTestBase; /** * Tests permission controls on workspaces. @@ -13,11 +10,13 @@ * @group workspace * @runTestsInSeparateProcesses * @preserveGlobalState disabled - * */ class WorkspacePermissionsTest extends BrowserTestBase { use WorkspaceTestUtilities; + /** + * @var array + */ public static $modules = ['workspace', 'workspace']; /** @@ -50,9 +49,9 @@ public function testCreateWorkspace() { // Now edit that same workspace; We shouldn't be able to do so, since // we don't have edit permissions. - /** @var EntityTypeManagerInterface $etm */ + /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $etm */ $etm = \Drupal::service('entity_type.manager'); - /** @var WorkspaceInterface $bears */ + /** @var \Drupal\workspace\Entity\WorkspaceInterface $bears */ $entity_list = $etm->getStorage('workspace')->loadByProperties(['label' => 'Bears']); $bears = current($entity_list); diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceSwitcherTest.php b/core/modules/workspace/tests/src/Functional/WorkspaceSwitcherTest.php index 0132452eaa..98e4e26c14 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceSwitcherTest.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceSwitcherTest.php @@ -2,10 +2,8 @@ namespace Drupal\Tests\workspace\Functional; -use Drupal\workspace\Entity\Workspace; use Drupal\simpletest\BlockCreationTrait; -use Drupal\simpletest\BrowserTestBase; -use Drupal\simpletest\WebTestBase; +use Drupal\Tests\BrowserTestBase; /** * Tests workspace switching functionality. @@ -50,6 +48,6 @@ public function testSwitchingWorkspaces() { $page->findButton(t('Activate'))->click(); $session->getPage()->findLink($gravity->label()); - } + } diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceTest.php b/core/modules/workspace/tests/src/Functional/WorkspaceTest.php index d34f31eb87..8027c705f0 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceTest.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceTest.php @@ -2,8 +2,7 @@ namespace Drupal\Tests\workspace\Functional; -use Drupal\simpletest\BrowserTestBase; -use Drupal\Tests\workspace\Functional\WorkspaceTestUtilities; +use Drupal\Tests\BrowserTestBase; /** * Test the workspace entity. @@ -39,4 +38,5 @@ public function testSpecialCharacters() { $page->findButton(t('Save'))->click(); $session->getPage()->hasContent("This value is not valid"); } -} \ No newline at end of file + +} diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceTestUtilities.php b/core/modules/workspace/tests/src/Functional/WorkspaceTestUtilities.php index b686db495f..6d5dd20dd7 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceTestUtilities.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceTestUtilities.php @@ -2,10 +2,8 @@ namespace Drupal\Tests\workspace\Functional; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\workspace\Entity\WorkspaceInterface; use Drupal\node\Entity\NodeType; -use Drupal\workspace\WorkspacePointerInterface; +use Drupal\workspace\Entity\WorkspaceInterface; /** * Utility methods for use in BrowserTestBase tests. @@ -22,7 +20,7 @@ * * @param $label * The label of the workspace to load. - * @return WorkspaceInterface + * @return \Drupal\workspace\Entity\WorkspaceInterface */ protected function getOneWorkspaceByLabel($label) { return $this->getOneEntityByLabel('workspace', $label); @@ -38,10 +36,10 @@ protected function getOneWorkspaceByLabel($label) { * The type of entity to load. * @param $label * The label of the entity to load. - * @return WorkspaceInterface + * @return \Drupal\workspace\Entity\WorkspaceInterface */ protected function getOneEntityByLabel($type, $label) { - /** @var EntityTypeManagerInterface $etm */ + /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $etm */ $etm = \Drupal::service('entity_type.manager'); $property = $etm->getDefinition($type)->getKey('label'); @@ -65,7 +63,7 @@ protected function getOneEntityByLabel($type, $label) { * @param string $machine_name * The machine name of the workspace to create. * - * @return WorkspaceInterface + * @return \Drupal\workspace\Entity\WorkspaceInterface * The workspace that was just created. * * @throws \Behat\Mink\Exception\ElementNotFoundException @@ -112,7 +110,7 @@ protected function setupWorkspaceSwitcherBlock() { * This assumes that the switcher block has already been setup by calling * setupWorkspaceSwitcherBlock(). * - * @param WorkspaceInterface $workspace + * @param \Drupal\workspace\Entity\WorkspaceInterface $workspace * The workspace to set active. */ protected function switchToWorkspace(WorkspaceInterface $workspace) { @@ -149,6 +147,7 @@ protected function createNodeType($label, $machine_name) { * * @param string $label * @param string $bundle + * @param bool $publish * * @return \Drupal\workspace\Entity\WorkspaceInterface * @@ -157,13 +156,16 @@ protected function createNodeType($label, $machine_name) { protected function createNodeThroughUI($label, $bundle, $publish = TRUE) { $this->drupalGet('/node/add/' . $bundle); + /** @var \Behat\Mink\Session $session */ $session = $this->getSession(); $this->assertSession()->statusCodeEquals(200); + /** @var \Behat\Mink\Element\DocumentElement $page */ $page = $session->getPage(); $page->fillField('Title', $label); if ($publish) { - $page->findButton(t('Save and publish'))->click(); + $button = $page->findButton(t('Save and publish')) ?: $page->findButton(t('Save')); + $button->click(); } else { $page->findButton(t('Save as unpublished'))->click(); @@ -181,11 +183,11 @@ protected function createNodeThroughUI($label, $bundle, $publish = TRUE) { * * @param \Drupal\workspace\Entity\WorkspaceInterface $workspace * The workspace for which we want a pointer. - * @return WorkspacePointerInterface + * @return \Drupal\workspace\WorkspacePointerInterface * The pointer to the provided workspace. */ protected function getPointerToWorkspace(WorkspaceInterface $workspace) { - /** @var EntityTypeManagerInterface $etm */ + /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $etm */ $etm = \Drupal::service('entity_type.manager'); $pointers = $etm->getStorage('workspace_pointer') diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceViewTest.php b/core/modules/workspace/tests/src/Functional/WorkspaceViewTest.php index 1eaecb14b5..fa9a3cc7a3 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceViewTest.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceViewTest.php @@ -11,7 +11,6 @@ * @group workspace * @runTestsInSeparateProcesses * @preserveGlobalState disabled - * */ class WorkspaceViewTest extends BrowserTestBase { use WorkspaceTestUtilities; @@ -101,4 +100,5 @@ public function testViewAnyWorkspace() { $this->drupalGet("admin/structure/workspace/{$packers->id()}/activate"); $this->assertEquals(200, $session->getStatusCode()); } + } diff --git a/core/modules/workspace/tests/src/Kernel/DatabaseStorageSortedSetTest.php b/core/modules/workspace/tests/src/Kernel/DatabaseStorageSortedSetTest.php index d0fe7cef2b..e2968e1f84 100644 --- a/core/modules/workspace/tests/src/Kernel/DatabaseStorageSortedSetTest.php +++ b/core/modules/workspace/tests/src/Kernel/DatabaseStorageSortedSetTest.php @@ -83,7 +83,7 @@ public function assertRecords($expected, $message = NULL) { /** * Helper method to generate a key based on microtime(). * - * @return integer + * @return int * A key based on microtime(). */ public function newKey() { diff --git a/core/modules/workspace/workspace.install b/core/modules/workspace/workspace.install index dfd134eaea..1b933b38b1 100644 --- a/core/modules/workspace/workspace.install +++ b/core/modules/workspace/workspace.install @@ -1,5 +1,10 @@ isRevisionable() && !in_array($entity_type->id(), ['content_workspace', 'workspace'])) { + 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.')) @@ -76,7 +76,7 @@ function workspace_views_query_alter(ViewExecutable $view, QueryPluginBase $quer $active_workspace = $workspace_manager->getActiveWorkspace(); $default_workspace_id = \Drupal::getContainer()->getParameter('workspace.default'); if ($active_workspace == $default_workspace_id) { - return; + return; } $entity_type = $view->getBaseEntityType(); @@ -86,21 +86,24 @@ function workspace_views_query_alter(ViewExecutable $view, QueryPluginBase $quer $configuration = [ 'table' => 'content_workspace_field_revision', - 'field' => 'content_entity_revision_id', + 'field' => 'content_entity_id', 'left_table' => $entity_type->getDataTable(), - 'left_field' => $entity_type->getKey('revision'), + 'left_field' => $entity_type->getKey('id'), 'operator' => '=', ]; /** @var \Drupal\views\Plugin\views\join\JoinPluginBase $join */ $join = Views::pluginManager('join') ->createInstance('standard', $configuration); /** @var \Drupal\views\Plugin\views\query\Sql $query */ + // @todo Don't use distinct. $query->addRelationship('cwrf', $join, 'content_workspace_field_revision'); - $query->addWhere(0, 'cwrf.workspace', [$active_workspace, $default_workspace_id], 'IN'); + $query->setWhereGroup('OR', 'workspace'); + $query->addWhere('workspace', 'cwrf.workspace', [$active_workspace, $default_workspace_id], 'IN'); + $query->addWhere('workspace', 'cwrf.workspace', NULL, 'IS'); + //$query->aggregationMethodSimple($entity_type->getDataTable(), $entity_type->getKey('id')); foreach ($query->where as $where_id => $where) { foreach ($where['conditions'] as $condition_id => $condition) { - if ($condition['field'] == $entity_type->getDataTable() . '.' . $entity_type->getKey('published')) { - //$query->where[$where_id]['conditions'][$condition_id]['field'] = 'cwrf.published'; + if ($condition['field'] == $entity_type->getDataTable() . '.' . $entity_type->getKey('published')) { $value = $query->where[$where_id]['conditions'][$condition_id]['value']; $query->setWhereGroup('OR', 'published'); $query->addWhere('published', 'cwrf.published', $value); @@ -109,6 +112,10 @@ function workspace_views_query_alter(ViewExecutable $view, QueryPluginBase $quer } } } + + foreach ($view->displayHandlers->getInstanceIds() as $display_id) { + $view->displayHandlers->get($display_id)->setOption('group_by', TRUE); + } } @@ -125,16 +132,19 @@ function workspace_entity_load(array &$entities, $entity_type_id) { $active_workspace = $workspace_manager->getActiveWorkspace(); $default_workspace_id = \Drupal::getContainer()->getParameter('workspace.default'); if ($active_workspace == $default_workspace_id) { - return; + return; } $keys = array_keys($entities); $results = \Drupal::entityTypeManager() ->getStorage('content_workspace') ->getQuery() + ->allRevisions() ->condition('content_entity_type_id', $entity_type_id) ->condition('content_entity_id', $keys, 'IN') ->condition('workspace', [$active_workspace, $default_workspace_id], 'IN') + ->sort('revision_id', 'DESC') + ->range(0, 1) ->execute(); foreach ($results as $revision_id => $entity_id) { /** @var \Drupal\workspace\Entity\ContentWorkspaceInterface $content_workspace */ @@ -158,7 +168,7 @@ function workspace_entity_load(array &$entities, $entity_type_id) { function workspace_element_info_alter(array &$types) { foreach ($types as &$type) { if (!isset($type['#pre_render'])) { - $type['#pre_render'] = array(); + $type['#pre_render'] =[]; } $type['#pre_render'][] = 'workspace_element_pre_render'; } @@ -209,7 +219,14 @@ function workspace_entity_presave(EntityInterface $entity) { if ($default_workspace_id != $workspace_manager->getActiveWorkspace()) { // As this is the non-default workspace only new entity revisions should be // made default. - $entity->isNew() || ($entity->original->workspace->target_id != $default_workspace_id) ? $entity->isDefaultRevision(TRUE) : $entity->isDefaultRevision(FALSE); + if (isset($entity->original) + && ($entity->original->workspace->target_id == $default_workspace_id + || is_null($entity->original->workspace->target_id))) { + $entity->isDefaultRevision(FALSE); + } + else { + $entity->isDefaultRevision(TRUE); + } // All entities in the non-default workspace get unpublished. $entity->setUnpublished(); @@ -220,7 +237,7 @@ function workspace_entity_presave(EntityInterface $entity) { /** * Implements hook_entity_insert(). */ -function workspace_entity_insert(Drupal\Core\Entity\EntityInterface $entity) { +function workspace_entity_insert(EntityInterface $entity) { /** @var \Drupal\workspace\WorkspaceManagerInterface $workspace_manager */ $workspace_manager = \Drupal::service('workspace.manager'); $workspace_manager->updateOrCreateFromEntity($entity); @@ -234,7 +251,7 @@ function workspace_entity_insert(Drupal\Core\Entity\EntityInterface $entity) { /** * Implements hook_entity_update(). */ -function workspace_entity_update(Drupal\Core\Entity\EntityInterface $entity) { +function workspace_entity_update(EntityInterface $entity) { /** @var \Drupal\workspace\WorkspaceManagerInterface $workspace_manager */ $workspace_manager = \Drupal::service('workspace.manager'); $workspace_manager->updateOrCreateFromEntity($entity); @@ -255,6 +272,49 @@ function workspace_active_id() { } /** + * Implements hook_theme(). + */ +function workspace_theme($existing, $type, $theme, $path) { + return [ + 'workspace_toolbox' => [ + 'variables' => [ + 'workspace_forms' => NULL, + 'control_block' => NULL, + 'deploy_form' => NULL, + ], + ], + ]; +} + +/** + * Implements hook_page_bottom(). + */ +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()]); + $deploy_form = \Drupal::formBuilder()->getForm(DeploymentForm::class, $active_workspace); + + $workspace_forms = []; + /** @var \Drupal\workspace\Entity\WorkspaceInterface $workspace */ + foreach (\Drupal::entityTypeManager()->getStorage('workspace')->loadMultiple() as $workspace) { + if ($workspace->id() != $active_workspace->id() && $workspace->access('view', \Drupal::currentUser())) { + $workspace_forms['workspace_' . $workspace->getMachineName()] = \Drupal::formBuilder()->getForm(WorkspaceSwitcherForm::class, $workspace); + } + } + + $page_bottom['workspace_toolbox'] = [ + '#theme' => 'workspace_toolbox', + '#workspace_forms' => $workspace_forms, + '#control_block' => $control_block, + '#deploy_form' => $deploy_form, + '#attached' => [ + 'library' => ['workspace/drupal.workspace.toolbox'], + ], + ]; +} + +/** * Implements hook_toolbar(). * * @see \Drupal\workspace\Toolbar @@ -274,20 +334,7 @@ function workspace_toolbar() { 'class' => ['workspace-toolbar-tab'], ], '#attached' => [ - 'library' => [ - 'workspace/drupal.workspace.toolbar', - ], - ], - ]; - - $items['deploy'] = [ - '#type' => 'toolbar_item', - '#weight' => 130, - '#wrapper_attributes' => [ - 'class' => ['workspace-deploy-toolbar-tab'], - ], - 'tab' => [ - \Drupal::formBuilder()->getForm(\Drupal\workspace\Form\DeploymentForm::class, $active_workspace), + 'library' => ['workspace/drupal.workspace.toolbar'], ], ]; @@ -301,28 +348,6 @@ function workspace_toolbar() { ], ]; - $create_link = [ - '#type' => 'link', - '#title' => t('Add workspace'), - '#url' => Url::fromRoute('entity.workspace.add_form'), - '#options' => ['attributes' => ['class' => ['add-workspace']]], - ]; - - $items['workspace_switcher']['tray'] = [ - '#heading' => t('Switch to workspace'), - '#pre_render' => ['workspace_switcher_toolbar_pre_render'], - // This wil get filled in via pre-render. - 'workspace_forms' => [], - 'create_link' => $create_link, - '#cache' => [ - 'contexts' => \Drupal::entityTypeManager()->getDefinition('workspace')->getListCacheContexts(), - 'tags' => \Drupal::entityTypeManager()->getDefinition('workspace')->getListCacheTags(), - ], - '#attributes' => [ - 'class' => ['toolbar-menu'], - ], - ]; - return $items; } diff --git a/core/modules/workspace/workspace.routing.yml b/core/modules/workspace/workspace.routing.yml index da89e77d46..9ed125affb 100644 --- a/core/modules/workspace/workspace.routing.yml +++ b/core/modules/workspace/workspace.routing.yml @@ -16,10 +16,12 @@ entity.workspace.activate_form: requirements: _workspace_view: 'TRUE' -workspace.deployment: - path: '/admin/config/workflow/deployment' +entity.workspace.deployment_form: + path: '/admin/structure/workspace/{workspace}/deployment' defaults: _title: 'Workspace deployment' _controller: '\Drupal\workspace\Controller\DeploymentController::workspaces' + options: + _admin_route: TRUE requirements: - _permission: 'administer workspaces' \ No newline at end of file + _permission: 'administer workspaces'