Translations
Info
All page names need to be in English.
en da  de  fr  it  ja  km  nl  ru  zh

Upgrade Flow

From TYPO3Wiki
Jump to: navigation, search
This page belongs to the Flow Team (category Flow)


Upgrading Instructions

This following instructions contain the essential steps for upgrading your FLOW3 1.0 based applications to FLOW3 1.1.

Full Changelog

If in doubt, you'll find many answers to possible questions still unanswered after reading this document by browsing through the full changelogs.

Automated Code Migration

A large part of the code changes you will need to do to your applications can be done automatically with the new code migration tool provided with FLOW3 1.1. If you have your packages under Git version control and the working copies are clean a simple:

./flow3 core:migrate

will adjust your code as needed and commit the changes as a migration, recording the applied migration in the commit message.

Feel free to amend the commit as needed, if further adjustments are needed.

Note: The migration tool will output a list of notes and warnings about things that you might need to adjust manually - make sure to read those.

Also, read the remainder of this document, it contains more details about the changes and possible solutions to problems. The code changes automated with the migration tool are explained in detail at the end of this document.

Conceptual Changes

Frozen packages

FLOW3 1.1 contains new mechanisms which improve the development and production speed. An important feature is the ability to freeze packages.

For performance reasons, the file monitor won't track modifications to files of frozen packages. After flushing the code caches with flow3:cache:flush FLOW3 will not reflect classes contained in frozen packages but instead retrieve reflection data from a special cache file which is preserved even during the cache flush.

If class files contained in frozen packages are modified, the whole application may behave rather unexpectedly. Therefore you need to make sure that the packages you are working on currently are not frozen.

There are few easy to use commands to control the frozen state of packages:

./flow3 package:list

will list all available packages and indicates which ones are currently frozen.

./flow3 package:freeze TYPO3.FLOW3

freezes the package TYPO3.FLOW3 and

./flow3 package:unfreeze TYPO3.FLOW3

unfreezes it again so that modifications are detected. If a package should stay frozen but its reflection data should be updated once, you can simply run:

./flow3 package:refreeze TYPO3.FLOW3

Instead of a package key you may also specify the magic keyword all or leave the package key out completely. If your application behaves strangely, possibly due to a prior fatal error, you can still use the new --force option which empties all existing caches and runs in a special "safe mode":

./flow3 flow3:cache:flush --force

Package layout changes

The Doctrine package that was part of the FLOW3 1.0 base distributions has been split into three packages Doctrine.Common, Doctrine.DBAL and Doctrine.ORM. If you maintain your own Git submodule records, you should remove the old Doctrine submodule and add the split Doctrine packages to your super project instead.

Session configuration changes

The configuration for the PhpSession is now read from a setting named PhpSession instead of the former PHPSession. You should adjust your settings accordingly.

Database schema changes

As always you should check the database migration status and apply new migrations if there are any. Use:

./flow3 doctrine:migrationstatus

to check and:

./flow3 doctrine:migrate

to apply any pending migrations.

This will take care of the schema updates for packages that supply their needed adjustments. For your own package you will most likely need to create (and adjust) a migration to accommodate it to new behavior in FLOW3 1.1. To do that use:

./flow3 doctrine:migrationgenerate

Here are the things that changed in FLOW3 that you should expect to see in a schema migration:

  • long table names get shortened
  • nullable column defaults and
  • unique keys for identity properties of entities.

(Overly) long table names (more than 63 chars in most cases) are now shortened. Thus you should make sure that affected tables are renamed correctly in your generated schema migrations.

NULL handling for columns has changed. FLOW3 1.1 now defaults to non-nullable columns to behave like Doctrine. This means any column for a literal property will be generated as a non-nullable column. For existing columns you will see adjustments in the generated schema migration.

If you want your column to actually be able to contain NULL values, you must annotate your property with:

@ORM\Column(nullable=true)

Another change is caused by a new feature: the properties of an entity that are marked with the Identity annotation are now transformed into an unique index in the database. The needed index creation statements will also be part of the generated schema migration.

Security framework

Configuration
  • The previously shipped *DefaultProvider* authentication provider
 configuration has been removed, you must configure all providers yourself now.
 Note:
  The authentication provider name (previously: "DefaultProvider") must match the
  provider name which is stored with each account. Either configure your own
  authentication provider with the name "DefaultProvider" or configure a new one
  with a different name and update the accounts accordingly.
  • providerClass is deprecated, use provider instead. Provider
 options are now given in providerOptions.
  • Authentication entrypoint configuration needs to be changed from:
  entryPoint:
    WebRedirect:
      uri: login.html
 to:
  entryPoint: 'WebRedirect'
  entryPointOptions:
    uri: 'login.html'
  • Content security ACL logic was inversed. This realizes a whitelist approach for
  content security ACLs. They now work with the same logic as method security.
Password hashing

The default hashing strategy for passwords was changed from PBKDF2 to BCrypt. Also it is now possible to use a mix of password hashing strategies, as the used strategy is stored in the credentialsSource property of an account.

One way to get existing accounts working again is to make sure your default strategy setting matches the used strategy for any accounts created before the change:

TYPO3:
  FLOW3:
    security:
      cryptography:
        hashingStrategies:
          default: pbkdf2

Setting the default strategy to match the one used for 1.0.x will not take advantage of the new (more secure) hashing. Therefore a new **fallback** configuration option was added. It allows to specify the strategy that was used to generate legacy credentials. It defaults to pbkdf2 and allows for a seamless migration from 1.0 to 1.1. New passwords will be hashed with the default strategy (bcrypt by default) and get the strategy identifier prepended.

Note:

For the strategy … your credentials look like …:
pbkdf2
 7kP/laYDXxQ=,iMoNTRTcbY01Q9LSeAaoxV9hq … QEmHm3ottU1yJdw==
bcrypt
 $2a$14$2zNPS6TfbMPCdnxuRlheu.2kZAJ … H3DaYwqqIeAgPzN6kTS
saltedmd5
 2f1861241e1951f8696f80cf71b43dee,029fc4310e

YAML syntax

The YAML parser has been updated and now behaves stricter and more correct:

* Boolean values must no longer be written as y, yes, n, no but
  as TRUE and FALSE instead.
* When using backslashes in strings, those are now handled as escape characters
  inside double quotes. So if you write class names, better wrap them in single
  quotes.

Routing

Widget configuration in *Routes.yaml* has changed and needs to be adjusted. If you used e.g. @widget_0.currentPage in *Routes.yaml* you need to change that to use the correct widget identifier prefixed a double dash. By default the widget identifier is the lowercased fully qualified widget classname with dashes instead of backslashes. For the paginate viewhelper it would thus be typo3-fluid-viewhelpers-widget-paginateviewhelper.

To make things easier and more telling, you can also set a custom widget id in your template. On the widget tag simply set the "widgetId" attribute and use the same in Routes.yaml. This way you can use e.g. "--paginate":

  • Template.html*:
 <f:widget.paginate widgetId="paginate" …>
  • Routes.yaml*:
 uriPattern:    'posts/page/{--paginate.currentPage}'
 defaults:
   '@controller': 'Post'
   '@action':     'index'
   '--paginate':
     '@controller':  
     '@package':     

Nested FLOW3 Application Contexts

With this change, it is possible to use nested FLOW3 contexts like "Production/Live" or "Production/Staging/Server1". The main context, has to be one of "Production", "Development" or "Testing", whereas arbitrary sub contexts are supported.

If you run in the context "Production/Staging/Server1", the configuration is inherited in the following way (from most specific to most general):

- Production/Staging/Server1 - Production/Staging - Production - as a fallback, the, non-context-specific configuration is used

This change is breaking in the following cases:

You called getContext()

 In this case, not the context string is returned anymore, but instead
 the \TYPO3\FLOW3\Core\ApplicationContext object. It can be cast to a string to
 get the old behavior back; but usually you instead want to call
 $context->isDevelopment(), $context->isProduction() or $context->isTesting().

You wrote your own cache backend.

 The cache backend constructor now expects the $context object to be of type
 TYPO3\FLOW3\Core\ApplicationContext.

Code Changes

This section details changes done to the code that will or could break your custom code and thus need your action. Most of this cannot be automated, and thus is not covered by the automated code migration.

Custom Request Handling

If you created custom RequestHandler/-Builder you most probably need to adjust those:

Custom RequestHandlers need to be registered in your *Package.php*:

 public function boot(\TYPO3\FLOW3\Core\Bootstrap $bootstrap) {
 	$bootstrap->registerRequestHandler(new \Your\Package\Your\RequestHandler($bootstrap));
 }

In your RequestHandler you probably want to create an *HttpRequest* first:

 $this->request = \TYPO3\FLOW3\Http\Request:createFromEnvironment();

Then you can create an *ActionRequest* with:

 $this->request->createActionRequest();

Some more pitfalls:

  • RequestBuilders are not required anymore, instead you create request & response
 in the RequestHandler
  • If you want to use the routing framework, have a look at
 \\TYPO3\\FLOW3\\Http\\RequestHandler:handleRequest()
  • Some convenience methods were removed from \\TYPO3\\FLOW3\\Utility\\Environment.
 You can use corresponding functions of the HttpRequest mostly

Persistence - Repository interface

You might need to adjust your code if you specifically extend the Persistence\Doctrine\Repository class - the return values have changed to be in sync with the generic repository class. In most cases that should just fix unexpected behavior, but if you relied on specific return values, check your tests for failures.

If you implemented RepositoryInterface from scratch, you must add the __call method, it is now required by the interface to ensure consistency.

If you already override __call in a repository of your's, you will need to adjust the name of the $methodName parameter to $method.

Fluid Templates

The form.textbox tag has been renamed to form.textfield.

Content Negotiation for Media Types

The way to define the supported formats of a controller has changed: Previously a class property $supportedFormats contained a list of filename extensions which would be supported. This property is not supported anymore. Instead, controllers may now specify a list of IANA Internet Media Types in a property $supportedMediaTypes.

The default setting for these supported media types in ActionController is text/html. You'll need to adjust your controllers accordingly if you relied on the $supportedFormats feature.

Also note that the format in ActionRequest is now NULL by default. The ActionController makes sure to set the correct format, but if you created your own ActionRequest for a special purpose, you need to take care of setting it yourself.

Session handling changes

With FLOW3 1.0 a session was always started, 1.1 only starts a session if needed. To start a session when a certain method is called, use the Session annotation with the autoStart argument.

For authentication the session annotation is set at the providers, not at the authentication manager. By this every provider can decide on its own, if a session is needed or not.

A previously missing parameter was added to the destroy() method signature of the SessionInterface. If you implemented your own session handler, you need to adjust the destroy() method accordingly.

Validation behavior

Most of the provided validators in FLOW3 1.0 did not accept empty values. This made it impossible to have an optional email address property for example (without using the disjunction validator).

FLOW3 1.1 adjusts all Validators to consider empty values (NULL or an empty string) valid.

This is a breaking change if you expected the previous behavior. In order to make a property required you now need to add the NotEmptyValidator explicitly!

Float and Integer converters now correctly handle errors and empty values. Empty strings are now correctly converted as NULL values. This is a breaking change if you relied upon the old behavior that empty values are converted to the number 0.

Whitelist-based Property Mapping Configuration

Up to now, property mapping always allowed to modify all properties of a given object. Especially in the MVC stack, this functionality was relied upon for all update and create actions. However, for nested objects, the user needed to configure whether updates and creations should be allowed.

This was an inconsistent behavior, especially because for read-only actions the object could be also modified.

The behavior is now changed to be more predictive:

  • the default PropertyMappingConfiguration used in the MVC stack is changed
 to be very restrictive: we do neither allow creation of any new objects nor
 modification of existing ones; and all properties which should be modified
 must be explicitly configured.
  • For each form, Fluid now generates a list of trusted properties, based upon
 which the PropertyMappingConfiguration is set correctly. This means only
 properties which have been rendered by fluid are allowed to be modified,
 and creation / insertion is only permitted if needed.

The changes in a nutshell:

  • If you used Fluid forms, everything will still work as expected.
  • If you used Fluid forms and needed to adjust the property mapping configuration
 manually, you can remove these manual adjustments.
  • If you manually called the Property Mapper and passed a custom Property Mapping
 Configuration, you probably need to call …->allowAllProperties() on the property
 mapping configuration.
  • If you did not used Fluid forms but relied upon the old behavior of the Property
 Mapper (e.g. in a web service), you need to configure the Property Mapper
 inside your initializeAction correctly now.
  • PropertyMappingConfiguration:doNotMapProperty (no public API) was removed.
 Instead, use :allowAllPropertiesExcept(…).
  • Furthermore, an exception is now thrown if a property is not allowed to be
 mapped. Before, the property was just ignored silently. You should either
 write your own TypeConverter to deal with that or filter the input data
 correctly before property mapping.

Cache backends

A new interface TaggableBackendInterface and a new SimpleFileBackend have been added. The latter does not support tagging but is faster in certain cases (where with a lot of tags/entries flushing everything is faster than flushing by tag).

If you have implemented a cache backend and support tagging, you must add the TaggableBackendInterface to the list of interfaces implemented by your backend.

Internationalization

To control the behavior of the i18n component a way to configure the "current" locale, fallback rules for resolving of translations and possible more was needed. Thus a Configuration object was added to the i18n code which encapsulates the configurable parts. Check the i18n documentation for details.

For early adopters this change means the calls to getDefaultLocale() and getCurrentLocale() on I18n\Service need to be routed to Service->getConfiguration()->… instead.

File Monitoring

The "ChangeDetectionStrategyInterface" contains the two new methods "setFileMonitor" and "shutdownObject" now, so if you implemented your own change detection strategy, you need to implement those.

Manual code migration

In case you do not want or cannot use the automated code migration, this is what needs to be adjusted (in addition to most of the above!):

  • Replace
 * TYPO3\FLOW3\MVC\CLI with TYPO3\FLOW3\Cli
 * TYPO3\FLOW3\MVC\Web\Routing with TYPO3\FLOW3\Mvc\Routing
 * TYPO3\FLOW3\MVC\Web\Request with TYPO3\FLOW3\Mvc\ActionRequest
 * TYPO3\FLOW3\MVC\Web\Response with TYPO3\FLOW3\Http\Response
 * TYPO3\FLOW3\MVC\Web\SubRequest with TYPO3\FLOW3\Mvc\ActionRequest
 * TYPO3\FLOW3\MVC\Web\SubResponse with TYPO3\FLOW3\Http\Response
 * TYPO3\FLOW3\MVC\Controller\CommandController with TYPO3\FLOW3\Cli\CommandController
 * TYPO3\FLOW3\Property\DataType\Uri with TYPO3\FLOW3\Http\Uri
 * TYPO3\FLOW3\AOP with TYPO3\FLOW3\Aop
 * TYPO3\FLOW3\MVC with TYPO3\FLOW3\Mvc
 * TYPO3\FLOW3\MVC\RequestInterface with TYPO3\FLOW3\Http\Request
 * \AOP with \Aop
 * \MVC with \Mvc
  • Use getMainRequest() instead of getRootRequest()
  • Use getInternalArgument('__submittedArgumentValidationResults') instead of getOriginalRequestMappingResults()
  • Use getInternalArgument('__submittedArguments') instead of getOriginalRequest()->getArguments()
  • Use $this->controllerContext->getRequest()->getHttpRequest()->getBaseUri() instead of $this->controllerContext->getRequest()->getBaseUri()
  • Use DataNotSerializableExceptioninstead of DataNotSerializeableException.
  • \TYPO3\FLOW3\MVC\Web\RequestBuilder does not exist anymore. If you need to
 create requests, do new ActionRequest($parentRequest).
  • \TYPO3\FLOW3\MVC\Web\SubRequestBuilder does not exist anymore. If you need to
 create sub requests, do new ActionRequest($parentRequest).
  • \TYPO3\FLOW3\MVC\RequestInterface has been removed, use
 \TYPO3\FLOW3\Http\Request instead - e.g. if you implemented your own token.
  • $supportedRequestTypes are not needed anymore in a controller.

Note: Class names in pointcut expressions might not be fully qualified, check whether (more) adjustments are needed.