Repository navigation
Prepare the template for plugins that succeed a 1.x release - #21
Merged
Merged
Conversation
A peer plugin had no supported way to read the plugin's slug, name or version. The slug lived only on Plugin::SLUG and the version only in the header, so a peer had to reach into the composition root's class or parse the header itself, which ties it to code the plugin is free to change. A plugin that succeeds a 1.x release also needs a home for that release's name and version functions, which peer plugins call. includes/metadata.php defines dws_tpl_get_plugin_slug(), dws_tpl_get_plugin_name() and dws_tpl_get_plugin_version(). Each reads only the header through get_file_data(), the slug as its Text Domain, so a getter that a partial deploy has already defined still answers when a later include throws, which a PartialDeployTest row checks. The name is translated only once init has fired, because WordPress flags translations loaded earlier, and through __() rather than get_plugin_data(), whose kses pass turns an & into &. AGENTS.md and docs/ARCHITECTURE.md name the file, the tests README's Integration row names the getters, and the add-on convention tells an add-on to call them from plugins_loaded on, behind function_exists(). Assisted-by: Claude Code:claude-opus-5-5
uninstall.php named the main file by its source name. A release that ships the main file under another name, as a plugin keeping its 1.x main file must, would leave the floor check reading a file that does not exist: get_file_data() then returns empty floors, which pass, so the uninstall engine would run on a site below the plugin's floors and be handed a missing plugin file. WP_UNINSTALL_PLUGIN cannot stand in for the name, because a bulk uninstall defines it once, for the first plugin it visits. uninstall.php takes the one PHP file in its folder that carries a Plugin Name header, and keeps the data when it finds none or several. An UninstallTest row runs the script with WP_UNINSTALL_PLUGIN naming another plugin and the main file renamed under a PHP floor no site meets, and expects the below-floor log line. Assisted-by: Claude Code:claude-opus-5-5
A plugin that succeeds a 1.x release whose main file was bootstrap.php must keep shipping that file, or the update deactivates it on every site. Nothing in the template said how, and the release workflow is one the fill-in never edits. The wordpress.org recipe gains a step that passes the old name as the release's archive-entry-file, with the comment its caller carries, and says why the rename suits only wordpress.org distribution: the GitHub updater reads the next release's floors from the main file at the tag, under its installed name. Assisted-by: Claude Code:claude-opus-5-5
4 of 10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three changes that a plugin succeeding a 1.x release needs, one commit each:
a peer plugin had no supported way to read the plugin's slug, name or version, short of the
Pluginclass or parsing the header;uninstall.phpnamed the main file by its source name, so a release shipping it under another name would run the floor check on a missing file, whose empty floors pass;nothing told such a plugin how to keep shipping its 1.x main file's name.
Peer getters:
includes/metadata.phpaddsdws_tpl_get_plugin_slug(),dws_tpl_get_plugin_name()anddws_tpl_get_plugin_version().get_file_data(), so a getter that a partial deploy has defined still answers when a later include throws.__()onceinithas fired, and keeps an&as written, whichget_plugin_data()'s kses pass would encode.plugins_loadedon, since an add-on may load first, and behindfunction_exists(), since a base plugin below its floors or with a partial build may not define them. AGENTS.md's layout,docs/ARCHITECTURE.mdand the tests README name the file.Uninstall:
uninstall.phptakes the one root*.phpin its folder that carries aPlugin Nameheader.WP_UNINSTALL_PLUGINcannot name it, because a bulk uninstall (delete_plugins(),wp plugin uninstall a b) defines it once, for the first plugin it visits. With none or several header files, the uninstall keeps the data.Recipe: the wordpress.org recipe gains a step that passes the 1.x name as the release's
archive-entry-file(Let a release ship the main plugin file under another name wordpress-configs#58), with its reason comment. It also says why the rename suits only wordpress.org distribution: the GitHub updater reads the next release's floors from the main file at the release tag, under its installed name.Code +68 −1 (2 files), tests +92 −1 (4 files), docs +10 −3 (3 files).
Type of change
Checklist
composer changelog:add): none; the v2 rebuild ships as "Initial release."MetadataTest: the slug and version against what WordPress lists, the name translated afterinitwith an&in the translation, and the name untranslated beforeinit;PartialDeployTest: withsrc/Plugin.phphidden,options.phpthrows aftermetadata.phphas loaded, and the getters still answer in that request;UninstallTest: withWP_UNINSTALL_PLUGINnaming another plugin and the main file renamed under a PHP floor no site meets, the uninstall logs that the site is below its floors.composer quality-checkpasses locallyBreaking changes for forks
Plugin Nameheader keeps its data on uninstall, since the main file cannot be told apart.Review points.
3cbd985, which lacksarchive-entry-file. Move the wordpress-configs pins to its current trunk #22 moves the pins to the merge of Let a release ship the main plugin file under another name wordpress-configs#58 and drops the recipe step's "from a wordpress-configs version that has the input".PartialDeployTestandUninstallTestrows renamesrc/Plugin.phpor the main file for one request or process and restore them infinally. A run killed mid-row can leave a.hiddenfile or abootstrap.phpbehind.Testing.
composer quality-checkpasses: validate, changelog validation, PHPCS on both profiles, PHPStan, Unit 6 and Integration 81.npm run test:e2epasses (3 of 3), andlint:scripts,lint:stylesandlint:typesare clean.includes/metadata.phpanduninstall.phpparse on PHP 7.4.&, the slug getter fataled withsrc/Plugin.phpmissing, and the uninstall read its floors from the source name, then from the other plugin's file.