Skip to content

Commit

Permalink
Merge pull request #3463 from dlubitz/90/changing-workspace
Browse files Browse the repository at this point in the history
FEATURE: Allow changing the base workspace of a workspace
  • Loading branch information
skurfuerst authored Apr 16, 2023
2 parents a8d780d + 4681fd0 commit 21998d9
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 75 deletions.
159 changes: 85 additions & 74 deletions Classes/Controller/BackendServiceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishIndividualNodesFromWorkspace;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard;
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Eel\FlowQuery\FlowQuery;
Expand Down Expand Up @@ -50,6 +49,12 @@
use Neos\Neos\Ui\Service\PublishingService;
use Neos\Neos\Ui\TypeConverter\ChangeCollectionConverter;
use Neos\Neos\Utility\NodeUriPathSegmentGenerator;
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;
use Neos\ContentRepository\Core\Feature\WorkspaceModification\Command\ChangeBaseWorkspace;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\Neos\Ui\Domain\Model\Feedback\Operations\ReloadDocument;
use Neos\Neos\Ui\Domain\Model\Feedback\Operations\Redirect;
use Neos\ContentRepository\Core\Feature\WorkspaceModification\Exception\WorkspaceIsNotEmptyException;

class BackendServiceController extends ActionController
{
Expand Down Expand Up @@ -308,86 +313,94 @@ public function discardAction(array $nodeContextPaths): void
* Change base workspace of current user workspace
*
* @param string $targetWorkspaceName ,
* @param Node $documentNode
* @param string $documentNode
* @return void
* @throws \Exception
*/
public function changeBaseWorkspaceAction(string $targetWorkspaceName, Node $documentNode)
public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $documentNode): void
{
$contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId;
$contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId);

$nodeAddressFactory = NodeAddressFactory::create($contentRepository);
$nodeAddress = $nodeAddressFactory->createFromUriString($documentNode);

$currentAccount = $this->securityContext->getAccount();
$userWorkspaceName = NeosWorkspaceName::fromAccountIdentifier(
$currentAccount->getAccountIdentifier()
)->toContentRepositoryWorkspaceName();

try {
throw new \BadMethodCallException('changeBaseWorkspaceAction is not yet implemented', 1645607154);
/*
$targetWorkspace = $this->workspaceFinder->findOneByName(WorkspaceName::fromString($targetWorkspaceName));
$currentAccount = $this->securityContext->getAccount();
$workspaceName = NeosWorkspaceName::fromAccountIdentifier(
$currentAccount->getAccountIdentifier()
)->toContentRepositoryWorkspaceName();
$userWorkspace = $this->workspaceFinder->findOneByName($workspaceName);
#if (count($this->workspaceService->getPublishableNodeInfo($userWorkspace)) > 0) {
# // TODO: proper error dialog
# throw new \Exception(
# 'Your personal workspace currently contains unpublished changes.'
# . ' In order to switch to a different target workspace you need to either publish'
# . ' or discard pending changes first.'
# );
#
#$userWorkspace->setBaseWorkspace($targetWorkspace);
#$this->workspaceFinder->update($userWorkspace);
$contentRepository->handle(
new ChangeBaseWorkspace(
$userWorkspaceName,
WorkspaceName::fromString($targetWorkspaceName),
$newCOnt = ContentStreamId::create()
)
)->block();
} catch (WorkspaceIsNotEmptyException $exception) {
$error = new Error();
$error->setMessage('Your personal workspace currently contains unpublished changes.'
. ' In order to switch to a different target workspace you need to either publish'
. ' or discard pending changes first.');

$success = new Success();
$success->setMessage(sprintf('Switched base workspace to %s.', $targetWorkspaceName));
$this->feedbackCollection->add($success);
$this->feedbackCollection->add($error);
$this->view->assign('value', $this->feedbackCollection);
return;
} catch (\Exception $exception) {
$error = new Error();
$error->setMessage($error->getMessage());

$updateWorkspaceInfo = new UpdateWorkspaceInfo();
#$updateWorkspaceInfo->setWorkspace($userWorkspace);
$this->feedbackCollection->add($updateWorkspaceInfo);
$this->feedbackCollection->add($error);
$this->view->assign('value', $this->feedbackCollection);
return;
}

// Construct base workspace context
$originalContext = $documentNode->getContext();
$contextProperties = $documentNode->getContext()->getProperties();
$contextProperties['workspaceName'] = $targetWorkspaceName;
$contentContext = $this->contextFactory->create($contextProperties);
// If current document node doesn't exist in the base workspace,
// traverse its parents to find the one that exists
$redirectNode = $documentNode;
while (true) {
$redirectNodeInBaseWorkspace = $contentContext->getNodeByIdentifier($redirectNode->getIdentifier());
if ($redirectNodeInBaseWorkspace) {
break;
} else {
$redirectNode = $redirectNode->getParent();
// get parent always returns Node
if (!$redirectNode) {
throw new \Exception(sprintf(
'Wasn\'t able to locate any valid node in rootline of node %s in the workspace %s.',
$documentNode->getContextPath(),
$targetWorkspaceName
), 1458814469);
}
}
}
$subgraph = $contentRepository->getContentGraph()
->getSubgraph(
$newCOnt,
$nodeAddress->dimensionSpacePoint,
VisibilityConstraints::withoutRestrictions()
);

$documentNode = $subgraph->findNodeById($nodeAddress->nodeAggregateId);

$success = new Success();
$success->setMessage(sprintf('Switched base workspace to %s.', $targetWorkspaceName));
$this->feedbackCollection->add($success);

// If current document node exists in the base workspace, then reload, else redirect
if ($redirectNode === $documentNode) {
$reloadDocument = new ReloadDocument();
$reloadDocument->setNode($documentNode);
$this->feedbackCollection->add($reloadDocument);
$updateWorkspaceInfo = new UpdateWorkspaceInfo($contentRepositoryId, $userWorkspaceName);
$this->feedbackCollection->add($updateWorkspaceInfo);

// If current document node doesn't exist in the base workspace,
// traverse its parents to find the one that exists
$redirectNode = $documentNode;
while (true) {
$redirectNodeInBaseWorkspace = $subgraph->findNodeById($redirectNode->nodeAggregateId);
if ($redirectNodeInBaseWorkspace) {
break;
} else {
$redirect = new Redirect();
$redirect->setNode($redirectNode);
$this->feedbackCollection->add($redirect);
$redirectNode = $subgraph->findParentNode($redirectNode->nodeAggregateId);
// get parent always returns Node
if (!$redirectNode) {
throw new \Exception(sprintf(
'Wasn\'t able to locate any valid node in rootline of node %s in the workspace %s.',
$documentNode->nodeAggregateId->value,
$targetWorkspaceName
), 1458814469);
}
}
}

$this->persistenceManager->persistAll();
*/
} catch (\Exception $e) {
$error = new Error();
$error->setMessage($e->getMessage());

$this->feedbackCollection->add($error);
// If current document node exists in the base workspace, then reload, else redirect
if ($redirectNode->equals($documentNode)) {
$reloadDocument = new ReloadDocument();
$reloadDocument->setNode($documentNode);
$this->feedbackCollection->add($reloadDocument);
} else {
$redirect = new Redirect();
$redirect->setNode($redirectNode);
$this->feedbackCollection->add($redirect);
}

$this->view->assign('value', $this->feedbackCollection);
Expand All @@ -411,8 +424,7 @@ public function copyNodesAction(array $nodes): void

/** @var array<int,NodeAddress> $nodeAddresses */
$nodeAddresses = array_map(
fn (string $serializedNodeAddress) =>
$nodeAddressFactory->createFromUriString($serializedNodeAddress),
fn(string $serializedNodeAddress) => $nodeAddressFactory->createFromUriString($serializedNodeAddress),
$nodes
);
$this->clipboard->copyNodes($nodeAddresses);
Expand Down Expand Up @@ -444,8 +456,7 @@ public function cutNodesAction(array $nodes): void

/** @var array<int,\Neos\Neos\FrontendRouting\NodeAddress> $nodeAddresses */
$nodeAddresses = array_map(
fn (string $serializedNodeAddress) =>
$nodeAddressFactory->createFromUriString($serializedNodeAddress),
fn(string $serializedNodeAddress) => $nodeAddressFactory->createFromUriString($serializedNodeAddress),
$nodes
);

Expand Down Expand Up @@ -571,7 +582,7 @@ public function flowQueryAction(array $chain): string
/** @var array<int,mixed> $payload */
$payload = $createContext['payload'] ?? [];
$flowQuery = new FlowQuery(array_map(
fn ($envelope) => $this->nodeService->getNodeFromContextPath($envelope['$node'], $contentRepositoryId),
fn($envelope) => $this->nodeService->getNodeFromContextPath($envelope['$node'], $contentRepositoryId),
$payload
));

Expand Down
1 change: 0 additions & 1 deletion Classes/Domain/Model/Changes/Property.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ public function apply(): void
$this->getValue()
);

// TODO: Make changing the node type a separated, specific/defined change operation.
if ($propertyName[0] !== '_' || $propertyName === '_hiddenInIndex') {
$originDimensionSpacePoint = $subject->originDimensionSpacePoint;
if (!$subject->subgraphIdentity->dimensionSpacePoint->equals($originDimensionSpacePoint)) {
Expand Down

0 comments on commit 21998d9

Please sign in to comment.