Flow 9.0

This release of Flow comes with some great new features, bugfixes and a lot of modernisation of the existing code base.

As usual, we worked hard to keep this release as backwards compatible as possible but, since it’s a major release, some of the changes might require manual adjustments. So please make sure to carefully read the upgrade instructions below.

Flow 9.0 also increases the minimal required PHP version to 8.2.

New Features

!!! FEATURE: Dispatcher psr overhaul

To ease the implementation of a custom controller now use a direct pattern of f(ActionRequest) => PsrResponseInterface. This is breaking if you implemented your own ControllerInterface or overwrote low level parts and methods of the ActionController.

```php class Dispatcher {

public function dispatch(ActionRequest $request): ResponseInterface;

}

interface ControllerInterface {

public function processRequest(ActionRequest $request): ResponseInterface;

}

Also, it’s discouraged to manipulate $this->response in controllers (the ActionResponse is deprecated), although it’s still supported in actions for now, please consider returning a new response instead.

<details>

<summary> Explanation of the legacy MVC response object. </summary>

Previously Flows MVC needed a single mutable response which was passed from dispatcher to controllers and even further to the view and other places via the controller context: ControllerContext::getResponse(). This allowed to manipulate the response at every place. With the dispatcher and controllers now directly returning a response, the mutability is no longer required. Additionally, the abstraction offers naturally nothing, that cant be archived by the psr response, as it directly translates to one: ActionResponse::buildHttpResponse() So you can and should use the immutable psr {@see ResponseInterface} instead where-ever possible. For backwards compatibility, each controller will might now manage an own instance of the action response via $this->response AbstractController::$response and pass it along to places. But this behaviour is deprecated! Instead, you can directly return a PSR repose \\GuzzleHttp\\Psr7\\Response from a controller:

```php public function myAction() {

return (new Response(status: 200, body: $output))

->withAddedHeader(‘X-My-Header’, ‘foo’);

}

</details>

Further the ForwardException does not extend the StopActionException anymore, meaning a try catch must be adjusted.

This is the main PR and it contains - https://github.com/neos/flow-development-collection/pull/3232 - https://github.com/neos/flow-development-collection/pull/3294

Followup: https://github.com/neos/flow-development-collection/pull/3301 Resolves: https://github.com/neos/flow-development-collection/issues/3289

This change needs an accompanying adjustment to Neos to adjust the PluginImplementation as well as Modules: https://github.com/neos/neos-development-collection/pull/4738

Upgrade instructions

WIP Upgrade notes: https://github.com/neos/flow-development-collection/pull/3232#issuecomment-1913166370

!!! FEATURE: update to doctrine/dbal version 3

update to 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.

Related Neos adjustments: https://github.com/neos/neos-development-collection/pull/5161

Upgrade instructions

We require now version 3 of doctrine/dbal but still operate doctrine/orm in version 2. In case you depend on DBAL directly you should have a look into their upgrade instructions: https://www.doctrine-project.org/2020/11/17/dbal-3.0.0.html

!!! FEATURE: ViewInterface returns PSR StreamInterface

Neos adjustments https://github.com/neos/neos-development-collection/pull/4856

  • the views are now independent of the ControllerContext - ViewInterface::setControllerContext is not part of the interface anymore and will only be called on demand

  • the ActionRequest if necessary can be accessed via the variable “request” (like “settings”)

  • ViewInterface::canRender was required for fallbackviews which have been removed long ago, and so this artefact will be removed as well.

  • !!! the return type is now forced to be either a ResponseInterface or a StreamInterface. Simple strings must be wrapped in a psr stream! (see StreamFactoryTrait::createStream)

Related to https://github.com/neos/flow-development-collection/pull/3232

!!! FEATURE: WIP Dispatcher and controller return ActionResponse (simpler controller pattern)

will not be merged directly into 9.0 but included in this mvc overhaul pr: https://github.com/neos/flow-development-collection/pull/3311

This change needs an accompanying adjustment to Neos to adjust the PluginImplementation as well as Modules.

~The new SimpleActionController gives you a direct and simple way to route an ActionRequest and return an ActionReponse with nothing in between. Routing should work just like with other ActionControllers.~

This is breaking if you implemented your own ControllerInterface or overwrote or expect some of the api methods of the ActionController. We now use a direct pattern of f(ActionRequest) => ActionResponse in more places. Adjusting existing controllers should be easy though. Additionally implementing your own dispatch loop (don’t do this) will need adjustments.

We discourage to manipulate $this->reponse in controllers, although it should still work fine in actions for now, please consider other options.

```php class Dispatcher {

public function dispatch(ActionRequest $request): ActionResponse;

}

FEATURE: Add CLDR-based date, time, and datetime formatting methods with “formatLength”

Adds feature to format dates, times and datetimes with the CLDR “Basic Formats” (known as “Format length” in Flow) to the Date Eel helper.

This feature was already implemented in fluids format viewhelper before.

See: * https://cldr.unicode.org/translation/date-time/date-time-patterns#basic-date-formats * https://cldr.unicode.org/translation/date-time/date-time-patterns#basic-time-formats * https://neos.readthedocs.io/en/stable/References/ViewHelpers/FluidAdaptor.html#f-format-date

FEATURE: Add depth option to configuration:show

This introduces similar to https://github.com/neos/neos-development-collection/pull/4619 a --depth option to flow configuration:show. It helps when inspecting large nested configuration parts and for scouting out only the first few keys:

``` ./flow configuration:show –path Neos.Neos.userInterface.inspector –depth 2 Configuration “Settings: Neos.Neos.userInterface.inspector”:

dataTypes:

string: … integer: … boolean: … array: … Neos\Media\Domain\Model\ImageInterface: … Neos\Media\Domain\Model\Asset: … array<Neos\Media\Domain\Model\Asset>: … DateTime: … reference: … references: …

editors:

Neos.Neos/Inspector/Editors/CodeEditor: … Neos.Neos/Inspector/Editors/DateTimeEditor: … Neos.Neos/Inspector/Editors/AssetEditor: … Neos.Neos/Inspector/Editors/ImageEditor: … Neos.Neos/Inspector/Editors/LinkEditor: … Neos.Neos/Inspector/Editors/ReferencesEditor: … Neos.Neos/Inspector/Editors/ReferenceEditor: … Neos.Neos/Inspector/Editors/SelectBoxEditor: …

```

Upgrade instructions

FEATURE: Introduce –help flag option for existing CLI commands

Upgrade instructions

_None_

Review instructions

This change introduces a new way of using the help function for existing Flow/Neos CLI commands.

Currently you always used:

`bash ./flow help user:create `

With this change it is possible to use the new --help flag as an alternative at the end of a CLI command:

`bash ./flow user:create --help `

But of course the first way will also still work!

### Demo

https://github.com/neos/flow-development-collection/assets/39345336/4f93f5cf-0435-4344-b37a-0a76b6df7824

FEATURE: Introduce EEL tracer for handling Neos9 deprecations

Related https://github.com/neos/neos-development-collection/issues/5022

In todays weekly @bwaidelich and me discussed a concrete way how to log deprecations like node.indentifier in Neos 8.4 and 9.0

The idea is to add a tracer to eel, that will be implemented in Fusion. Technically we would need to add an abstraction to Neos.Fusion as well to not access the Node from there as this is architecturally illegal but to simplify the code and in light that this is just considered for temporary time we propose to implement it as such:

```php <?php

namespace Neos\Fusion\Core;

use Neos\Flow\Annotations as Flow; use Psr\Log\LoggerInterface;

final class Neos9RuntimeMigrationTracer implements EelInvocationTracerInterface {

/** @Flow\Inject */ protected LoggerInterface $logger;

private const DEPRECATED_NODE_PROPERTIES = [

‘identifier’ => true, ‘nodetype’ => true, // …

];

public function __construct(

private readonly string $eelExpression, private readonly bool $showMercy

) { }

public function recordPropertyAccess(object $object, string $propertyName): void {

if (

$object instanceof \Neos\ContentRepository\Domain\Model\Node && array_key_exists(strtolower($propertyName), self::DEPRECATED_NODE_PROPERTIES)

) {
$this->logDeprecationOrThrowException(

sprintf(‘“node.%s” is deprecated in “%s”’, $propertyName, $this->eelExpression)

);

}

}

public function recordMethodCall(object $object, string $methodName): void { }

private function logDeprecationOrThrowException(string $message): void {

if ($this->showMercy) {

$this->logger->debug($message);

} else {

throw new \RuntimeException($message);

}

}

}

and instantiate this Neos9RuntimeMigrationTracer (name tbd) in \\Neos\\Fusion\\Core\\Runtime::evaluateEelExpression

`diff - return EelUtility::evaluateEelExpression($expression, $this->eelEvaluator, $contextVariables); + $tracer =.$this->settings['enableDeprecationTracer'] ? new Neos9RuntimeMigrationTracer($expression, $this->settings['strictEelMode'] ?? false) : null; + return EelUtility::evaluateEelExpression($expression, $this->eelEvaluator, $contextVariables, $tracer); `

Upgrade instructions

FEATURE: Support doctrine/dbal 2.x and 3.x

Declares compatibility with doctrine/dbal 3.x (in addition to the already supported versions 2.13+) and adjusts affected code such that it works with both versions

Upgrade instructions

Any code that (heavily) uses Doctrine DBAL specifics should be checked for compatibility issues. Even if things still work, you may want to replace things deprecated in Doctrine DBAL 3. See https://www.doctrine-project.org/2020/11/17/dbal-3.0.0.html

One example: You need to replace, as the json_array type is removed in Doctrine DBAL 3.0. `php @ORM\\Column(type="json_array", nullable=true) ` with `php @ORM\\Column(type="flow_json_array", nullable=true) `

Review instructions

We allow now version 3 of doctrine/dbal but still only support doctrine/orm in version 2.

Related Neos 9 part https://github.com/neos/flow-development-collection/pull/2637

FEATURE: Allow PositionalArraySorter to keep null values

By default, the PositionalArraySorter removes all null values. This change makes this behavior an _option_ that can be passed to the constructor:

`php (new PositionalArraySorter(['foo' => null]))->toArray(); // [] (new PositionalArraySorter(['foo' => null], removeNullValues: false))->toArray(); // ['foo'] `

Besides, this cleans up the code and tests

FEATURE: Introduce PHP 8.2 DNF type support

The Reflection Service now supports Disjunctive Normal Form (DNF) types for method arguments.

See: https://www.php.net/releases/8.2/en.php#dnf_types

Related issue: #3026

FEATURE: Consider PHP attributes in proxy method building

Added support for preserving PHP 8 attributes in generated proxy class methods. This feature enables correct argument passing from attributes to proxied methods which allows developers to use attributes instead of annotations in most cases.

Related issue: #3075

FEATURE: Add FlowInjectCache Attribute / Annotation for property injection

In many cases an Objects.yaml is created just to inject caches which can feel a bit cumbersome as one already had specified the cache in Caches.yaml.

To address this the new @Flow\\InjectCache annotation allows to assign a cache frontend of a configured cache directly to a property without having to configure the Objects.yaml at all.

```php

#[Flow\InjectCache(identifier: ‘Flow_Mvc_Routing_Resolve’)] protected VariableFrontend $cache;

```

FEATURE: introduce UriHelper to work with query parameters

FYI: This pr was refactored again via https://github.com/neos/flow-development-collection/pull/3336

While working on https://github.com/neos/flow-development-collection/pull/2744 and also https://github.com/neos/neos-development-collection/issues/4552 we always came to the conclusion that the $queryParameters merging of the psr uri is limited.

This introduces a utility to do this:

`php UriHelper::uriWithAdditionalQueryParameters($this->someUriBuilder->uriFor(...), ['q' => 'search term']); `

and allows us to remove any $queryParam logic from the uribuilder(s)

Upgrade instructions

FEATURE: Add FlowRoute Attribute/Annotation

The Flow\\Route attribute allows to define routes directly on the affected method. This allows to avoid dealing with Routes.yaml in projects in simple cases where is sometimes is annoying to look up the exact syntax for that.

Usage:

```php use Neos\Flow\Mvc\Controller\ActionController; use Neos\Flow\Annotations as Flow;

class ExampleController extends ActionController {

#[Flow\Route(uriPattern:’my/path’, httpMethods: [‘GET’])] public function someAction(): void { }

#[Flow\Route(uriPattern:’my/other/b-path’, defaults: [‘test’ => ‘b’])] #[Flow\Route(uriPattern:’my/other/c-path’, defaults: [‘test’ => ‘c’])] public function otherAction(string $test): void { }

}

To use annotation routes packages have to register the AttributeRoutesProviderFactory in Neos.Flow.mvc.routes with Controller classNames or patterns.

Settings.yaml: ```yaml Neos:

Flow:
mvc:
routes:
Vendor.Example.attributes:

position: ‘before Neos.Neos’ providerFactory: \Neos\Flow\Mvc\Routing\AttributeRoutesProviderFactory providerOptions:

classNames:
  • Vendor\Example\Controller\ExampleController

```

This pr also adds the general option to register provider and providerOptions in the Setting Neos.Flow.mvc.routes which was required obviously.

The package: WebSupply.RouteAnnotation by @sorenmalling implemented similar ideas earlier.

Upgrade instructions

Review instructions

Alsow see: `#3324 <https://github.com/neos/flow-development-collection/issues/3324>`_resolving #2060, both solutions ideally would work hand in hand

Related issue: #2059

FEATURE: InjectConfiguration for constructor arguments

Flow now supports InjectConfiguration attributes for constructor arguments which allows for injecting configuration, such as settings, via the constructor. Compared to property injection, constructor injection results in more portable and better testable code.

Related issue: #3077

FEATURE: Introduce PHP 8.2 DNF type support

The Reflection Service now supports Disjunctive Normal Form (DNF) types for method arguments.

See: https://www.php.net/releases/8.2/en.php#dnf_types

Related issue: #3026

FEATURE: Separate RouteConfiguration from Router

This separates the Routes configuration from the router by introducing a RoutesProviderInterface which will be used by the router implementation together with a ConfigurationRoutesProvider that implements the current configuration from Routes.yaml.

Switching out the internal implementation of the RoutesProviderInterface can be done via Objects.yaml to add custom behaviour. But be aware that this is not covered by our api promises. All Implementations should include the routes provided by the ConfigurationRoutesProvider.

This change also makes sure, that the RouteCommandController uses the current RoutesProviderInterface implementation, instead of hard coded Flow router. That ensures that all Routes available to the router are now also visible to route cli-commands.

Upgrade instructions

This change removes the methods getRoutes and addRoute from the Router that previously were mainly used in functional-tests as they were never part of the Router Interface.

To adjust for that the existing utility FunctionalTestCase->registerRoute method has to be used instead of FunctionalTestCase->router->addRoute.

The method Router::setRoutesConfiguration, which was also previously used for internal testing has been removed without official replacement. You _could_ technically inject a custom routes provider to do so but be aware that this is internal behaviour.

Review instructions

Run the ./flow routing:list command - you will see the list as expected

Related issue: #2948

FEATURE: Consider PHP attributes in proxy method building

Added support for preserving PHP 8 attributes in generated proxy class methods. This feature enables correct argument passing from attributes to proxied methods which allows developers to use attributes instead of annotations in most cases.

Related issue: #3075

FEATURE: Add FlowInjectCache Attribute / Annotation for property injection

In many cases an Objects.yaml is created just to inject caches which can feel a bit cumbersome as one already had specified the cache in Caches.yaml.

To address this the new @Flow\\InjectCache annotation allows to assign a cache frontend of a configured cache directly to a property without having to configure the Objects.yaml at all.

```php

#[Flow\InjectCache(identifier: ‘Flow_Mvc_Routing_Resolve’)] protected VariableFrontend $cache;

```

FEATURE: Add more information for object arguments in debugging

For stacktraces in exceptions and logs we now render some representation of content for objects to ease debugging with DTOs.

Specifically we will try to obtain a string representation for such an object by using either in this order:

  • a string cast if __toString() is available

  • json_encode if it is JsonSerializable

  • json_encode on the array of public properties

For readability json_encode will be limited to the first level, also all of those string representations will be cut off after 100 characters.

If any of those options works we will also shorten the className to avoid this output becoming overly long.

Note that we use JSON_PARTIAL_OUTPUT_ON_ERROR to make sure some output is provided. This might lead to partial or weird outputs depending on the object structure, but might still provide pointers for debugging.

Related issue: #3165

9.0 FEATURE: Add unique flowQuery operation

This operation applies array_unique to the current flowQuery context.

While the same could previously achieved via Array.unique() the flow query operation can be placed in an operation chain without extra wrapping.

Review instructions

There is also a node specific implementation of the unique operation in https://github.com/neos/neos-development-collection/pull/4355

I know the php code looks oldish but the style is in line with the other flowQuery operations around.

FEATURE: Add getAccessorByPath to NeosUtilityArrays for type safe accessing of array values

_**Please note that this is an experimental feature and the API is not stable yet.**_

The array utility allows to create a type safe accessor via Arrays::getAccessorByPath($arrayValue, 'your.path'). The accessor provides the following methods that will either return the requested type or throw a \\UnexpectedValueException.

  • int(): int

  • float(): float

  • number(): int|float

  • string(): string

  • classString(): string - with annotation for class-string

  • array(): array

  • instanceOf(string $className): object - with annotation for dynamic type

  • intOrNull(): ?int

  • floatOrNull(): ?float

  • numberOrNull(): null|int|float

  • stringOrNull(): ?string

  • classStringOrNull(): ?string - with annotation for class-string | null

  • arrayOrNull(): ?array

  • instanceOfOrNull(string $className): ?object - with annotation for dynamic type | null

This will allow to write code that accesses settings via pathes without checking every level for existence still beeing type safe and accessible for static analysis.

This can be used together with settingInjection.

```php public function injectSettings(array $settings): void {

$this->limit = Arrays::getAccessorByPath($settings, ‘limit’)->intOrNull();

}

Review instructions

It may look inefficient to manually throw TypeErrors that in many cases would be thrown automatically because of the declared return types. However this is not a performance issue as those are never on the happy-path and the created TypeError provides additional informations to help understand and fix problems faster.

Inspired by https://github.com/PackageFactory/extractor

Related issue: #3164

FEATURE: Exclude classes from constructor autowiring

Classes can now explicitly be excluded from constructor autowiring through a new setting.

The setting accepts an array of fully qualified class names, each class name being a regular expression. Classes of scope prototype which expect objects to be passed to their constructor are usually considered for autowiring which results in a proxy class being generated.

This option allows to exclude classes from this process. This is useful for classes like data transfer objects, read models, commands, events and value objects which usually don’t rely on dependency injection.

Flow cannot reliably detect weather a prototype class depends on autowiring for constructor arguments or not. Use this option to optimize your application to avoid the small but measurable overhead of proxy generation for those kinds of classes.

Note that if there are other reasons than constructor injection which require a proxy class to be generated, the proxy class will be generated no matter what.

This change partly reverts `#3050 <https://github.com/neos/flow-development-collection/issues/3050>`_because now proxy classes _are_ generated for prototype classes by default. Otherwise a lot of existing Flow applications would not work correctly anymore.

resolves: #3049

FEATURE: Replace self with static in proxy classes

Factory methods which use code like new self() for creating a new instance are now handled correctly in proxy classes. The compiler automatically replaces “self” keywords with “static” in the rendered proxy class file to make this possible.

This implementation has not been optimized for performance.

Related issue: #3059

FEATURE: Support private constructors in proxy classes

Flow now can correctly build proxy classes for classes with private constructors. Previously, such classes caused errors and proxy class building had to be disabled with the Proxy(false) annotation. Now classes with private constructors can take advantage of setter and property injection and are considered for advices through the AOP framework.

Related issue: #3058

FEATURE: Add support for readonly classes

Flow now respects readonly classes during proxy class building and makes sure that proxy classes are readonly as well.

resolves: #3025

This section contains instructions for upgrading your Flow 8.3 based applications to Flow 9.0.

In general just make sure to run the following commands:

To clear all file caches:

./flow flow:cache:flush --force

If you have additional cache backends configured, make sure to flush them too.

To apply core migrations:

./flow flow:core:migrate <Package-Key>

For every package you have control over (see Upgrading existing code below).

To validate/fix the database encoding, apply pending migrations and to (re)publish file resources:

./flow database:setcharset
./flow doctrine:migrate
./flow resource:publish

If you are upgrading from a lower version than 8.3, be sure to read the upgrade instructions from the previous Release Notes first.

Upgrading existing code

There have been major API changes in Flow 9.0 which require your code to be adjusted. As with earlier changes to Flow that required code changes on the user side we provide a code migration tool.

Given you have a Flow system with your (outdated) package in place you should run the following before attempting to fix anything by hand:

./flow core:migrate Acme.Demo

This will adjust the package code automatically and/or output further information. Read the output carefully and manually adjust the code if needed.

To see all the other helpful options this command provides, make sure to run:

./flow help core:migrate

Also make sure to read about the `Potentially breaking changes`_ below.

The tool roughly works like this:

  • Collect all code migrations from packages

  • Collect all files from the specified package

  • For each migration

    • Check for clean git working copy (otherwise skip it)

    • Check if migration is needed (looks for Migration footers in commit messages)

    • Apply migration and commit the changes

Afterwards you probably get a list of warnings and notes from the migrations, check those to see if anything needs to be done manually.

Check the created commits and feel free to amend as needed, should things be missing or wrong. The only thing you must keep in place from the generated commits is the migration data in composer.json. It is used to detect if a migration has been applied already, so if you drop it, things might get out of hands in the future.

Flow 9.0 comes with some breaking changes and removes several deprecated functionalities, be sure to read the following changes and adjust your code respectively. For a full list of changes please refer to the change log.

!!! FEATURE: Dispatcher psr overhaul

To ease the implementation of a custom controller now use a direct pattern of f(ActionRequest) => PsrResponseInterface. This is breaking if you implemented your own ControllerInterface or overwrote low level parts and methods of the ActionController.

```php class Dispatcher {

public function dispatch(ActionRequest $request): ResponseInterface;

}

interface ControllerInterface {

public function processRequest(ActionRequest $request): ResponseInterface;

}

Also, it’s discouraged to manipulate $this->response in controllers (the ActionResponse is deprecated), although it’s still supported in actions for now, please consider returning a new response instead.

<details>

<summary> Explanation of the legacy MVC response object. </summary>

Previously Flows MVC needed a single mutable response which was passed from dispatcher to controllers and even further to the view and other places via the controller context: ControllerContext::getResponse(). This allowed to manipulate the response at every place. With the dispatcher and controllers now directly returning a response, the mutability is no longer required. Additionally, the abstraction offers naturally nothing, that cant be archived by the psr response, as it directly translates to one: ActionResponse::buildHttpResponse() So you can and should use the immutable psr {@see ResponseInterface} instead where-ever possible. For backwards compatibility, each controller will might now manage an own instance of the action response via $this->response AbstractController::$response and pass it along to places. But this behaviour is deprecated! Instead, you can directly return a PSR repose \\GuzzleHttp\\Psr7\\Response from a controller:

```php public function myAction() {

return (new Response(status: 200, body: $output))

->withAddedHeader(‘X-My-Header’, ‘foo’);

}

</details>

Further the ForwardException does not extend the StopActionException anymore, meaning a try catch must be adjusted.

This is the main PR and it contains - https://github.com/neos/flow-development-collection/pull/3232 - https://github.com/neos/flow-development-collection/pull/3294

Followup: https://github.com/neos/flow-development-collection/pull/3301 Resolves: https://github.com/neos/flow-development-collection/issues/3289

This change needs an accompanying adjustment to Neos to adjust the PluginImplementation as well as Modules: https://github.com/neos/neos-development-collection/pull/4738

Upgrade instructions

WIP Upgrade notes: https://github.com/neos/flow-development-collection/pull/3232#issuecomment-1913166370

!!! FEATURE: update to doctrine/dbal version 3

update to 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.

Related Neos adjustments: https://github.com/neos/neos-development-collection/pull/5161

Upgrade instructions

We require now version 3 of doctrine/dbal but still operate doctrine/orm in version 2. In case you depend on DBAL directly you should have a look into their upgrade instructions: https://www.doctrine-project.org/2020/11/17/dbal-3.0.0.html

!!! FEATURE: ViewInterface returns PSR StreamInterface

Neos adjustments https://github.com/neos/neos-development-collection/pull/4856

  • the views are now independent of the ControllerContext - ViewInterface::setControllerContext is not part of the interface anymore and will only be called on demand

  • the ActionRequest if necessary can be accessed via the variable “request” (like “settings”)

  • ViewInterface::canRender was required for fallbackviews which have been removed long ago, and so this artefact will be removed as well.

  • !!! the return type is now forced to be either a ResponseInterface or a StreamInterface. Simple strings must be wrapped in a psr stream! (see StreamFactoryTrait::createStream)

Related to https://github.com/neos/flow-development-collection/pull/3232

!!! FEATURE: WIP Dispatcher and controller return ActionResponse (simpler controller pattern)

will not be merged directly into 9.0 but included in this mvc overhaul pr: https://github.com/neos/flow-development-collection/pull/3311

This change needs an accompanying adjustment to Neos to adjust the PluginImplementation as well as Modules.

~The new SimpleActionController gives you a direct and simple way to route an ActionRequest and return an ActionReponse with nothing in between. Routing should work just like with other ActionControllers.~

This is breaking if you implemented your own ControllerInterface or overwrote or expect some of the api methods of the ActionController. We now use a direct pattern of f(ActionRequest) => ActionResponse in more places. Adjusting existing controllers should be easy though. Additionally implementing your own dispatch loop (don’t do this) will need adjustments.

We discourage to manipulate $this->reponse in controllers, although it should still work fine in actions for now, please consider other options.

```php class Dispatcher {

public function dispatch(ActionRequest $request): ActionResponse;

}