Flow 4.0
Upgrade Instructions
This section contains instructions for upgrading your Flow 3.3 based applications to Flow 4.0.
What has changed
Flow 4.0 comes with major changes, numerous fixes and improvements. Here’s a list of changes that might need special attention when upgrading.
In general make sure to run the commands:
./flow flow:cache:flush --force
./flow core:migrate
./flow database:setcharset
./flow doctrine:migrate
./flow resource:publish
when upgrading (see below).
Namespace change
All namespaces beginning with TYPO3\\
have been changed to the Neos\\
vendor namespace.
Migrations are provided for automatically adjusting user packages.
Fluid standalone
Replaces TYPO3.Fluid
with Neos.FluidAdaptor
integrating standalone fluid.
This change brings the following:
Standalone Fluid integration (see https://github.com/typo3/fluid)
Flow no longer depends on Fluid, the default View is configurable
Partials can be called with a package prefix “Vendor.Package:Path/Partial”
Standalone Fluid in general is faster and many of the Flow specific ViewHelpers were rewritten to take advantage of compiling as well to make it even faster.
The change is breaking because:
Standalone Fluid is a major rewrite, it might react differently for edge cases
Notably escaping now also escapes single quotes.
The
ViewInterface
got a new staticcreateWithOptions(array $options)
construct method, which needs to be implemented by custom view classes to have a defined way to instantiate views.Flow no longer depends on Fluid, which means you might need to require it yourself in your distribution or package(s)
TYPO3\\Fluid\\*
classes have moved toNeos\\FluidAdaptor\\*
and a lot of classes are gone and instead to be used from the standalone fluid package if needed.Boilerplate code to create Fluid views is slightly different and might need to be adapted in projects.
Make Cache FileBackends independent of external locks
This avoids using external locks, which are prone to platform issues (race conditions and tombstones for lock files or missing semaphore extension) and instead directly uses the file locking mechanism of PHP to lock the cache files.
This should noticeably improve performance for the FileBackend caches and avoid having thousands of Lock files which clobber the file system and created issues with big setups previously.
Reuse join aliases on same property paths in QueryBuilder
Previously a query object like
$query->logicalAnd($query->equals('related.property', 'foo'), $query->equals('related.otherProperty', 'bar'));
would generate an SQL statement with two joins to the related entity, one for each condition, translating to
“get all objects that have any related entity with a `property` ‘foo’ and any related entity with `otherProperty` ‘bar’”.
With this change, it will only generate a single join and reuse the join for multiple conditionals, therefore translating the above query object to the more common
“get all objects that have a related entity with both a `property` ‘foo’ and `otherProperty` ‘bar’”
This also improves performance of such queries by avoiding unnecessary joins.
Runtime evaluation of env and constants in Configuration
The configuration is now cached with php expressions that read environment variables and constants at runtime to allow writing the configuration cache on a different environment.
Scalar to object converter
This introduces a simple type converter which can convert a scalar value (string, integer, float or boolean) into an object by passing that value to the class constructor.
This converter helps developers using Value Objects (not managed by the persistence framework) or other Data Transfer Objects in places where type conversion is supported. One common case is to use Value Object class names as a type hint for arguments in a command line controller method.
Parse media types from file content
MediaTypes::getMediaTypeFromFileContent()
can be used to return the media type from a given file content.
Extend AuthenticationManagerInterface with getter for providers
Adds a new getter method to the AuthenticationManagerInterface
, that has to return all provided authentication providers.
Array.flip()
Eel helper
With this helper it is possible to flip the keys and values from an array.
Add String.pregSplit
Eel helper
Adds a new helper method to the string helper for splitting strings with a PREG pattern.
Example:
String.pregSplit("foo bar baz", "/\\s+/") == ['foo', 'bar', 'baz']
Internal TypeConverters
Creating a new TypeConverter can have major side-effects on existing applications. This change allows TypeConverters to have a negative priority in order to mark them “internal”. Internal TypeConverters will be skipped from PropertyMapping by default.
To use them explicitly the PropertyMappingConfiguration
can be used:
$configuration = new PropertyMappingConfiguration();
$configuration->setTypeConverter(new SomeInternalTypeConverter());
$this->propertyMapper->convert($source, $targetType, $configuration);
Allow property mapping of DateTimeImmutables
This extends DateTimeConverter
and StringConverter
so that they support
any class implementing the \\DateTimeInterface
(including \\DateTimeImmutable
).
Support for protected static compiled methods
With this change static methods annotated @Flow\\CompileStatic
can now
be protected
allowing for more concise public APIs.
If the annotated method is private
or not static
an exception is
thrown during compile time in Production context.
As a side-effect this change adds a new API method ReflectionService:: getMethodsAnnotatedWith()
that allows for retrieval of all method names of a class that are annotated with a
given annotation.
Dependency Injection and AOP for final classes
This adds support for proxied final classes.
Previously those were always skipped from proxy building disallowing Dependency Injection. Besides final classes could not be targeted by AOP advices.
With this change, final classes are now also proxied by default.
To _disable_ AOP/DI for those the already existing Proxy
annotation can be used:
use TYPO3\\Flow\\Annotations as Flow;
/**
* @Flow\\Proxy(false)
*/
final class SomeClass
{
// ...
Background:
Marking classes final
is an important tool for framework code as it allows to define extension points
more explicitly, but until now we had to avoid the final
keyword in order to support DI and AOP.
ViewConfiguration use only the settings of highest weighted request filter
Before this the higher weighted requestFilters were merged into the lower-weighted ones which placed the array-properties of the higher weighted filters last in the merged configuration. This made it impossible to add a new path templatePath that would be considered before.
This patch removes the merging of view-configurations entirely since this lead to confusion in the integration because the merging was unexpected.
This is breaking if you have multiple configurations with filters that apply to the same request and expect some option from one of the configurations to still be present despite another configuration having a higher weight.
Rename [TYPO3][Flow][Security][Authentication]
This change adjusts the path used for the POST argument used for authentication with username and password to the new vendor namespace.
Any application - and especially its Fluid templates and JavaScript - relying on the old path needs to be updated.
This change provides a core migration which carries out these changes.
Remove deprecated ResourcePublisher
and pointer
The old resource management pre Flow 3.0 used the ResourcePublisher
as main service to get public URLs to resources and the ResourcePointer
to keep track of unique resources. Both became unnecessary and were
deprecated with Flow 3.0 and are therefore removed with this major release.
Remove deprecated support for relative uri paths
Removed the long-deprecated compat flag for relative uri paths and the according code in the UriBuilder and UriBuilder test.
Remove deprecated support of temporary path setting
The setting TYPO3.Flow.utility.environment.temporaryDirectoryBase
was deprecated and with this change finally removed.
The temporary path defaults to FLOW_PATH_ROOT . 'Data/Temporary'
, but
you can always override the temporary path via the environment variable
FLOW_PATH_TEMPORARY_BASE
instead.
Note that in either case a sub path will be created based on the current application context.
Remove deprecated EarlyLogger
Remove deprecated PropertyMappingConfigurationBuilder
The PropertyMappingConfigurationBuilder
class was deprecated and
is bound to be removed.
It can be fully replaced by calling
PropertyMapper::buildPropertyMappingConfiguration
from now on.
Remove deprecated getClassTag
and constants
The CacheManager::getClassTag
method was unused since
quite some time and became deprecated in previous releases.
It is therefore bound for removal in this major version.
Additionally the unused tagging constants in the FrontendInterface
are removed as they are also no longer needed.
Remove relations to party in Account
and Security\\Context
Since 3.0 something like a Party
is not attached to the account directly anymore.
Fetch your user/party/organization etc. instance on your own using Domain Services or Repositories.
One example is TYPO3\\Party\\Domain\\Service\\PartyService
.
Remove deprecated properties and methods in Argument
Remove deprecated class ResourcePublisher
Rename object and resource
This renames the class Resource
to ResourceObject
and renames the namespaces
TYPO3\\Flow\\Object
and TYPO3\\Flow\\Resource
to TYPO3\\Flow\\ObjectManagement
and TYPO3\\Flow\\ResourceManagement
respectively.
A Doctrine migration and two core migrations to help with adjusting code are added.
Remove internal properties request and response from RequestHandler
Since the Request
and Response
instances are supposed to change inside the ComponentChain,
it is error-prone to keep a reference to the initial instances inside the RequestHandler.
This change removes the class properties $request and $response and instead uses local variables.
This is marked breaking only for the reason that some RequestHandler implementations could exist that still somehow depend on this internal detail. It is not really breaking as those properties were never part of the public api though.
Remove “fallback” password hashing strategy
This removes the fallback for password hashing strategies.
This is a breaking change for installations that had accounts created with a Flow version lower than 1.1 (and whose passwords were never updated since then). In that case make sure to add the prefix to the corresponding accounts in the accounts table. For the default configuration the corresponding SQL query would be:
UPDATE typo3_flow_security_account SET credentialssource = CONCAT(‘bcrypt=>’, credentialssource)
Background:
Due to some problems caused by older Flow installations that migrated from 1.0, a fallback mechanism for the password hashing strategies was implemented for password hashes that don’t contain the strategy prefix (i.e. “bcrypt=>”).
As a result the default strategy for HashService::hashPassword()
is a different one than for
HashService::validatePassword()
unless specified explicitly because for the latter the configured
fallback strategy would be used rather than the default.
Remove deprecated setting injection
This removes the deprecated injection of settings via the @Flow\\Inject
annotation.
Instead, use the @Flow\InjectConfiguration
annotation.
Remove deprecated TypeHandling::hex2bin
method
Remove deprecated StringHelper::match
method
Remove deprecated Http\\Message
class
Remove deprecated TranslationHelper::translateById
Remove deprecated redirectToReferringRequest
Remove deprecated Route::getMatchingUri
Remove deprecated methods from TemplateView
Upgrading your Packages
Upgrading existing code
There have been major API changes in Flow 4.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 --package-key Acme.Demo
The package key is optional, if left out it will work on all packages it finds (except for library packages and packages prefixed with “TYPO3.*” or “Neos.*”) - for the first run you might want to limit things a little to keep the overview, though.
Make sure to run:
./flow help core:migrate
to see all the other helpful options this command provides.
Inside core:migrate
The tool roughly works like this:
Collect all code migrations from packages
Collect all files from all packages (except Framework and Libraries) or the package given with
--package-key
For each migration and package
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.
Upgrading the database schema
Upgrading the schema is done by running:
./flow doctrine:migrate
to update your database with any changes to the framework-supplied schema.
Famous last words
In a nutshell, running:
./flow core:migrate
./flow doctrine:migrationgenerate
in Development Context, padded with some manual checking and adjustments needs to be done. That should result in a working package.
If it does not and you have no idea what to do next, please get in touch with us.