JPKCom Allow Block Types

abilities.php

WordPress Abilities API integration.

Registers one read-only ability: which blocks the calling user may actually insert, and how the restriction is configured per role.

The effective answer is produced BY the filter this plugin registers, not by a re-derivation of it. Two rules make a re-derivation get it wrong:

  • A user's blocked set is the INTERSECTION across their roles, not the union. A user holding two roles is blocked only from what both roles block, and a single role with an empty list lifts the restriction entirely.
  • manage_options exempts a user completely, and that exemption is itself filterable, so a site can move it.
Tags
author

Jean Pierre Kolb jpk@jpkc.com

license

GPL-2.0-or-later

link
https://github.com/JPKCom/jpkcom-allow-blocks

Table of Contents

Constants

JPKCOM_ALLOWBLOCKS_ABILITY_CATEGORY  : mixed = 'jpkcom-content'
Ability category.
JPKCOM_ALLOWBLOCKS_ABILITY_INPUT_KEYS  : mixed = ['jpkcom-allow-blocks/list-allowed-blocks' => []]
Top-level input keys the ability declares.

Functions

jpkcom_allow_blocks_abilities_enabled()  : bool
Decide whether the ability should be registered at all.
jpkcom_allow_blocks_ability_log()  : void
Write a debug line, and only with WP_DEBUG.
jpkcom_allow_blocks_ability_error()  : WP_Error
Build a WP_Error carrying an HTTP status.
jpkcom_allow_blocks_ability_boundary()  : array<string, mixed>|WP_Error
Turn a Throwable out of the callback into a WP_Error.
jpkcom_allow_blocks_ability_capability()  : bool
Check the capability required to run the ability.
jpkcom_allow_blocks_ability_meta()  : array<string, mixed>
Build the meta array for the ability.
jpkcom_allow_blocks_ability_normalise_input()  : array<string, mixed>|null
Bring the value core hands the callback into array form.
jpkcom_allow_blocks_ability_validate_input_keys()  : true|WP_Error
Refuse a top-level input key the ability does not declare.
jpkcom_allow_blocks_ability_list_inner()  : array<string, mixed>|WP_Error
Report which blocks the calling user may insert, and how roles are configured.
jpkcom_allow_blocks_ability_permission()  : bool
Permission callback.
jpkcom_allow_blocks_ability_list()  : array<string, mixed>|WP_Error
Execute callback.
jpkcom_allow_blocks_get_ability_definitions()  : array<string, array<string, mixed>>
Build the registration arguments.
jpkcom_allow_blocks_register_ability_category()  : void
Register the shared category, unless a sibling plugin already did.
jpkcom_allow_blocks_register_abilities()  : void
Register the ability.

Constants

JPKCOM_ALLOWBLOCKS_ABILITY_CATEGORY

Ability category.

public mixed JPKCOM_ALLOWBLOCKS_ABILITY_CATEGORY = 'jpkcom-content'

Categories are global and registration is FIRST-WINS, so this goes through wp_has_ability_category() rather than assuming.

Tags
since
3.1.0

JPKCOM_ALLOWBLOCKS_ABILITY_INPUT_KEYS

Top-level input keys the ability declares.

public mixed JPKCOM_ALLOWBLOCKS_ABILITY_INPUT_KEYS = ['jpkcom-allow-blocks/list-allowed-blocks' => []]

Cross-checked against the registered schema by tests/test-abilities.php.

Tags
since
3.1.0

Functions

jpkcom_allow_blocks_abilities_enabled()

Decide whether the ability should be registered at all.

jpkcom_allow_blocks_abilities_enabled() : bool

Both spellings of the kill switch are honoured. README.md and CLAUDE.md have always documented the separated JPKCOM_ALLOW_BLOCKS_ABILITIES, but 3.1.0 shipped a check for the run-together JPKCOM_ALLOWBLOCKS_ABILITIES, so the documented constant did nothing and only the undocumented one worked. Accepting both keeps a 3.1.0 workaround working while making the documented spelling authoritative.

The plugin's constant naming is genuinely split, which is how the slip survived review: the main file uses JPKCOM_ALLOW_BLOCKS_* (VERSION, PATH, IMPORT_MAX_BYTES), while the two other constants in THIS file run the words together (JPKCOM_ALLOWBLOCKS_ABILITY_CATEGORY, _ABILITY_INPUT_KEYS). Writing the local spelling here was the natural mistake to make.

Tags
since
3.1.0
3.1.1

Honours the documented JPKCOM_ALLOW_BLOCKS_ABILITIES.

Return values
bool

True when registration should proceed.

jpkcom_allow_blocks_ability_log()

Write a debug line, and only with WP_DEBUG.

jpkcom_allow_blocks_ability_log(string $message) : void
Parameters
$message : string

Message.

Tags
since
3.1.0

jpkcom_allow_blocks_ability_error()

Build a WP_Error carrying an HTTP status.

jpkcom_allow_blocks_ability_error(string $code, string $message[, int $status = 400 ]) : WP_Error

Without data['status'] rest_ensure_response() defaults to 500, and a 5xx tells an agent "transient fault, retry unchanged" - the opposite of what a caller mistake needs to hear.

Parameters
$code : string

Error code.

$message : string

Message.

$status : int = 400

HTTP status.

Tags
since
3.1.0
Return values
WP_Error

Error.

jpkcom_allow_blocks_ability_boundary()

Turn a Throwable out of the callback into a WP_Error.

jpkcom_allow_blocks_ability_boundary(callable $body, string $ability) : array<string, mixed>|WP_Error
Parameters
$body : callable

Callback.

$ability : string

Ability name.

Tags
since
3.1.0
Return values
array<string, mixed>|WP_Error

Result or error.

jpkcom_allow_blocks_ability_capability()

Check the capability required to run the ability.

jpkcom_allow_blocks_ability_capability(string $ability) : bool

edit_posts: the answer is only meaningful to someone who edits content, and it reports how the site restricts every role, which is configuration rather than visitor-facing content.

Parameters
$ability : string

Ability name.

Tags
since
3.1.0
Return values
bool

True when the current user may run it.

jpkcom_allow_blocks_ability_meta()

Build the meta array for the ability.

jpkcom_allow_blocks_ability_meta(string $ability) : array<string, mixed>

All three annotations explicit: they default to null and the REST run controller derives the HTTP verb from them, so without readonly the run route would be POST-only.

Parameters
$ability : string

Ability name.

Tags
since
3.1.0
Return values
array<string, mixed>

Meta array.

jpkcom_allow_blocks_ability_normalise_input()

Bring the value core hands the callback into array form.

jpkcom_allow_blocks_ability_normalise_input(mixed $input) : array<string, mixed>|null

normalize_input() substitutes the schema's top-level default when the input is exactly null, and that default is a stdClass - so the callback receives an object and must read it.

Parameters
$input : mixed

Raw input.

Tags
since
3.1.0
Return values
array<string, mixed>|null

Array form, or null when unusable.

jpkcom_allow_blocks_ability_validate_input_keys()

Refuse a top-level input key the ability does not declare.

jpkcom_allow_blocks_ability_validate_input_keys(array<string, mixed> $input, array<string|int, string> $allowed) : true|WP_Error
Parameters
$input : array<string, mixed>

Raw input.

$allowed : array<string|int, string>

Declared keys.

Tags
since
3.1.0
Return values
true|WP_Error

True when every key is declared.

jpkcom_allow_blocks_ability_list_inner()

Report which blocks the calling user may insert, and how roles are configured.

jpkcom_allow_blocks_ability_list_inner([mixed $input = null ]) : array<string, mixed>|WP_Error

The effective list comes from running the plugin's OWN filter with true as the incoming value - "everything is allowed so far" - so the answer is whatever the editor would actually be handed. It is not re-derived from the option, and that matters twice over:

  • The blocked set for a user is the INTERSECTION across their roles. A user with two roles is blocked only from what both block, and one role with an empty list lifts the restriction entirely. A union would be the opposite answer.
  • The exemption is manage_options and is itself filterable, so a site can move it somewhere this ability has no way to predict.
Parameters
$input : mixed = null

Ability input.

Tags
since
3.1.0
Return values
array<string, mixed>|WP_Error

Result.

jpkcom_allow_blocks_ability_permission()

Permission callback.

jpkcom_allow_blocks_ability_permission([mixed $input = null ]) : bool
Parameters
$input : mixed = null

Validated input, unused.

Tags
since
3.1.0
Return values
bool

True when the current user may run the ability.

jpkcom_allow_blocks_ability_list()

Execute callback.

jpkcom_allow_blocks_ability_list([mixed $input = null ]) : array<string, mixed>|WP_Error
Parameters
$input : mixed = null

Ability input.

Tags
since
3.1.0
Return values
array<string, mixed>|WP_Error

Result.

jpkcom_allow_blocks_get_ability_definitions()

Build the registration arguments.

jpkcom_allow_blocks_get_ability_definitions() : array<string, array<string, mixed>>

Reads no WordPress state and touches no registry, which is what lets the CI harness assert the shape without a WordPress installation.

Tags
since
3.1.0
Return values
array<string, array<string, mixed>>

Ability name => registration args.

jpkcom_allow_blocks_register_ability_category()

Register the shared category, unless a sibling plugin already did.

jpkcom_allow_blocks_register_ability_category() : void
Tags
since
3.1.0

jpkcom_allow_blocks_register_abilities()

Register the ability.

jpkcom_allow_blocks_register_abilities() : void

wp_register_ability() returns null on EVERY failure path and reports only through _doing_it_wrong(), which is silent in production - and so is the debug log without WP_DEBUG.

Tags
since
3.1.0
On this page

Search results