This section contains instructions for upgrading your Flow 3.3 based applications to Flow 4.0.
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).
All namespaces beginning with TYPO3\\
have been changed to the Neos\\
vendor namespace. Migrations are provided for automatically adjusting user packages.
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.
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.
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.
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.
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.
MediaTypes::getMediaTypeFromFileContent()
can be used to return the media type from a given file content.
Adds a new getter method to the AuthenticationManagerInterface
, that has to return all provided authentication providers.
With this helper it is possible to flip the keys and values from an array.
Now the stripTags
string eel helper will accept a second optional argument in form of a list of allowed tags which will not be stripped from the string.
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']
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);
This extends DateTimeConverter
and StringConverter
so that they support any class implementing the \\DateTimeInterface
(including \\DateTimeImmutable
).
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.
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.
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.
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.
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.
Removed the long-deprecated compat flag for relative uri paths and the according code in the UriBuilder and UriBuilder test.
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.
The PropertyMappingConfigurationBuilder
class was deprecated and is bound to be removed.
It can be fully replaced by calling PropertyMapper::buildPropertyMappingConfiguration
from now on.
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.
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
.
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.
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.
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.
This removes the deprecated injection of settings via the @Flow\\Inject
annotation. Instead, use the @Flow\InjectConfiguration
annotation.
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.
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 schema is done by running:
./flow doctrine:migrate
to update your database with any changes to the framework-supplied schema.
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.