run:R W Run
11.52 KB
2026-03-11 16:18:51
R W Run
7.32 KB
2026-03-11 16:18:51
R W Run
5.76 KB
2026-03-11 16:18:51
R W Run
22.23 KB
2026-03-11 16:18:51
R W Run
error_log
📄class-wp-ability.php
1<?php
2/**
3 * Abilities API
4 *
5 * Defines WP_Ability class.
6 *
7 * @package WordPress
8 * @subpackage Abilities API
9 * @since 6.9.0
10 */
11
12declare( strict_types = 1 );
13
14/**
15 * Encapsulates the properties and methods related to a specific ability in the registry.
16 *
17 * @since 6.9.0
18 *
19 * @see WP_Abilities_Registry
20 */
21class WP_Ability {
22
23 /**
24 * The default value for the `show_in_rest` meta.
25 *
26 * @since 6.9.0
27 * @var bool
28 */
29 protected const DEFAULT_SHOW_IN_REST = false;
30
31 /**
32 * The default ability annotations.
33 * They are not guaranteed to provide a faithful description of ability behavior.
34 *
35 * @since 6.9.0
36 * @var array<string, bool|null>
37 */
38 protected static $default_annotations = array(
39 // If true, the ability does not modify its environment.
40 'readonly' => null,
41 /*
42 * If true, the ability may perform destructive updates to its environment.
43 * If false, the ability performs only additive updates.
44 */
45 'destructive' => null,
46 /*
47 * If true, calling the ability repeatedly with the same arguments will have no additional effect
48 * on its environment.
49 */
50 'idempotent' => null,
51 );
52
53 /**
54 * The name of the ability, with its namespace.
55 * Example: `my-plugin/my-ability`.
56 *
57 * @since 6.9.0
58 * @var string
59 */
60 protected $name;
61
62 /**
63 * The human-readable ability label.
64 *
65 * @since 6.9.0
66 * @var string
67 */
68 protected $label;
69
70 /**
71 * The detailed ability description.
72 *
73 * @since 6.9.0
74 * @var string
75 */
76 protected $description;
77
78 /**
79 * The ability category.
80 *
81 * @since 6.9.0
82 * @var string
83 */
84 protected $category;
85
86 /**
87 * The optional ability input schema.
88 *
89 * @since 6.9.0
90 * @var array<string, mixed>
91 */
92 protected $input_schema = array();
93
94 /**
95 * The optional ability output schema.
96 *
97 * @since 6.9.0
98 * @var array<string, mixed>
99 */
100 protected $output_schema = array();
101
102 /**
103 * The ability execute callback.
104 *
105 * @since 6.9.0
106 * @var callable( mixed $input= ): (mixed|WP_Error)
107 */
108 protected $execute_callback;
109
110 /**
111 * The optional ability permission callback.
112 *
113 * @since 6.9.0
114 * @var callable( mixed $input= ): (bool|WP_Error)
115 */
116 protected $permission_callback;
117
118 /**
119 * The optional ability metadata.
120 *
121 * @since 6.9.0
122 * @var array<string, mixed>
123 */
124 protected $meta;
125
126 /**
127 * Constructor.
128 *
129 * Do not use this constructor directly. Instead, use the `wp_register_ability()` function.
130 *
131 * @access private
132 *
133 * @since 6.9.0
134 *
135 * @see wp_register_ability()
136 *
137 * @param string $name The name of the ability, with its namespace.
138 * @param array<string, mixed> $args {
139 * An associative array of arguments for the ability.
140 *
141 * @type string $label The human-readable label for the ability.
142 * @type string $description A detailed description of what the ability does.
143 * @type string $category The ability category slug this ability belongs to.
144 * @type callable $execute_callback A callback function to execute when the ability is invoked.
145 * Receives optional mixed input and returns mixed result or WP_Error.
146 * @type callable $permission_callback A callback function to check permissions before execution.
147 * Receives optional mixed input and returns bool or WP_Error.
148 * @type array<string, mixed> $input_schema Optional. JSON Schema definition for the ability's input.
149 * @type array<string, mixed> $output_schema Optional. JSON Schema definition for the ability's output.
150 * @type array<string, mixed> $meta {
151 * Optional. Additional metadata for the ability.
152 *
153 * @type array<string, bool|null> $annotations {
154 * Optional. Semantic annotations describing the ability's behavioral characteristics.
155 * These annotations are hints for tooling and documentation.
156 *
157 * @type bool|null $readonly Optional. If true, the ability does not modify its environment.
158 * @type bool|null $destructive Optional. If true, the ability may perform destructive updates to its environment.
159 * If false, the ability performs only additive updates.
160 * @type bool|null $idempotent Optional. If true, calling the ability repeatedly with the same arguments
161 * will have no additional effect on its environment.
162 * }
163 * @type bool $show_in_rest Optional. Whether to expose this ability in the REST API. Default false.
164 * }
165 * }
166 */
167 public function __construct( string $name, array $args ) {
168 $this->name = $name;
169
170 $properties = $this->prepare_properties( $args );
171
172 foreach ( $properties as $property_name => $property_value ) {
173 if ( ! property_exists( $this, $property_name ) ) {
174 _doing_it_wrong(
175 __METHOD__,
176 sprintf(
177 /* translators: %s: Property name. */
178 __( 'Property "%1$s" is not a valid property for ability "%2$s". Please check the %3$s class for allowed properties.' ),
179 '<code>' . esc_html( $property_name ) . '</code>',
180 '<code>' . esc_html( $this->name ) . '</code>',
181 '<code>' . __CLASS__ . '</code>'
182 ),
183 '6.9.0'
184 );
185 continue;
186 }
187
188 $this->$property_name = $property_value;
189 }
190 }
191
192 /**
193 * Prepares and validates the properties used to instantiate the ability.
194 *
195 * Errors are thrown as exceptions instead of WP_Errors to allow for simpler handling and overloading. They are then
196 * caught and converted to a WP_Error when by WP_Abilities_Registry::register().
197 *
198 * @since 6.9.0
199 *
200 * @see WP_Abilities_Registry::register()
201 *
202 * @param array<string, mixed> $args {
203 * An associative array of arguments used to instantiate the ability class.
204 *
205 * @type string $label The human-readable label for the ability.
206 * @type string $description A detailed description of what the ability does.
207 * @type string $category The ability category slug this ability belongs to.
208 * @type callable $execute_callback A callback function to execute when the ability is invoked.
209 * Receives optional mixed input and returns mixed result or WP_Error.
210 * @type callable $permission_callback A callback function to check permissions before execution.
211 * Receives optional mixed input and returns bool or WP_Error.
212 * @type array<string, mixed> $input_schema Optional. JSON Schema definition for the ability's input. Required if ability accepts an input.
213 * @type array<string, mixed> $output_schema Optional. JSON Schema definition for the ability's output.
214 * @type array<string, mixed> $meta {
215 * Optional. Additional metadata for the ability.
216 *
217 * @type array<string, bool|null> $annotations {
218 * Optional. Semantic annotations describing the ability's behavioral characteristics.
219 * These annotations are hints for tooling and documentation.
220 *
221 * @type bool|null $readonly Optional. If true, the ability does not modify its environment.
222 * @type bool|null $destructive Optional. If true, the ability may perform destructive updates to its environment.
223 * If false, the ability performs only additive updates.
224 * @type bool|null $idempotent Optional. If true, calling the ability repeatedly with the same arguments
225 * will have no additional effect on its environment.
226 * }
227 * @type bool $show_in_rest Optional. Whether to expose this ability in the REST API. Default false.
228 * }
229 * }
230 * @return array<string, mixed> {
231 * An associative array of arguments with validated and prepared properties for the ability class.
232 *
233 * @type string $label The human-readable label for the ability.
234 * @type string $description A detailed description of what the ability does.
235 * @type string $category The ability category slug this ability belongs to.
236 * @type callable $execute_callback A callback function to execute when the ability is invoked.
237 * Receives optional mixed input and returns mixed result or WP_Error.
238 * @type callable $permission_callback A callback function to check permissions before execution.
239 * Receives optional mixed input and returns bool or WP_Error.
240 * @type array<string, mixed> $input_schema Optional. JSON Schema definition for the ability's input.
241 * @type array<string, mixed> $output_schema Optional. JSON Schema definition for the ability's output.
242 * @type array<string, mixed> $meta {
243 * Additional metadata for the ability.
244 *
245 * @type array<string, bool|null> $annotations {
246 * Semantic annotations describing the ability's behavioral characteristics.
247 * These annotations are hints for tooling and documentation.
248 *
249 * @type bool|null $readonly If true, the ability does not modify its environment.
250 * @type bool|null $destructive If true, the ability may perform destructive updates to its environment.
251 * If false, the ability performs only additive updates.
252 * @type bool|null $idempotent If true, calling the ability repeatedly with the same arguments
253 * will have no additional effect on its environment.
254 * }
255 * @type bool $show_in_rest Whether to expose this ability in the REST API. Default false.
256 * }
257 * }
258 * @throws InvalidArgumentException if an argument is invalid.
259 */
260 protected function prepare_properties( array $args ): array {
261 // Required args must be present and of the correct type.
262 if ( empty( $args['label'] ) || ! is_string( $args['label'] ) ) {
263 throw new InvalidArgumentException(
264 __( 'The ability properties must contain a `label` string.' )
265 );
266 }
267
268 if ( empty( $args['description'] ) || ! is_string( $args['description'] ) ) {
269 throw new InvalidArgumentException(
270 __( 'The ability properties must contain a `description` string.' )
271 );
272 }
273
274 if ( empty( $args['category'] ) || ! is_string( $args['category'] ) ) {
275 throw new InvalidArgumentException(
276 __( 'The ability properties must contain a `category` string.' )
277 );
278 }
279
280 if ( empty( $args['execute_callback'] ) || ! is_callable( $args['execute_callback'] ) ) {
281 throw new InvalidArgumentException(
282 __( 'The ability properties must contain a valid `execute_callback` function.' )
283 );
284 }
285
286 if ( empty( $args['permission_callback'] ) || ! is_callable( $args['permission_callback'] ) ) {
287 throw new InvalidArgumentException(
288 __( 'The ability properties must provide a valid `permission_callback` function.' )
289 );
290 }
291
292 // Optional args only need to be of the correct type if they are present.
293 if ( isset( $args['input_schema'] ) && ! is_array( $args['input_schema'] ) ) {
294 throw new InvalidArgumentException(
295 __( 'The ability properties should provide a valid `input_schema` definition.' )
296 );
297 }
298
299 if ( isset( $args['output_schema'] ) && ! is_array( $args['output_schema'] ) ) {
300 throw new InvalidArgumentException(
301 __( 'The ability properties should provide a valid `output_schema` definition.' )
302 );
303 }
304
305 if ( isset( $args['meta'] ) && ! is_array( $args['meta'] ) ) {
306 throw new InvalidArgumentException(
307 __( 'The ability properties should provide a valid `meta` array.' )
308 );
309 }
310
311 if ( isset( $args['meta']['annotations'] ) && ! is_array( $args['meta']['annotations'] ) ) {
312 throw new InvalidArgumentException(
313 __( 'The ability meta should provide a valid `annotations` array.' )
314 );
315 }
316
317 if ( isset( $args['meta']['show_in_rest'] ) && ! is_bool( $args['meta']['show_in_rest'] ) ) {
318 throw new InvalidArgumentException(
319 __( 'The ability meta should provide a valid `show_in_rest` boolean.' )
320 );
321 }
322
323 // Set defaults for optional meta.
324 $args['meta'] = wp_parse_args(
325 $args['meta'] ?? array(),
326 array(
327 'annotations' => static::$default_annotations,
328 'show_in_rest' => self::DEFAULT_SHOW_IN_REST,
329 )
330 );
331 $args['meta']['annotations'] = wp_parse_args(
332 $args['meta']['annotations'],
333 static::$default_annotations
334 );
335
336 return $args;
337 }
338
339 /**
340 * Retrieves the name of the ability, with its namespace.
341 * Example: `my-plugin/my-ability`.
342 *
343 * @since 6.9.0
344 *
345 * @return string The ability name, with its namespace.
346 */
347 public function get_name(): string {
348 return $this->name;
349 }
350
351 /**
352 * Retrieves the human-readable label for the ability.
353 *
354 * @since 6.9.0
355 *
356 * @return string The human-readable ability label.
357 */
358 public function get_label(): string {
359 return $this->label;
360 }
361
362 /**
363 * Retrieves the detailed description for the ability.
364 *
365 * @since 6.9.0
366 *
367 * @return string The detailed description for the ability.
368 */
369 public function get_description(): string {
370 return $this->description;
371 }
372
373 /**
374 * Retrieves the ability category for the ability.
375 *
376 * @since 6.9.0
377 *
378 * @return string The ability category for the ability.
379 */
380 public function get_category(): string {
381 return $this->category;
382 }
383
384 /**
385 * Retrieves the input schema for the ability.
386 *
387 * @since 6.9.0
388 *
389 * @return array<string, mixed> The input schema for the ability.
390 */
391 public function get_input_schema(): array {
392 return $this->input_schema;
393 }
394
395 /**
396 * Retrieves the output schema for the ability.
397 *
398 * @since 6.9.0
399 *
400 * @return array<string, mixed> The output schema for the ability.
401 */
402 public function get_output_schema(): array {
403 return $this->output_schema;
404 }
405
406 /**
407 * Retrieves the metadata for the ability.
408 *
409 * @since 6.9.0
410 *
411 * @return array<string, mixed> The metadata for the ability.
412 */
413 public function get_meta(): array {
414 return $this->meta;
415 }
416
417 /**
418 * Retrieves a specific metadata item for the ability.
419 *
420 * @since 6.9.0
421 *
422 * @param string $key The metadata key to retrieve.
423 * @param mixed $default_value Optional. The default value to return if the metadata item is not found. Default `null`.
424 * @return mixed The value of the metadata item, or the default value if not found.
425 */
426 public function get_meta_item( string $key, $default_value = null ) {
427 return array_key_exists( $key, $this->meta ) ? $this->meta[ $key ] : $default_value;
428 }
429
430 /**
431 * Normalizes the input for the ability, applying the default value from the input schema when needed.
432 *
433 * When no input is provided and the input schema is defined with a top-level `default` key, this method returns
434 * the value of that key. If the input schema does not define a `default`, or if the input schema is empty,
435 * this method returns null. If input is provided, it is returned as-is.
436 *
437 * @since 6.9.0
438 *
439 * @param mixed $input Optional. The raw input provided for the ability. Default `null`.
440 * @return mixed The same input, or the default from schema, or `null` if default not set.
441 */
442 public function normalize_input( $input = null ) {
443 if ( null !== $input ) {
444 return $input;
445 }
446
447 $input_schema = $this->get_input_schema();
448 if ( ! empty( $input_schema ) && array_key_exists( 'default', $input_schema ) ) {
449 return $input_schema['default'];
450 }
451
452 return null;
453 }
454
455 /**
456 * Validates input data against the input schema.
457 *
458 * @since 6.9.0
459 *
460 * @param mixed $input Optional. The input data to validate. Default `null`.
461 * @return true|WP_Error Returns true if valid or the WP_Error object if validation fails.
462 */
463 public function validate_input( $input = null ) {
464 $input_schema = $this->get_input_schema();
465 if ( empty( $input_schema ) ) {
466 if ( null === $input ) {
467 return true;
468 }
469
470 return new WP_Error(
471 'ability_missing_input_schema',
472 sprintf(
473 /* translators: %s ability name. */
474 __( 'Ability "%s" does not define an input schema required to validate the provided input.' ),
475 esc_html( $this->name )
476 )
477 );
478 }
479
480 $valid_input = rest_validate_value_from_schema( $input, $input_schema, 'input' );
481 if ( is_wp_error( $valid_input ) ) {
482 return new WP_Error(
483 'ability_invalid_input',
484 sprintf(
485 /* translators: %1$s ability name, %2$s error message. */
486 __( 'Ability "%1$s" has invalid input. Reason: %2$s' ),
487 esc_html( $this->name ),
488 $valid_input->get_error_message()
489 )
490 );
491 }
492
493 return true;
494 }
495
496 /**
497 * Invokes a callable, ensuring the input is passed through only if the input schema is defined.
498 *
499 * @since 6.9.0
500 *
501 * @param callable $callback The callable to invoke.
502 * @param mixed $input Optional. The input data for the ability. Default `null`.
503 * @return mixed The result of the callable execution.
504 */
505 protected function invoke_callback( callable $callback, $input = null ) {
506 $args = array();
507 if ( ! empty( $this->get_input_schema() ) ) {
508 $args[] = $input;
509 }
510
511 return $callback( ...$args );
512 }
513
514 /**
515 * Checks whether the ability has the necessary permissions.
516 *
517 * Please note that input is not automatically validated against the input schema.
518 * Use `validate_input()` method to validate input before calling this method if needed.
519 *
520 * @since 6.9.0
521 *
522 * @see validate_input()
523 *
524 * @param mixed $input Optional. The valid input data for permission checking. Default `null`.
525 * @return bool|WP_Error Whether the ability has the necessary permission.
526 */
527 public function check_permissions( $input = null ) {
528 if ( ! is_callable( $this->permission_callback ) ) {
529 return new WP_Error(
530 'ability_invalid_permission_callback',
531 /* translators: %s ability name. */
532 sprintf( __( 'Ability "%s" does not have a valid permission callback.' ), esc_html( $this->name ) )
533 );
534 }
535
536 return $this->invoke_callback( $this->permission_callback, $input );
537 }
538
539 /**
540 * Executes the ability callback.
541 *
542 * @since 6.9.0
543 *
544 * @param mixed $input Optional. The input data for the ability. Default `null`.
545 * @return mixed|WP_Error The result of the ability execution, or WP_Error on failure.
546 */
547 protected function do_execute( $input = null ) {
548 if ( ! is_callable( $this->execute_callback ) ) {
549 return new WP_Error(
550 'ability_invalid_execute_callback',
551 /* translators: %s ability name. */
552 sprintf( __( 'Ability "%s" does not have a valid execute callback.' ), esc_html( $this->name ) )
553 );
554 }
555
556 return $this->invoke_callback( $this->execute_callback, $input );
557 }
558
559 /**
560 * Validates output data against the output schema.
561 *
562 * @since 6.9.0
563 *
564 * @param mixed $output The output data to validate.
565 * @return true|WP_Error Returns true if valid, or a WP_Error object if validation fails.
566 */
567 protected function validate_output( $output ) {
568 $output_schema = $this->get_output_schema();
569 if ( empty( $output_schema ) ) {
570 return true;
571 }
572
573 $valid_output = rest_validate_value_from_schema( $output, $output_schema, 'output' );
574 if ( is_wp_error( $valid_output ) ) {
575 return new WP_Error(
576 'ability_invalid_output',
577 sprintf(
578 /* translators: %1$s ability name, %2$s error message. */
579 __( 'Ability "%1$s" has invalid output. Reason: %2$s' ),
580 esc_html( $this->name ),
581 $valid_output->get_error_message()
582 )
583 );
584 }
585
586 return true;
587 }
588
589 /**
590 * Executes the ability after input validation and running a permission check.
591 * Before returning the return value, it also validates the output.
592 *
593 * @since 6.9.0
594 *
595 * @param mixed $input Optional. The input data for the ability. Default `null`.
596 * @return mixed|WP_Error The result of the ability execution, or WP_Error on failure.
597 */
598 public function execute( $input = null ) {
599 $input = $this->normalize_input( $input );
600 $is_valid = $this->validate_input( $input );
601 if ( is_wp_error( $is_valid ) ) {
602 return $is_valid;
603 }
604
605 $has_permissions = $this->check_permissions( $input );
606 if ( true !== $has_permissions ) {
607 if ( is_wp_error( $has_permissions ) ) {
608 // Don't leak the permission check error to someone without the correct perms.
609 _doing_it_wrong(
610 __METHOD__,
611 esc_html( $has_permissions->get_error_message() ),
612 '6.9.0'
613 );
614 }
615
616 return new WP_Error(
617 'ability_invalid_permissions',
618 /* translators: %s ability name. */
619 sprintf( __( 'Ability "%s" does not have necessary permission.' ), esc_html( $this->name ) )
620 );
621 }
622
623 /**
624 * Fires before an ability gets executed, after input validation and permissions check.
625 *
626 * @since 6.9.0
627 *
628 * @param string $ability_name The name of the ability.
629 * @param mixed $input The input data for the ability.
630 */
631 do_action( 'wp_before_execute_ability', $this->name, $input );
632
633 $result = $this->do_execute( $input );
634 if ( is_wp_error( $result ) ) {
635 return $result;
636 }
637
638 $is_valid = $this->validate_output( $result );
639 if ( is_wp_error( $is_valid ) ) {
640 return $is_valid;
641 }
642
643 /**
644 * Fires immediately after an ability finished executing.
645 *
646 * @since 6.9.0
647 *
648 * @param string $ability_name The name of the ability.
649 * @param mixed $input The input data for the ability.
650 * @param mixed $result The result of the ability execution.
651 */
652 do_action( 'wp_after_execute_ability', $this->name, $input, $result );
653
654 return $result;
655 }
656
657 /**
658 * Wakeup magic method.
659 *
660 * @since 6.9.0
661 * @throws LogicException If the ability object is unserialized.
662 * This is a security hardening measure to prevent unserialization of the ability.
663 */
664 public function __wakeup(): void {
665 throw new LogicException( __CLASS__ . ' should never be unserialized.' );
666 }
667
668 /**
669 * Sleep magic method.
670 *
671 * @since 6.9.0
672 * @throws LogicException If the ability object is serialized.
673 * This is a security hardening measure to prevent serialization of the ability.
674 */
675 public function __sleep(): array {
676 throw new LogicException( __CLASS__ . ' should never be serialized.' );
677 }
678}
679
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1