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.
- Bernhard Schmitt
- Denny Lubitz
- Martin Ficzel
- Bastian Waidelich
- Christian Müller
- Marc Henry Schultz
- Karsten Dambekalns
- Paula Kallert
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 ⛁ might need optional care regarding the database.
⛁¹ 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
⛁² (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.) !!!
Highlight
Avoiding conflicts via soft removal
- FEATURE: Soft removal subtree tag
removed
- FEATURE: Soft removal garbage collection
- TASK: Test workspace publishing service - especially for soft and hard removal
- TASK: Adjust document uri projection to soft removals
- Neos Ui Adjustments
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
- TASK: Discourage
DisableNodeAggregate
and remove duplicated command handling - TASK: Disallow disabling tethered nodes
- Neos Ui Adjustments
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 astag
Neos’NeosSubtreeTag::disabled()
:
Deprecation of EnableNodeAggregate
introduced early
- please use
UntagSubtree
instead and specify astag
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
orgetContentSubgraph()
instead
Deprecation of VisibilityConstraints::withoutRestrictions()
introduced early
- please use
NeosVisibilityConstraints::excludeRemoved()
orVisibilityConstraints::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
- !!!TASK: Reduce complexity of ReflectionService on 8.4
- TASK: Adjust to removed package freezing API’s
- !!! TASK: Followup #3443 remove dead package freezing API’s
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
- BUGFIX: Fix and test tethered node structure adjustment
- FEATURE: Make adjustments for missing tethered nodes recursive
⛁² TASK: Followup 4969 remove duplicate peer creations
- BUGFIX: Build URI path based on parent frwom “target” dimensionSpacePoint
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
- BUGFIX: 4909 fusion plugins and tests
- BUGFIX: Replace node identity converter aspect with
NeosRouteValueNormalizer
- !!! TASK: Decouple routing from persistence manager
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) !!!
Highlight
The query update / node aggregate update:
- FEATURE: Fetch multiple nodes or node aggregates
- FEATURE: Introduce
ContentGraphInterface::findNodeAggregatesTaggedBy
- FEATURE: expose all NodeTags via
getCoveredDimensionsTaggedBy
on NodeAggregate - BUGFIX: Add hierarchical level tracking for ancestor node queries
- BUGFIX:
findParentNodeAggregates
returns subtree tags of child node - TASK: Remove misleading
NodeAggregate::getNodeByCoveredDimensionSpacePoint()
& TASK: Replace only (fully obsolete) usage ofgetNodeByCoveredDimensionSpacePoint
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 seegetNodeByOccupiedDimensionSpacePoint()
- the internal
NodeAggregate::getDimensionSpacePointsTaggedWith()
was replaced in favour ofgetCoveredDimensionsTaggedBy()
Other features
- FEATURE: Add depth option to
configuration:show
& TASK: Rename --level to --depth - FEATURE: Allow to register custom node migrations
- FEATURE: Workspace UI - Add second confirmation window for rebasing
- FEATURE: Add
onAfterHandle
to CommandHookInterface - TASK: Add the new login wallpaper for Neos 9 after discuss voting
- FEATURE: Use proper performant
getDependantWorkspacesRecursively
- FEATURE: Auto rebase workspace on backend module opening if necessary
Other bugfixes / Tasks
Neos
- BUGFIX: Remove users personal workspace on user deletion
- BUGFIX - Decouple CR Registry from BehavioralTests
- BUGFIX: Render attributes in Neos.Neos:Content as HTML attributes string
- BUGFIX: Improve workspace module change handling
- TASK: Add debug information to identify original event after rebase
- TASK: Remove obsolete possibly expensive
getContentGraph()
- TASK: Remove
markStale()
andWithMarkStaleInterface
&& Fully remove dead caching forDocumentUriPathFinder
Dev only relevant
List of things
Ui
Flow
Neos