PluginProbe ʕ •ᴥ•ʔ
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.12.3
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.12.3
2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 0.0.8 0.0.9 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.1.0 1.1.1 1.1.2 1.10.0 1.10.1 1.11.0 1.12.0 1.12.1 1.12.2 1.12.3 1.13.0 1.13.1 1.13.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.5.0 1.5.1 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.8.0 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.2.0 2.2.1 2.2.2 2.3.0 2.4.0 2.5.0 2.5.2 2.6.0
sureforms / inc / abilities / abstract-ability.php
sureforms / inc / abilities Last commit date
analytics 5 months ago entries 3 weeks ago forms 1 month ago settings 1 month ago abilities-registrar.php 2 months ago abstract-ability.php 2 months ago
abstract-ability.php
260 lines
1 <?php
2 /**
3 * Abstract Ability Base Class.
4 *
5 * Provides the foundation for all SureForms abilities registered
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 if ( ! defined( 'ABSPATH' ) ) {
15 exit; // Exit if accessed directly.
16 }
17
18 /**
19 * Abstract_Ability class.
20 *
21 * All SureForms abilities must extend this class and implement
22 * the abstract methods: get_input_schema(), get_output_schema(), and execute().
23 *
24 * @since 2.5.2
25 */
26 abstract class Abstract_Ability {
27 /**
28 * Minimum required capability for registration policy enforcement.
29 *
30 * @since 2.5.2
31 */
32 private const MIN_CAPABILITY = 'manage_options';
33 /**
34 * Unique ability identifier.
35 *
36 * @var string
37 * @since 2.5.2
38 */
39 protected $id = '';
40
41 /**
42 * Human-readable label.
43 *
44 * @var string
45 * @since 2.5.2
46 */
47 protected $label = '';
48
49 /**
50 * Ability description.
51 *
52 * @var string
53 * @since 2.5.2
54 */
55 protected $description = '';
56
57 /**
58 * Ability category.
59 *
60 * @var string
61 * @since 2.5.2
62 */
63 protected $category = 'sureforms';
64
65 /**
66 * Required WordPress capability.
67 *
68 * @var string
69 * @since 2.5.2
70 */
71 protected $capability = 'manage_options';
72
73 /**
74 * Option gate key.
75 *
76 * When non-empty, the ability is disabled only if the option is explicitly set to '0'.
77 * Abilities default to enabled — they are only gated off when an admin explicitly
78 * disables them via the AI settings page.
79 *
80 * @var string
81 * @since 2.6.0
82 */
83 protected $gated = '';
84
85 /**
86 * Get the JSON Schema for ability input.
87 *
88 * @since 2.5.2
89 * @return array<string,mixed>
90 */
91 abstract public function get_input_schema();
92
93 /**
94 * Get the JSON Schema for ability output.
95 *
96 * @since 2.5.2
97 * @return array<string,mixed>
98 */
99 abstract public function get_output_schema();
100
101 /**
102 * Execute the ability.
103 *
104 * @param array<string,mixed> $input Validated input data.
105 * @since 2.5.2
106 * @return array<string,mixed>|\WP_Error
107 */
108 abstract public function execute( $input );
109
110 /**
111 * Check whether this ability is enabled based on its option gate.
112 *
113 * Returns false when the ability has a gate key and the corresponding
114 * option is falsy. Used by the registrar to skip registration of
115 * disabled abilities so they don't appear in MCP listings.
116 *
117 * @since 2.6.0
118 * @return bool
119 */
120 public function is_enabled() {
121 if ( ! empty( $this->gated ) && ! get_option( $this->gated, true ) ) {
122 return false;
123 }
124
125 return true;
126 }
127
128 /**
129 * Permission callback.
130 *
131 * Delegates to current_user_can() with the configured capability.
132 *
133 * @since 2.5.2
134 * @return bool
135 */
136 public function permission_callback() {
137 if ( ! get_option( 'srfm_abilities_api', false ) ) {
138 return false;
139 }
140
141 if ( ! $this->is_enabled() ) {
142 return false;
143 }
144
145 return current_user_can( $this->capability );
146 }
147
148 /**
149 * Check if this ability meets the minimum capability policy.
150 *
151 * Prevents third-party abilities registered via srfm_register_abilities
152 * from downgrading the required capability below manage_options.
153 *
154 * @since 2.5.2
155 * @return bool
156 */
157 public function meets_capability_policy() {
158 return self::MIN_CAPABILITY === $this->capability;
159 }
160
161 /**
162 * Get ability annotations.
163 *
164 * Returns MCP-compatible annotations for readonly, destructive, idempotent,
165 * priority, and openWorldHint flags. Subclasses should override to customize.
166 *
167 * @since 2.5.2
168 * @return array<string,bool|float|string>
169 */
170 public function get_annotations() {
171 return [
172 'readonly' => false,
173 'destructive' => false,
174 'idempotent' => false,
175 'priority' => 2.0,
176 'openWorldHint' => false,
177 ];
178 }
179
180 /**
181 * Execution wrapper with pre/post hooks.
182 *
183 * @param array<string,mixed> $input Validated input data.
184 * @since 2.5.2
185 * @return array<string,mixed>|\WP_Error
186 */
187 public function execute_wrapper( $input ) {
188 /**
189 * Fires before an ability is executed.
190 *
191 * @param string $id Ability ID.
192 * @param array<string,mixed> $input Input data.
193 * @since 2.5.2
194 */
195 do_action( 'srfm_before_ability_execute', $this->id, $input );
196
197 $output = $this->execute( $input );
198
199 /**
200 * Fires after an ability is executed.
201 *
202 * @param string $id Ability ID.
203 * @param array<string,mixed> $input Input data.
204 * @param array<string,mixed>|\WP_Error $output Output data.
205 * @since 2.5.2
206 */
207 do_action( 'srfm_after_ability_execute', $this->id, $input, $output );
208
209 return $output;
210 }
211
212 /**
213 * Register this ability with the WordPress Abilities API.
214 *
215 * @since 2.5.2
216 * @return void
217 */
218 public function register() {
219 if ( ! function_exists( 'wp_register_ability' ) ) {
220 return;
221 }
222
223 $annotations = $this->get_annotations();
224
225 // wp_register_ability() is a WP 6.9+ Abilities API function. It is only reached
226 // after the function_exists() guard above (and via the wp_abilities_api_init hook),
227 // so it is inert on WP 6.4-6.8. Plugin Check's static WP-version check cannot see the
228 // runtime guard, so it reports a false positive here.
229 wp_register_ability(
230 $this->id,
231 [
232 'label' => $this->label,
233 'description' => $this->description,
234 'category' => $this->category,
235 'input_schema' => $this->get_input_schema(),
236 'output_schema' => $this->get_output_schema(),
237 'permission_callback' => [ $this, 'permission_callback' ],
238 'execute_callback' => [ $this, 'execute_wrapper' ],
239 'meta' => [
240 'show_in_rest' => true,
241 'annotations' => $annotations,
242 'mcp' => [
243 'public' => false,
244 ],
245 ],
246 ]
247 );
248 }
249
250 /**
251 * Get the ability ID.
252 *
253 * @since 2.5.2
254 * @return string
255 */
256 public function get_id() {
257 return $this->id;
258 }
259 }
260