I had taken over the maintenance on these sites in early 2017. By early 2018 it had become clear that as their client base was growing the demands of the traffic were not being met by the existing code base.
Over and above that, the functionality had all been written as one monolithic plugin which was a nightmare to maintain and often fixing one part led to breaking another.
In March 2018 we set out to do a complete redesign, my working on the backend, PHP, plugin code and Mike from Hive Minder working on the front end and design.
Goals of this WordPress Redevelopment Project
We had several goals:
- Split the plugin into several plugins (similar to micro services)
- Code closer to WordPress standards
- Use existing plugins with proven track records where available
- Be able to scale during peak times
Split the plugin into several plugins
A competition has several parts to it: entrants and entries, competitions (start date, end date, etc), voters, payments, etc
The existing code base I inherited had everything in one huge plugin file. This was an absolute nightmare to maintain. We decided to split this into several plugins. An entries plugin to manage entrant and entries. A competition plugin to manage admin of competitions (dates, winners, etc). A voters plugin to manage votes (we decided not to include that functionality into the entries plugin because we needed to code up a few different ways for voters to vote and want to keep each plugin as small as possible).
We also included a payments plugin because whereas the existing site only allowed votes to vote by sending premium rated sms, we wanted to allow other voting options like direct bank payments, snap scan, credit card, paypal, etc.
The payment plugin had a base class and each payment gateway had their own derived classes. In this way, the gateways worked almost like plugins to the plugin.
Splitting the plugin up into various plugins will make maintenance much much simpler. We wanted to implement a similar approach to micro services.
Each plugin should be responsible for what it does and other plugins should not directly touch the database for that plugins data. Data should only be manipulated through built in wordpress functions (like get_postmeta) or through an API class in each plugin.
Code closer to WordPress standards
Another issue with the existing site is that many functions were written in custom PHP code and replaced built in wordpress functionality. As one example, viewing the entries in the wordpress admin dashboard’s CPT for entries, the listing looked similar to the normal post’s entries page in WordPress, but looking at the code it was a complete rewrite.
This was done so that they could display additional columns in the list page. In this particular case we simply added the wordpress filter manage_CPT_posts_columns and action manage_CPT_posts_custom_column. To add in our new columns:
By coding using built in wordpress functions, hook, actions, filters, etc we not only future proof our application, but we make it much easier for future developers to built and maintain.
Use existing plugins with proven track records where available
I’m a big believer in not reinventing the wheel. This is a competition entries site and as such it needs a web form to gather entrant. In the old code base, this form was generated by a custom form generator, and as established from above, I don’t like putting in custom code when there is already existing functions.
So, we used contact form 7. However, this is not just a simple use case of contact form 7. Things need to happen when someone completes the form.
Entries need to be created, images need to be uploaded, entries need to be verified.
Also, we don’t want the admin team to manually create the contact forms because we expect certain fields to be present. In the end we added functions that the admin can simply click a button to create their contact form 7 form, based on the competition site. From there they can add fields if they require them, but the basic required fields would be left in tact
User selects which contact form 7 to create:
Contact form 7 is automatically created:
We also hook into the contact form 7 hooks to grab the content and verify and create posts.
Be able to scale during peak times
Twice a year they run annual competitions which attract a huge amount of attention. This is in the order of black friday. During the last such competition the server bombed out in the first hour and only came back up when we had a whole new bigger server installed. This took hours and for most of the first day the site was down.
This year we want to be prepared for that!
We have moved this annual competition from our Apache hosting server and create and Amazon AWS EC2 server. We installed Nginx rather than Apache.
The EC2 instance was saved as an image so we could quickly set up new servers if needed.
We then setup an Amazon load balancer in front of that to evenly distribute requests over these servers. Of course this leads to the problem of keeping data in sync between various servers in a group.
For the database data that’s not really an issue. We set up a single AWS MySQL instance and point all server images to it. But image uploads when user’s enter is another story. How do we ensure that an image uploaded on one server is available to the other servers in the group?
Enter “WP Offload S3 Lite” plugin. This plugins allows you to send your media files to an Amazon S3 bucket. This was, entries images are sent directly to an S3 bucket and served from their.
In front of this whole lot we put Cloud Flare. This gives us a great caching server, SSL and local edge servers in our country.
In our bombardier tests we went from being able to serve about 200 requests a second directly from our hosting server to being able to server about 15 000 requests a second through Cloud Flare -> AWS load balancer -> 5 micro EC2 servers.
That is a massive, massive improvement.
The proof is yet to come. Tomorrow the competition entries open and in May the voting starts. We’ll see how well our new site and server set up copes.
All things considered, buy sticking to WordPress functionality and well known plugins, as well as a different server architecture we’re confident that this WordPress site will handle well under big loads.
John McMurray is a freelance PHP developer. Experienced in PHP, Laravel and WordPress he can code anything you need.
Based in Plettenberg Bay, Western Cape I am available for PHP, Laravel or WordPress freelance jobs in Johannesburg, Pretoria, Cape Town, Port Elizabeth. I also often do remote PHP freelance work all over South Africa and the rest of the world.