Skip to content

🐛 fix: expose $this->plugin in Console commands#67

Open
dansleboby wants to merge 11 commits intowpbones:masterfrom
dansleboby:fix/console-command-plugin-access
Open

🐛 fix: expose $this->plugin in Console commands#67
dansleboby wants to merge 11 commits intowpbones:masterfrom
dansleboby:fix/console-command-plugin-access

Conversation

@dansleboby
Copy link
Copy Markdown
Contributor

  • Add protected $plugin property and setPluginAttribute() setter to Command
  • Fix loadWordPress() to use $currentDir (plugin root via $_SERVER['PWD']) instead of DIR for vendor/bootstrap paths, which was resolving to the wrong directory inside the vendor tree
  • Capture the return value of bootstrap/plugin.php so $this->plugin is populated after calling loadWordPress()
  • Add Kernel::setPlugin() to propagate the plugin instance to all registered command instances
  • Store plugin in BonesCommandLine and pass it to the kernel before dispatching custom commands

- Add protected $plugin property and setPluginAttribute() setter to Command
- Fix loadWordPress() to use $currentDir (plugin root via $_SERVER['PWD'])
  instead of __DIR__ for vendor/bootstrap paths, which was resolving to
  the wrong directory inside the vendor tree
- Capture the return value of bootstrap/plugin.php so $this->plugin is
  populated after calling loadWordPress()
- Add Kernel::setPlugin() to propagate the plugin instance to all
  registered command instances
- Store plugin in BonesCommandLine and pass it to the kernel before
  dispatching custom commands
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to make the plugin instance available inside custom console commands (via $this->plugin) by capturing it from bootstrap/plugin.php and propagating it through the console kernel, while also fixing WordPress/bootstrap path resolution when running commands from a plugin root directory.

Changes:

  • Add a $plugin property + setter on Console\Command, and populate it from bootstrap/plugin.php during loadWordPress().
  • Add Kernel::setPlugin() to inject the plugin instance into registered command instances.
  • Track the plugin instance in the bones CLI and pass it into the kernel before dispatching custom commands.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
src/Foundation/Console/Kernel.php Adds setPlugin() to propagate the plugin instance to registered command objects.
src/Console/bin/bones Stores plugin instance in the CLI runtime and attempts to pass it to the kernel before handling custom commands.
src/Console/Command.php Introduces a protected $plugin property + setter and updates loadWordPress() to use the working directory for vendor/bootstrap paths and to capture the plugin instance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Collaborator

@gfazioli gfazioli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR! I ran it on WPKirk-Boilerplate and the core feature works as advertised:

  • $this->plugin is correctly populated with a WPKirk\WPBones\Foundation\Plugin instance after $this->loadWordPress() in a custom command's handle().
  • No regression on --help, custom kernel commands (wp:sample, wpkirk:sample), code generators (make:controller), or the no-WordPress Docker-like deploy path (wpLoaded=false → graceful warning → deploy completes from an isolated /tmp dir).
  • It also fixes a pre-existing bug in Command::loadWordPress() where __DIR__ resolved inside the vendor tree for vendor/autoload.php and bootstrap/plugin.php — those were never being included. 👍

Before we merge I'd like to raise three observations. None are strict blockers but they would make the change more robust.

1. require_oncerequire semantics change

Switching to require is needed to capture the return value, but it's not idempotent. The current WPKirk boilerplate's bootstrap/plugin.php creates a brand new Plugin instance and fires do_action('wp-kirk_loaded') every time the file executes. In the single-invocation CLI flow it's not reached twice today, but if a custom command (or any downstream code) ends up calling loadWordPress() twice, you'd get double plugin instantiation and double action firing.

Safer alternatives:

  • Cache the instance inside bootstrap/plugin.php (static cache + return the cached instance on subsequent requires).
  • Keep require_once and resolve the instance via a container accessor / global function (e.g. WPKirk()) instead of relying on the require return value.

2. \$this->plugin can silently become int(1)

If class_exists('\WPKirk\WPBones\Foundation\Plugin') returns false inside bootstrap/plugin.php (e.g. right after a rename, before composer dump-autoload), the file returns nothing and PHP's require returns 1. So \$this->plugin becomes the integer 1 with no warning. A user then doing \$this->plugin->options or get_class(\$this->plugin) hits a confusing error — I actually ran into exactly this during testing.

Possible mitigations:

  • Type-guard in setPluginAttribute(): only assign if the value is an object.
  • Ensure bootstrap/plugin.php always returns either the instance or null (never falls through without a return).

3. The setPlugin() call in bin/bones is unreachable in the declared use case

BonesCommandLine::\$this->plugin is populated only inside the CLI's own loadWordPress(), which boot() only invokes for tinker and deploy. For custom kernel commands, boot() falls through to handle() without calling loadWordPress(), so \$this->plugin in the CLI stays null and the guarded \$this->kernel->setPlugin(\$this->plugin) never fires. The mechanism that actually exposes \$this->plugin to custom commands is Command::loadWordPress() (the command sets \$this->plugin on its own instance).

Not harmful, but the kernel setPlugin() + the guard in bin/bones end up being dead code unless a future flow loads WordPress in the CLI before dispatching kernel commands. Worth either documenting the intent or removing if not needed.


Test setup for reference: WPKirk-Boilerplate with the patch applied manually to vendor/wpbones/wpbones/... + a custom wpkirk:plugin-access command. After a fresh composer dump-autoload, \$this->plugin resolves to the expected WPKirk\WPBones\Foundation\Plugin object. Also re-ran on /tmp/no-wp-deploy-test/ (isolated, no WP parent) to confirm php bones deploy /path --pkgm=npm --no-build still completes cleanly via the graceful wpLoaded=false branch.

Happy to merge once we align on 1 and 2 (3 is cosmetic). Thanks again!

Copilot AI and others added 10 commits April 18, 2026 14:02
Agent-Logs-Url: https://github.com/dansleboby/WPBones/sessions/dca69aca-0215-425d-9f0e-49a1d7998433

Co-authored-by: dansleboby <4716382+dansleboby@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dansleboby/WPBones/sessions/dca69aca-0215-425d-9f0e-49a1d7998433

Co-authored-by: dansleboby <4716382+dansleboby@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dansleboby/WPBones/sessions/dca69aca-0215-425d-9f0e-49a1d7998433

Co-authored-by: dansleboby <4716382+dansleboby@users.noreply.github.com>
…pres

Harden CLI plugin bootstrap loading against re-execution and invalid return types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants