Neos 9 Beta-11 Release

Today we released another Neos 9 Beta.

It contains many bugfixes, big refactoring and great new features.

Thanks to all who contributed <3.

Upgrade instructions from Beta 10

previous beta → Neos 9 Beta-10 Release

In your composer.json you should require 9.0.0-beta11 for all Neos packages from the development distribution and for the NeosUi as well as Flow:

"neos/neos": "9.0.0-beta11",
"neos/neos-ui": "9.0.0-beta11",
"neos/contentgraph-doctrinedbaladapter": "9.0.0-beta11"

:bulb: Composer conflicts after updatating / for new installations

Setting up a new project via composer create-project neos/neos-base-distribution:9.0.0-beta11 or updating your project will still reference the package neos/contentrepositoryregistry-doctrinedbalclient.
It was dropped and neos/contentgraph-doctrinedbaladapter needs to be referenced instead! Composer create will be fixed with beta12

The database can be migrated the following:

A setup to apply the latest schema adjustments can be run via (feel free to inspect via cr:status what will be adjusted)

./flow cr:setup

Additionally, PRs marked with :boom:⛁ might need a dedicated migration.

  • :boom:⛁¹ Event migration for fixing already published events to include the workspace name:
./flow migrateevents:migratePayloadToWorkspaceName
  • :boom:⛁² Rewrites all events containing a workspaceName, which doesn’t match the new workspaceName constraints and rewrites them.
./flow migrateevents:migratepayloadtovalidworkspacenames

If the migration found some workspaceNames or baseWorkspaceNames to migrate, please run a projection replay of the workspace projection.

./flow cr:projectionreplay --projection workspace

Features

!!! 1.) Remove previously deprecated Beta10 APIs

Removal of field Node::$contentSubgraphIdentity and ContentSubgraphIdentity

The ContentSubgraphIdentity was intermediate part of the node’s “Read Model” identity.
Please use Node::$contentRepositoryId, Node::$workspaceName, Node::$dimensionSpacePoint, and Node::$aggregateId instead,
or see NodeAddress::fromNode() for passing the identity around.
The visibility-constraints now reside in Node::$visibilityConstraints.
There is no replacement for the previously attached content-stream-id. Please refactor the code to use the newly available workspace-name.

Removal of Node::getLabel()

To get the label for a Node in PHP, one must replace Node::getLabel() with a call to Neos\Neos\Domain\NodeLabel\NodeLabelGeneratorInterface::getLabel:

+ #[Flow\Inject]
+ protected NodeLabelGeneratorInterface $nodeLabelGenerator;
+ 
+ $this->nodeLabelGenerator->getLabel($node);
- $node->getLabel();

For Fusion please use the new FlowQuery operation:

- ${node.label}
+ ${q(node).label()}

Rename of field Node::$nodeAggregateId

In php Node::nodeAggregateId was renamed to Node::aggregateId.

- ${node.nodeAggregateId.value}
- ${node.identifier}
+ ${q(node).id()}

Removal of field Node::$nodeType

In php Node::nodeType was removed. Please use NodeTypeManager::getNodeType instead:

- $node->nodeType;
+ $contentRepository = $this->contentRepositoryRegistry->get($node->contentRepositoryId);
+ $nodeType = $contentRepository->getNodeTypeManager()->getNodeType($node->nodeTypeName);

The use in Fusion is discouraged (tip use a custom EEL Helper), but you can access it like:

- ${node.nodeType}
+ ${Neos.Node.getNodeType(node)}

Rename of field Node::$nodeName

In php Node::nodeName was renamed to Node::name.

The use in Fusion is discouraged, but you can still access it like:

${node.name.value}

Removal of CommandResult::block

The CommandResult::block calls must be removed.

- $contentRepository->handle($command)->block();
+ $contentRepository->handle($command);

!!! 2.) :sparkles: New node uri building

Introduces a new API for node-uribuilding to replace the LinkingService
The previous Neos9-Beta10 did already contain a similar new NodeUriBuilder but this change overhauls the API to not expose the implementations of the Flow UriBuilder.

The new NodeUriBuilder is not a singleton and thus cannot be injected but must be created via the NodeUriBuilderFactory with the current ActionRequest at hand.

Simple case:

// before
#[Flow\Inject]
protected LinkingService $linkingService;

public function uriForNode(Node $node, ControllerContext $controllerContext): string
{
    return $this->linkingService
        ->createNodeUri(
            controllerContext: $controllerContext,
            node: $node
        );
}
// after
#[Flow\Inject]
protected NodeUriBuilderFactory $nodeUriBuilderFactory;

public function uriForNode(Node $node, ActionRequest $actionRequest): UriInterface
{
    return $this->nodeUriBuilderFactory
        ->forActionRequest($actionRequest)
        ->uriFor(
            NodeAddress::fromNode($node)
        );
}

Advanced case:

// before
#[Flow\Inject]
protected LinkingService $linkingService;

public function uriForNode(Node $node, ControllerContext $controllerContext): string
{
    return $this->linkingService
        ->createNodeUri(
            controllerContext: $controllerContext,
            node: $node,
            format: 'json',
            absolute: true,
            arguments: ['simple-query' => 'abc'],
            section: 'my-anchor'
        );
}
// after
#[Flow\Inject]
protected NodeUriBuilderFactory $nodeUriBuilderFactory;

public function uriForNode(Node $node, ActionRequest $actionRequest): UriInterface
{
    $resolvedUri = $this->nodeUriBuilderFactory
        ->forActionRequest($actionRequest)
        ->uriFor(
            NodeAddress::fromNode($node),
            Options::create(forceAbsolute: true)->withCustomFormat('json')
        );

    return UriHelper::uriWithAdditionalQueryParameters($resolvedUri, ['simple-query' => 'abc'])
        ->withFragment('my-anchor');
}

Also notice that the PHP api for uri building will no longer keep the current format of the action request by default unlike in the Fusion api.
If this behaviour is required it should be implemented via $options->withCustomFormat($actionRequest->getFormat());

!!! 3.) :sparkles: Flow requires doctrine/dbal version 3

  • doctrines json_array type is deprecated, therefore flow_json_array is based off of json type now
  • We use PSR6 caches now instead of the deprecated doctrine cache implementation
  • New Cache Flow_Persistence_Doctrine_Metadata for ORM class metadata
  • Repository::findAllIterator directly returns an iterable, the Repository::iterate method is gone
  • All doctrine migration commands have a new optional migration-folder argument that allows to overwrite the “platform name part” in migration resolving (e.g. “Mysql”) as the resolving changed and we cannot be sure deducing it from the current connection will work long term for all cases. Currently MySQL/MariaDB (map to “Mysql”), PostgreSQL (maps to “Postgresql” and SQLite (maps to “Sqlite”) all work fine automatically still.

upgrade instructions from doctrine dbal: New Major Release: Doctrine DBAL 3.0 - Doctrine: PHP Open Source Project

4.) Streamlining the new content repository

5.) Other refactorings

Bugfixes

Neos Content Repository

Neos Ui

Flow

Dev only relevant

List of things

Neos

Neos Ui

:sparkles: New included features from upcoming Neos 8.4 :sparkles:

2 Likes

While writing the release notes for Neos9-Beta14 i noticed we didn’t document the changes of the successor of Neos9-Beta11.

Just for reference Neos9-Beta12 was malformed, but Neos9-Beta13 was released a week later as followup with the following bugfixes:

1 Like