diff --git a/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php b/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php index b9d6ad520f..c0f9929e02 100644 --- a/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php +++ b/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php @@ -23,7 +23,6 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\ActionRequest; use Neos\Neos\Domain\Service\NodeTypeNameFactory; -use Neos\Neos\Domain\Workspace\WorkspaceProvider; use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper; @@ -36,8 +35,6 @@ #[Flow\Scope("singleton")] final class ReloadNodesQueryHandler { - #[Flow\Inject] - protected WorkspaceProvider $workspaceProvider; #[Flow\Inject] protected ContentRepositoryRegistry $contentRepositoryRegistry; diff --git a/Classes/Application/SyncWorkspace/SyncWorkspaceCommandHandler.php b/Classes/Application/SyncWorkspace/SyncWorkspaceCommandHandler.php index 834837747e..48656206f1 100644 --- a/Classes/Application/SyncWorkspace/SyncWorkspaceCommandHandler.php +++ b/Classes/Application/SyncWorkspace/SyncWorkspaceCommandHandler.php @@ -18,7 +18,7 @@ use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Neos\Domain\NodeLabel\NodeLabelGeneratorInterface; -use Neos\Neos\Domain\Workspace\WorkspaceProvider; +use Neos\Neos\Domain\Service\WorkspacePublishingService; /** * The application layer level command handler to for rebasing the workspace @@ -32,7 +32,7 @@ final class SyncWorkspaceCommandHandler protected ContentRepositoryRegistry $contentRepositoryRegistry; #[Flow\Inject] - protected WorkspaceProvider $workspaceProvider; + protected WorkspacePublishingService $workspacePublishingService; #[Flow\Inject] protected NodeLabelGeneratorInterface $nodeLabelGenerator; @@ -40,12 +40,11 @@ final class SyncWorkspaceCommandHandler public function handle(SyncWorkspaceCommand $command): void { try { - $workspace = $this->workspaceProvider->provideForWorkspaceName( + $this->workspacePublishingService->rebaseWorkspace( $command->contentRepositoryId, - $command->workspaceName + $command->workspaceName, + $command->rebaseErrorHandlingStrategy ); - - $workspace->rebase($command->rebaseErrorHandlingStrategy); } catch (WorkspaceRebaseFailed $e) { $conflictsBuilder = Conflicts::builder( contentRepository: $this->contentRepositoryRegistry diff --git a/Classes/ContentRepository/Service/WorkspaceService.php b/Classes/ContentRepository/Service/WorkspaceService.php index b1d71bfb65..85253b568e 100644 --- a/Classes/ContentRepository/Service/WorkspaceService.php +++ b/Classes/ContentRepository/Service/WorkspaceService.php @@ -56,6 +56,12 @@ class WorkspaceService */ protected $domainUserService; + /** + * @Flow\Inject + * @var \Neos\Neos\Domain\Service\WorkspaceService + */ + protected $neosWorkspaceService; + /** * Get all publishable node context paths for a workspace * @@ -132,6 +138,9 @@ public function getPublishableNodeInfo(WorkspaceName $workspaceName, ContentRepo public function getAllowedTargetWorkspaces(ContentRepository $contentRepository): array { $user = $this->domainUserService->getCurrentUser(); + if ($user === null) { + return []; + } $workspacesArray = []; foreach ($contentRepository->getWorkspaceFinder()->findAll() as $workspace) { @@ -149,12 +158,13 @@ public function getAllowedTargetWorkspaces(ContentRepository $contentRepository) // Skip other personal workspaces continue; } + $workspacePermissions = $this->neosWorkspaceService->getWorkspacePermissionsForUser($contentRepository->id, $workspace->workspaceName, $user); $workspaceArray = [ 'name' => $workspace->workspaceName->jsonSerialize(), 'title' => $workspace->workspaceTitle->jsonSerialize(), 'description' => $workspace->workspaceDescription->jsonSerialize(), - 'readonly' => !$this->domainUserService->currentUserCanPublishToWorkspace($workspace) + 'readonly' => !$workspacePermissions->write, ]; $workspacesArray[$workspace->workspaceName->jsonSerialize()] = $workspaceArray; } diff --git a/Classes/Controller/BackendController.php b/Classes/Controller/BackendController.php index a70a803b48..bac47b7357 100644 --- a/Classes/Controller/BackendController.php +++ b/Classes/Controller/BackendController.php @@ -19,11 +19,10 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\Controller\ActionController; use Neos\Flow\Persistence\PersistenceManagerInterface; -use Neos\Flow\Security\Context; use Neos\Neos\Domain\Repository\DomainRepository; use Neos\Neos\Domain\Repository\SiteRepository; use Neos\Neos\Domain\Service\NodeTypeNameFactory; -use Neos\Neos\Domain\Service\WorkspaceNameBuilder; +use Neos\Neos\Domain\Service\WorkspaceService; use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\NodeUriBuilderFactory; use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult; @@ -78,12 +77,6 @@ class BackendController extends ActionController */ protected $contentRepositoryRegistry; - /** - * @Flow\Inject - * @var Context - */ - protected $securityContext; - /** * @Flow\Inject * @var ConfigurationProviderInterface @@ -126,6 +119,12 @@ class BackendController extends ActionController */ protected $nodeUriBuilderFactory; + /** + * @Flow\Inject + * @var WorkspaceService + */ + protected $workspaceService; + /** * Displays the backend interface * @@ -138,23 +137,19 @@ public function indexAction(string $node = null) $contentRepository = $this->contentRepositoryRegistry->get($siteDetectionResult->contentRepositoryId); $nodeAddress = $node !== null ? NodeAddressFactory::create($contentRepository)->createFromUriString($node) : null; - unset($node); $user = $this->userService->getBackendUser(); if ($user === null) { $this->redirectToUri($this->uriBuilder->uriFor('index', [], 'Login', 'Neos.Neos')); } - $currentAccount = $this->securityContext->getAccount(); - assert($currentAccount !== null); - $workspaceName = WorkspaceNameBuilder::fromAccountIdentifier($currentAccount->getAccountIdentifier()); - try { - $contentGraph = $contentRepository->getContentGraph($workspaceName); + $workspace = $this->workspaceService->getPersonalWorkspaceForUser($siteDetectionResult->contentRepositoryId, $user->getId()); } catch (WorkspaceDoesNotExist) { // todo will cause infinite loop: https://github.com/neos/neos-development-collection/issues/4401 $this->redirectToUri($this->uriBuilder->uriFor('index', [], 'Login', 'Neos.Neos')); } + $contentGraph = $contentRepository->getContentGraph($workspace->workspaceName); $backendControllerInternals = $this->contentRepositoryRegistry->buildService( $siteDetectionResult->contentRepositoryId, diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index 4454e852eb..3ff4e2cf50 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -17,7 +17,6 @@ use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; use Neos\ContentRepository\Core\Feature\WorkspaceModification\Exception\WorkspaceIsNotEmptyException; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Dto\RebaseErrorHandlingStrategy; -use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregateCurrentlyDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregateDoesCurrentlyNotCoverDimensionSpacePoint; @@ -33,17 +32,12 @@ use Neos\Flow\Property\PropertyMapper; use Neos\Flow\Security\Context; use Neos\Neos\Domain\Service\WorkspaceNameBuilder; -use Neos\Neos\Domain\Workspace\WorkspaceProvider; +use Neos\Neos\Domain\Service\WorkspacePublishingService; use Neos\Neos\FrontendRouting\NodeAddress; use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult; use Neos\Neos\Service\UserService; use Neos\Neos\Ui\Application\ChangeTargetWorkspace; -use Neos\Neos\Ui\Application\DiscardAllChanges; -use Neos\Neos\Ui\Application\DiscardChangesInDocument; -use Neos\Neos\Ui\Application\DiscardChangesInSite; -use Neos\Neos\Ui\Application\PublishChangesInDocument; -use Neos\Neos\Ui\Application\PublishChangesInSite; use Neos\Neos\Ui\Application\ReloadNodes\ReloadNodesQuery; use Neos\Neos\Ui\Application\ReloadNodes\ReloadNodesQueryHandler; use Neos\Neos\Ui\Application\SyncWorkspace\ConflictsOccurred; @@ -136,9 +130,9 @@ class BackendServiceController extends ActionController /** * @Flow\Inject - * @var WorkspaceProvider + * @var WorkspacePublishingService */ - protected $workspaceProvider; + protected $workspacePublishingService; /** * @Flow\Inject @@ -164,16 +158,16 @@ protected function initializeController(ActionRequest $request, ActionResponse $ /** * Apply a set of changes to the system - * @psalm-param list> $changes + * @psalm-param list> $changeCollection */ public function changeAction(array $changes): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $changes = $this->changeCollectionConverter->convert($changes, $contentRepositoryId); + $changeCollection = $this->changeCollectionConverter->convert($changes, $contentRepositoryId); try { - $count = $changes->count(); - $changes->apply(); + $count = $changeCollection->count(); + $changeCollection->apply(); $success = new Info(); $success->setMessage( @@ -201,23 +195,19 @@ public function publishChangesInSiteAction(array $command): void try { /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $command['contentRepositoryId'] = $contentRepositoryId->value; - $command['siteId'] = $this->nodeService->deserializeNodeAddress( + $siteNodeAddress = $this->nodeService->deserializeNodeAddress( $command['siteId'], $contentRepositoryId - )->nodeAggregateId->value; - $command = PublishChangesInSite::fromArray($command); - $workspace = $this->workspaceProvider->provideForWorkspaceName( - $command->contentRepositoryId, - $command->workspaceName ); - $publishingResult = $workspace - ->publishChangesInSite($command->siteId); - + $publishingResult = $this->workspacePublishingService->publishChangesInSite( + $contentRepositoryId, + $siteNodeAddress->workspaceName, + $siteNodeAddress->nodeAggregateId, + ); $this->view->assign('value', [ 'success' => [ 'numberOfAffectedChanges' => $publishingResult->numberOfPublishedChanges, - 'baseWorkspaceName' => $workspace->getCurrentBaseWorkspaceName()?->value + 'baseWorkspaceName' => $publishingResult->targetWorkspaceName->value ] ]); } catch (\Exception $e) { @@ -242,26 +232,21 @@ public function publishChangesInDocumentAction(array $command): void try { /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $command['contentRepositoryId'] = $contentRepositoryId->value; - $command['documentId'] = $this->nodeService->deserializeNodeAddress( + $documentNodeAddress = $this->nodeService->deserializeNodeAddress( $command['documentId'], $contentRepositoryId - )->nodeAggregateId->value; - $command = PublishChangesInDocument::fromArray($command); - - $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - + ); try { - $workspace = $this->workspaceProvider->provideForWorkspaceName( - $command->contentRepositoryId, - $command->workspaceName + $publishingResult = $this->workspacePublishingService->publishChangesInDocument( + $contentRepositoryId, + $documentNodeAddress->workspaceName, + $documentNodeAddress->nodeAggregateId, ); - $publishingResult = $workspace->publishChangesInDocument($command->documentId); $this->view->assign('value', [ 'success' => [ 'numberOfAffectedChanges' => $publishingResult->numberOfPublishedChanges, - 'baseWorkspaceName' => $workspace->getCurrentBaseWorkspaceName()?->value + 'baseWorkspaceName' => $publishingResult->targetWorkspaceName->value, ] ]); } catch (NodeAggregateCurrentlyDoesNotExist $e) { @@ -299,15 +284,9 @@ public function discardAllChangesAction(array $command): void try { /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $command['contentRepositoryId'] = $contentRepositoryId->value; - $command = DiscardAllChanges::fromArray($command); - - $workspace = $this->workspaceProvider->provideForWorkspaceName( - $command->contentRepositoryId, - $command->workspaceName - ); - $discardingResult = $workspace->discardAllChanges(); + $workspaceName = WorkspaceName::fromString($command['workspaceName']); + $discardingResult = $this->workspacePublishingService->discardAllWorkspaceChanges($contentRepositoryId, $workspaceName); $this->view->assign('value', [ 'success' => [ 'numberOfAffectedChanges' => $discardingResult->numberOfDiscardedChanges @@ -335,18 +314,16 @@ public function discardChangesInSiteAction(array $command): void try { /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $command['contentRepositoryId'] = $contentRepositoryId->value; - $command['siteId'] = $this->nodeService->deserializeNodeAddress( + $siteNodeAddress = $this->nodeService->deserializeNodeAddress( $command['siteId'], $contentRepositoryId - )->nodeAggregateId->value; - $command = DiscardChangesInSite::fromArray($command); + ); - $workspace = $this->workspaceProvider->provideForWorkspaceName( - $command->contentRepositoryId, - $command->workspaceName + $discardingResult = $this->workspacePublishingService->discardChangesInSite( + $contentRepositoryId, + $siteNodeAddress->workspaceName, + $siteNodeAddress->nodeAggregateId ); - $discardingResult = $workspace->discardChangesInSite($command->siteId); $this->view->assign('value', [ 'success' => [ @@ -375,18 +352,11 @@ public function discardChangesInDocumentAction(array $command): void try { /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $command['contentRepositoryId'] = $contentRepositoryId->value; - $command['documentId'] = $this->nodeService->deserializeNodeAddress( + $documentNodeAddress = $this->nodeService->deserializeNodeAddress( $command['documentId'], $contentRepositoryId - )->nodeAggregateId->value; - $command = DiscardChangesInDocument::fromArray($command); - - $workspace = $this->workspaceProvider->provideForWorkspaceName( - $command->contentRepositoryId, - $command->workspaceName ); - $discardingResult = $workspace->discardChangesInDocument($command->documentId); + $discardingResult = $this->workspacePublishingService->discardChangesInDocument($contentRepositoryId, $documentNodeAddress->workspaceName, $documentNodeAddress->nodeAggregateId); $this->view->assign('value', [ 'success' => [ @@ -421,7 +391,13 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d $nodeAddressFactory = NodeAddressFactory::create($contentRepository); $currentAccount = $this->securityContext->getAccount(); - assert($currentAccount !== null); + if ($currentAccount === null) { + $error = new Error(); + $error->setMessage('No authenticated account'); + $this->feedbackCollection->add($error); + $this->view->assign('value', $this->feedbackCollection); + return; + } $userWorkspaceName = WorkspaceNameBuilder::fromAccountIdentifier( $currentAccount->getAccountIdentifier() ); @@ -435,11 +411,7 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d ); try { - $workspace = $this->workspaceProvider->provideForWorkspaceName( - $command->contentRepositoryId, - $command->workspaceName - ); - $workspace->changeBaseWorkspace($command->targetWorkspaceName); + $this->workspacePublishingService->changeBaseWorkspace($contentRepositoryId, $userWorkspaceName, WorkspaceName::fromString($targetWorkspaceName)); } catch (WorkspaceIsNotEmptyException $exception) { $error = new Error(); $error->setMessage( @@ -458,13 +430,14 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d return; } - $subgraph = $contentRepository->getContentGraph($workspace->name) + $subgraph = $contentRepository->getContentGraph($userWorkspaceName) ->getSubgraph( $command->documentNode->dimensionSpacePoint, VisibilityConstraints::withoutRestrictions() ); - $documentNode = $subgraph->findNodeById($command->documentNode->nodeAggregateId); + $documentNodeInstance = $subgraph->findNodeById($command->documentNode->nodeAggregateId); + assert($documentNodeInstance !== null); $success = new Success(); $success->setMessage( @@ -478,7 +451,7 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d // If current document node doesn't exist in the base workspace, // traverse its parents to find the one that exists // todo ensure that https://github.com/neos/neos-ui/pull/3734 doesnt need to be refixed in Neos 9.0 - $redirectNode = $documentNode; + $redirectNode = $documentNodeInstance; while (true) { // @phpstan-ignore-next-line $redirectNodeInBaseWorkspace = $subgraph->findNodeById($redirectNode->aggregateId); @@ -492,7 +465,7 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d throw new \Exception( sprintf( 'Wasn\'t able to locate any valid node in rootline of node %s in the workspace %s.', - $documentNode?->aggregateId->value, + $documentNodeInstance->aggregateId->value, $targetWorkspaceName ), 1458814469 @@ -500,13 +473,11 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d } } } - /** @var Node $documentNode */ - /** @var Node $redirectNode */ // If current document node exists in the base workspace, then reload, else redirect - if ($redirectNode->equals($documentNode)) { + if ($redirectNode->equals($documentNodeInstance)) { $reloadDocument = new ReloadDocument(); - $reloadDocument->setNode($documentNode); + $reloadDocument->setNode($documentNodeInstance); $this->feedbackCollection->add($reloadDocument); } else { $redirect = new Redirect(); @@ -575,8 +546,7 @@ public function cutNodesAction(array $nodes): void public function getWorkspaceInfoAction(): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $workspaceHelper = new WorkspaceHelper(); - $personalWorkspaceInfo = $workspaceHelper->getPersonalWorkspace($contentRepositoryId); + $personalWorkspaceInfo = (new WorkspaceHelper())->getPersonalWorkspace($contentRepositoryId); $this->view->assign('value', $personalWorkspaceInfo); } diff --git a/Classes/Domain/Model/Changes/Property.php b/Classes/Domain/Model/Changes/Property.php index dbff01dffc..bac13bd64c 100644 --- a/Classes/Domain/Model/Changes/Property.php +++ b/Classes/Domain/Model/Changes/Property.php @@ -239,8 +239,7 @@ private function handleNodeReferenceChange(Node $subject, string $propertyName): $subject->workspaceName, $subject->aggregateId, $subject->originDimensionSpacePoint, - ReferenceName::fromString($propertyName), - NodeReferencesToWrite::fromNodeAggregateIds(NodeAggregateIds::fromArray($destinationNodeAggregateIds)) + NodeReferencesToWrite::fromNodeAggregateIds(ReferenceName::fromString($propertyName), NodeAggregateIds::fromArray($destinationNodeAggregateIds)) ) ); } diff --git a/Classes/Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php b/Classes/Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php index 53577a573b..82762f33f8 100644 --- a/Classes/Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php +++ b/Classes/Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php @@ -11,15 +11,15 @@ * source code. */ -use Neos\ContentRepository\Core\Projection\Workspace\Workspace; -use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; +use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; +use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; +use Neos\Flow\Mvc\Controller\ControllerContext; +use Neos\Neos\PendingChangesProjection\ChangeFinder; use Neos\Neos\Ui\ContentRepository\Service\WorkspaceService; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; -use Neos\Flow\Mvc\Controller\ControllerContext; -use Neos\Neos\Domain\Workspace\WorkspaceProvider; /** * @internal @@ -34,9 +34,9 @@ class UpdateWorkspaceInfo extends AbstractFeedback /** * @Flow\Inject - * @var WorkspaceProvider + * @var ContentRepositoryRegistry */ - protected $workspaceProvider; + protected $contentRepositoryRegistry; /** * UpdateWorkspaceInfo constructor. @@ -87,8 +87,8 @@ public function isSimilarTo(FeedbackInterface $feedback) if (!$feedback instanceof UpdateWorkspaceInfo) { return false; } - - return $this->getWorkspaceName()->equals($feedback->getWorkspaceName()); + $feedbackWorkspaceName = $feedback->getWorkspaceName(); + return $feedbackWorkspaceName !== null && $this->getWorkspaceName()?->equals($feedbackWorkspaceName); } /** @@ -99,11 +99,17 @@ public function isSimilarTo(FeedbackInterface $feedback) */ public function serializePayload(ControllerContext $controllerContext) { - $workspace = $this->workspaceProvider->provideForWorkspaceName( - $this->contentRepositoryId, - $this->workspaceName - ); - $totalNumberOfChanges = $workspace->countAllChanges(); + if (!$this->workspaceName) { + return null; + } + $contentRepository = $this->contentRepositoryRegistry->get($this->contentRepositoryId); + $workspace = $contentRepository->findWorkspaceByName($this->workspaceName); + if ($workspace === null) { + return null; + } + /** @var ChangeFinder $changeFinder */ + $changeFinder = $contentRepository->projectionState(ChangeFinder::class); + $totalNumberOfChanges = $changeFinder->countByContentStreamId($workspace->currentContentStreamId); return [ 'name' => $this->workspaceName->value, @@ -112,8 +118,8 @@ public function serializePayload(ControllerContext $controllerContext) $this->workspaceName, $this->contentRepositoryId ), - 'baseWorkspace' => $workspace->getCurrentBaseWorkspaceName()?->value, - 'status' => $workspace->getCurrentStatus() + 'baseWorkspace' => $workspace->baseWorkspaceName?->value, + 'status' => $workspace->status->value, ]; } } diff --git a/Classes/Fusion/Helper/WorkspaceHelper.php b/Classes/Fusion/Helper/WorkspaceHelper.php index c22e35837f..586373e708 100644 --- a/Classes/Fusion/Helper/WorkspaceHelper.php +++ b/Classes/Fusion/Helper/WorkspaceHelper.php @@ -16,13 +16,16 @@ use Neos\Eel\ProtectedContextAwareInterface; use Neos\Flow\Annotations as Flow; use Neos\Flow\Security\Context; -use Neos\Neos\Domain\Service\WorkspaceNameBuilder; -use Neos\Neos\Domain\Workspace\WorkspaceProvider; +use Neos\Neos\Domain\Service\UserService; +use Neos\Neos\Domain\Service\WorkspacePublishingService; +use Neos\Neos\Domain\Service\WorkspaceService as NeosWorkspaceService; use Neos\Neos\Ui\ContentRepository\Service\WorkspaceService; /** * @internal implementation detail of the Neos Ui to build its initialState. * and used for the workspace-info endpoint. + * + * TODO REMOVE */ class WorkspaceHelper implements ProtectedContextAwareInterface { @@ -46,34 +49,40 @@ class WorkspaceHelper implements ProtectedContextAwareInterface /** * @Flow\Inject - * @var WorkspaceProvider + * @var WorkspacePublishingService + */ + protected $workspacePublishingService; + + /** + * @Flow\Inject + * @var UserService */ - protected $workspaceProvider; + protected $userService; + + /** + * @Flow\Inject + * @var NeosWorkspaceService + */ + protected $neosWorkspaceService; /** * @return array */ public function getPersonalWorkspace(ContentRepositoryId $contentRepositoryId): array { - $currentAccount = $this->securityContext->getAccount(); - assert($currentAccount !== null); - // todo use \Neos\Neos\Service\UserService::getPersonalWorkspaceName instead? - $personalWorkspaceName = WorkspaceNameBuilder::fromAccountIdentifier($currentAccount->getAccountIdentifier()); - - $workspace = $this->workspaceProvider->provideForWorkspaceName( - $contentRepositoryId, - $personalWorkspaceName - ); - + $currentUser = $this->userService->getCurrentUser(); + if ($currentUser === null) { + return []; + } + $personalWorkspace = $this->neosWorkspaceService->getPersonalWorkspaceForUser($contentRepositoryId, $currentUser->getId()); + $personalWorkspacePermissions = $this->neosWorkspaceService->getWorkspacePermissionsForUser($contentRepositoryId, $personalWorkspace->workspaceName, $currentUser); return [ - 'name' => $workspace->name, - 'totalNumberOfChanges' => $workspace->countAllChanges(), - 'publishableNodes' => $this->workspaceService->getPublishableNodeInfo($personalWorkspaceName, $contentRepositoryId), - 'baseWorkspace' => $workspace->getCurrentBaseWorkspaceName(), - // TODO: FIX readonly flag! - //'readOnly' => !$this->domainUserService->currentUserCanPublishToWorkspace($baseWorkspace) - 'readOnly' => false, - 'status' => $workspace->getCurrentStatus() + 'name' => $personalWorkspace->workspaceName->value, + 'totalNumberOfChanges' => $this->workspacePublishingService->countPendingWorkspaceChanges($contentRepositoryId, $personalWorkspace->workspaceName), + 'publishableNodes' => $this->workspaceService->getPublishableNodeInfo($personalWorkspace->workspaceName, $contentRepositoryId), + 'baseWorkspace' => $personalWorkspace->baseWorkspaceName?->value, + 'readOnly' => !($personalWorkspace->baseWorkspaceName !== null && $personalWorkspacePermissions->write), + 'status' => $personalWorkspace->status->value, ]; }