| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Source view] [Print] [Project Stats]
Abilities API: WP_Abilities_Content class.
| File Size: | 1762 lines (67 kb) |
| Included or required: | 1 time |
| Referenced: | 0 times |
| Includes or requires: | 0 files |
| register() X-Ref |
| Registers all content abilities. Must run on the `wp_abilities_api_init` hook. |
| register_content_query() X-Ref |
| Registers the read-only `core/content-query` ability. |
| check_permission( $input = array() X-Ref |
| Permission callback for the `core/content-query` ability. The request is only gated as a whole here: it needs a logged-in user, a post type exposed to abilities, and the capabilities to query the explicitly requested statuses. It reads no post. {@see self::execute_content_query()} enforces row-level read permissions, since individual rows are unknown until the query runs. param: mixed $input Optional. The ability input. Default empty array. return: bool True if the request may proceed, false otherwise. |
| parse_filter_int( $value, int $min ) X-Ref |
| Parses a raw input value into an integer of at least a minimum, or null when invalid. Accepts the whole numbers that the integer schema accepts: native integers, floats such as the 2.0 that JSON encoders produce, and integer strings such as "2", "2.0", or "+2". Only the REST run controller converts input to the schema types, so other callers, such as the MCP adapter or a direct WP_Ability::execute() call, pass them on unconverted. Anything else, such as a fraction, is rejected rather than coerced: a malformed ID would otherwise resolve to another post, and a malformed `parent` filter would be read as 0, which asks for top-level posts. param: mixed $value The raw input value. param: int $min The smallest acceptable value. return: int|null The parsed integer, or null when the value is not an integer >= $min. |
| parse_list_input( array $input, string $key ) X-Ref |
| Parses a raw list input into a list of strings. Like schema validation, it also accepts a scalar or a comma-separated string, and parses it the same way, with wp_parse_list(). A number, such as a slug sent as 2024, is read as its string form. param: array<mixed> $input The ability input, or one of its objects, such as `where`. param: string $key The input key holding the list. return: list<string> The parsed string values; empty when absent or unparseable. |
| can_query_statuses( array $where, WP_Post_Type $post_type_object ) X-Ref |
| Checks whether the current user may query the explicitly requested statuses. The statuses a query covers by default, see {@see self::normalize_statuses()}, only hold statuses the current user may query, so they need no check. param: array<mixed> $where The `where` filters. param: WP_Post_Type $post_type_object The post type object. return: bool True if the requested statuses may be queried. |
| can_query_status( string $status, WP_Post_Type $post_type_object ) X-Ref |
| Checks whether the current user may query posts in a status. Like the REST posts controller, any user may query `publish`, while other statuses, such as `draft`, require edit access. Any user may also query the other publicly viewable statuses, and `private`, since the query only covers the private posts the user can read, see {@see self::execute_content_query()}. param: string $status The post status slug. param: WP_Post_Type $post_type_object The post type object. return: bool True if the status may be queried. |
| check_read_permission( WP_Post $post, array $checked_post_ids = array() X-Ref |
| Checks if a post can be read by the current user. Mirrors the REST posts controller's read permission, while keeping this ability authenticated-only via {@see self::check_permission()}. param: WP_Post $post Post object. param: array<int, true> $checked_post_ids Post IDs already checked while walking inherited parents. return: bool Whether the post can be read. |
| execute_content_query( $input = array() X-Ref |
| Executes the `core/content-query` ability. {@see WP_Ability::execute()} always runs {@see self::check_permission()} first, which gates the request as a whole. The query still filters every row by read permission, because the gate cannot know the rows before the query runs. param: mixed $input Optional. The ability input. Default empty array. return: array<string, mixed>|WP_Error A page of posts, or a WP_Error on failure. |
| get_input_object( array $input, string $key ) X-Ref |
| Reads an object member of the input, such as `where` or `pagination`. Accepts what schema validation reads as an object: an array, a `stdClass`, or an empty string. Only the REST run controller converts input to the schema types, so callers that bypass it, such as a direct WP_Ability::execute() call, can pass any of them. param: array<mixed> $input The ability input. param: string $key The member name. return: array<mixed>|null The member as an array, an empty array when it is omitted, |
| normalize_per_page( array $pagination, bool $lists_posts ) X-Ref |
| Normalizes the requested per-page value to the supported bounds. An explicit `per_page` always wins. Otherwise a request that lists posts by ID or slug pages to the maximum, as `core/users-query` does for its lists, so a caller loading a known set of posts receives them in one call rather than silently losing the ones past the default page size. The input schema caps each list at {@see self::MAX_PER_PAGE}, so every post that `ids` lists fits on the first page. A slug can match several posts, though, so the matches of `slugs` only continue past the first page when more than that many posts match. param: array<mixed> $pagination The `pagination` input. param: bool $lists_posts Whether the query lists `ids` or `slugs`. return: int The clamped per-page value. |
| get_query_total( WP_Query $query, array $query_args, int $page ) X-Ref |
| Returns the query total, recovering it when WP_Query skipped the count. WP_Query leaves `found_posts` at 0 when a requested page has no rows. Re-run a minimal unpaged query so the caller can distinguish an out-of-range page from an empty result set, matching the REST posts controller behavior. param: WP_Query $query The executed query. param: array<mixed> $query_args The arguments used for the executed query. param: int $page The requested page. return: int Total matching rows across all pages. |
| should_prime_post_caches( array $fields ) X-Ref |
| Checks whether requested fields benefit from page-level cache priming. A whole object counts as a request for its sub-fields, so `content` primes the caches as `content.rendered` does. param: list<string> $fields The requested field paths. return: bool True when post meta and term caches should be primed. |
| is_field_requested( string $path, array $fields ) X-Ref |
| Checks whether a field path is requested. Matches paths as the REST API's `_fields` parameter does, with rest_is_field_included(): a field such as `title` is requested when it or one of its paths, such as `title.rendered`, is requested, and a path such as `title.rendered` is requested when it or its whole field is. param: string $path The field path, such as `title` or `title.rendered`. param: list<string> $fields The requested field paths. return: bool Whether the field path is requested. |
| get_author_by_slug( $slug, WP_Post_Type $post_type_object ) X-Ref |
| Looks up the user an author slug names. The slug is the user's nicename, which the REST API users endpoint returns as `slug`. It is looked up as given, like that endpoint's `slug` filter, so the database collation decides whether a variant in another case matches. A user the current user may not see is reported like a missing one. The current user can see themselves, any user of the site when they can list users, and authors with posts in a publicly viewable post type. A user who can edit others' posts of the post type can also see any user of the site, since they may make any of them the author, so for them the lookup does tell whether such an account exists. On multisite the lookup searches the whole network, so posts by authors who are not members of the site, such as super admins, can still be filtered. Those users are only visible as the current user or as authors with posts in a publicly viewable post type, so the lookup does not tell whether an account exists elsewhere on the network. param: mixed $slug The author slug. param: WP_Post_Type $post_type_object The post type the author is looked up for. return: WP_User|null The user, or null when the slug does not name a visible user. |
| get_exposed_post_type( $post_type ) X-Ref |
| Returns a post type exposed through the Abilities API. Deliberately resolved on every call rather than cached: post types can be unregistered or re-registered with different arguments between the ability being registered and the ability being used. param: mixed $post_type The post type name. return: WP_Post_Type|null The post type object, or null when the post type is not exposed. |
| get_requested_statuses( array $where ) X-Ref |
| Returns the statuses the `status` filter explicitly requests. param: array<mixed> $where The `where` filters. return: list<string> Sanitized post status slugs; empty when none is requested. |
| normalize_statuses( array $statuses, WP_Post_Type $post_type_object, bool $lists_posts ) X-Ref |
| Normalizes the statuses a query covers. Explicitly requested statuses are queried as given, once the permission callback has allowed them. Otherwise a query covers `publish`, as in the REST posts controller, unless it lists `ids` or `slugs`. Such a query names the posts it wants, which may be drafts or private posts, so it covers every non-internal status that {@see self::can_query_status()} allows instead. The row-level read checks still withhold the posts the current user cannot read, such as other users' drafts. param: list<string> $statuses The explicitly requested statuses; empty when none is requested. param: WP_Post_Type $post_type_object The post type object. param: bool $lists_posts Whether the query lists `ids` or `slugs`. return: list<string> Post status slugs. |
| normalize_ids( array $where ) X-Ref |
| Normalizes the post IDs the `ids` filter lists. Like schema validation, it also accepts a single ID or a comma-separated string. Each ID is read with {@see self::parse_filter_int()}, and one that is not a whole number of at least 1, such as a fraction, a negative number, or a float too large to hold its integer exactly, is dropped rather than coerced, so it can never select another post. A digit string beyond the integer range saturates to PHP_INT_MAX, as REST sanitization does, which selects no post either. param: array<mixed> $where The `where` filters. return: list<int> Unique post IDs; empty when none is valid. |
| normalize_slugs( array $where ) X-Ref |
| Normalizes the post slugs the `slugs` filter lists. Like schema validation, it also accepts a single slug, even one sent as a number, or a comma-separated string. Each slug is sanitized with sanitize_title(), as WordPress sanitizes a post slug when it saves the post, so `Hello-World` matches `hello-world`. A slug that sanitizes to an empty string, such as `!!!`, is dropped: it names no post, and querying it would match the posts that have no slug yet, such as drafts. param: array<mixed> $where The `where` filters. return: list<string> Unique post slugs; empty when none is valid. |
| normalize_fields( array $input ) X-Ref |
| Returns the requested field paths, or a lean default set when none are given. An empty or absent `fields` value selects a lean set of common read fields. Otherwise the requested paths are returned. The input schema has already validated them against the supported set before the ability executes, and {@see self::build_post_fields()} ignores any other path. param: array<mixed> $input The ability input. return: list<string> List of requested field paths. |
| get_post_properties() X-Ref |
| Returns the post field definitions, keyed by field name in output order. This is the single source of truth for the ability's post fields: the output schema uses the definitions directly, while the input schema `fields` enum lists each field, followed by the path of each of its sub-fields, such as `title.rendered`. Read-context fields are returned for readable posts; the `raw` sub-fields only for posts the current user can edit. return: array<string, mixed> Post field definitions. |
| get_field_paths() X-Ref |
| Returns the field paths the `fields` input accepts, in output order. Each post field is followed by the path of each of its sub-fields, such as `title`, `title.raw` and `title.rendered`. Requesting a field returns all of its sub-fields that apply, while a sub-field path returns only that sub-field, as the REST API's `_fields` parameter does. return: list<string> The field paths. |
| get_fields_input_schema() X-Ref |
| Builds the schema of the `fields` input, shared by all content abilities. return: array<string, mixed> The `fields` JSON Schema. |
| get_content_query_input_schema( array $post_types, array $statuses ) X-Ref |
| Builds the input schema for the `core/content-query` ability. The input has three members: `where` selects the posts, `fields` selects the fields returned for each post, and `pagination` selects the page of results. `where` holds the post type to query in `type`, and any of the filters `ids`, `slugs`, `status`, `author_slug`, and `parent`, which all combine. Every object sets `additionalProperties: false`, so an unknown key, such as a misspelled filter, fails validation instead of being silently ignored. param: list<string> $post_types Exposed post type names. param: list<string> $statuses Requestable post status slugs. return: array<string, mixed> The input JSON Schema. |
| get_content_output_schema() X-Ref |
| Builds the output schema of a single post, shared by all content abilities. Only `id` is required, because it is always returned. The other fields are optional because the `fields` input lets the caller request any subset, and a field is only present when its post type supports it. return: array<string, mixed> The post JSON Schema. |
| get_content_query_output_schema() X-Ref |
| Builds the output schema for the `core/content-query` ability. Every request returns the same shape: a page of posts in `items`, and the totals across all pages in `pagination`. return: array<string, mixed> The output JSON Schema. |
| format_post( WP_Post $post, array $fields ) X-Ref |
| Formats a post into the ability output shape. As the REST posts controller does, the post is set up as the global post while its fields are built, so filters that rely on loop globals, including title filters, see the requested post. For an editor of a password-protected post, the cookie-based password gate is also suspended, so rendered fields resolve to real values instead of protected-post placeholders. The field projection itself is delegated to {@see self::build_post_fields()}. param: WP_Post $post The post object. param: list<string> $fields The requested field paths. return: array<string, mixed> The formatted post data. |
| build_post_fields( WP_Post $post, array $fields, bool $can_edit, bool $is_protected ) X-Ref |
| Builds the requested field projection for a post. Fields are selected as the REST API's `_fields` parameter selects them, with {@see self::is_field_requested()}. The `id` is always included, whether or not it was requested, so every returned post can be identified. This also means a post is never empty, so it always encodes as a JSON object. Only the fields that the post type supports and the current user can see are included, and a field none of whose requested sub-fields remain is left out, so it never encodes as an empty JSON array. Raw sub-fields are edit-context fields, included only when the current user can edit the post, whether they were requested on their own or through their field. Rendered sub-fields are read-context fields and are withheld for password-protected posts unless the current user can edit the post, mirroring the REST API behavior. param: WP_Post $post The post object. param: list<string> $fields The requested field paths. param: bool $can_edit Whether the current user can edit the post. param: bool $is_protected Whether rendered fields must be withheld as password-protected. return: array<string, mixed> The formatted post data. |
| allow_password_content( $required, $post ) X-Ref |
| Filters {@see post_password_required()} to unlock only posts the current user can edit. Added by {@see self::format_post()} while formatting a password-protected post the current user can edit, so rendered fields resolve to real values without also unlocking other protected posts that the content filter may render. Mirrors the REST posts controller's check_password_required(). param: mixed $required Whether the post currently requires a password. param: mixed $post The post being checked; a WP_Post when invoked by the core filter. return: bool Whether the post still requires a password. |
| get_title( WP_Post $post ) X-Ref |
| Returns the post title with the protected/private prefixes stripped. param: WP_Post $post The post object. return: string The post title. |
| get_rendered_excerpt( WP_Post $post ) X-Ref |
| Returns the post excerpt transformed for display. Applies the `get_the_excerpt` and `the_excerpt` filter chains, as the REST posts controller does. {@see self::format_post()} has set the post up as the global post. param: WP_Post $post The post object. return: string Rendered post excerpt. |
| get_rendered_content( WP_Post $post ) X-Ref |
| Returns post content transformed for display. Applies `the_content`, as the REST posts controller does. {@see self::format_post()} has set the post up as the global post. param: WP_Post $post The post object. return: string Rendered post content. |
| get_post_context() X-Ref |
| Returns the global post context, so it can be restored after a post is rendered. return: array<string, mixed> The loop globals, keyed by name, leaving out those that are not set. |
| set_up_post_context( WP_Post $post ) X-Ref |
| Sets up the global post context for rendering a post. Sets the global post and calls setup_postdata(), as the REST posts controller does before it renders a post, so filters that rely on loop globals render against the requested post. param: WP_Post $post The post to render. |
| restore_post_context( array $previous_context, bool $the_post_fired ) X-Ref |
| Restores the global post context saved by {@see self::get_post_context()}. Each loop global gets its previous value back, or is unset again when it was not set. wp_reset_postdata() alone is not enough: it does nothing when the main query has no post, which would leave the rendered post's data in the globals. When a post was set up before, setup_postdata() first runs for it again, as wp_reset_postdata() would, so callbacks on the `the_post` action can restore their own globals too. The saved values are put back even when such a callback throws. A global post that was never set up keeps the loop globals that setup_postdata() gives it. The `the_post` count is reset only when the ability was the first thing to fire that action and no global post was set, so rendering a post before the main query does not count as starting the loop. param: array<string, mixed> $previous_context The loop globals that get_post_context() returned. param: bool $the_post_fired Whether the `the_post` action had fired before the ability set up the post. |
| format_date( WP_Post $post, string $field, bool $gmt ) X-Ref |
| Formats a post date field as an ISO 8601 string, in the site's timezone or in GMT. In GMT, it reads the stored GMT date, deriving it from the local date when it is missing (e.g. drafts), mirroring the REST posts controller. param: WP_Post $post The post object. param: string $field Either 'date' or 'modified'. param: bool $gmt Whether to format the date in GMT instead of the site's timezone. return: string|null The ISO 8601 date, or null if unavailable. |
| prepare_output( array $items, int $total, int $total_pages ) X-Ref |
| Builds the ability output for a page of formatted posts. param: array<int, array<string, mixed>> $items The formatted posts on the page. param: int $total Total number of posts across all pages. param: int $total_pages Total number of pages. return: array<string, mixed> The ability output. |
| invalid_page_number_error() X-Ref |
| Builds the error for a page past the last page of results. A page that does not exist is reported as not found rather than as an empty list, so callers can tell it apart from a request that matches no posts. return: WP_Error The invalid page number error. |
| invalid_filter_error( string $param, string $message ) X-Ref |
| Builds the error for a filter that cannot be honored. As in the REST API's `rest_invalid_param` errors, the error data maps the filter's input path to the message under `params`, so callers can tell which filter failed without parsing the translated message. param: string $param The filter's input path, such as `where[ids]`. param: string $message The error message. return: WP_Error The invalid filter error. |
| Generated : Sat Oct 17 08:20:33 2026 | Cross-referenced by PHPXref |