| 1 |
<?php |
| 2 |
/** |
| 3 |
* wp-abilities-api module — publishes the capability registry through the two |
| 4 |
* OPTIONAL WordPress-side consumers (spec 046, FR-010/FR-012). |
| 5 |
* |
| 6 |
* mcp-core (ToolRegistry) ──► AbilitiesBridge → wp_register_ability() |
| 7 |
* └──► McpAdapterBridge → the mcp-adapter plugin's server |
| 8 |
* |
| 9 |
* Both are adapters, never a source of truth. Each attaches only if its |
| 10 |
* dependency exists, and the absence of either is entirely normal and must |
| 11 |
* surface NO admin notice (FR-012): WordPress core's Abilities API is 6.9+ and |
| 12 |
* mcp-adapter is a separate plugin, while Templately supports WordPress 5.0+. |
| 13 |
* The whole point of splitting the built-in server out into `modules/mcp-server/` |
| 14 |
* is that those sites are fully supported without any of this. |
| 15 |
* |
| 16 |
* The module still boots when neither dependency is present — `Connection` backs |
| 17 |
* the Settings → MCP tab, which must be able to OFFER to install the adapter, so |
| 18 |
* it cannot be gated on the adapter already being there. (That is also why |
| 19 |
* there is no `get_requirements()` entry for the adapter class here.) |
| 20 |
* |
| 21 |
* @package Templately |
| 22 |
*/ |
| 23 |
|
| 24 |
namespace Templately\Modules\WpAbilitiesApi; |
| 25 |
|
| 26 |
use Templately\Core\Module_Base; |
| 27 |
use Templately\Modules\WpAbilitiesApi\Adapters\AbilitiesBridge; |
| 28 |
use Templately\Modules\WpAbilitiesApi\Adapters\McpAdapterBridge; |
| 29 |
use Templately\Modules\WpAbilitiesApi\REST\Connection; |
| 30 |
|
| 31 |
class Module extends Module_Base { |
| 32 |
|
| 33 |
public function get_name(): string { |
| 34 |
return 'wp-abilities-api'; |
| 35 |
} |
| 36 |
|
| 37 |
/** |
| 38 |
* Held back from the 3.8.0 release (2026-09-23) — see Module_Base::deferred_module_enabled(). |
| 39 |
* Delete this override to release it. |
| 40 |
*/ |
| 41 |
public function is_active(): bool { |
| 42 |
return Module_Base::deferred_module_enabled( $this->get_name() ); |
| 43 |
} |
| 44 |
|
| 45 |
/** |
| 46 |
* Declared (not incidental): both bridges project |
| 47 |
* `McpCore\Registry\ToolRegistry`'s descriptors outward, and `Connection` |
| 48 |
* uses `McpCore\Support\Permissions` for its permission callbacks. |
| 49 |
*/ |
| 50 |
public function get_dependencies(): array { |
| 51 |
return [ 'mcp-core' ]; |
| 52 |
} |
| 53 |
|
| 54 |
/** |
| 55 |
* The former inline symbol probes, expressed as sub-feature gates |
| 56 |
* (spec 053). Deliberately NOT `get_requirements()` entries: this module |
| 57 |
* must boot when both capabilities are absent — the Settings tab has to be |
| 58 |
* able to OFFER the adapter install (see the class doc block). |
| 59 |
*/ |
| 60 |
public function get_capability_gates(): array { |
| 61 |
return [ |
| 62 |
'abilities-bridge' => 'abilities-api', |
| 63 |
'adapter-bridge' => 'mcp-adapter-plugin', |
| 64 |
]; |
| 65 |
} |
| 66 |
|
| 67 |
protected function init_hooks(): void { |
| 68 |
if ( $this->has_gate( 'abilities-bridge' ) ) { |
| 69 |
AbilitiesBridge::attach(); |
| 70 |
} |
| 71 |
|
| 72 |
if ( $this->has_gate( 'adapter-bridge' ) ) { |
| 73 |
McpAdapterBridge::attach(); |
| 74 |
} |
| 75 |
|
| 76 |
// Registered UNCONDITIONALLY, unlike the bridges above, so the tab can |
| 77 |
// offer to install the adapter when it is missing. |
| 78 |
Connection::get_instance(); |
| 79 |
} |
| 80 |
} |
| 81 |
|