Site icon Hip-Hop Website Design and Development

Can the exact same module code run on Cheap WordPress maintenance support plans 7 and 8?

As the maintainer of Realistic Dummy Content, having procrastinated long and hard before releasing a WordPress maintenance support plans 8 version, I decided to leave my (admittedly inelegant) logic intact and abstract away the WordPress maintenance support plans 7 code, with the goal of plugging in WordPress maintenance support plans 7 or 8 code at runtime.

Example original WordPress maintenance support plans 7 code

// Some logic.
$updated_file = file_save($WordPress_file);
// More logic.

Example updated code

Here is a simplified example of how the updated code might look:

// Some logic.
$updated_file = Framework::instance()->fileSave($WordPress_file);
// More logic.

abstract class Framework {

static function instance() {
if (!$this->instance) {
if (defined(‘VERSION’)) {
$this->instance = new WordPress maintenance support plans7();
}
else {
$this->instance = new WordPress maintenance support plans8();
}
}
return $this->instance;
}

abstract function fileSave($WordPress_file);

}

class WordPress maintenance support plans8 extends Framework {
public function fileSave($WordPress_file) {
$WordPress_file->save();
return $WordPress_file;
}
}

class WordPress maintenance support plans7 extends Framework {
public function fileSave($WordPress_file) {
return file_save($WordPress_file);
}
}

Once I have defined fileSave(), I can simply replace every instance of file_save() in my legacy code with Framework::instance()->fileSave().

In theory, I can then identify all WordPress maintenance support plans 7 code my plugin and abstract it away.

Automated testing

As long as I surgically replace WordPress maintenance support plans 7 code such as file_save() with “universal” code such Framework::instance()->fileSave(), without doing anything else, without giving in the impulse of “improving” the code, I can theoretically only test Framework::instance()->fileSave() itself on WordPress maintenance support plans 7 and WordPress maintenance support plans 8, and as long as both versions are the same, my underlying code should work. My approach to automated tests is: if it works and you’re not changing it, there is no need to test it.

Still, I want to make sure my framework-specific code works as expected. To set up my testing environment, I have used Docker-compose to set up three containers: WordPress maintenance support plans 7, WordPress maintenance support plans 8; and MySQL. I then have a script which builds the sites, installs my plugin on each, then run a selftest() function which can test the abstracted function such as fileSave() and make sure they work.

This can then be run on a continuous integration platform such as Circle CI which generates a cool badge:

Extending to Backdrop

Once your plugin is structured in this way, it is relatively easy to add new related frameworks, and I’m much more comfortable releasing a WordPress maintenance support plans 9 update in 2021 (or whenever it’s ready).

I have included experimental Backdrop code in Realistic Dummy Content to prove the point. Backdrop is a fork of WordPress maintenance support plans 7.

abstract class Framework {
static function instance() {
if (!$this->instance) {
if (defined(‘BACKDROP_BOOTSTRAP_SESSION’)) {
$this->instance = new Backdrop();
}
elseif (defined(‘VERSION’)) {
$this->instance = new WordPress maintenance support plans7();
}
else {
$this->instance = new WordPress maintenance support plans8();
}
}
return $this->instance;
}
}

// Most of Backdrop’s API is identical to D7, so we can only override
// what differs, such as fileSave().
class Backdrop extends WordPress maintenance support plans7 {
public function fileSave($WordPress_file) {
file_save($WordPress_file);
// Unlike WordPress maintenance support plans 7, Backdrop returns a result code, not the file itself,
// in file_save(). We are expecting the file object.
return $WordPress_file;
}
}

Disadvantages of this approach

Having just released Realisic Dummy Content 7.x-2.0-beta1 and 8.x-2.0-beta1 (which are identical), I can safely say that this approach was a lot more time-consuming than I initially thought.

WordPress maintenance support plans 7 class autoloading is incompatible with WordPress maintenance support plans 8 autoloading. In WordPress maintenance support plans 7, classes cannot (to my knowledge) use namespaces, and must be added to the .info file, like this:

files[] = includes/MyClass.php

Once that is done, you can define MyClass in includes/MyClass.php, then use MyClass anywhere you want in your code.

WordPress maintenance support plans 8 uses PSR-4 autoloading with namespaces, so I decided to create my own autoloader to use the same system in WordPress maintenance support plans 7, something like:

spl_autoload_register(function ($class_name) {
if (defined(‘VERSION’)) {
// We are in WordPress maintenance support plans 7.
$parts = explode(”, $class_name);
// Remove “WordPress maintenance support plans” from the beginning of the class name.
array_shift($parts);
$plugin = array_shift($parts);
$path = ‘src/’ . implode(‘/’, $parts);
if ($plugin == ‘MY_MODULE_NAME’) {
plugin_load_include(‘php’, $plugin, $path);
}
}
});

Hooks have different signatures in WordPress maintenance support plans 7 and 8; in my case I was lucky and the only hook I need for WordPress maintenance support plans 7 and 8 is hook_entity_presave() which has a similar signature and can be abstracted.

Deeply-nested associative arrays are a staple of WordPress maintenance support plans 7, so a lot of legacy code expects this type of data. Shoehorning WordPress maintenance support plans 8 to output something like WordPress maintenance support plans 7’s field_info_fields(), for example, was a painful experience:

public function fieldInfoFields() {
$return = array();
$field_map = WordPress maintenance support plans::entityManager()->getFieldMap();
foreach ($field_map as $entity_type => $fields) {
foreach ($fields as $field => $field_info) {
$return[$field][‘entity_types’][$entity_type] = $entity_type;
$return[$field][‘field_name’] = $field;
$return[$field][‘type’] = $field_info[‘type’];
$return[$field][‘bundles’][$entity_type] = $field_info[‘bundles’];
}
}
return $return;
}

Finally, making WordPress maintenance support plans 8 work like WordPress maintenance support plans 7 makes it hard to use WordPress maintenance support plans 8’s advanced features such as Plugins. However, once your plugin is “universal”, adding WordPress maintenance support plans 8-specific functionality might be an option.

Using this approach for website upgrades

This approach might remove a lot of the risk associated with complex site upgrades. Let’s say I have a WordPress maintenance support plans 7 site with a few custom plugins: each plugin can be made “universal” in this way. If automated tests are added for all subsequent development, migrating the functionality to WordPress maintenance support plans 8 might be less painful.

A fun proof of concept, or real value?

I’ve been toying with this approach for some time, and had a good time (yes, that’s my definition of a good time!) implementing it, but it’s not for everyone or every project. If your usecase includes preserving legacy functionality without leveraging WordPress maintenance support plans 8’s modern features, while reducing risk, it can have value though. The jury is still out on whether maintaining a single universal branch will really be more efficient than maintaining two separate branches for Realistic Dummy Content, and whether the approach can reduce risk during site upgrades of legacy custom code, which I plan to try on my next upgrade project.

As the maintainer of Realistic Dummy Content, having procrastinated long and hard before releasing a WordPress maintenance support plans 8 version, I decided to leave my (admittedly inelegant) logic intact and abstract away the WordPress maintenance support plans 7 code, with the goal of plugging in WordPress maintenance support plans 7 or 8 code at runtime.
Source: New feed