Skip to content

Give consumer-a the template's footprint, loader and definitions - #60

Merged
ahegyes merged 4 commits into
trunkfrom
refactor/consumer-a-parity
Oct 28, 2026
Merged

ahegyes merged 4 commits into
trunkfrom
refactor/consumer-a-parity

Conversation

@ahegyes

@ahegyes ahegyes commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

Summary. The plugin template now copies consumer-a's anatomy, and three of consumer-a's shapes did not survive the copy: its definitions declared a container parameter they never read, which the production PHPCS profile reports, its footprint sat in the composition root and missed part of what its own framework roots store, and it had no loader for includes/. consumer-a and the definitions in consumer-b, the core persona and core's README now match the template.

  • Definitions: the six definition closures take no parameter, and convention 2 says a definition takes ContainerInterface $c only when it reads the container. PHP-DI passes the container either way.
  • Footprint: Footprint::DATA in src/Footprint.php replaces Plugin::FOOTPRINT and adds the transients PluginBoot records boot failures in, AdminNotices' user options and network-wide user meta, and its network notices option on a network.
  • Loader: functions.php requires every includes/*.php in name order, skipping names that start with an underscore, and throws when the directory cannot be read, so the entry reports an incomplete build.

Fixtures +94 −29 (7 files), tests +16 (3 files), core README +1 −2, AGENTS.md +1 −1.

Review points.

  • The footprint leaves out the bootstrap updater's release cache, which carries the text domain and expires on its own (convention 8); the docblock says the footprint covers the plugin's data under its prefix.
  • includes/_unloaded.php exists only so the boot row can see the underscore skip.

Testing.

  • composer quality-check passes: validate, changelog validation, PHPCS on both profiles, the four PHPStan profiles and the seven fixtures' PHPStan, Unit 189 and Integration 1333.
  • composer test:integration:multisite passes: 40. composer test:integration:lowest passes: 33. composer test:integration:php74 passes: 2.
  • The consenting uninstall row seeds and checks a row of each added kind, and the rows for an engine that cannot run gain a build without src/Footprint.php; hand mutants (a footprint kind removed, a loader without the underscore skip) fail them.

Convention 2 spelled every definition as static fn ( ContainerInterface
$c ), so consumer-a, consumer-b and the core persona declared $c in six
closures that never read it. Under the production PHPCS profile each
one is a Generic.CodeAnalysis.UnusedFunctionParameter warning, which
fails the run: the plugin template, built from consumer-a's anatomy,
reported four of them, while the fixtures passed only because they sit
under the tests profile, which excludes the sniff. PHP-DI calls a
factory with the container whether or not it declares the parameter,
and PHP ignores extra arguments to a closure.

The six closures take no parameter, their docblocks return
\Closure(): object, and core's README excerpt follows its persona.
Convention 2 now reads that definitions are static closures, taking
ContainerInterface $c only when they read the container, or
autowiring.

Assisted-by: Claude Code:claude-opus-5-5
consumer-a declared its footprint as Plugin::FOOTPRINT, which put
uninstall data in the composition root, and its one option prefix
missed part of what its own roots store: the transients PluginBoot
records boot failures in, AdminNotices' user options and network-wide
user meta, and, on a network, its network notices option. A consenting
uninstall therefore kept those rows, and the plugin template, which
takes consumer-a's anatomy, would have copied the gap.

The footprint is now Footprint::DATA in src/Footprint.php, beside
Migrations::STEPS, and covers those kinds through the transient
variants of the prefix, the site and global user meta prefixes and the
network notices option. The consenting uninstall row seeds and checks
one row of each, and the rows for an engine that cannot run gain a
build without src/Footprint.php.

Assisted-by: Claude Code:claude-opus-5-5
The plugin template's functions.php requires every includes/*.php in
name order and skips names that start with an underscore, so a plugin
can park a file there without loading it; consumer-a, the anatomy the
template follows, loaded only safeguards.php, from its entry.

consumer-a's functions.php now runs the same loader, throwing when the
directory cannot be read so the entry's build-error handling reports
it, and ships includes/_unloaded.php, whose function the boot row
asserts is never defined.

Assisted-by: Claude Code:claude-opus-5-5
The docblock said the footprint covers every transient the plugin and
its framework components write, but the bootstrap updater caches its
releases under the text domain, in {slug}_github_release_{channel},
which expires on its own and which the footprint leaves out on
purpose.

The docblock now names what the footprint covers: the plugin's data
under its prefix.

Assisted-by: Claude Code:claude-opus-5-5
@ahegyes ahegyes changed the title Refactor/consumer a parity Give consumer-a the template's footprint, loader and definitions Oct 28, 2026
@ahegyes
ahegyes merged commit 443461d into trunk Oct 28, 2026
23 checks passed
@ahegyes
ahegyes deleted the refactor/consumer-a-parity branch October 28, 2026 13:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant