Most developers know the situation: the currently used LTS version of the old and big and clunky TYPO3 system that was passed from maintainer to maintainer over the years approaches its end of life. Every extension that was available on TER in the last two years is installed or at least available for installing. Lately the maintenance strategy all developers agreed upon was not to touch anything. But now ... when everybody is still kind of amazed by the fact that the website still works and does what it does, the terrifying truth is inevitable: The project needs to be upgraded to the next LTS.
Although this was an exaggeration and most TYPO3 projects I've seen so far are in a much better shape, an upgrade to the next LTS can be a challenging task. So even if the story above sounds familiar: it does not have to be like this. Here are some things I like to do when a system needs an upgrade. It's all about keeping the overview in terms of what is there vs what is needed.
Preface
Upgrading TYPO3 projects becomes a lot easier if the big technology gap between version 4.5 and 6.2 or even 7.6 has not to be dealt with. Upgrading from 7 LTS to 8 LTS will be significantly less painful than touching a really old project might be. Also the size and shape of the project obviously matters. If your installation only uses a few extensions and a single page tree with first and foremost mere content - then you are probably fine and do not really need to care too much about everything I am going to say in this post.
But if you happen to work on a rather big installation that has complex applications going on and is somewhat crucial to your client (as most websites are) you might find some of this advice helpful. As usual there might be additional things that are good ideas during the upgrade process of such a project which I do not cover. Please don't hesitate to contact me on Slack or via Email so I can incorporate them here for everybody.
Preparation
Here is a fact about TYPO3 upgrades:
The problems come with extensions not with the core!
The TYPO3 core can be flawlessly upgraded from LTS to LTS, the Upgrade Wizards in the Install Tool are doing all the changes to the infrastructure to make the core run. Extensions are another story. That is why you should use as few as possible.
But you most likely won't be able to run your TYPO3 system without the help of any extension. And because of that it is worth mentioning that there are many things you can do prior to the update to reduce issues with extensions to a minimum. These things include cleaning up the code base, double checking all installed extensions as well as defining and revaluating the requirements for the system after the upgrade. Let's look at those tasks one at a time.
Cleaning the Code Base
You should avoid running into countless exceptions and fatal errors after an upgrade because your code uses no namespaces or calls some old TYPO3 APIs that have been removed in the new LTS release.
Namespaces
Since TYPO3 7 LTS there is no longer support for calling the old TYPO3 classes from the pre namespace era. t3lib_div::makeInstance()
will simply fail. So if you are coming from TYPO3 6.2 replace all those calls with the respective new class names (e.g. \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance()
) prior to the update and also add namespaces to all classes in your own extensions. In TYPO3 6.2 a legacy support for the old class names was implemented, that can function as a map for the migration from old class name to new class name as well (see LegacyClassesForIde.php on github).
Removed or changed APIs
Chasing errors after an upgrade can be very frustrating, especially if the API changed and your code breaks because of it. To prevent such a scenario you should do some research before the upgrade. Because (and this should be no news to you, but in case it is, you already learned an important thing) every breaking change and every deprecation (which represents a breaking change in the future) in the TYPO3 core is documented. In fact a patch with a breaking change or a new deprecation does not get merged without a documentation .rst file attached to it. You find the full documentation here (you can switch the TYPO3 version at the bottom of the menu).
During the development of TYPO3 v8 the .rst files have been included in the install tool as well, where they can be searched and filtered under the menu entry "Upgrade Analysis":
A convenient way to check your code right now for potential issues with breaking changes in the target version of TYPO3 is to enable the deprecation log. This can be done via$GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'] = 'file';
in any configuration file that is loaded during bootstrap or in the Install Tool (which writes in to LocalConfiguration.php
).
The TYPO3 core writes to the deprecation log whenever a method is called or an argument was used that was marked as deprecated. Sometimes the migration strategy is logged with the call:
7-01-16 21:47: TYPO3\CMS\Core\Utility\GeneralUtility::array_merge() - since TYPO3 CMS 7, will be removed in TYPO3 CMS 8 - native php '+' operator instead -[...]
This entry tells you what the issue is and what you should do about it. It contains a full stack trace of the logged call so you can identify the line of code that calls this deprecated function. Migrate it now and you have one fatal error less to worry about after the upgrade.
Some entries will not include the migration strategy.
15-01-17 21:13: TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconClasses() - since TYPO3 CMS 7, will be removed in TYPO3 CMS 8 - [...]
In such a case you should look into the code where the deprecation was logged. For the example that would be IconUtility::getSpriteIconClasses()
.
/**
* [...]
* @param string $iconName Iconname like 'actions-document-new'
* @return string A list of all CSS classes needed for the HTML tag
* @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
*/
public static function getSpriteIconClasses($iconName)
{
GeneralUtility::logDeprecatedFunction();
This does not really help a lot but if you look around, you will see that every public method of the class is deprecated and that in fact the whole class will be removed in the next LTS release:
/**
* [...]
* @deprecated since TYPO3 CMS 7, will be removed with TYPO3 CMS 8, use IconFactory instead
*/
class IconUtility
{
Now you have a better idea how to migrate your code so that it no longer uses the deprecated API of IconUtility
.
Another good way to find out what to do is to look for the .rst documentation file that covers the deprecation you are affected by. Because every deprecation has such a documentation you will eventually find it. You could either look for it online in the core documentation linked above or use git to find the commit that introduced the deprecation as that commit also added the .rst file. Most .rst files that cover deprecations also document migration strategies for affected code. The documentation file for the example used here can be found under Deprecation: #69057 - Deprecate IconUtility and move methods into IconFactory.
It's all documented - use it!
Your ultimate goal is to have no entries in the deprecation log triggered by your own extensions. You have no direct influence on the code of the TER extensions that may produce deprecation log entries. Of course you can file issues, provide pull requests or contact the developers but after all it stays 3rd party code and yet another reason for keeping the amount of TER extensions as low as possible.
CGL
Since TYPO3 7 LTS PSR-2 is used as a coding guideline throughout the TYPO3 core. If our code is not PSR-2 compliant we should use a tool like the PHP-CS-Fixer to migrate our code beforehand, so that we could use the PSR-2 sniffs in our IDE in the upgrade project right from the beginning.
All in all we want to follow the good Practices in TYPO3 Extensions (read my article on that topic here).
Revaluate the Requirements of the Project
I cannot stress this enough: take some time and revaluate your system requirements. That includes a list of every extension. Write down what it does and where it is used in the system. Most likely you will find some extensions right on the spot that simply are no longer needed. Remove them! Every removed extension eases your upgrade.
For each extension that provides frontend plugins, query the database for a list of (undeleted) pages where the plugin is actually used and if you found none revaluate if that frontend plugin is still needed. If not: remove the extension.
Check the list of new features the core will have after the upgrade and look for extensions that were used for one or more of those features. Document the migration to the core functionality and remove the extension when you begin the upgrade.
Look for uninstalled extensions. Remove them.
For each extension, check if the functionality it provides is actually still needed. Check the TER for modern alternatives that have more recent updates or just take a moment and think about if you could implement that functionality without much effort on your own - because most of the time that is preferable over installing an extension from TER.
Identify extensions that will most likely not work after the update and look for alternatives. Don't hesitate to involve the TYPO3 community for this. Somebody might have just the right solution for you. We've all been there. A new TYPO3 core means most likely a new PHP version on the server, so make sure to include that in your evaluation.
After that process you should have a full list (or table) with each extension and most important a migration strategy for every extension. Whether you remove it right away, remove it during the upgrade, replace it or just keep it and update it. You will feel much more comfortable now.
The Update (doing it right - or at least not totally wrong)
If you followed some of the preparation suggestions from above you should be in good shape to perform the actual update. I'll give some general advice first.
General Tips
Here are some tips for a successful update, when your preparations are finished.
- Don't upgrade your only copy of the project. Obviously. Clone the project and upgrade the clone. Always keep the "old" project as a reference and a backup. You can get rid of the old project as the last step some time after the upgraded version was launched - it marks the end of the successful process.
- Use git. You will do many things during an upgrade. Use git for a documentation of those steps by making meaningful commits.
- Document you migration path. Whenever you perform a task that changes records in the database or physically changes files that are not under version control, document it and don't bother to tag the git commit you are on while doing it. You want to generate a upgrade log that is so detailed that it can be followed by somebody else step by step and result in the same state of the project.
- Good practices. While you're on it embrace good practices in TYPO3 projects.
- Use the target system requirements. Don't perform the upgrade in the system environment the project was used to run in, but in the new environment. The new TYPO3 core needs a specific version of PHP and MySQL - use it as early as possible in the upgrade process to identify issues you might have overlooked before.
TCA Migrations
Due to heavy refactoring in this area of the TYPO3 core your TCA might need some adjustments. Once more a look to the deprecation log can be the first step as many no-longer-functional configurations are listed there alongside a hint for a migration:
26-02-17 13:30: Automatic TCA migration done during bootstrap. Please adapt TCA accordingly, these migrations will be removed with TYPO3 CMS 8. The backend module "Configuration -> TCA" shows the modified values. Please adapt these areas:
Changed showitem string of TCA table "tx_securedownloads_domain_model_log" type "1" due to changed field "sys_language_uid".
Migrated TCA table "tx_securedownloads_domain_model_log" showitem field of type "1": Moved additional palette with name "1" as 3rd argument of field "hidden" to an own palette. The result of this part is: "hidden, --palette--;;1" [tx_securedownloads_domain_model_log.ctrl.iconfile] relative path to ../typo3conf/ext/ is deprecated, use EXT: instead
Using select fields without the "renderType" setting is deprecated in table "fe_users" and column "member"
In addition to these information that are already available in the deprecation log of TYPO3 7LTS, you can find a very helpful tool in the Install Tool of TYPO3 8 LTS (so it should be available after the update). Under "Important Actions" you'll find the buttons "TCA Migrations" and "TCA in ext_tables.php check".
The former provides you with a list of every line of TCA configuration that needs a change. Depending on your project that list could be very long but it still is a very useful tool to identify no-longer-working TCA configuration.
The 2nd button looks in every extension for ext_tables.php
files that contain changes to the TCA as those overrides have to be moved to Configuration/TCA/Overrides
. If you followed the good practices in TYPO3 extensions, your extensions should not be listed here =)
.
So that concludes this article. Thank you for reading until the end and feel invited to provide feedback even if you only find a typo.
Further Information
- Issues you might run into when upgrading TYPO3 Extensions, 2017 by Frank Nägler, typo3.com
- Credit for the icons used in the graphic goes to iconmonstr.com