A client recently asked me to setup a Silverstripe site on their server. They were in the process of getting the files and database extract to me and then I would be good to go. I hadn’t used Silverstripe since 2008 but figured, why not? Setting it up on a new server shouldn’t be too much of an issue…oh boy, was I wrong!
After a while, I received the files and a database dump. Everything seemed ok although I was surprised to see an included vendor folder. I checked the composer.json file to see what I was working with and well, I was a little concerned. PHP was set to 5.6 and all but two requirements were set to dev-master and silverstripe/recipe-cms was set as 4.2.*, released sometime in 2018.
Get it working
OK, so the developers had installed Silverstripe in 2018 and never felt the need to upgrade it, not even once. So I thought, I’ll set up a dev environment and get going.
I created a Docker container with PHP5.6, MySQL 5.7, and a few extensions. I copied everything in, including the vendor folder and managed to get a half working website running. It wasn’t quite as easy as described as I needed to work out what extensions I needed and fix a couple of minor bugs, but the site was working.
I thought cool, now I can start upgrading the site. It was at this point I recalled every dependency was set to dev-master. So the first step was to set the correct version for each dependency. Well, the version as of 2018 and get a composer install to work.
I checked the installed.json inside vendor/composer and found the commit hash for each dependency. I then found the related version on GitHub and updated the composer.json. This was tedious work; however, I figured I was working towards getting a working composer.json. When done, I discovered this wasn’t going to work; the provided composer.json did not create the included vendor directory and there was too much stuff missing.
I decided to go back to basics and create a brand-new composer.json including every package listed in vendor/composer/installed.json. Eventually I got to the point where I could run composer install with no vendor directory or composer.lock file and get a working vendor directory. Awesome!
Although this worked, I couldn’t yet start upgrading as there was too much listed in my composer.json. I started checking each package to see if it was a core requirement or a dependency of something else and pruned the composer.json file down to the bare minimum. Several hours later, I again had a working composer.json file.
A day in and I had a working Silverstripe site, running on PHP5.6 and MySQL 5.7. I was also confident I could clear the “vendor” directory and recreate it. As joyous as I was, I was no further along. I couldn’t put this online as I needed it to be running PHP8.0 at a minimum and MySQL8. Additionally, I was having to use composer 1.10.26 – that also had to change.
I started the upgrade process; I went step by step starting at 4.2.0 all the way up to version 4.10.0. At each release, I would trash the vendor directory and composer.lock file and see if I ended up with a working site. It was slow as I kept needing to tweak things. Every time Silverstripe added support for an updated version of PHP, I would rebuild my Docker container and test again, slowly fixing bugs and correcting dependencies as I went. As soon I was running PHP8, I switched to MySQL 8 and manually updated the database schema.
Stable & Supportable
The site is now sitting on a staging server for the client. There are a few small issues here and there that I need to fix, and I need to continue upgrading to the latest version of Silverstripe, however, for now, this client is happy.
The moral of the story – upgrade your stuff. If you are selling a website to a client, at least have the decency to upgrade it. Handing them a hot mess four years later is disgusting and the “development house” in question should be ashamed of themselves.
I’m not going to name the “development house” as I don’t know if this was a one off. I expect not but it isn’t for me say as I never dealt with them directly, I just had to pick up the mess.