Upgrade to Sulu 2.5.0 with Rector
In this post I'd like to summarize some common pitfalls to make it easier to upgrade to Sulu version 2.5.0.
The right upgrade sequence is gold
As mentioned in the release blog post for Sulu 2.5.0 the order of upgrading Sulu to 2.5.0 should be:
- Upgrade your project to Symfony 5.4
- Upgrade your Project to PHP 8.0 / 8.1
- Upgrade your database to create the new schema for 2FA
- Fix any conflicting return types
- Optional but recommended: Replace usage of Swiftmailer with Symfony Mailer
- Now follow our Upgrading Sulu 2.x documentation to update your project to Sulu 2.5
- Optional but recommended: Update to Symfony 6
This sequence is highly recommended by us and you should try to do it step by step. Trying to do everything at once can be really frustrating and could end in chaos.
In the next steps I will show you how to achieve a successful update using Rector.
Step 0: Installing Rector and PHPStan
First we need to install Rector. Like any dependency, we install it via Composer. Since Rector is built on top of PHPStan we also need to install this (including its Symfony dependencies). If you have one or both tools already installed, make sure you are updating them to the latest version and install the recommended extensions shown here:
Configure PHPStan
The recommended way of configuring PHPStan is:
The PHPStan configuration requires two additional ".php" files to be in our project. You can copy the following two code snippets to create them:
Step 1: Upgrading Symfony to 5.4
If you are already using Symfony 5.4 you can skip this step. If not, this is the important first step before you update anything else.
This step requires the most work and includes the most pitfalls because you are required to jump on a new major version of Symfony. But with Rector we are also trying to automate most things.
To update our code to be compatible with Symfony 5.4 we will first configure our rector.php
the following way. We are keeping the Rector file small so we can concentrate on the Symfony upgrade:
After configuring this, you can run vendor/bin/rector process
to upgrade your code.
Now we need to adjust the composer.json and change all "symfony/" dependencies from "^4.4" to " ^5.4". By running composer update
, all your Symfony dependencies should be updated to Symfony 5.4. You can then check if all Symfony dependencies were updated correctly via the composer info
command.
There are mainly 2 changes that affect typical Symfony projects when upgrading from 4.4 to 5.4. Depending on how successfully Rector was able to analyze your code, some parts will have been updated already.
The first change is that Symfony removed the "Symfony\Bundle\FrameworkBundle\Controller\Controller" class, and you will need to replace it with "Symfony\Bundle\FrameworkBundle\Controller\AbstractController". For this, you need to define your services via the getSubscribedService method. Take a look at the official Symfony documentation for details.
A short example of the upgrade might look like this:
The second change is that there is a required update of your custom commands. Symfony removed the "Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand" class, and you will need to replace it with the "Symfony\Component\Console\Command\Command". Also if "autoconfigure" is not activated, the command services need to be tagged with "console.command". Here's an example for this:
Now test your project to see if everything works as expected. Then eventually update other breaking changes of Symfony 4 - 5 update. Only continue after fixing all additional incompatibilities to Symfony 5.4.
Step 2: Upgrading PHP to 8.1
If you are already on PHP 8.0 or 8.1 you can skip this step. If not, we are now upgrading our code to be compatible with the latest PHP version. For this make sure you have PHP 8.1 installed on your system. In your composer.json, update the "php" requirement to "8.1.*". If required, update the "config.platform.php" version to "8.1.8". After this change you should run "composer update" to update all your dependencies to a compatible PHP 8.1 version.
In the next step we will update our PHP code to be compatible with PHP 8.1. We can achieve this via the following rector config:
After running the vendor/bin/rector process
command, your code should be updated. Re-check all changes and gradually update them to your requirements.
Step 3: Upgrade Database schema
To upgrade your project database schema you can use manual migration via SQLs, as documented in the UPGRADE.md. Alternatively, you can use the DoctrineMigrationBundle, or the recommended bin/console doctrine:schema:update
command to update the schema of your database.
Step 4: Fix conflicting return types
Some return types has been changed from Sulu 2.4 to Sulu 2.5 so have a look at the list in the UPGRADE.md about this. The breaking changes here can again be updated via a Rector rule. We are now adjusting our rector.php
to the following:
Step 5: Replace Swiftmailer with Symfony Mailer
This step is optional but recommend for future upgrades of your project. If you use the Swiftmailer in your project you should migrate all instances of it to the Symfony Mailer component. For this have a look at the official Symfony Mailer documentation.
Step 6: Upgrade Sulu to 2.5
In the next step you should upgrade Sulu to the latest 2.5 version by following the upgrade documentation. As documented the first step is to update the composer.json via composer require sulu/sulu:"~2.5.0" --no-update
and composer update
command. Most skeleton changes are not required, but if you want to follow best practice, have a look at the changes from 2.4.4 -> to 2.5.0 via Github.
Most of the breaking changes have already been fixed in Step 4 via Rector. So the last step to Sulu 2.5 is to update its JavaScript build via the bin/console sulu:admin:update-build
command. For all projects with a custom JavaScript build, we recommend testing it first with the shipped build and then add your customization after you verify that Sulu 2.5 works as expected.
If you run into any errors, check the UPGRADE.md file. If you are upgrading from a version before 2.4.x, you also need to follow the upgrade steps of the previous versions.
Step 7: Upgrade to Symfony 6.1
This step is optional but recommended. After you have upgraded successfully to Sulu 2.5 you should have no problem also upgrading to Symfony 6. Depending on that all your other dependencies are also uptodate. Here again Rector will help you, depending if you had skiped step 1 and 2 you need to create or adjust or the rector.php in your project root directory to the following:
After this you are on the latest version of supported dependencies of Sulu. I recommend now to update your rector.php
with the following configuration to activate the code quality checks of Rector:
For future upgrades, just adjust your rector.php
to the desired version and Rector will do 90% of the work for you. Still, don't forget to follow the official upgrade docs and upgrade.md files of your dependencies.
Conclusion
With Rector and the sequence recommended here, we are keeping the update simple and focused on a single task. To me this is the most important thing when doing major upgrades.
Projects that keep Symfony and PHP up-to-date benefit here as they can simply skip the first two steps. And most of the work necessary will probably be in doing the Symfony upgrade from 4.4 to 5.4.
As always, we are happy to hear your feedback about this new release of Sulu CMS.
Feel free to create an issue or a discussion on GitHub for bugs and feature requests. You can also contact us via Slack or our website anytime.
Any problems?
The blog should give you step by step tutorial for upgrading. It still can happen that not all of your project changes are targetted. If you run into any problems make sure to read the UPGRADE.md of Sulu which lists all changes. A project mostly includes other dependencies then Sulu make sure if your composer update between any steps did a major version jump or you run into any issue to read the changelog and upgrade files of that specific library.