PHPackages                             spenserhale/wp-autohook-library - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. spenserhale/wp-autohook-library

ActiveLibrary

spenserhale/wp-autohook-library
===============================

A library for automatically hooking classes into WordPress actions and filters.

1.4.0(3mo ago)573MITPHPCI passing

Since Feb 8Pushed 3mo ago2 watchersCompare

[ Source](https://github.com/spenserhale/wp-autohooks-library)[ Packagist](https://packagist.org/packages/spenserhale/wp-autohook-library)[ RSS](/packages/spenserhale-wp-autohook-library/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (8)Dependencies (1)Versions (10)Used By (0)

WP AutoHooks
------------

[](#wp-autohooks)

[![Screen Shot](images/explainer.png)](images/explainer.png)

WP AutoHooks is a PHP Library that allows you to define Attributes on Classes and Methods to document and register WordPress Hooks.

Features
--------

[](#features)

- **Developer Experience**: Document hooks next to the method, giving you context and a better developer experience.
- **Performance**: Hooks are registered without loading classes or instantiating objects until needed.
- **Flexibility**: The underlying PHP Library can be used for both simple and complex projects.
- **Modularity**: Ability to add and remove standalone classes quickly and easily.

Getting Started
---------------

[](#getting-started)

### Prerequisites

[](#prerequisites)

By default, the library is geared toward Composer, but there is flexibility, and you can integrate the library with your class loading system.

### Installation

[](#installation)

```
composer require spenserhale/wp-autohook-library
```

### Basic Usage

[](#basic-usage)

Attribute your class and methods with the `Hook` and `Shortcode` attributes.

#### Method-Level Attributes

[](#method-level-attributes)

Apply attributes directly to methods. The method name is automatically used as the callback:

```
#[Hook('cli_init', priority: 9)]
public static function registerCommand(): void {}

#[Hook('rest_api_init')]
public static function registerController(): void {}

#[Hook('wp_init', 99)]
public static function boot(): void {}
```

#### Named Parameters

[](#named-parameters)

Use named parameters for flexibility in argument order:

```
#[Hook(priority: 100, tag: 'pre_update_option')]
public static function filterOption(string $value): string {}
```

#### Multiple Hooks on a Single Method

[](#multiple-hooks-on-a-single-method)

Apply multiple hooks to the same method using stacked attributes or comma-separated syntax:

```
// Stacked attributes
#[Hook('wp_insert_blog_meta')]
#[Hook('wp_insert_post_meta')]
public static function logInsert(array $data, array $postarr): array {}

// Comma-separated (same line)
#[Hook('update_post_meta'), Hook('update_option_meta')]
public static function logChange(mixed $old_value, mixed $new_value): void {}
```

#### Shortcodes

[](#shortcodes)

Register shortcodes using the `Shortcode` attribute:

```
#[Shortcode('example_shortcode')]
public static function shortcode(): string {}
```

#### Class-Level Attributes (Inherited Methods)

[](#class-level-attributes-inherited-methods)

Apply attributes at the class level when you need to hook methods inherited from a parent class. Since attributes on parent methods aren't scanned in child classes, class-level attributes let you register hooks for inherited methods:

```
abstract class AbstractAdminPage
{
    public static function registerPage(): void {}

    public static function renderPage(): void {}
}

#[Hook('admin_menu', callback: 'registerPage')]
#[Hook('admin_init', callback: 'renderPage')]
class SettingsPage extends AbstractAdminPage
{
    // Inherited methods are hooked via class-level attributes
}
```

#### Complete Example

[](#complete-example)

```
namespace ACME;

#[Hook('facade_example_hook', callback: 'facadeMethod', arguments: 3)]
#[Shortcode('other_shortcode', 'otherShortcode')]
class ExamplesClass
{
    #[Hook('cli_init', priority: 9)]
    public static function registerCommand(): void {}

    #[Hook('rest_api_init')]
    public static function registerController(): void {}

    #[Hook('wp_init', 99)]
    public static function boot(): void {}

    #[Hook(priority: 100, tag: 'pre_update_option')]
    public static function filterOption(string $value): string {}

    #[Hook('wp_insert_blog_meta')]
    #[Hook('wp_insert_post_meta')]
    public static function logInsert(array $data, array $postarr): array {}

    #[Hook('update_post_meta'), Hook('update_option_meta')]
    public static function logChange(mixed $old_value, mixed $new_value): void {}

    #[Shortcode('example_shortcode')]
    public static function shortcode(): string {}

    public static function facadeMethod($arg1, $arg2, $arg3): mixed {}

    public static function otherShortcode(): string {}
}
```

#### Generated Output

[](#generated-output)

The above example generates:

```
//=== Start AutoHooks Generated Section ===
add_action('cli_init', 'ACME\ExamplesClass::registerCommand', 9, 0);
add_filter('facade_example_hook', 'ACME\ExamplesClass::facadeMethod', 10, 3);
add_filter('pre_update_option', 'ACME\ExamplesClass::filterOption', 100, 1);
add_action('rest_api_init', 'ACME\ExamplesClass::registerController', 10, 0);
add_action('update_option_meta', 'ACME\ExamplesClass::logChange', 10, 2);
add_action('update_post_meta', 'ACME\ExamplesClass::logChange', 10, 2);
add_action('wp_init', 'ACME\ExamplesClass::boot', 99, 0);
add_filter('wp_insert_blog_meta', 'ACME\ExamplesClass::logInsert', 10, 2);
add_filter('wp_insert_post_meta', 'ACME\ExamplesClass::logInsert', 10, 2);
add_shortcode('example_shortcode', 'ACME\ExamplesClass::shortcode');
add_shortcode('other_shortcode', 'ACME\ExamplesClass::otherShortcode');
//=== End AutoHooks Generated Section ===
```

#### Build/Wire Up

[](#buildwire-up)

```
// Get the list of classes
$classes = \SH\AutoHook\ComposerJsonParser::getClasses($composerJsonPath);

// Process classes to string
[$output] = \SH\AutoHook\AttributeResolver::processClassesToString($classes);

// Write to file
(bool) $written = \SH\AutoHook\FileWriter::write($output, $outputPath);
```

### Advanced Usage

[](#advanced-usage)

Some projects may not have the composer.json available at runtime, so you can use the class loader object.

#### Build/Wire Up

[](#buildwire-up-1)

```
// Get Classloader object
$loader = require 'vendor/autoload.php';

// Get the list of classes
$classes = \SH\AutoHook\ComposerClassLoaderParser::getClasses($loader, ['App\\', 'MyNamespace\\']);

// Process classes to string
[$output] = \SH\AutoHook\AttributeResolver::processClassesToString($classes);

// Write to file
(bool) $written = \SH\AutoHook\FileWriter::write($output, $outputPath);
```

Tests
-----

[](#tests)

To run tests, make sure to create class list through composer:

```
composer du -o
```

Then run the tests:

```
 composer test
```

License
-------

[](#license)

The WordPress AutoHooks Library is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

([back to top](#readme-top))

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance79

Regular maintenance activity

Popularity15

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~102 days

Recently: every ~154 days

Total

8

Last Release

111d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f16952fe5cd35044cf68bac905c9880af4219a0f4318bba55bc03bd6b9f1379f?d=identicon)[spenserhale](/maintainers/spenserhale)

---

Top Contributors

[![spenserhale](https://avatars.githubusercontent.com/u/5643366?v=4)](https://github.com/spenserhale "spenserhale (18 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/spenserhale-wp-autohook-library/health.svg)

```
[![Health](https://phpackages.com/badges/spenserhale-wp-autohook-library/health.svg)](https://phpackages.com/packages/spenserhale-wp-autohook-library)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
