If you’ve been watching our support area lately you probably have noticed the last month has been a complicated time for us dealing with numerous cases of reporting menus disappearing from sites using our Advanced Sidebar Menu plugin.
With 10s of thousands of websites using the plugin and thousands of sites using widget settings in various states from more than 10 years of installs, tracking an issue can sometimes be a daunting task requiring careful analysis and resolution.
Now that things have calmed down and we have resolved every known case of the issue we wanted to be as transparent as possible with what went wrong, what we did to fix the issues, and how we’re preventing them in the future.
Problem #1
Back in March we released version 9.5 of the plugin. Part of this release included a new title and exclude panel which looks like this:
Advanced Sidebar
Title used for this page’s link when it is displayed in the Advanced Sidebar menus.
Exclude this page from all Advanced Sidebar menus.
The concept behind introducing a new panel was to use native Gutenberg panels instead of a meta box for Advanced Sidebar settings. Using a native panel allows Gutenberg to load the editor in an iframe, among other improvements.
The title and excluded settings are stored in post meta which is handled a bit differently in Gutenberg panels vs a legacy meta box. Meta values are updated using the REST API which does not support sending a delete request for meta value without deleting the entire post. You may however delete a meta key by sending a null
value to the endpoint. I realize there is a lot of technical jargon here, but the main takeaway is a checkbox or toggle is expected to have a true/false
value, not a null
value.
When a page is not excluded, the excluded key is deleted from the page’s post meta. It is done this way to greatly improve the queries required to handle excluding of pages. The first implementation of the new Gutenberg panel used null
to delete the excluded key when toggled off. We didn’t realize at the time the block editor expects a true/false
for toggle and does not know how to handle the null
value.
If you toggle excluded to on then toggle it back to off, the block editor thinks the value has changed and will set the meta value to “”. Advanced Sidebar Menu knows the value did not change so it did not change the “” to null
and you end up with a “” in the database which broke the exclude queries.
We discovered the issue fairly quickly and implemented the following solution:
- Changed the toggle to use
true/false
instead oftrue/null
. - Moved the deleting of the meta data to the plugin.
- Added several unit tests to our automated test suite to make sure this does not happen again.
- Introduced an automatic migration script to the plugin to fix affected sites.
The solutions were released in versions 9.5.1 and 9.5.2.
Problem #2
As part of our initiative to convert the plugin to modern strict types and a fully static analyzable codebase, we have been periodically improving various code. One of our focuses has been to remove calls to the PHP empty
function due to loose comparison nature and ensuing side effects.
One of the conditions which was updated in version 9.5 was changed from an empty
condition to checking for an empty ''
string when checking to see if a post type had been set in the block or widget settings. Based on the state of the code at the time of version 9.5 it appeared this condition would have no side effects as there were no paths which would return anything other than a post type or an empty string.
Going back through the logs we discovered that years ago the widget’s post type setting used to use “0” as the default value instead of “page” as it is today. Back in version 9.0 (2022) we improved the widget settings to only store a real post type value and no longer store “0.”
For widgets using the default value for post type and had not been changed since version 9.0, the value remained “0” and when compared against ''
the “0” value was treated as a post type which broke the queries used to retrieve the pages.
This problem took us a while to track down. In fact it took getting a database dump from one of our users to understand how the pages could be missing widgets after a plugin update.
We implemented the following solutions:
- No longer check the value type in favor of checking for an available post type before using the value stored in the widget.
- Added several unit tests to our automated test suite to make sure this does not happen again.
No data migration is required. The solutions were introduced in version 9.5.4.
In Closing
Sadly there is no perfect process for updating plugin, theme, or WordPress core code. As time goes on our test suite becomes more and more verbose lowering the probability of bugs being introduced with releases.
It has always been a complicated trade off between releasing new modern features and maintaining backward compatibility with ever changing WordPress core and the plugin ecosystem. We remain dedicated to producing plugins of the highest quality and standards.