Neos 9 Beta-19 Release

Let’s say the 9 in 19 brings luck for the 9’er release!

After another month of hard work and a secret mini-mini sprint, we are proud to have once again proven the impossible wrong with this Neos 9 Beta!

Thanks to all who contributed <3.

Upgrade instructions from Beta 18

previous beta → Neos 9 Beta-18 Release

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

"neos/flow": "9.0.0-beta19",
"neos/neos": "9.0.0-beta19",
"neos/neos-ui": "9.0.0-beta19"

The database can be migrated the following way:

A setup to apply the latest schema adjustments:

./flow doctrine:migrate
./flow cr:setup

Additionally, PRs marked with :collision:⛁ might need optional care regarding the database.

  • :collision:⛁¹ not a migration, but restriction regarding legacy copy events from before Neos 9 Beta 16

In case you have used Neos 9 before Beta 16, your instance might contain legacy events - see below (6).
Tool to detect if any of your workspaces is affected:

./flow migrateevents:copynodesstatus
  • :collision:⛁² (optional) migration to fix misfired structure adjustment events that might trouble the uri path projection

In case you have used ./flow structureadjustments:fix in the past, needless events might have been published.

./flow migrateevents:migrateDuplicateNodeVariations
./flow subscription:replay Neos.Neos:DocumentUriPathProjection

Features

1.) !!! :sparkles: Highlight :sparkles: Avoiding conflicts via soft removal

Removing nodes in the new content repository via RemoveNodeAggregate removes any trace where a node might have been.
This is complex for the Ui to react upon as it cant know in the afterevent on which document to place a change.
Hacks like the removalAttachmentPoint made this possible and working almost okay-ish for many cases.

One edge case required to fully rework this as workspaces could run into not be publish- or discard-able via the Neos Ui (only via a workspace wide publish).
In short, the ege case was that publishing the removal of nodes which had NESTED modifications or creations failed:

Publication failed, events cannot be reordered as filtered: “Node aggregate “main-content” does currently not exist.”

On the core’s site the problem is logical, as the Neos publishing failed to provide all node aggregate ids that were in the changed descendants because the hierarchy was removed.

We decided to introduce soft removals to circumvent this case. Also, soft removals convinced by solving other workspace conflicts and a future potential to un-remove nodes.

Soft removals are implemented by using the subtree tags feature. Neos provides a tag “removed” (NeosSubtreeTag::removed()) which similar to “disabled” hides a node and its descendants.
In difference to disabled nodes, soft removed nodes are never shown via getContentSubgraph() - regardless of any policy. When fetching the subgraph manually via getSubgraph() this must be taken care of by using NeosVisibilityConstraints::excludeRemoved().

All drawn out removal related edge cases are now solved - not only the initial bug.
Soft removing now prevents conflicts where a workspace rebase was troubling before.
One of these cases is having a child node moved away from a node which was removed on live via another user. Changes like these will be frictionless publish- or rebase-able.

To have the database cleaned up eventually by having the soft removed nodes actually removed, a SoftRemovalGarbageCollector has been introduced.
Its responsibility is to find soft removals which will not be the cause of a conflict and have these removed.
A removal will not take place if any users workspace is still outdated and thus has the node visible, or if another workspace contains changes inside the removal.

2.) Neos high level disabled tag

With Neos 9 Beta 8 the generic concept of subtree tags was introduced.
The core’s disabling command publishes since then SubtreeWasTagged events.

Now we made the content repository core even more generic - it doesn’t know about a specific tag like disabled anymore.
The disabled handling now resides in Neos. And to disable/enable a node TagSubtree/UntagSubtree should be used:

- DisableNodeAggregate::create(
+ TagSubtree::create(
      $node->workspaceName,
      $node->aggregateId,
      $node->dimensionSpacePoint,
      NodeVariantSelectionStrategy::STRATEGY_ALL_SPECIALIZATIONS,
+     NeosSubtreeTag::disabled()
  )

3.) Deprecations → legacy stubs are kept until Neos 10

Due to the nature of the changes and new API’s in 1 and 2 its legacy counterparts are now deprecated

Deprecation of DisableNodeAggregate introduced early

  • please use TagSubtree instead and specify as tag Neos’ NeosSubtreeTag::disabled():

Deprecation of EnableNodeAggregate introduced early

  • please use UntagSubtree instead and specify as tag Neos’ NeosSubtreeTag::disabled():

Deprecation of SubtreeTag::disabled() introduced via Neos 9 Beta 8

  • please use NeosSubtreeTag::disabled() instead

Deprecation of VisibilityConstraints::fromTagConstraints() introduced via Neos 9 Beta 16

  • please use VisibilityConstraints::excludeSubtreeTags() instead

Deprecation of VisibilityConstraints::default() last changed via Neos 9 Beta 16

  • please look into NeosVisibilityConstraints or getContentSubgraph() instead

Deprecation of VisibilityConstraints::withoutRestrictions() introduced early

  • please use NeosVisibilityConstraints::excludeRemoved() or VisibilityConstraints::createEmpty() instead

4.) New command reference

As part of the new Neos 9 documentation we also now provide a full list of possible content repository commands (in case you don’t have your IDE at hand)
This rendered list can be found at read the docs: ContentRepository Command Reference — Neos CMS 9.0.x documentation

5.) !!! Removed package freezing & simplified ReflectionService

This overhaul in Flow 8.4 and 9.0 tackles some problems within the reflection service that stem from historically increasing complexity due to various caching mechanisms depending on application context and compile time status.

The aim was to cut down on this complexity, while ensuring that all existing use-cases continue working as intended.

This ultimately also fixes an issue by providing the same reflection data across all possible contexts.

6) !!! Remove legacy CopyNodesRecursively command

This change removes the legacy internal CopyNodesRecursively command. Use of this command was prevented with Neos 9 Beta 16 which introduced NodeDuplicationService as replacement.

The removal of the command handling has the breaking side effect as announced that legacy copy nodes events from before Neos 9 Beta 16 will not be publishable any longer.
On publish or rebase the event will be discarded. To work around this either publish the event to live in a previous beta or recopy the nodes and choose “drop conflicting changes” when rebasing.

Now to see if your instance still contains these legacy events you can use this flow command as described earlier.

./flow migrateevents:copynodesstatus

In case you don’t understand the output feel free to ask.

7) Fix tethered node structure adjustment & Uri path projection

The duplicate NodePeerVariantWasCreated events were targeting for example the site node multiple times, varying the same source to the same target multiple times.
These events lead to the uri paths being overridden again and again from the source, even though they were already translated in that dimension.

In case you experience a similar buggy behaviour or have used the structure adjustments in a multi dimensional site in the past, please apply the migration and replay the projections.

flow migrateevents:migrateDuplicateNodeVariations

Also when creating a node variant via switching of dimensions, the URI path projection did not take the URI (path) of the (new) parent into account.
To repair the uri path projection it now can be replayed:

flow subscription:replay Neos.Neos:DocumentUriPathProjection

8) Bugfix routing and plugins

Re-enables passing Node instances when building uris via fusion, php in a clean way:

$uriBuilder->uriFor(
    'someThing',
    ['node' => $node]
);

Also fixes Neos.Neos:Plugin usages on the node frontend route. And example for that is the Extension packages & plugins listing.

9) !!! :sparkles: Highlight :sparkles: The query update / node aggregate update:

To make the new Soft removal garbage collection (1) a viable performant operation, we introduced new database queries and apis:

For the ContentGraphInterface:

/**
 * @api
 * @return NodeAggregates the node aggregates that exist in this graph. The order is not defined.
 */
public function findNodeAggregatesByIds(
    NodeAggregateIds $nodeAggregateIds
): NodeAggregates;

/**
 * @internal experimental api, the order of the returned node aggregates is undefined and does not follow the hierarchy
 */
public function findNodeAggregatesTaggedBy(SubtreeTag $subtreeTag): NodeAggregates;

For the ContentSubgraphInterface:

/**
 * Find all nodes by the specified aggregate ids
 *
 * @api
 * @return Nodes the nodes that exist in this subgraph. The order is not defined.
 */
public function findNodesByIds(NodeAggregateIds $nodeAggregateIds): Nodes;

Further NodeAggregate changes:

  • NodeAggregate::getNodeByCoveredDimensionSpacePoint() has been removed see getNodeByOccupiedDimensionSpacePoint()
  • the internal NodeAggregate::getDimensionSpacePointsTaggedWith() was replaced in favour of getCoveredDimensionsTaggedBy()

Other features

Other bugfixes / Tasks

Neos

Dev only relevant

List of things

Ui

Flow

Neos

3 Likes