diff --git a/core/modules/workspace/src/Entity/Form/WorkspaceForm.php b/core/modules/workspace/src/Entity/Form/WorkspaceForm.php index e7f6159..15819fb 100644 --- a/core/modules/workspace/src/Entity/Form/WorkspaceForm.php +++ b/core/modules/workspace/src/Entity/Form/WorkspaceForm.php @@ -33,15 +33,14 @@ public function form(array $form, FormStateInterface $form_state) { '#title' => $this->t('Label'), '#maxlength' => 255, '#default_value' => $workspace->label(), - '#description' => $this->t("Label for the Workspace."), '#required' => TRUE, ]; - $form['machine_name'] = [ + $form['id'] = [ '#type' => 'machine_name', '#title' => $this->t('Workspace ID'), '#maxlength' => 255, - '#default_value' => $workspace->get('machine_name')->value, + '#default_value' => $workspace->id(), '#disabled' => !$workspace->isNew(), '#machine_name' => [ 'exists' => '\Drupal\workspace\Entity\Workspace::load', @@ -72,7 +71,7 @@ public function form(array $form, FormStateInterface $form_state) { protected function getEditedFieldNames(FormStateInterface $form_state) { return array_merge([ 'label', - 'machine_name', + 'id', ], parent::getEditedFieldNames($form_state)); } @@ -85,7 +84,7 @@ protected function flagViolations(EntityConstraintViolationListInterface $violat // contained in the display. $field_names = [ 'label', - 'machine_name', + 'id', 'upstream' ]; foreach ($violations->getByFields($field_names) as $violation) { @@ -100,21 +99,22 @@ protected function flagViolations(EntityConstraintViolationListInterface $violat */ public function save(array $form, FormStateInterface $form_state) { $workspace = $this->entity; - $insert = $workspace->isNew(); - $workspace->save(); + $status = $workspace->save(); + \Drupal::service('workspace.upstream_manager')->clearCachedDefinitions(); + $info = ['%info' => $workspace->label()]; $context = ['@type' => $workspace->bundle(), '%info' => $workspace->label()]; $logger = $this->logger('workspace'); - if ($insert) { - $logger->notice('@type: added %info.', $context); - drupal_set_message($this->t('Workspace %info has been created.', $info)); - } - else { + if ($status == SAVED_UPDATED) { $logger->notice('@type: updated %info.', $context); drupal_set_message($this->t('Workspace %info has been updated.', $info)); } + else { + $logger->notice('@type: added %info.', $context); + drupal_set_message($this->t('Workspace %info has been created.', $info)); + } if ($workspace->id()) { $form_state->setValue('id', $workspace->id()); diff --git a/core/modules/workspace/src/Entity/Workspace.php b/core/modules/workspace/src/Entity/Workspace.php index 8251c59..5c8ee09 100644 --- a/core/modules/workspace/src/Entity/Workspace.php +++ b/core/modules/workspace/src/Entity/Workspace.php @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityChangedTrait; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\user\UserInterface; /** @@ -19,6 +20,7 @@ * handlers = { * "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage", * "list_builder" = "\Drupal\workspace\WorkspaceListBuilder", + * "access" = "Drupal\workspace\WorkspaceAccessControlHandler", * "route_provider" = { * "html" = "\Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", * }, @@ -34,7 +36,7 @@ * data_table = "workspace_field_data", * revision_data_table = "workspace_field_revision", * entity_keys = { - * "id" = "machine_name", + * "id" = "id", * "revision" = "revision_id", * "uuid" = "uuid", * "label" = "label", @@ -59,54 +61,44 @@ class Workspace extends ContentEntityBase implements WorkspaceInterface { * {@inheritdoc} */ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { + $fields = parent::baseFieldDefinitions($entity_type); - $fields['machine_name'] = BaseFieldDefinition::create('string') - ->setLabel(t('Workaspace ID')) - ->setDescription(t('The workspace machine name.')) + $fields['id'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Workaspace ID')) + ->setDescription(new TranslatableMarkup('The workspace ID.')) ->setSetting('max_length', 128) ->setRequired(TRUE) ->addPropertyConstraints('value', ['Regex' => ['pattern' => '/^[\da-z_$()+-\/]*$/']]); - $fields['uuid'] = BaseFieldDefinition::create('uuid') - ->setLabel(t('UUID')) - ->setDescription(t('The workspace UUID.')) - ->setReadOnly(TRUE); - - $fields['revision_id'] = BaseFieldDefinition::create('integer') - ->setLabel(t('Revision ID')) - ->setDescription(t('The revision ID.')) - ->setReadOnly(TRUE) - ->setSetting('unsigned', TRUE); - $fields['label'] = BaseFieldDefinition::create('string') - ->setLabel(t('Workaspace name')) - ->setDescription(t('The workspace name.')) + ->setLabel(new TranslatableMarkup('Workaspace name')) + ->setDescription(new TranslatableMarkup('The workspace name.')) ->setRevisionable(TRUE) ->setSetting('max_length', 128) ->setRequired(TRUE); $fields['uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Owner')) - ->setDescription(t('The workspace owner.')) + ->setLabel(new TranslatableMarkup('Owner')) + ->setDescription(new TranslatableMarkup('The workspace owner.')) ->setRevisionable(TRUE) ->setSetting('target_type', 'user') ->setDefaultValueCallback('Drupal\workspace\Entity\Workspace::getCurrentUserId'); $fields['changed'] = BaseFieldDefinition::create('changed') - ->setLabel(t('Changed')) - ->setDescription(t('The time that the workspace was last edited.')) + ->setLabel(new TranslatableMarkup('Changed')) + ->setDescription(new TranslatableMarkup('The time that the workspace was last edited.')) ->setRevisionable(TRUE); $fields['created'] = BaseFieldDefinition::create('created') - ->setLabel(t('Created')) - ->setDescription(t('The UNIX timestamp of when the workspace has been created.')); + ->setLabel(new TranslatableMarkup('Created')) + ->setDescription(new TranslatableMarkup('The UNIX timestamp of when the workspace has been created.')); $fields['upstream'] = BaseFieldDefinition::create('string') - ->setLabel(t('Assign default target workspace')) - ->setDescription(t('The workspace to push to and pull from.')) + ->setLabel(new TranslatableMarkup('Assign default target workspace')) + ->setDescription(new TranslatableMarkup('The workspace to push to and pull from.')) ->setRevisionable(TRUE) ->setRequired(TRUE) - ->setDefaultValueCallback('workspace_active_id'); + ->setDefaultValueCallback('Drupal\workspace\Entity\Workspace::getActiveWorkspaceId'); return $fields; } @@ -136,13 +128,6 @@ public function getStartTime() { /** * {@inheritdoc} */ - public function getMachineName() { - return $this->get('machine_name')->value; - } - - /** - * {@inheritdoc} - */ public function getOwner() { return $this->get('uid')->entity; } @@ -182,4 +167,16 @@ public static function getCurrentUserId() { return [\Drupal::currentUser()->id()]; } + /** + * Default value callback for 'upstream' base field definition. + * + * @see ::baseFieldDefinitions() + * + * @return array + * An array of default values. + */ + public static function getActiveWorkspaceId() { + return ['workspace:' . \Drupal::service('workspace.manager')->getActiveWorkspace()]; + } + } diff --git a/core/modules/workspace/src/Entity/WorkspaceInterface.php b/core/modules/workspace/src/Entity/WorkspaceInterface.php index 2b5caad..93cc55d 100644 --- a/core/modules/workspace/src/Entity/WorkspaceInterface.php +++ b/core/modules/workspace/src/Entity/WorkspaceInterface.php @@ -33,12 +33,4 @@ public function setCreatedTime($timestamp); */ public function getStartTime(); - /** - * Returns the workspace machine name. - * - * @return string - * Machine name of the workspace. - */ - public function getMachineName(); - } diff --git a/core/modules/workspace/src/EntityAccess.php b/core/modules/workspace/src/EntityAccess.php index ad3f8c5..b67d281 100644 --- a/core/modules/workspace/src/EntityAccess.php +++ b/core/modules/workspace/src/EntityAccess.php @@ -141,56 +141,6 @@ protected function bypassAccessResult(AccountInterface $account) { } /** - * Hook bridge; - * - * @see hook_entity_access() - * @see hook_ENTITY_TYPE_access() - * - * @param WorkspaceInterface $workspace - * @param string $operation - * @param AccountInterface $account - * - * @return AccessResult - */ - public function workspaceAccess(WorkspaceInterface $workspace, $operation, AccountInterface $account) { - - $operations = [ - 'view' => ['any' => 'view any workspace', 'own' => 'view own workspace'], - 'update' => ['any' => 'edit any workspace', 'own' => 'edit own workspace'], - 'delete' => ['any' => 'delete any workspace', 'own' => 'delete own workspace'], - ]; - - // The default workspace is always viewable, no matter what. - $result = AccessResult::allowedIf($operation == 'view' && $workspace->id() == $this->defaultWorkspaceId) - // Or if the user has permission to access any workspace at all. - ->orIf(AccessResult::allowedIfHasPermission($account, $operations[$operation]['any'])) - // Or if it's their own workspace, and they have permission to access their own workspace. - ->orIf( - AccessResult::allowedIf($workspace->getOwnerId() == $account->id()) - ->andIf(AccessResult::allowedIfHasPermission($account, $operations[$operation]['own'])) - ) - ->orIf(AccessResult::allowedIfHasPermission($account, $operation . '_workspace_' . $workspace->id())); - - return $result; - } - - /** - * Hook bridge; - * - * @see hook_create_access(); - * @see hook_ENTITY_TYPE_create_access() - * - * @param \Drupal\Core\Session\AccountInterface $account - * @param array $context - * @param $entity_bundle - * - * @return AccessResult - */ - public function workspaceCreateAccess(AccountInterface $account, array $context, $entity_bundle) { - return AccessResult::allowedIfHasPermission($account, 'create workspace'); - } - - /** * Returns an array of workspace-specific permissions. * * Note: This approach assumes that a site will have only a small number diff --git a/core/modules/workspace/src/WorkspaceAccessControlHandler.php b/core/modules/workspace/src/WorkspaceAccessControlHandler.php new file mode 100644 index 0000000..cd01bf0 --- /dev/null +++ b/core/modules/workspace/src/WorkspaceAccessControlHandler.php @@ -0,0 +1,50 @@ + ['any' => 'view any workspace', 'own' => 'view own workspace'], + 'update' => ['any' => 'edit any workspace', 'own' => 'edit own workspace'], + 'delete' => ['any' => 'delete any workspace', 'own' => 'delete own workspace'], + ]; + + // The default workspace is always viewable, no matter what. + $default_workspace = \Drupal::getContainer()->getParameter('workspace.default'); + $result = AccessResult::allowedIf($operation == 'view' && $entity->id() == $default_workspace)->addCacheableDependency($entity) + // Or if the user has permission to access any workspace at all. + ->orIf(AccessResult::allowedIfHasPermission($account, $operations[$operation]['any'])) + // Or if it's their own workspace, and they have permission to access their own workspace. + ->orIf( + AccessResult::allowedIf($entity->getOwnerId() == $account->id())->addCacheableDependency($entity) + ->andIf(AccessResult::allowedIfHasPermission($account, $operations[$operation]['own'])) + ) + ->orIf(AccessResult::allowedIfHasPermission($account, $operation . '_workspace_' . $entity->id())); + + return $result; + } + + /** + * {@inheritdoc} + */ + protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { + return AccessResult::allowedIfHasPermission($account, 'create workspace'); + } + +} diff --git a/core/modules/workspace/src/WorkspaceListBuilder.php b/core/modules/workspace/src/WorkspaceListBuilder.php index 02be42b..d16e238 100644 --- a/core/modules/workspace/src/WorkspaceListBuilder.php +++ b/core/modules/workspace/src/WorkspaceListBuilder.php @@ -52,9 +52,9 @@ public static function createInstance(ContainerInterface $container, EntityTypeI * {@inheritdoc} */ public function buildHeader() { - $header['label'] = t('Workspace'); - $header['uid'] = t('Owner'); - $header['status'] = t('Status'); + $header['label'] = $this->t('Workspace'); + $header['uid'] = $this->t('Owner'); + $header['status'] = $this->t('Status'); return $header + parent::buildHeader(); } @@ -64,7 +64,7 @@ public function buildHeader() { */ public function buildRow(EntityInterface $entity) { /** @var \Drupal\workspace\Entity\WorkspaceInterface $entity */ - $row['label'] = $entity->label() . ' (' . $entity->getMachineName() . ')'; + $row['label'] = $entity->label() . ' (' . $entity->id() . ')'; $row['owner'] = $entity->getOwner()->getDisplayname(); $active_workspace = $this->workspaceManager->getActiveWorkspace(); $row['status'] = $active_workspace == $entity->id() ? $this->t('Active') : $this->t('Inactive'); diff --git a/core/modules/workspace/src/WorkspacePointerInterface.php b/core/modules/workspace/src/WorkspacePointerInterface.php deleted file mode 100644 index 5c66ba9..0000000 --- a/core/modules/workspace/src/WorkspacePointerInterface.php +++ /dev/null @@ -1,97 +0,0 @@ -getPage(); $page->fillField('label', 'Bears'); - $page->fillField('machine_name', 'bears'); + $page->fillField('id', 'bears'); $page->findButton(t('Save'))->click(); $session->getPage()->hasContent('Bears (bears)'); @@ -90,7 +90,7 @@ public function testEditOwnWorkspace() { $page = $session->getPage(); $page->fillField('label', 'Bears again'); - $page->fillField('machine_name', 'bears'); + $page->fillField('id', 'bears'); $page->findButton(t('Save'))->click(); $session->getPage()->hasContent('Bears again (bears)'); @@ -142,7 +142,7 @@ public function testEditAnyWorkspace() { $page = $session->getPage(); $page->fillField('label', 'Bears again'); - $page->fillField('machine_name', 'bears'); + $page->fillField('id', 'bears'); $page->findButton(t('Save'))->click(); $session->getPage()->hasContent('Bears again (bears)'); diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceTest.php b/core/modules/workspace/tests/src/Functional/WorkspaceTest.php index 02a548e..50d7a9e 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceTest.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceTest.php @@ -34,7 +34,7 @@ public function testSpecialCharacters() { $this->assertEquals(200, $session->getStatusCode()); $page = $session->getPage(); $page->fillField('label', 'workspace2'); - $page->fillField('machine_name', 'A!"£%^&*{}#~@?'); + $page->fillField('id', 'A!"£%^&*{}#~@?'); $page->findButton(t('Save'))->click(); $session->getPage()->hasContent("This value is not valid"); } diff --git a/core/modules/workspace/tests/src/Functional/WorkspaceTestUtilities.php b/core/modules/workspace/tests/src/Functional/WorkspaceTestUtilities.php index cd74b3f..2985c05 100644 --- a/core/modules/workspace/tests/src/Functional/WorkspaceTestUtilities.php +++ b/core/modules/workspace/tests/src/Functional/WorkspaceTestUtilities.php @@ -61,15 +61,15 @@ protected function getOneEntityByLabel($type, $label) { * * @param string $label * The label of the workspace to create. - * @param string $machine_name - * The machine name of the workspace to create. + * @param string $id + * The ID of the workspace to create. * * @return \Drupal\workspace\Entity\WorkspaceInterface * The workspace that was just created. * * @throws \Behat\Mink\Exception\ElementNotFoundException */ - protected function createWorkspaceThroughUI($label, $machine_name) { + protected function createWorkspaceThroughUI($label, $id) { $this->drupalGet('/admin/structure/workspace/add'); $session = $this->getSession(); @@ -78,13 +78,13 @@ protected function createWorkspaceThroughUI($label, $machine_name) { /** @var DocumentElement $page */ $page = $session->getPage(); $page->fillField('label', $label); - $page->fillField('machine_name', $machine_name); - if ($machine_name == 'dev') { + $page->fillField('id', $id); + if ($id == 'dev') { $page->selectFieldOption('upstream', 'workspace:stage'); } $page->findButton(t('Save'))->click(); - $session->getPage()->hasContent("$label ($machine_name)"); + $session->getPage()->hasContent("$label ($id)"); return $this->getOneWorkspaceByLabel($label); } diff --git a/core/modules/workspace/workspace.install b/core/modules/workspace/workspace.install index 923fb47..6ed94d8 100644 --- a/core/modules/workspace/workspace.install +++ b/core/modules/workspace/workspace.install @@ -12,11 +12,11 @@ */ function workspace_install() { /** @var \Drupal\workspace\Entity\WorkspaceInterface $live */ - $live = Workspace::create(['machine_name' => 'live', 'label' => 'Live']); + $live = Workspace::create(['id' => 'live', 'label' => 'Live']); $live->save(); /** @var \Drupal\workspace\Entity\WorkspaceInterface $stage */ - $stage = Workspace::create(['machine_name' => 'stage', 'label' => 'Stage']); + $stage = Workspace::create(['id' => 'stage', 'label' => 'Stage']); $stage->set('upstream', 'workspace:' . $live->id()); $stage->save(); } diff --git a/core/modules/workspace/workspace.module b/core/modules/workspace/workspace.module index b38d075..5683157 100644 --- a/core/modules/workspace/workspace.module +++ b/core/modules/workspace/workspace.module @@ -265,15 +265,6 @@ function workspace_entity_update(EntityInterface $entity) { } /** - * Default value callback for 'upstream' base field definition. - * - * @return array - */ -function workspace_active_id() { - return 'workspace:' . \Drupal::service('workspace.manager')->getActiveWorkspace(); -} - -/** * Implements hook_theme(). */ function workspace_theme($existing, $type, $theme, $path) { @@ -307,7 +298,7 @@ function workspace_page_bottom(array &$page_bottom) { /** @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() + $workspace_forms['workspace_' . $workspace->id()] = \Drupal::formBuilder() ->getForm(WorkspaceSwitcherForm::class, $workspace); } } @@ -373,7 +364,7 @@ function workspace_switcher_toolbar_pre_render(array $element) { /** @var \Drupal\workspace\Entity\WorkspaceInterface $workspace */ foreach (\Drupal::entityTypeManager()->getStorage('workspace')->loadMultiple() as $workspace) { if ($workspace->access('view', \Drupal::currentUser())) { - $element['workspace_forms']['workspace_' . $workspace->getMachineName()] = \Drupal::formBuilder()->getForm(WorkspaceSwitcherForm::class, $workspace); + $element['workspace_forms']['workspace_' . $workspace->id()] = \Drupal::formBuilder()->getForm(WorkspaceSwitcherForm::class, $workspace); } } @@ -401,25 +392,3 @@ function workspace_entity_create_access(AccountInterface $account, array $contex ->getInstanceFromDefinition(EntityAccess::class) ->entityCreateAccess($account, $context, $entity_bundle); } - -/** - * Implements hook_ENTITY_TYPE_access(). - * - * @see \Drupal\workspace\EntityAccess - */ -function workspace_workspace_access(EntityInterface $entity, $operation, AccountInterface $account) { - return \Drupal::service('class_resolver') - ->getInstanceFromDefinition(EntityAccess::class) - ->workspaceAccess($entity, $operation, $account); -} - -/** - * Implements hook_ENTITY_TYPE_create_access(). - * - * @see \Drupal\workspace\EntityAccess - */ -function workspace_workspace_create_access(AccountInterface $account, array $context, $entity_bundle) { - return \Drupal::service('class_resolver') - ->getInstanceFromDefinition(EntityAccess::class) - ->workspaceCreateAccess($account, $context, $entity_bundle); -}