Hooks

The Hooks Service (AAM_Framework_Service_Hooks) is a runtime access-control layer for WordPress hooks (actions and filters). It allows you to deny, allow, modify, merge, or fully replace hook execution behavior without changing the underlying plugin or theme code.

It operates as a policy engine on top of WordPress hooks system, dynamically applying rules per access level (user/visitor/admin context) and priority.

At a high level, this service:

Definition

class AAM_Framework_Service_Hooks {

    public deny(string $hook, string|int $priority = 10) : bool
    public allow(string $hook, string|int $priority = 10) : bool
    public alter(string $hook, mixed $return, string|int $priority = 10) : bool
    public merge(string $hook, array $data, string|int $priority = 10) : bool
    public replace(string $hook, mixed $value, string|int $priority = 10) : bool

    public reset() : bool
}

Core Concept

Each hook rule is stored as a permission record:

[
  'name'     => 'hook_name',
  'priority' => 10,
  'effect'   => 'deny|allow|alter|merge|replace',
  'return'   => mixed (optional)
]

The service converts these rules into runtime WordPress filter behavior.

Methods

deny()

Prevents execution of all callbacks registered at a specific hook priority.

public function deny(string $hook, string|int $priority = 10) : bool

Behavior

Use Case

Example

$hooks->deny('wp_mail', 10);

allow()

Explicitly marks a hook as allowed (used for governance consistency).

public function allow(string $hook, string|int $priority = 10) : bool

Behavior

Example

$hooks->allow('the_content', 10);

alter()

Overrides the return value of a hook with a custom value or transformation.

public function alter(string $hook, mixed $return, string|int $priority = 10) : bool

Behavior

Supported override types:

Example

$hooks->alter('the_title', 'New Title');

merge()

Merges the original hook output with additional data.

public function merge(string $hook, array $data, string|int $priority = 10) : bool

Behavior

Example

$hooks->merge('wp_nav_menu_items', [
    'extra_item' => 'Dashboard'
]);

Internal logic

array_merge(original_value, injected_data)

replace()

Completely replaces hook execution output and removes all existing filters at that priority.

public function replace(string $hook, mixed $value, string|int $priority = 10) : bool

Behavior

Example

$hooks->replace('the_content', 'Access Restricted');

reset()

Removes all hook permissions for the current access level.

public function reset() : bool

Behavior

Example

$hooks->reset();

listen()

Attaches runtime listeners to hooks based on defined policies.

public function listen($hook = null)

Behavior

Listen to all hooks
$hooks->listen();

Registers all stored hook policies.

Listen to specific hook
$hooks->listen([
  'name' => 'the_content',
  'priority' => 10
]);

Hook Effects

deny

Hard stop execution at priority level.

alter

Overrides return value using:

_override_return_value()

Supports:

merge

Combines arrays:

array_merge(original, injected)

replace

Fully replaces execution chain.

Expression System (Advanced)

The service supports filter expressions inside strings and arrays.

Syntax

&:filter(condition)

Example

&:filter($value == "admin")

Supported Operators

Operator Meaning
== equals
!= not equals
*= contains
^= starts with
$= ends with
> < >= <= comparisons
in / ∈ in list
!in / ∉ not in list

Array filtering

If all items are filter expressions:

[
  &:filter($value == "admin"),
  &:filter($value != "guest")
]

They are executed as a filter chain.

Listener Behavior

When _modify() is triggered:

Execution flow:

$value → alter/merge logic → return modified value

Error Handling

Every public method is wrapped:

try {
    ...
} catch (Exception $e) {
    $result = $this->_handle_error($e);
}

So the service is:

Access Level Restrictions

listen() only works for:

Any other access level throws:

LogicException: Only user and visitor access level can listen to a hook