DWS WP Framework
  • Welcome
  • Primary goals
    • Modular design
    • No 3rd-party dependencies
  • Key concepts and dev tools
    • PHP and WP requirements
    • Object-Oriented Programming
    • Semantic Versioning
    • Version Control (git / GitHub)
    • Dependency Management (Composer)
    • Automated Testing (Codeception + Github Actions)
    • Dependency Injection (PHP-DI)
    • Coding Standards (PHPCS and PHPMD)
    • Dependencies Scoping (PHP-Scoper)
    • TypeScript and Sass
    • Task Runners (Grunt)
  • Setting up your dev environment
    • Windows
  • Your first plugin
    • Multiple plugins using the framework on the same site
  • Frequently Asked Questions
  • Bootstrapper Module
    • Motivation
    • How it works
    • How to use
    • White Labeling
  • Helpers Module
    • Motivation
    • How to use
  • Foundations Module
    • Motivation and How to use
    • Actions
      • Local action traits
      • Extension action traits
      • Integration action traits
    • States
    • Utilities
      • Stores
      • Handlers and Services
        • Logging Service
  • Plugin
    • Main Plugin Instance
    • Plugin Components
  • Hierarchies
  • Helpers
  • Utilities Module
    • Motivation and How to use
    • Hooks Service
      • Scoped Handler
    • Shortcodes Service
    • Templating Service
    • Assets Service
      • Scripts Handler
      • Styles Handler
    • CRON Events Service
      • Action Scheduler Handler
    • Admin Notices Service
    • Dependencies Service
    • Validation Service
  • Core Module
    • Motivation and How to use
    • Plugin Tree
      • Plugin Root
      • Plugin Functionality
    • Plugin Components
      • Internationalization
      • Installation / Upgrade / Uninstallation
  • Settings Module
    • Motivation and How to use
    • Settings Service
      • WordPress Handler
      • MetaBox Handler
      • ACF Handler
    • Validated Settings
  • WooCommerce Module
    • Motivation and How to use
    • Extended WC Logger
    • WC Settings Handler
Powered by GitBook
On this page
  • Bypassing the late registration
  • Available Traits

Was this helpful?

  1. Utilities Module

Hooks Service

PreviousMotivation and How to useNextScoped Handler

Last updated 4 years ago

Was this helpful?

The hooks service is first-of-all and second-of-all a object. It's a service designed to work with WordPress actions and filters (commonly referred to as hooks). Basically the service provides the following public methods:

  • add_action - registers an action with the handler

  • remove_action - removes an action registered with the handler

  • remove_all_actions - removes all actions registered with the handler

  • add_filter - registers a filter with the handler

  • remove_filter - remove a filter registered with the handler

  • remove_all_filters - removes all filters registered with the handler

All of these methods are just wrappers against the registered handler. Any handler implementing the can be registered with the hooks service, but you may also decide to simply use the default handler instantiated if no handler is passed on in the constructor. The default handler is an instance of the inspired defined in the .

The intention is to only register the hooks with the WordPress system if the plugin was successfully initialized. If an error occurred, we don't want any half-hooks being called.

The default handler maintains all of the registered hooks in protected arrays and calls WordPress' own add_action and add_filter functions on its own run action.

The handler's run and reset methods are automatically called when the hooks service's respective methods are called.

Bypassing the late registration

This approach arguably has its downsides. For example, you can't use any of your own hooks during plugin initialization (because that's when you're supposed to call run on the service). If you want to bypass this, there are 2 options available:

  1. Just don't use the service. We think the advantages outweigh the disadvantages, but that's for you to decide.

  2. Write your own custom handler implementing the interface and have it call the WP API directly.

Available Traits

There are 3 traits available for working with the hooks service.

<?php

namespace DeepWebSolutions\Plugins\MyPlugin;

use DeepWebSolutions\Framework\Utilities\Hooks\HooksService;
use DeepWebSolutions\Framework\Utilities\Hooks\HooksServiceAwareInterface ;
use DeepWebSolutions\Framework\Utilities\Hooks\HooksServiceAwareTrait;

defined( 'ABSPATH' ) || exit;

class MyClass implements HooksServiceAwareInterface {
    use HooksServiceAwareTrait;
    
    public function register_my_hooks() {
        $hooks_service = $this->get_hooks_service();
        $hooks_service->add_filter( 'dws_myplugin_filter', $this, 'filter_value' );
    }
    
    public function filter_value( $value_to_filter ) {
        // ...modify 'value_to_filter'
        return $value_to_filter;
    }
}

$hooks_service = new HooksService( $plugin_instance, $logging_service_instance );

$my_class = new MyClass();
$my_class->set_hooks_service( $hooks_service );
$my_class->register_my_hooks();

$hooks_service->run();
<?php

namespace DeepWebSolutions\Plugins\MyPlugin;

use DeepWebSolutions\Framework\Utilities\Hooks\HooksService;
use DeepWebSolutions\Framework\Utilities\Hooks\HooksServiceRegisterInterface;
use DeepWebSolutions\Framework\Utilities\Hooks\HooksServiceRegisterTrait;

defined( 'ABSPATH' ) || exit;

class MyClass implements HooksServiceRegisterInterface {
    use HooksServiceRegisterTrait;
    
    public function register_hooks( HooksService $hooks_service ) {
        $hooks_service->add_filter( $this->get_hook_tag( 'dws_myplugin_filter' ), $this, 'filter_value' );
    }
    
    public function filter_value( $value_to_filter ) {
        // ...modify 'value_to_filter'
        return $value_to_filter;
    }
}

$hooks_service = new HooksService( $plugin_instance, $logging_service_instance );

$my_class = new MyClass();
$my_class->register_hooks( $hooks_service );

$hooks_service->run();

Putting it all together, your code could look something like this:

<?php

namespace DeepWebSolutions\Plugins\MyPlugin;

use DeepWebSolutions\Framework\Foundations\Actions\InitializableInterface;
use DeepWebSolutions\Framework\Foundations\Actions\Initializable\InitializableTrait;
use DeepWebSolutions\Framework\Foundations\Actions\SetupableInterface;
use DeepWebSolutions\Framework\Foundations\Actions\Setupable\SetupableTrait;

use DeepWebSolutions\Framework\Foundations\Utilities\DependencyInjection\ContainerAwareInterface;
use DeepWebSolutions\Framework\Foundations\Utilities\DependencyInjection\ContainerAwareTrait;

use DeepWebSolutions\Framework\Utilities\Actions\Initializable\InitializeHooksServiceTrait;
use DeepWebSolutions\Framework\Utilities\Actions\Setupable\SetupHooksTrait;

use DeepWebSolutions\Framework\Utilities\Hooks\HooksService;
use DeepWebSolutions\Framework\Utilities\Hooks\HooksServiceRegisterInterface;
use DeepWebSolutions\Framework\Utilities\Hooks\HooksServiceRegisterTrait;

defined( 'ABSPATH' ) || exit;

class MyClass implements ContainerAwareInterface, InitializableInterface, SetupableInterface {
    use ContainerAwareTrait;
    use InitializeHooksServiceTrait;
    use InitializableTrait;
    use SetupableTrait;
    use SetupHooksTrait;
    
    public function register_hooks( HooksService $hooks_service ) {
        // register your hooks in here...
    }
}

$my_class = new MyClass();
$my_class->set_container( $my_dependency_injection_container );

$my_class->initialize(); // the hooks service will be set on the instance from the DI container
$my_class->setup(); // the 'register_hooks' method will be automagically called

If the number of imported interfaces and traits in the example above is scarring you, you can find some comfort in the fact that this is an extreme example built from scratch! Normally you would create pre-built abstract objects that implement most of these features and simply extend them. That's basically what our Core Module does!

First there is the and the corresponding . Basically this allows you to call upon the hooks service instance from anywhere within the object. Technically, you can also use more than one service in your plugin and register different ones with different objects.

The second method involves injecting the hooks service from outside the instance. This behavior is modelled by the interface and the .

The recommended way, however, is to use the action trait. It's an for automagically calling the aforementioned register_hooks methods upon the setup action. If attempts to obtain an instance of the HooksService either from the object itself (if it implements the HooksServiceAwareInterface interface) or from a container.

There is also an accompanying action trait. This one attempts to set the hooks service on the instance by first querying its parent and lastly the container for an instance.

a single-handler service
runnable and resettable
HooksHandlerInterface
DefaultHooksHandler
by the loader
WordPress Plugin Boilerplate by DevinVinson
HooksHandlerInterface
HooksServiceAwareTrait
HooksServiceAwareInterface
HooksServiceRegisterInterface
HooksServiceRegisterTrait
SetupHooksTrait
action extension trait
dependency injection
InitializeHooksServiceTrait
dependency injection