diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphFactory.php index 2599353780a..367fd11f87d 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphFactory.php @@ -40,6 +40,10 @@ public function __construct( public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraph { + if ($workspaceName->isReferencingUnusedContentStream()) { + return $this->buildForWorkspaceAndContentStream($workspaceName, $workspaceName->getReferencingUnusedContentStreamId()); + } + // FIXME: Should be part of this projection, this is forbidden $tableName = strtolower(sprintf( 'cr_%s_p_%s', @@ -71,7 +75,7 @@ public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraph return $this->buildForWorkspaceAndContentStream($workspaceName, ContentStreamId::fromString($currentContentStreamId)); } - public function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraph + private function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraph { return new ContentGraph($this->dbal, $this->nodeFactory, $this->contentRepositoryId, $this->nodeTypeManager, $this->tableNames, $workspaceName, $contentStreamId); } diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphFactory.php index 55b8b529a80..fa2cb3f0623 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphFactory.php @@ -31,6 +31,10 @@ public function __construct( public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraphInterface { + if ($workspaceName->isReferencingUnusedContentStream()) { + return $this->buildForWorkspaceAndContentStream($workspaceName, $workspaceName->getReferencingUnusedContentStreamId()); + } + // FIXME: Should be part of this projection, this is forbidden $tableName = strtolower(sprintf( 'cr_%s_p_%s', @@ -55,7 +59,7 @@ public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraphInt return $this->buildForWorkspaceAndContentStream($workspaceName, ContentStreamId::fromString($row['currentcontentstreamid'])); } - public function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface + private function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface { return new ContentHyperGraph($this->dbal, $this->nodeFactory, $this->contentRepositoryId, $this->nodeTypeManager, $this->tableNamePrefix, $workspaceName, $contentStreamId); } diff --git a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php index c0b5270cc37..53a5c282b5c 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php @@ -83,7 +83,7 @@ public function overrideContentStreamId(WorkspaceName $workspaceName, ContentStr throw new \RuntimeException('Contentstream override for this workspace already in effect, nesting not allowed.', 1715170938); } - $contentGraph = $this->contentRepository->projectionState(ContentGraphFinder::class)->getByWorkspaceNameAndContentStreamId($workspaceName, $contentStreamId); + $contentGraph = $this->contentRepository->getContentGraph(WorkspaceName::createReferenceForUnusedContentStream($contentStreamId)); $this->overridenContentGraphInstances[$workspaceName->value] = $contentGraph; try { diff --git a/Neos.ContentRepository.Core/Classes/ContentGraphFactoryInterface.php b/Neos.ContentRepository.Core/Classes/ContentGraphFactoryInterface.php index 2a766579751..eafba61bb26 100644 --- a/Neos.ContentRepository.Core/Classes/ContentGraphFactoryInterface.php +++ b/Neos.ContentRepository.Core/Classes/ContentGraphFactoryInterface.php @@ -16,7 +16,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\SharedModel\Exception\WorkspaceDoesNotExist; -use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** @@ -30,6 +29,4 @@ interface ContentGraphFactoryInterface * @throws WorkspaceDoesNotExist if the workspace does not exist */ public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraphInterface; - - public function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface; } diff --git a/Neos.ContentRepository.Core/Classes/ContentGraphFinder.php b/Neos.ContentRepository.Core/Classes/ContentGraphFinder.php index 8244c2e0640..1cf9cf7812a 100644 --- a/Neos.ContentRepository.Core/Classes/ContentGraphFinder.php +++ b/Neos.ContentRepository.Core/Classes/ContentGraphFinder.php @@ -67,16 +67,4 @@ public function forgetInstances(): void { $this->contentGraphInstances = []; } - - /** - * For testing we allow getting an instance set by both parameters, effectively overriding the relationship at will - * - * @param WorkspaceName $workspaceName - * @param ContentStreamId $contentStreamId - * @internal Only for testing - */ - public function getByWorkspaceNameAndContentStreamId(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface - { - return $this->contentGraphFactory->buildForWorkspaceAndContentStream($workspaceName, $contentStreamId); - } } diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Workspace/WorkspaceName.php b/Neos.ContentRepository.Core/Classes/SharedModel/Workspace/WorkspaceName.php index 37ac2fc8c24..f9fe6784b82 100644 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Workspace/WorkspaceName.php +++ b/Neos.ContentRepository.Core/Classes/SharedModel/Workspace/WorkspaceName.php @@ -48,6 +48,11 @@ public static function fromString(string $value): self return self::instance($value); } + public static function createReferenceForUnusedContentStream(ContentStreamId $contentStreamId): self + { + return self::instance('cs:' . $contentStreamId->value); + } + public static function forLive(): self { return self::instance(self::WORKSPACE_NAME_LIVE); @@ -92,6 +97,19 @@ public function isLive(): bool return $this->value === self::WORKSPACE_NAME_LIVE; } + /** + * @phpstan-assert-if-true ContentStreamId $this->getReferencingUnusedContentStreamId() + */ + public function isReferencingUnusedContentStream(): bool + { + return str_starts_with($this->value, 'cs:'); + } + + public function getReferencingUnusedContentStreamId(): ?ContentStreamId + { + return $this->isReferencingUnusedContentStream() ? ContentStreamId::fromString(substr($this->value, 3)) : null; + } + public function jsonSerialize(): string { return $this->value; diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php index f5c2204d01d..81cc13a6133 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php @@ -37,8 +37,6 @@ trait CRTestSuiteRuntimeVariables { protected ?ContentRepository $currentContentRepository = null; - protected ?ContentStreamId $currentContentStreamId = null; - protected ?WorkspaceName $currentWorkspaceName = null; protected ?DimensionSpacePoint $currentDimensionSpacePoint = null; @@ -92,7 +90,7 @@ public function theCurrentDateAndTimeIs(string $timestamp): void */ public function iAmInContentStream(string $contentStreamId): void { - $this->currentContentStreamId = ContentStreamId::fromString($contentStreamId); + $this->currentWorkspaceName = WorkspaceName::createReferenceForUnusedContentStream(ContentStreamId::fromString($contentStreamId)); } /** @@ -101,7 +99,6 @@ public function iAmInContentStream(string $contentStreamId): void public function iAmInWorkspace(string $workspaceName): void { $this->currentWorkspaceName = WorkspaceName::fromString($workspaceName); - $this->currentContentStreamId = null; } /** @@ -147,11 +144,6 @@ public function getCurrentSubgraph(): ContentSubgraphInterface { $contentGraphFinder = $this->currentContentRepository->projectionState(ContentGraphFinder::class); $contentGraphFinder->forgetInstances(); - if (isset($this->currentContentStreamId)) { - // This must still be supported for low level tests, e.g. for content stream forking - return $contentGraphFinder->getByWorkspaceNameAndContentStreamId($this->currentWorkspaceName, $this->currentContentStreamId)->getSubgraph($this->currentDimensionSpacePoint, $this->currentVisibilityConstraints); - } - return $contentGraphFinder->getByWorkspaceName($this->currentWorkspaceName)->getSubgraph( $this->currentDimensionSpacePoint, $this->currentVisibilityConstraints diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index 057edaa23b6..193215f7125 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -97,7 +97,6 @@ public function beforeEventSourcedScenarioDispatcher(BeforeScenarioScope $scope) $this->currentVisibilityConstraints = VisibilityConstraints::frontend(); $this->currentDimensionSpacePoint = null; $this->currentRootNodeAggregateId = null; - $this->currentContentStreamId = null; $this->currentWorkspaceName = null; $this->currentNodeAggregate = null; $this->currentNode = null;