Loading core/modules/workspaces/src/Controller/WorkspacesHtmlEntityFormController.php +11 −6 Original line number Diff line number Diff line Loading @@ -35,11 +35,16 @@ public function __construct( */ public function getContentResult(Request $request, RouteMatchInterface $route_match): array { $form_arg = $this->getFormArgument($route_match); $form_object = $this->getFormObject($route_match, $form_arg); // If no operation is provided, use 'default'. $form_arg .= '.default'; [$entity_type_id, $operation] = explode('.', $form_arg); if ($route_match->getRawParameter($entity_type_id) !== NULL) { /** @var \Drupal\Core\Entity\EntityInterface $entity */ $entity = $form_object->getEntity(); if ($this->workspaceInfo->isEntitySupported($entity)) { $entity = $route_match->getParameter($entity_type_id); } if (isset($entity) && $this->workspaceInfo->isEntitySupported($entity)) { $active_workspace = $this->workspaceManager->getActiveWorkspace(); // Prepare a minimal render array in case we need to return it. Loading @@ -48,7 +53,7 @@ public function getContentResult(Request $request, RouteMatchInterface $route_ma $build['#cache']['max-age'] = $entity->getCacheMaxAge(); // Prevent entities from being edited if they're tracked in workspace. if ($form_object->getOperation() !== 'delete') { if ($operation !== 'delete') { $constraints = array_values(array_filter($entity->getTypedData()->getConstraints(), function ($constraint) { return $constraint instanceof EntityWorkspaceConflictConstraint; })); Loading @@ -68,7 +73,7 @@ public function getContentResult(Request $request, RouteMatchInterface $route_ma // Prevent entities from being deleted in a workspace if they have a // published default revision. if ($form_object->getOperation() === 'delete' && $active_workspace && !$this->workspaceInfo->isEntityDeletable($entity, $active_workspace)) { if ($operation === 'delete' && $active_workspace && !$this->workspaceInfo->isEntityDeletable($entity, $active_workspace)) { $build['#markup'] = $this->t('This @entity_type_label can only be deleted in the Live workspace.', [ '@entity_type_label' => $entity->getEntityType()->getSingularLabel(), ]); Loading core/modules/workspaces/tests/modules/workspaces_test/src/Hook/WorkspacesTestHooks.php +55 −1 Original line number Diff line number Diff line Loading @@ -4,13 +4,21 @@ namespace Drupal\workspaces_test\Hook; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\KeyValueStore\KeyValueFactoryInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; /** * Hook implementations for workspaces_test. */ class WorkspacesTestHooks { public function __construct( #[Autowire(service: 'keyvalue')] protected readonly KeyValueFactoryInterface $keyValueFactory, ) {} /** * Implements hook_entity_type_alter(). */ Loading @@ -31,7 +39,53 @@ public function entityTypeAlter(array &$entity_types) : void { public function entityTranslationCreate(): void { /** @var \Drupal\workspaces\WorkspaceManagerInterface $workspace_manager */ $workspace_manager = \Drupal::service('workspaces.manager'); \Drupal::keyValue('ws_test')->set('workspace_was_active', $workspace_manager->hasActiveWorkspace()); $this->keyValueFactory->get('ws_test')->set('workspace_was_active', $workspace_manager->hasActiveWorkspace()); } /** * Implements hook_entity_create(). */ #[Hook('entity_create')] public function entityCreate(EntityInterface $entity): void { $this->incrementHookCount('hook_entity_create', $entity); } /** * Implements hook_entity_presave(). */ #[Hook('entity_presave')] public function entityPresave(EntityInterface $entity): void { $this->incrementHookCount('hook_entity_presave', $entity); } /** * Implements hook_entity_insert(). */ #[Hook('entity_insert')] public function entityInsert(EntityInterface $entity): void { $this->incrementHookCount('hook_entity_insert', $entity); } /** * Implements hook_entity_update(). */ #[Hook('entity_update')] public function entityUpdate(EntityInterface $entity): void { $this->incrementHookCount('hook_entity_update', $entity); } /** * Increments the invocation count for a specific entity hook. * * @param string $hook_name * The name of the hook being invoked (e.g., 'hook_entity_create'). * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object involved in the hook. */ protected function incrementHookCount(string $hook_name, EntityInterface $entity): void { $key = $entity->getEntityTypeId() . '.' . $hook_name . '.count'; $count = $this->keyValueFactory->get('ws_test')->get($key, 0); $this->keyValueFactory->get('ws_test')->set($key, $count + 1); } } core/modules/workspaces/tests/src/Functional/WorkspaceTest.php +4 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ class WorkspaceTest extends BrowserTestBase { 'user', 'workspaces', 'workspaces_ui', 'workspaces_test', ]; /** Loading Loading @@ -364,7 +365,9 @@ public function testPublishWorkspace(): void { $this->assertSession()->pageTextContains('There are no changes that can be published from Test workspace to Live.'); // Create a node in the workspace. $this->createNodeThroughUi('Test node', 'test'); $this->drupalGet('/node/add/test'); $this->assertEquals(1, \Drupal::keyValue('ws_test')->get('node.hook_entity_create.count')); $this->submitForm(['title[0][value]' => 'Test node'], 'Save'); $this->drupalGet('/admin/config/workflow/workspaces/manage/test_workspace/publish'); $this->assertSession()->statusCodeEquals(200); Loading Loading
core/modules/workspaces/src/Controller/WorkspacesHtmlEntityFormController.php +11 −6 Original line number Diff line number Diff line Loading @@ -35,11 +35,16 @@ public function __construct( */ public function getContentResult(Request $request, RouteMatchInterface $route_match): array { $form_arg = $this->getFormArgument($route_match); $form_object = $this->getFormObject($route_match, $form_arg); // If no operation is provided, use 'default'. $form_arg .= '.default'; [$entity_type_id, $operation] = explode('.', $form_arg); if ($route_match->getRawParameter($entity_type_id) !== NULL) { /** @var \Drupal\Core\Entity\EntityInterface $entity */ $entity = $form_object->getEntity(); if ($this->workspaceInfo->isEntitySupported($entity)) { $entity = $route_match->getParameter($entity_type_id); } if (isset($entity) && $this->workspaceInfo->isEntitySupported($entity)) { $active_workspace = $this->workspaceManager->getActiveWorkspace(); // Prepare a minimal render array in case we need to return it. Loading @@ -48,7 +53,7 @@ public function getContentResult(Request $request, RouteMatchInterface $route_ma $build['#cache']['max-age'] = $entity->getCacheMaxAge(); // Prevent entities from being edited if they're tracked in workspace. if ($form_object->getOperation() !== 'delete') { if ($operation !== 'delete') { $constraints = array_values(array_filter($entity->getTypedData()->getConstraints(), function ($constraint) { return $constraint instanceof EntityWorkspaceConflictConstraint; })); Loading @@ -68,7 +73,7 @@ public function getContentResult(Request $request, RouteMatchInterface $route_ma // Prevent entities from being deleted in a workspace if they have a // published default revision. if ($form_object->getOperation() === 'delete' && $active_workspace && !$this->workspaceInfo->isEntityDeletable($entity, $active_workspace)) { if ($operation === 'delete' && $active_workspace && !$this->workspaceInfo->isEntityDeletable($entity, $active_workspace)) { $build['#markup'] = $this->t('This @entity_type_label can only be deleted in the Live workspace.', [ '@entity_type_label' => $entity->getEntityType()->getSingularLabel(), ]); Loading
core/modules/workspaces/tests/modules/workspaces_test/src/Hook/WorkspacesTestHooks.php +55 −1 Original line number Diff line number Diff line Loading @@ -4,13 +4,21 @@ namespace Drupal\workspaces_test\Hook; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\KeyValueStore\KeyValueFactoryInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; /** * Hook implementations for workspaces_test. */ class WorkspacesTestHooks { public function __construct( #[Autowire(service: 'keyvalue')] protected readonly KeyValueFactoryInterface $keyValueFactory, ) {} /** * Implements hook_entity_type_alter(). */ Loading @@ -31,7 +39,53 @@ public function entityTypeAlter(array &$entity_types) : void { public function entityTranslationCreate(): void { /** @var \Drupal\workspaces\WorkspaceManagerInterface $workspace_manager */ $workspace_manager = \Drupal::service('workspaces.manager'); \Drupal::keyValue('ws_test')->set('workspace_was_active', $workspace_manager->hasActiveWorkspace()); $this->keyValueFactory->get('ws_test')->set('workspace_was_active', $workspace_manager->hasActiveWorkspace()); } /** * Implements hook_entity_create(). */ #[Hook('entity_create')] public function entityCreate(EntityInterface $entity): void { $this->incrementHookCount('hook_entity_create', $entity); } /** * Implements hook_entity_presave(). */ #[Hook('entity_presave')] public function entityPresave(EntityInterface $entity): void { $this->incrementHookCount('hook_entity_presave', $entity); } /** * Implements hook_entity_insert(). */ #[Hook('entity_insert')] public function entityInsert(EntityInterface $entity): void { $this->incrementHookCount('hook_entity_insert', $entity); } /** * Implements hook_entity_update(). */ #[Hook('entity_update')] public function entityUpdate(EntityInterface $entity): void { $this->incrementHookCount('hook_entity_update', $entity); } /** * Increments the invocation count for a specific entity hook. * * @param string $hook_name * The name of the hook being invoked (e.g., 'hook_entity_create'). * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object involved in the hook. */ protected function incrementHookCount(string $hook_name, EntityInterface $entity): void { $key = $entity->getEntityTypeId() . '.' . $hook_name . '.count'; $count = $this->keyValueFactory->get('ws_test')->get($key, 0); $this->keyValueFactory->get('ws_test')->set($key, $count + 1); } }
core/modules/workspaces/tests/src/Functional/WorkspaceTest.php +4 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ class WorkspaceTest extends BrowserTestBase { 'user', 'workspaces', 'workspaces_ui', 'workspaces_test', ]; /** Loading Loading @@ -364,7 +365,9 @@ public function testPublishWorkspace(): void { $this->assertSession()->pageTextContains('There are no changes that can be published from Test workspace to Live.'); // Create a node in the workspace. $this->createNodeThroughUi('Test node', 'test'); $this->drupalGet('/node/add/test'); $this->assertEquals(1, \Drupal::keyValue('ws_test')->get('node.hook_entity_create.count')); $this->submitForm(['title[0][value]' => 'Test node'], 'Save'); $this->drupalGet('/admin/config/workflow/workspaces/manage/test_workspace/publish'); $this->assertSession()->statusCodeEquals(200); Loading