diff --git a/Neos.ContentRepository.Core/Classes/Projection/Workspace/WorkspaceFinder.php b/Neos.ContentRepository.Core/Classes/Projection/Workspace/WorkspaceFinder.php index db8414b0875..a5f49004cd2 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/Workspace/WorkspaceFinder.php +++ b/Neos.ContentRepository.Core/Classes/Projection/Workspace/WorkspaceFinder.php @@ -91,32 +91,6 @@ public function findOneByCurrentContentStreamId( return $workspace; } - /** - * @return array - */ - public function findByPrefix(WorkspaceName $prefix): array - { - $result = []; - - $connection = $this->client->getConnection(); - $workspaceRows = $connection->executeQuery( - ' - SELECT * FROM ' . $this->tableName . ' - WHERE workspaceName LIKE :workspaceNameLike - ', - [ - 'workspaceNameLike' => $prefix->value . '%' - ] - )->fetchAllAssociative(); - - foreach ($workspaceRows as $workspaceRow) { - $similarlyNamedWorkspace = $this->createWorkspaceFromDatabaseRow($workspaceRow); - $result[$similarlyNamedWorkspace->workspaceName->value] = $similarlyNamedWorkspace; - } - - return $result; - } - /** * @return array * @throws \Doctrine\DBAL\DBALException diff --git a/Neos.Neos/Classes/Controller/Module/Management/WorkspacesController.php b/Neos.Neos/Classes/Controller/Module/Management/WorkspacesController.php index bf782bfc86f..98a1c25cb1b 100644 --- a/Neos.Neos/Classes/Controller/Module/Management/WorkspacesController.php +++ b/Neos.Neos/Classes/Controller/Module/Management/WorkspacesController.php @@ -15,31 +15,23 @@ namespace Neos\Neos\Controller\Module\Management; use Neos\ContentRepository\Core\ContentRepository; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; -use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Exception\WorkspaceAlreadyExists; -use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindAncestorNodesFilter; -use Neos\ContentRepository\Core\Projection\ContentGraph\NodeTypeConstraints; -use Neos\ContentRepository\Core\SharedModel\Node\NodeName; -use Neos\Flow\I18n\Exception\IndexOutOfBoundsException; -use Neos\Flow\I18n\Exception\InvalidFormatPlaceholderException; -use Neos\Flow\Mvc\Exception\StopActionException; -use Neos\Neos\Domain\Model\SiteNodeName; -use Neos\Neos\PendingChangesProjection\ChangeFinder; -use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\Workspace\Workspace; use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Command\CreateWorkspace; +use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Exception\WorkspaceAlreadyExists; +use Neos\ContentRepository\Core\Feature\WorkspaceModification\Command\ChangeWorkspaceOwner; +use Neos\ContentRepository\Core\Feature\WorkspaceModification\Command\DeleteWorkspace; +use Neos\ContentRepository\Core\Feature\WorkspaceModification\Command\RenameWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\DiscardIndividualNodesFromWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\DiscardWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishIndividualNodesFromWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishWorkspace; -use Neos\ContentRepository\Core\Feature\WorkspaceModification\Command\RenameWorkspace; -use Neos\ContentRepository\Core\Feature\WorkspaceModification\Command\DeleteWorkspace; -use Neos\ContentRepository\Core\Feature\WorkspaceModification\Command\ChangeWorkspaceOwner; -use Neos\Neos\FrontendRouting\NodeAddress; -use Neos\Neos\FrontendRouting\NodeAddressFactory; -use Neos\ContentRepository\Core\SharedModel\User\UserId; +use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; +use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; +use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindAncestorNodesFilter; +use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; +use Neos\ContentRepository\Core\Projection\Workspace\Workspace; +use Neos\ContentRepository\Core\SharedModel\Node\NodeName; +use Neos\ContentRepository\Core\SharedModel\User\UserId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceDescription; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -47,21 +39,28 @@ use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Diff\Diff; use Neos\Diff\Renderer\Html\HtmlArrayRenderer; -use Neos\Neos\Controller\Module\ModuleTranslationTrait; -use Neos\Neos\Domain\Model\WorkspaceName as NeosWorkspaceName; -use Neos\Flow\Annotations as Flow; use Neos\Error\Messages\Message; +use Neos\Flow\Annotations as Flow; +use Neos\Flow\I18n\Exception\IndexOutOfBoundsException; +use Neos\Flow\I18n\Exception\InvalidFormatPlaceholderException; use Neos\Flow\Mvc\ActionRequest; +use Neos\Flow\Mvc\Exception\StopActionException; use Neos\Flow\Package\PackageManager; use Neos\Flow\Property\PropertyMapper; use Neos\Flow\Security\Context; use Neos\Media\Domain\Model\AssetInterface; use Neos\Media\Domain\Model\ImageInterface; use Neos\Neos\Controller\Module\AbstractModuleController; +use Neos\Neos\Controller\Module\ModuleTranslationTrait; +use Neos\Neos\Domain\Model\SiteNodeName; use Neos\Neos\Domain\Model\User; use Neos\Neos\Domain\Repository\SiteRepository; use Neos\Neos\Domain\Service\UserService; +use Neos\Neos\Domain\Service\WorkspaceNameBuilder; +use Neos\Neos\FrontendRouting\NodeAddress; +use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult; +use Neos\Neos\PendingChangesProjection\ChangeFinder; /** * The Neos Workspaces module controller @@ -121,8 +120,7 @@ public function indexAction() $currentAccount = $this->securityContext->getAccount(); $userWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName( - NeosWorkspaceName::fromAccountIdentifier($currentAccount->getAccountIdentifier()) - ->toContentRepositoryWorkspaceName() + WorkspaceNameBuilder::fromAccountIdentifier($currentAccount->getAccountIdentifier()) ); if (is_null($userWorkspace)) { throw new \RuntimeException('Current user has no workspace', 1645485990); @@ -462,8 +460,7 @@ public function rebaseAndRedirectAction(Node $targetNode, Workspace $targetWorks $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); $currentAccount = $this->securityContext->getAccount(); - $personalWorkspaceName = NeosWorkspaceName::fromAccountIdentifier($currentAccount->getAccountIdentifier()) - ->toContentRepositoryWorkspaceName(); + $personalWorkspaceName = WorkspaceNameBuilder::fromAccountIdentifier($currentAccount->getAccountIdentifier()); $personalWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName($personalWorkspaceName); /** @var Workspace $personalWorkspace */ diff --git a/Neos.Neos/Classes/Domain/Model/WorkspaceName.php b/Neos.Neos/Classes/Domain/Model/WorkspaceName.php deleted file mode 100644 index c59ba79951d..00000000000 --- a/Neos.Neos/Classes/Domain/Model/WorkspaceName.php +++ /dev/null @@ -1,81 +0,0 @@ -name = $name; - } - - public static function fromAccountIdentifier(string $accountIdentifier): self - { - $name = preg_replace('/[^A-Za-z0-9\-]/', '-', self::PREFIX . $accountIdentifier); - if (is_null($name)) { - throw new \InvalidArgumentException( - 'Cannot convert account identifier ' . $accountIdentifier . ' to workspace name.', - 1645656253 - ); - } - - return new self($name); - } - - /** - * @param array $takenWorkspaceNames - */ - public function increment(array $takenWorkspaceNames): self - { - $name = $this->name; - $i = 1; - while (array_key_exists($name, $takenWorkspaceNames)) { - $name = $this->name . self::SUFFIX_DELIMITER . $i; - $i++; - } - - if ($i > 1) { - return new WorkspaceName($name); - } else { - return $this; - } - } - - public function toContentRepositoryWorkspaceName(): ContentRepositoryWorkspaceName - { - return ContentRepositoryWorkspaceName::fromString($this->name); - } - - public function jsonSerialize(): string - { - return $this->name; - } - - public function __toString(): string - { - return $this->name; - } -} diff --git a/Neos.Neos/Classes/Domain/Service/WorkspaceNameBuilder.php b/Neos.Neos/Classes/Domain/Service/WorkspaceNameBuilder.php new file mode 100644 index 00000000000..44d75e72086 --- /dev/null +++ b/Neos.Neos/Classes/Domain/Service/WorkspaceNameBuilder.php @@ -0,0 +1,35 @@ +partyService->getAssignedPartyOfAccount($token->getAccount()); - if ($user instanceof User) { - $workspaceName = AdjustmentsWorkspaceName::fromAccountIdentifier( - $token->getAccount()->getAccountIdentifier() - ); - $workspace = $contentRepository->getWorkspaceFinder()->findOneByName( - $workspaceName->toContentRepositoryWorkspaceName() - ); - - if (!$workspace) { - // @todo: find base workspace for user - /** @var Workspace $baseWorkspace */ - $baseWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName(WorkspaceName::forLive()); - $editorsNewContentStreamId = ContentStreamId::create(); - $similarlyNamedWorkspaces = $contentRepository->getWorkspaceFinder()->findByPrefix( - $workspaceName->toContentRepositoryWorkspaceName() - ); - if (!empty($similarlyNamedWorkspaces)) { - $workspaceName = $workspaceName->increment($similarlyNamedWorkspaces); - } - - $contentRepository->handle( - CreateWorkspace::create( - $workspaceName->toContentRepositoryWorkspaceName(), - $baseWorkspace->workspaceName, - new WorkspaceTitle((string) $user->getName()), - new WorkspaceDescription(''), - $editorsNewContentStreamId, - UserId::fromString($this->persistenceManager->getIdentifierByObject($user)) - ) - )->block(); - } else { - CatchUpTriggerWithSynchronousOption::synchronously(fn() => - $contentRepository->handle( - RebaseWorkspace::create( - $workspace->workspaceName, - ) - )->block()); - } - } + if (!$isEditor) { + return; + } + $user = $this->partyService->getAssignedPartyOfAccount($token->getAccount()); + if (!$user instanceof User) { + return; } + $workspaceName = WorkspaceNameBuilder::fromAccountIdentifier( + $token->getAccount()->getAccountIdentifier() + ); + $workspace = $contentRepository->getWorkspaceFinder()->findOneByName($workspaceName); + if ($workspace !== null) { + CatchUpTriggerWithSynchronousOption::synchronously(fn() => $contentRepository->handle( + RebaseWorkspace::create( + $workspace->workspaceName, + ) + )->block()); + return; + } + + /** @var Workspace $baseWorkspace */ + $baseWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName(WorkspaceName::forLive()); + $editorsNewContentStreamId = ContentStreamId::create(); + $contentRepository->handle( + CreateWorkspace::create( + $workspaceName, + $baseWorkspace->workspaceName, + new WorkspaceTitle((string) $user->getName()), + new WorkspaceDescription(''), + $editorsNewContentStreamId, + UserId::fromString($this->persistenceManager->getIdentifierByObject($user)) + ) + )->block(); } } diff --git a/Neos.Neos/Classes/Utility/User.php b/Neos.Neos/Classes/Utility/User.php index 051eedb8fb5..1d7f0840544 100644 --- a/Neos.Neos/Classes/Utility/User.php +++ b/Neos.Neos/Classes/Utility/User.php @@ -2,7 +2,7 @@ namespace Neos\Neos\Utility; -use Neos\Neos\Domain\Model\WorkspaceName; +use Neos\Neos\Domain\Service\WorkspaceNameBuilder; /** * Utility functions for dealing with users in the Content Repository. @@ -17,7 +17,7 @@ class User */ public static function getPersonalWorkspaceNameForUsername($username): string { - return (string)WorkspaceName::fromAccountIdentifier($username); + return WorkspaceNameBuilder::fromAccountIdentifier($username)->value; } /**