Porting TGMPA to my Namespace

TGMPA

Rubix Cube with WordPress LogoIf you are not familiar with TGMPA, if you are a WordPress admin you probably have installed themes and plugins that use it.

WordPress Core lacks the ability for a theme or plugin to recommend other plugins. TGMPA provides that capability.

To be honest, I’m not sure what the ‘TGM’ stands for, but the ‘PA’ stands for Plugin Activation.

WordPress Core does not make any use of namespaces, it may be because the first versions of WordPress had to run on PHP versions that did not support namespaces, I am not sure. Namespaces I believe did not exist until PHP 5.3.0 but I might be wrong about that.

Those developing classes for PHP would often emulate namespaces using a prefix followed by an underscore. You can see this in PEAR classes, for example, which definitely predate namespaces.

The problem is even though that reduces name collisions in classes, you either have to have a ridiculously long class prefix or the possibility of collisions exist.

With namespaces, you can have a long vendor prefix followed by a product prefix and the chances of an accidental collision is greatly reduced.

At one point, TGMPA used TGM_ as their prefix but another product also used TGM_ as their prefix, and both had a Utilities class named TGM_Utilities.

That’s why I really like namespaces. The same kind of thing can still happen, but it is much less likely to.

With that introduction out of the way, TGMPA is the perfect type of product to use with namespaced autoloading. Many different themes and plugins use it by including it in their own code in order to get functionality that probably should exist in WordPress Core. This results over time in many different versions existing and which one gets loaded is entirely a crap shoot depending upon which theme or plugin loads first. Problems can result.

By using a namespaced version of the class with an autoloader, my classes (when I am done with the port to namespacing) will not be impacted by TGMPA loaded by other themes and plugins, and at the same time, will not contribute to the problem. My plugins will just simply call the namespaced version and get exactly what they expect.

I’m not forking the entire project mind you, just the class-tgm-plugin-activation.php file that normally I would have to include in my plugins to use.

Porting to work with a PSR-4 autoloader means each class within the file needs to be split into its own file with a filename matching the class name. At the same, I am porting the classes to PSR-2 coding standard because that’s what I use, and I guarantee there will initially be problems that need to be solved as a result. Using PSR-2 makes it easier for me to find what is causing them with my existing tools that look at code, without me needing to adjust how those tools are configured. Basically porting them to PSR-2 cuts down on the noise in the output of those tools.

It should of course be noted that PHP itself does not care about tabs and spaces and camelCase or not or how phpdoc comments are formatted. It is just that I have adopted PSR-2 so for me, it is easier to work with code that uses PSR-2.

For the namespace I am using \AWonderPHP\TGMPA and since I am using a namespace, I am dropping the emulated namespace from the beginning of the class names.

Whenever porting a class that previously was in the root namespace to a specified namespace, you always have to go through the code and try to find each occurrence where the class called another class in the root namespace, because once the namespace has been declared, it will look for those classes in the declared namespace. So for example you have to change $foo = new stdClass() to $foo = new \stdClass() or PHP will look for a class named \AWonderPHP\TGMPA\stdClass() which of course does not exist.

For the PSR-4 autoloading, one class per file named after the class is enough but for PSR-2 compliance, the class names need to be UC first CamelCase and the methods in the class need to be LC first camelCase. Underscore is not used in CamelCase.

All the classes and methods in TGMPA follow the WordPress tradition of using completely lower cases letters for every word in the method name delimited by an underscore.

Fixing the class names was relatively easy, but fixing the method names is going to take some time just because of the sheer number of them. With each change, you have to go through and find everywhere they were called by the old name and fix it to use the new name, but you can’t just do a simple sed search and replace, because sometimes the method is named after a WordPress action it is related to and calls.

Once I have all the method names fixed, I have to start looking at what to do with the few functions that exist outside of classes. I may just put them in a static class.

Then will come the testing time, testing that it works both for how I currently use TGMPA and in scenarios I do not currently use, so I can find everything I broke with the change to namespaced autoloading.

Once it is all working as expected, the fun part of going through the code and removing everything that exists there for legacy versions of PHP. My classes require PHP 7.1 so I do not need to worry about older versions and it would be best to remove code only needed for legacy.

Then the real fun part comes. Testing what happens when using both the namespaced version on the same WordPress install that has a plugin that uses the upstream version.

Well, that’s what I’m working on. It will take awhile and is somewhat low priority, but that’s what I’m working on.

The work is in github in the TGMPA branch of my AWonderPHP project: https://github.com/AliceWonderMiscreations/AWonderPHP/tree/TGMPA

Note that it is not in my master branch. That won’t happen until it is stable.

2 thoughts on “Porting TGMPA to my Namespace

  1. I am *mostly* done with porting the PluginActivation class to PSR2 camelCase method names, but I have a strong feeling that when everything is working as intended, and I try it on a WordPress install that uses upstream root namespace TGMPA, I’ll discover I’ll need to change the `$GLOBALS[‘tgmpa’]` to something else, like $GLOBALS[‘awmtgmpa’] to avoid conflict.
    This comment box, not sure if it’s the theme or not, but it put blanks lines between everything even when the line wraps. I wonder if it supports Markdown. Doubt it, I’ll have to look at creating a comment box that does.

Leave a Reply

Your email address will not be published. Required fields are marked *

Anonymity protected with AWM Pluggable Unplugged