| 1 |
<?php |
| 2 |
/** |
| 3 |
* Abilities Registrar. |
| 4 |
* |
| 5 |
* Orchestrates registration of all SureForms abilities |
| 6 |
* with the WordPress Abilities API (WP 6.9+). |
| 7 |
* |
| 8 |
* @package sureforms |
| 9 |
* @since 2.5.2 |
| 10 |
*/ |
| 11 |
|
| 12 |
namespace SRFM\Inc\Abilities; |
| 13 |
|
| 14 |
use SRFM\Inc\Abilities\Analytics\Get_Form_Analytics; |
| 15 |
use SRFM\Inc\Abilities\Entries\Bulk_Get_Entries; |
| 16 |
use SRFM\Inc\Abilities\Entries\Delete_Entry; |
| 17 |
use SRFM\Inc\Abilities\Entries\Get_Entry; |
| 18 |
use SRFM\Inc\Abilities\Entries\List_Entries; |
| 19 |
use SRFM\Inc\Abilities\Entries\Update_Entry_Status; |
| 20 |
use SRFM\Inc\Abilities\Forms\Create_Form; |
| 21 |
use SRFM\Inc\Abilities\Forms\Delete_Form; |
| 22 |
use SRFM\Inc\Abilities\Forms\Duplicate_Form as Duplicate_Form_Ability; |
| 23 |
use SRFM\Inc\Abilities\Forms\Get_Form; |
| 24 |
use SRFM\Inc\Abilities\Forms\Get_Form_Stats; |
| 25 |
use SRFM\Inc\Abilities\Forms\Get_Shortcode; |
| 26 |
use SRFM\Inc\Abilities\Forms\List_Forms; |
| 27 |
use SRFM\Inc\Abilities\Forms\Update_Form; |
| 28 |
use SRFM\Inc\Abilities\Settings\Get_Global_Settings; |
| 29 |
use SRFM\Inc\Abilities\Settings\Update_Global_Settings; |
| 30 |
use SRFM\Inc\Traits\Get_Instance; |
| 31 |
|
| 32 |
if ( ! defined( 'ABSPATH' ) ) { |
| 33 |
exit; // Exit if accessed directly. |
| 34 |
} |
| 35 |
|
| 36 |
/** |
| 37 |
* Abilities_Registrar class. |
| 38 |
* |
| 39 |
* @since 2.5.2 |
| 40 |
*/ |
| 41 |
class Abilities_Registrar { |
| 42 |
use Get_Instance; |
| 43 |
|
| 44 |
/** |
| 45 |
* Constructor. |
| 46 |
* |
| 47 |
* Bails early if wp_register_ability() is not available (WP < 6.9). |
| 48 |
* |
| 49 |
* @since 2.5.2 |
| 50 |
*/ |
| 51 |
public function __construct() { |
| 52 |
// Graceful degradation for WP < 6.9. |
| 53 |
if ( ! function_exists( 'wp_register_ability' ) ) { |
| 54 |
return; |
| 55 |
} |
| 56 |
|
| 57 |
add_action( 'wp_abilities_api_categories_init', [ $this, 'register_category' ] ); |
| 58 |
add_action( 'wp_abilities_api_init', [ $this, 'register_abilities' ] ); |
| 59 |
|
| 60 |
if ( self::mcp_adapter_enabled() ) { |
| 61 |
add_action( 'mcp_adapter_init', [ $this, 'register_mcp_server' ] ); |
| 62 |
} |
| 63 |
} |
| 64 |
|
| 65 |
/** |
| 66 |
* Check if the MCP adapter integration should be active. |
| 67 |
* |
| 68 |
* @since 2.6.0 |
| 69 |
* @return bool |
| 70 |
*/ |
| 71 |
public static function mcp_adapter_enabled() { |
| 72 |
return function_exists( 'wp_register_ability' ) && |
| 73 |
class_exists( 'WP\MCP\Plugin' ) && |
| 74 |
(bool) get_option( 'srfm_mcp_server', false ); |
| 75 |
} |
| 76 |
|
| 77 |
/** |
| 78 |
* Register a dedicated SureForms MCP server with the MCP adapter. |
| 79 |
* |
| 80 |
* Creates endpoint: {site_url}/wp-json/sureforms/v1/mcp |
| 81 |
* |
| 82 |
* @param \WP\MCP\Adapter\Adapter $adapter The MCP adapter instance. |
| 83 |
* @since 2.6.0 |
| 84 |
* @return void |
| 85 |
*/ |
| 86 |
public function register_mcp_server( $adapter ) { |
| 87 |
// wp_get_abilities() is a WP 6.9+ Abilities API function. This method is only hooked |
| 88 |
// when mcp_adapter_enabled() is true, which itself requires function_exists( 'wp_register_ability' ), |
| 89 |
// so it is inert on WP 6.4-6.8. Plugin Check's static WP-version check reports a false positive here. |
| 90 |
$abilities = wp_get_abilities(); |
| 91 |
$tools = []; |
| 92 |
|
| 93 |
foreach ( $abilities as $ability ) { |
| 94 |
if ( 0 === strpos( $ability->get_name(), 'sureforms/' ) ) { |
| 95 |
$tools[] = $ability->get_name(); |
| 96 |
} |
| 97 |
} |
| 98 |
|
| 99 |
$transport_class = class_exists( '\WP\MCP\Transport\HttpTransport' ) |
| 100 |
? \WP\MCP\Transport\HttpTransport::class |
| 101 |
: \WP\MCP\Transport\Http\RestTransport::class; |
| 102 |
|
| 103 |
$adapter->create_server( |
| 104 |
'sureforms', |
| 105 |
'sureforms/v1', |
| 106 |
'mcp', |
| 107 |
__( 'SureForms MCP Server', 'sureforms' ), |
| 108 |
__( 'SureForms MCP Server for form building and management.', 'sureforms' ), |
| 109 |
SRFM_VER, |
| 110 |
[ $transport_class ], |
| 111 |
\WP\MCP\Infrastructure\ErrorHandling\ErrorLogMcpErrorHandler::class, |
| 112 |
\WP\MCP\Infrastructure\Observability\NullMcpObservabilityHandler::class, |
| 113 |
$tools, |
| 114 |
[], |
| 115 |
[] |
| 116 |
); |
| 117 |
} |
| 118 |
|
| 119 |
/** |
| 120 |
* Register the sureforms ability category. |
| 121 |
* |
| 122 |
* Uses wp_has_ability_category() guard to avoid collision with zipwp-mcp. |
| 123 |
* |
| 124 |
* @since 2.5.2 |
| 125 |
* @return void |
| 126 |
*/ |
| 127 |
public function register_category() { |
| 128 |
// wp_has_ability_category() / wp_register_ability_category() are WP 6.9+ Abilities API |
| 129 |
// functions, each called only behind its own function_exists() guard, so they are inert |
| 130 |
// on WP 6.4-6.8. Plugin Check's static WP-version check reports false positives here. |
| 131 |
if ( function_exists( 'wp_has_ability_category' ) && wp_has_ability_category( 'sureforms' ) ) { |
| 132 |
return; |
| 133 |
} |
| 134 |
|
| 135 |
if ( function_exists( 'wp_register_ability_category' ) ) { |
| 136 |
wp_register_ability_category( |
| 137 |
'sureforms', |
| 138 |
[ |
| 139 |
'label' => __( 'SureForms', 'sureforms' ), |
| 140 |
'description' => __( 'Form building and management abilities powered by SureForms.', 'sureforms' ), |
| 141 |
] |
| 142 |
); |
| 143 |
} |
| 144 |
} |
| 145 |
|
| 146 |
/** |
| 147 |
* Register all SureForms abilities. |
| 148 |
* |
| 149 |
* Uses the srfm_register_abilities filter to allow third-party plugins |
| 150 |
* to add their own abilities that extend Abstract_Ability. |
| 151 |
* |
| 152 |
* @since 2.5.2 |
| 153 |
* @return void |
| 154 |
*/ |
| 155 |
public function register_abilities() { |
| 156 |
// Bail early if the master Abilities API toggle is off. |
| 157 |
if ( ! get_option( 'srfm_abilities_api', false ) ) { |
| 158 |
return; |
| 159 |
} |
| 160 |
|
| 161 |
$abilities = [ |
| 162 |
new List_Forms(), |
| 163 |
new Create_Form(), |
| 164 |
new Get_Form(), |
| 165 |
new Get_Shortcode(), |
| 166 |
new Delete_Form(), |
| 167 |
new Duplicate_Form_Ability(), |
| 168 |
new Update_Form(), |
| 169 |
new Get_Form_Stats(), |
| 170 |
new List_Entries(), |
| 171 |
new Get_Entry(), |
| 172 |
new Bulk_Get_Entries(), |
| 173 |
new Update_Entry_Status(), |
| 174 |
new Delete_Entry(), |
| 175 |
new Get_Global_Settings(), |
| 176 |
new Update_Global_Settings(), |
| 177 |
new Get_Form_Analytics(), |
| 178 |
]; |
| 179 |
|
| 180 |
/** |
| 181 |
* Filters the list of abilities to register. |
| 182 |
* |
| 183 |
* Third-party plugins can add their own abilities by hooking into this filter. |
| 184 |
* Each ability must extend SRFM\Inc\Abilities\Abstract_Ability. |
| 185 |
* |
| 186 |
* @param array<Abstract_Ability> $abilities Array of ability instances. |
| 187 |
* @since 2.5.2 |
| 188 |
*/ |
| 189 |
$abilities = apply_filters( 'srfm_register_abilities', $abilities ); |
| 190 |
|
| 191 |
foreach ( $abilities as $ability ) { |
| 192 |
if ( ! $ability instanceof Abstract_Ability ) { |
| 193 |
continue; |
| 194 |
} |
| 195 |
|
| 196 |
// Enforce minimum capability policy — reject abilities with caps weaker than manage_options. |
| 197 |
if ( ! $ability->meets_capability_policy() ) { |
| 198 |
continue; |
| 199 |
} |
| 200 |
|
| 201 |
// Skip disabled abilities so they don't appear in MCP listings. |
| 202 |
if ( ! $ability->is_enabled() ) { |
| 203 |
continue; |
| 204 |
} |
| 205 |
|
| 206 |
// Skip abilities already registered by zipwp-mcp. |
| 207 |
// wp_has_ability() is a WP 6.9+ Abilities API function, called only behind its |
| 208 |
// function_exists() guard, so it is inert on WP 6.4-6.8. Plugin Check's static |
| 209 |
// WP-version check reports a false positive here. |
| 210 |
if ( function_exists( 'wp_has_ability' ) && wp_has_ability( $ability->get_id() ) ) { |
| 211 |
continue; |
| 212 |
} |
| 213 |
|
| 214 |
$ability->register(); |
| 215 |
} |
| 216 |
} |
| 217 |
} |
| 218 |
|