neos / contentrepository-development-collection

Work in Progress on the Event Sourced Content Repository as installable set of packages
4 stars 9 forks source link

Event Sourced Content Repository Collection

Build Status StyleCI

This is the package bundle you can install alongside a plain Neos to play around with the event-sourced CR.

Feature comparison

✅ Done

⏩ Currently worked on

🚫 Will not be supported

Feature Current CR Event Sourced CR
Basics
Create/ Edit / Delete Nodes
Shortcut Handling
Query Nodes
Cut / Copy / Paste
Move Nodes
Hide Nodes
History (✅)
Basic Workspaces
Workspace Module
Nested Workspaces
Undo / Redo 🚫
Setting Start / End time
Resolving Referencing Nodes 🚫
Menu Rendering
Dimension Menu Rendering
Supporting "not in menu"
Change node type
Advanced
Dimensions
Dimension Fallback
Multiple Sites
Permissions / Policy
Maintenance
Export / Import ✅⏩
Node Migrations
Structure Adjustments a.k.a. node:repair
Integrity Checks 🚫
API
Separate Read and Write API 🚫
More convenient write API
Extensible Read API (✅) custom Node ✅ NodeAccessors
FlowQuery is compatible
Advanced test cases 🚫
Don't use ORM, but direct SQL queries 🚫
Asynchronous operations possible 🚫
performant node moving 🚫
performant node deletion 🚫
near-constant read performance 🚫
performant URL generation (routing) 🚫
MySQL support
Postgres support ⏩ (much higher performance)
usage without Neos/Flow 🚫 prepared
extensible property serialization 🚫 ✅ through Symfony Serializer
traverse node references in both directions 🚫
content merge conflict detection 🚫
content merge conflict resolution 🚫
User Interface
Ensure node deletion can be published in UI
Support Dimension Constraints
Publish Workspace
Publish Current Page
Discard all
Discard Current Page
Change node type in UI

Package Compatibility

Requirements

DB

The Event Sourced Content Repository relies on a feature called (Recursive) Common Table Expressions (CTE) that require

Lateron, we will also support PostgreSQL. (We know it will work, but we did not create migrations or did testing yet).

PHP

The new code should be compatible with PHP 7.4

Getting Started / Installation

See https://github.com/neos/neos-development-distribution/tree/event-sourced

Linting

Linting is done via CodeSniffer and PHPStan. Both are integrated as composer scripts (see composer.json). To manually lint your branch before opening a PR, you can run

composer lint

from the folder the collection resides (probably Packages/CR in a Neos distribution)

Commit hooks

Linting can be added to commit hooks if desired. In the collection folder (probably Packages/CR in a Neos distribution), add lines similar to the following to your .git/hooks/pre-commit file (the example is for a DDEV environment):

#!/bin/sh
ddev exec "cd Packages/CR; composer lint"

Road to first running beta

Development of the Postgres Adapter

By default, the Mysql Adapter is active right now, as Postgres is still in development.

To activate Postgres, right now, the following steps are needed in your distribution:

# Configuration/Objects.yaml

Neos\EventSourcedContentRepository\Domain\Projection\Content\ContentGraphInterface:
  className: 'Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\ContentHypergraph'

if you want to run Postgres and MySQL side by side for the tests, you need the following config:

# Configuration/Settings.yaml

Neos:
  EventSourcedContentRepository:
    unstableInternalWillChangeLater:
      testing:
        projectorsToBeReset:
          'Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\HypergraphProjector': true
        activeContentGraphs:
          'Postgres': 'Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\ContentHypergraph'
      projection:
        defaultProjectorsToBeBlocked:
          'Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\HypergraphProjector': true

if you want to run Postgres without MySQL, you need the following config:

# Configuration/Settings.yaml

Neos:
  EventSourcedContentRepository:
    unstableInternalWillChangeLater:
      testing:
        projectorsToBeReset:
          'Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\HypergraphProjector': true
          'Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\GraphProjector': false
        activeContentGraphs:
          'Postgres': 'Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\ContentHypergraph'
          'DoctrineDBAL': false
      projection:
        defaultProjectorsToBeBlocked:
          'Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\HypergraphProjector': true
          'Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\GraphProjector': false

Technical Description (for developers)

This section should give an overview about the different involved packages, to ease understanding the different moving parts.

Neos.ContentRepository

see https://github.com/neos/neos-development-collection/pull/2202 for the Pull Request.

Neos.Neos

see https://github.com/neos/neos-development-collection/pull/2202 for the Pull Request.

Neos.ContentRepository.DimensionSpace

APIs to query the configured dimension space

CR / Neos.EventSourcedContentRepository

Transition package implementing the event sourced CR core. In the longer run, will probably be merged into Neos.ContentRepository.

CR / Neos.ContentGraph.DoctrineDbalAdapter

implementation of the ContentGraphInterface and ContentSubgraphInterface using MySQL queries.

CR / Neos.ContentGraph.PostgreSQLAdapter

implementation of the ContentGraphInterface and ContentSubgraphInterface using PostgreSQL queries.

CR / Neos.EventSourcedNeosAdjustments

It turns out that there are numerous changes needed to the details of Neos.Neos - so this package hooks into various places in the Neos lifecycle to override certain Neos functionality.

We often completely override certain classes / behaviors from the Neos core completely; so that should make merging the changes back to the Neos.Neos package at some point a lot easier because we can then replace full classes instead of only individual pieces.

This package consists of the following bounded contexts, listed in their order during request processing:

NodeImportFromLegacyCR

This contains a CommandController and a service to generate events from reading NodeData. It can be activated using the new CLI command.

EventSourcedRouting

We replace the default FrontendNodeRoutePartHandler by providing an extra implementation of FrontendNodeRoutePartHandlerInterface.

Activation: We replace the implementation of FrontendNodeRoutePartHandlerInterface in Objects.yaml.

EventSourcedFrontController

This is a replacement for Frontend\NodeController of Neos.Neos.

Activation: We trigger this controller by AOP (in NodeControllerAspect): We call the new controller when processRequest() is called for the Neos controller.

Fusion

Fluid

ContentElementWrapping

We implement a completely new ContentElementWrappingService and ContentElementWrappingService; mainly because they change quite a bit and their interfaces now require TraversableNodeInterface instead of the legacy NodeInterface.

The new services are used in the overridden ViewHelpers (see section Fluid above); and in overridden Fusion implementations (see section Fusion above).

NodeAddress (Domain\Context\Content)

A NodeAddress is an external representation of a node (used in routing). TODO: Move to Neos.EventSourcedContentRepository.

Ui