Skip to main content

Hook

Vasyl MartyniukAbout 5 min

Syntax

Hook:<filter-or-action-name>
Hook:<filter-or-action-name>:<priority>

Note!

If priority is not specified, it defaults to 10. With premium add-on, you can define a wildcard priority * (e.g. Hook:all_plugins:*).

Definition

Focus on a specific hook (action or filter) and choose to either prevent its execution or intervene in the filter chain to alter the outcome according to the specified "Effect" property. This directive applies solely to actions and filters established subsequent to the WordPress core action plugins_loadedopen in new window.

A comprehensive grasp of WordPress filters and actions is essential for harnessing the potential of managing hooks, particularly concerning the sequencing of execution priorities.

Currently, AAM facilitates the following effects:

  • deny: Eliminates execution of all callback functions for a designated filter or action.
  • apply or override: Substitutes the response value. This category incorporates additional functionalities to regulate the overriding process, detailed further below. It's noteworthy that this effect permits the original callback function's execution, only modifying the return value.
  • merge: Assumes the returned value to be an array and merge it with the specified array values.
  • replace: Removes registered callback functions for the specified hook and returns the provided value instead.

Deny Effect

The "deny" effect completely eradicates registered callback functions associated with any given action or filter. Since WordPress permits the registration of multiple callback functions for the same hook with varying priorities, it's necessary to explicitly specify which priority to deny.

For instance, the following policy effectively halts the execution of all registered functions for the admin_menuopen in new window WordPress core action at the default priority of 10. Consequently, no plugins or themes can register a new admin menu.

{
    "Statement": {
        "Effect": "deny",
        "Resource": "Hook:admin_menu"
    }
}

It's crucial to note that the above example targets the default priority 10. While most plugin/theme developers typically don't alter this priority, exceptions may exist. Hence, the premium add-on allows for the targeting of all priorities using the wildcard * annotation. This ensures denial of all callback functions across all priorities. The following statement targets all callbacks:

{
    "Statement": [
        {
            "Effect": "deny",
            "Resource": "Hook:admin_menu:*"
        }
    ]
}

Note!

In the example above, the wildcard * (asterisk) functionality is exclusive to the premium Complete Package add-on. It enables the targeting of all priorities, offering assistance when unsure about the registered callback priority.

Apply/Override Effect

Both the "apply" and "override" effects serve the same purpose, allowing you to replace the final result of a given filter. It's important to note that these effects don't prevent the execution of registered callback functions; they solely modify the ultimate return value. To stop the execution of registered functions altogether, you should utilize the replace effect instead.

Note!

The "apply" or "override" effect is intended for targeting WordPress filters exclusively; they have no impact on actions since actions, by nature, do not return results.

In the following example, we demonstrate the use of the "override" effect to alter the behavior of the WordPress core filter screen_options_show_screenopen in new window, thereby inhibiting user interaction with the "Screen Options" button located in the top right corner of nearly all default WordPress backend pages.

{
    "Statement": [
        {
            "Effect": "override",
            "Resource": "Hook:screen_options_show_screen",
            "Response": false
        }
    ]
}

To enhance the manipulation of return values, you can employ the &:filter(...) annotation within the Response property. Here's how it operates.

The &:filter(...) annotation is a specialized syntax designed exclusively for the Hook resource. It's intended to be utilized within the Response property. Within the parentheses, you specify the comparison expression, where:

  • The left operand can either be the reserved keyword $key or $value. $key represents a key within an associative array or a property name within an object, while $value represents an actual value. $value can also denote a full path to any value within complex data structures, such as $value.roles[0].name.
  • The comparison operator can be any of the following: == (equals), *= (contains), ^= (starts with), $= (ends with), != (not equals), > (greater than), < (less than), >= (greater or equals to), <= (less than or equals to).
  • More complex comparison operator can be used. The in or checks if $key or $value is in array of values. The !in or checks if it is not. For example: &:filter($key !in [de,fr]).
  • The right operand is the static value used to compare with the left operand based on the comparison operator.

The following examples illustrate how this works in practice:

  1. Retain only the value in the array/object associated with the a key/property:
{
    "Statement": {
        "Effect": "override",
        "Resource": "Hook:aam_test_filter:10",
        "Response": "&:filter($key == a)"
    }
}
  1. Remove the a key/property from the array/object:
{
    "Statement": {
        "Effect": "override",
        "Resource": "Hook:aam_test_filter:10",
        "Response": "&:filter($key != a)"
    }
}
  1. Retain only values in the array/object that contain the dev string in a key/property:
{
    "Statement": {
        "Effect": "override",
        "Resource": "Hook:aam_test_filter:10",
        "Response": "&:filter($key *= dev)"
    }
}
  1. Retain only values in the array/object that start with the dev string in a key/property:
{
    "Statement": {
        "Effect": "override",
        "Resource": "Hook:aam_test_filter:10",
        "Response": "&:filter($key ^= dev)"
    }
}
  1. Retain only values in the array/object that end with the no string:
{
    "Statement": {
        "Effect": "override",
        "Resource": "Hook:aam_test_filter:10",
        "Response": "&:filter($value $= on)"
    }
}
  1. Remove values that are not equal to hello:
{
    "Statement": {
        "Effect": "override",
        "Resource": "Hook:aam_test_filter:10",
        "Response": "&:filter($value != hello)"
    }
}
  1. Filter complex return values:
{
    "Statement": {
        "Effect": "override",
        "Resource": "Hook:aam_test_filter:10",
        "Response": "&:filter($value.test[0].test != hello)"
    }
}

Additionally, you can provide the array of filters. In this case, the return value will be transformed sequentially through the list of provided filters.

{
    "Statement": {
        "Effect": "override",
        "Resource": "Hook:aam_test_filter:10",
        "Response": [
            "&:filter($key != hello)",
            "&:filter($value > 5)"
        ]
    }
}

Merge Effect

The "merge" effect operates similarly to "apply," altering the final return value. However, it anticipates the return value to be a valid array. If it is indeed an array, the "merge" effect combines it with additional values specified in the Response property.

In the following example, we include an additional list of trusted domains:

{
    "Statement": [
        {
            "Effect": "merge",
            "Resource": "Hook:allowed_redirect_hosts",
            "Response": [
                "members.aamportal.com",
                "store.aamportal.com"
            ]
        }
    ]
}

Replace Effect

In contrast to the "merge" or "apply" effects, "replace" dynamically removes all callback functions for a given priority or for all priorities simultaneously (if the wildcard * annotation is utilized). Instead, it provides the value specified in the Response property. This effect proves valuable when aiming to prevent the execution of any registered callback functions.

The following statement ensures that no other plugins or themes execute their functionality concerning the ability to change a user's password on the profile page:

{
    "Statement": [
        {
            "Effect": "replace",
            "Resource": "Hook:show_password_fields:*",
            "Response": false
        }
    ]
}