Renaming a Field Type Class

Renaming a field type’s class name (or its namespace) can be a little tricky when it comes to updating existing fields:

  • Updating the type values in the fields table is insufficient, because those changes won’t automatically effect the project config. The project-config/rebuild command would need to be run afterward, which could be easily overlooked.
  • Updating the fields’ config arrays within the project config isn’t very practical either, because field configs aren’t stored centrally. (Global fields are stored under fields, but Matrix sub-fields are stored within their block type configs, etc.)

Therefore it’s recommended that field classes aren’t immediately renamed at all. Instead, the old class name should be registered as an alias of the new class name, using class_alias().

Register the legacy autoload root #

If the plugin’s root namespace has changed (e.g. acme\myplugin\bigco\myplugin\), the plugin will need to add the old root namespace to its autoload array within composer.json, pointed to a separate source folder such as src-legacy/:

{
  "autoload": {
    "psr-4": {
      "bigco\\myplugin\\ "src/",
      "acme\\myplugin\\": "src-legacy/"
    }
  },
  "...": "..."
}

Make the old class autoloadable #

For Composer’s autoloader to continue supporting the old class, it must be able to find it. So create a file with the same name as the old class name, in the appropriate directory based on the PSR-4 autoloading standard.

For example, if the old class name was acme\myplugin\fields\MyField and there’s a registered namespace root for acme\myplugin\ pointed to src-legacy/, that file should be located at src-legacy/fields/MyField.php.

The file should contain a class definition (wrapped within a false condition so it never actually gets executed), plus a class_exists() call, which will cause the new class to get autoloaded:

namespace acme\myplugin\fields;

if (false) {
    class MyField {}
}

class_exists(\bigco\myplugin\fields\MyField::class);

Register the class alias #

Finally, register the class alias at the end of the new field type’s PHP file:

namespace bigco\myplugin\fields;

class MyField {
    // ...
}

class_alias(MyField::class, \acme\myplugin\fields\MyField::class);

With that in place, if any fields are still set to the old class name, the autoloader will initially load the old field class’ PHP file, which in turn will load the new class and the alias, and the new class will be used instead.

Applies to Craft CMS 3.