Skip to content

Instantly share code, notes, and snippets.

  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save carlalexander/d439be349fffe01cd381 to your computer and use it in GitHub Desktop.
WordPress event management system
<?php
/**
* An event subscriber who stores an instance of the WordPress event
* manager so that it can trigger additional events.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
abstract class AbstractEventManagerAwareSubscriber implements EventManagerAwareSubscriberInterface
{
/**
* The WordPress event manager.
*
* @var EventManager
*/
protected $event_manager;
/**
* Set the WordPress event manager for the subscriber.
*
* @param EventManager $event_manager
*/
public function set_event_manager(EventManager $event_manager)
{
$this->event_manager = $event_manager;
}
}
<?php
/**
* An event subscriber who stores an instance of the WordPress plugin API
* manager so that it can trigger additional events.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
abstract class AbstractPluginAPIManagerAwareSubscriber implements PluginAPIManagerAwareSubscriberInterface
{
/**
* WordPress Plugin API manager.
*
* @var PluginAPIManager
*/
protected $plugin_api_manager;
/**
* Set the WordPress Plugin API manager for the subscriber.
*
* @param PluginAPIManager $plugin_api_manager
*/
public function set_plugin_api_manager(PluginAPIManager $plugin_api_manager)
{
$this->plugin_api_manager = $plugin_api_manager;
}
}
<?php
/**
* The WordPress event manager manages events using the WordPress plugin API.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
class EventManager
{
/**
* The WordPress plugin API manager.
*
* @var PluginAPIManager
*/
private $plugin_api_manager;
/**
* Constructor.
*
* @param PluginAPIManager $plugin_api_manager
*/
public function __construct(PluginAPIManager $plugin_api_manager)
{
$this->plugin_api_manager = $plugin_api_manager;
}
/**
* Adds the given event listener to the list of event listeners
* that listen to the given event.
*
* @param string $event_name
* @param callable $listener
* @param int $priority
* @param int $accepted_args
*/
public function add_listener($event_name, $listener, $priority = 10, $accepted_args = 1)
{
$this->plugin_api_manager->add_callback($event_name, $listener, $priority, $accepted_args);
}
/**
* Adds an event subscriber.
*
* The event manager adds the given subscriber to the list of event listeners
* for all the events that it wants to listen to.
*
* @param SubscriberInterface $subscriber
*/
public function add_subscriber(SubscriberInterface $subscriber)
{
if ($subscriber instanceof PluginAPIManagerAwareSubscriberInterface) {
$subscriber->set_plugin_api_manager($this->plugin_api_manager);
}
foreach ($subscriber->get_subscribed_events() as $event_name => $parameters) {
$this->add_subscriber_listener($subscriber, $event_name, $parameters);
}
}
/**
* Removes the given event listener from the list of event listeners
* that listen to the given event.
*
* @param string $event_name
* @param callable $listener
* @param int $priority
*/
public function remove_listener($event_name, $listener, $priority = 10)
{
$this->plugin_api_manager->remove_callback($event_name, $listener, $priority);
}
/**
* Removes an event subscriber.
*
* The event manager removes the given subscriber from the list of event listeners
* for all the events that it wants to listen to.
*
* @param SubscriberInterface $subscriber
*/
public function remove_subscriber(SubscriberInterface $subscriber)
{
foreach ($subscriber->get_subscribed_events() as $event_name => $parameters) {
$this->remove_subscriber_listener($subscriber, $event_name, $parameters);
}
}
/**
* Adds the given subscriber listener to the list of event listeners
* that listen to the given event.
*
* @param SubscriberInterface $subscriber
* @param string $event_name
* @param mixed $parameters
*/
private function add_subscriber_listener(SubscriberInterface $subscriber, $event_name, $parameters)
{
if (is_string($parameters)) {
$this->add_listener($event_name, array($subscriber, $parameters));
} elseif (is_array($parameters) && isset($parameters[0])) {
$this->add_listener($event_name, array($subscriber, $parameters[0]), isset($parameters[1]) ? $parameters[1] : 10, isset($parameters[2]) ? $parameters[2] : 1);
}
}
/**
* Adds the given subscriber listener to the list of event listeners
* that listen to the given event.
*
* @param SubscriberInterface $subscriber
* @param string $event_name
* @param mixed $parameters
*/
private function remove_subscriber_listener(SubscriberInterface $subscriber, $event_name, $parameters)
{
if (is_string($parameters)) {
$this->remove_listener($event_name, array($subscriber, $parameters));
} elseif (is_array($parameters) && isset($parameters[0])) {
$this->remove_listener($event_name, array($subscriber, $parameters[0]), isset($parameters[1]) ? $parameters[1] : 10);
}
}
}
<?php
/**
* The WordPress event manager manages events using the WordPress plugin API.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
class EventManager extends PluginAPIManager
{
/**
* Add an event subscriber.
*
* The event manager registers all the hooks that the given subscriber
* wants to register with the WordPress Plugin API.
*
* @param SubscriberInterface $subscriber
*/
public function add_subscriber(SubscriberInterface $subscriber)
{
if ($subscriber instanceof EventManagerAwareSubscriberInterface) {
$subscriber->set_event_manager($this);
}
foreach ($subscriber->get_subscribed_hooks() as $hook_name => $parameters) {
$this->add_subscriber_callback($subscriber, $hook_name, $parameters);
}
}
/**
* Remove an event subscriber.
*
* The event manager removes all the hooks that the given subscriber
* wants to register with the WordPress Plugin API.
*
* @param SubscriberInterface $subscriber
*/
public function remove_subscriber(SubscriberInterface $subscriber)
{
foreach ($subscriber->get_subscribed_hooks() as $hook_name => $parameters) {
$this->remove_subscriber_callback($subscriber, $hook_name, $parameters);
}
}
/**
* Adds the given subscriber's callback to a specific hook
* of the WordPress plugin API.
*
* @param SubscriberInterface $subscriber
* @param string $hook_name
* @param mixed $parameters
*/
private function add_subscriber_callback(SubscriberInterface $subscriber, $hook_name, $parameters)
{
if (is_string($parameters)) {
$this->add_callback($hook_name, array($subscriber, $parameters));
} elseif (is_array($parameters) && isset($parameters[0])) {
$this->add_callback($hook_name, array($subscriber, $parameters[0]), isset($parameters[1]) ? $parameters[1] : 10, isset($parameters[2]) ? $parameters[2] : 1);
}
}
/**
* Removes the given subscriber's callback to a specific hook
* of the WordPress plugin API.
*
* @param SubscriberInterface $subscriber
* @param string $hook_name
* @param mixed $parameters
*/
private function remove_subscriber_callback(SubscriberInterface $subscriber, $hook_name, $parameters)
{
if (is_string($parameters)) {
$this->remove_callback($hook_name, array($subscriber, $parameters));
} elseif (is_array($parameters) && isset($parameters[0])) {
$this->remove_callback($hook_name, array($subscriber, $parameters[0]), isset($parameters[1]) ? $parameters[1] : 10);
}
}
}
<?php
/**
* The WordPress event manager manages events using the WordPress plugin API.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
class EventManager
{
/**
* Adds a callback to a specific hook of the WordPress plugin API.
*
* @uses add_filter()
*
* @param string $hook_name
* @param callable $callback
* @param int $priority
* @param int $accepted_args
*/
public function add_callback($hook_name, $callback, $priority = 10, $accepted_args = 1)
{
add_filter($hook_name, $callback, $priority, $accepted_args);
}
/**
* Add an event subscriber.
*
* The event manager registers all the hooks that the given subscriber
* wants to register with the WordPress Plugin API.
*
* @param SubscriberInterface $subscriber
*/
public function add_subscriber(SubscriberInterface $subscriber)
{
if ($subscriber instanceof EventManagerAwareSubscriberInterface) {
$subscriber->set_event_manager($this);
}
foreach ($subscriber->get_subscribed_hooks() as $hook_name => $parameters) {
$this->add_subscriber_callback($subscriber, $hook_name, $parameters);
}
}
/**
* Executes all the callbacks registered with the given hook.
*
* @uses do_action()
*
* @param string $hook_name
*/
public function execute()
{
$args = func_get_args();
return call_user_func_array('do_action', $args);
}
/**
* Filters the given value by applying all the changes from the callbacks
* registered with the given hook. Returns the filtered value.
*
* @uses apply_filters()
*
* @param string $hook_name
* @param mixed $value
*
* @return mixed
*/
public function filter()
{
$args = func_get_args();
return call_user_func_array('apply_filters', $args);
}
/**
* Get the name of the hook that WordPress plugin API is executing. Returns
* false if it isn't executing a hook.
*
* @uses current_filter()
*
* @return string|bool
*/
public function get_current_hook()
{
return current_filter();
}
/**
* Checks the WordPress plugin API to see if the given hook has
* the given callback. The priority of the callback will be returned
* or false. If no callback is given will return true or false if
* there's any callbacks registered to the hook.
*
* @uses has_filter()
*
* @param string $hook_name
* @param mixed $callback
*
* @return bool|int
*/
public function has_callback($hook_name, $callback = false)
{
return has_filter($hook_name, $callback);
}
/**
* Removes the given callback from the given hook. The WordPress plugin API only
* removes the hook if the callback and priority match a registered hook.
*
* @uses remove_filter()
*
* @param string $hook_name
* @param callable $callback
* @param int $priority
*
* @return bool
*/
public function remove_callback($hook_name, $callback, $priority = 10)
{
return remove_filter($hook_name, $callback, $priority);
}
/**
* Remove an event subscriber.
*
* The event manager removes all the hooks that the given subscriber
* wants to register with the WordPress Plugin API.
*
* @param SubscriberInterface $subscriber
*/
public function remove_subscriber(SubscriberInterface $subscriber)
{
foreach ($subscriber->get_subscribed_hooks() as $hook_name => $parameters) {
$this->remove_subscriber_callback($subscriber, $hook_name, $parameters);
}
}
/**
* Adds the given subscriber's callback to a specific hook
* of the WordPress plugin API.
*
* @param SubscriberInterface $subscriber
* @param string $hook_name
* @param mixed $parameters
*/
private function add_subscriber_callback(SubscriberInterface $subscriber, $hook_name, $parameters)
{
if (is_string($parameters)) {
$this->add_callback($hook_name, array($subscriber, $parameters));
} elseif (is_array($parameters) && isset($parameters[0])) {
$this->add_callback($hook_name, array($subscriber, $parameters[0]), isset($parameters[1]) ? $parameters[1] : 10, isset($parameters[2]) ? $parameters[2] : 1);
}
}
/**
* Removes the given subscriber's callback to a specific hook
* of the WordPress plugin API.
*
* @param SubscriberInterface $subscriber
* @param string $hook_name
* @param mixed $parameters
*/
private function remove_subscriber_callback(SubscriberInterface $subscriber, $hook_name, $parameters)
{
if (is_string($parameters)) {
$this->remove_callback($hook_name, array($subscriber, $parameters));
} elseif (is_array($parameters) && isset($parameters[0])) {
$this->remove_callback($hook_name, array($subscriber, $parameters[0]), isset($parameters[1]) ? $parameters[1] : 10);
}
}
}
<?php
/**
* The login error subscriber adds a custom error to the WordPress login page.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
class LoginErrorSubscriber implements SubscriberInterface
{
/**
* The error code that our login error subscriber creates.
*/
const ERROR_CODE = 'my-login-error-code';
/**
* Returns an array of hooks that this subscriber wants to register with
* the WordPress plugin API.
*
* @return array
*/
public static function get_subscribed_hooks()
{
return array(
'shake_error_codes' => 'add_error_code',
'wp_login_errors' => 'add_error',
);
}
/**
* Add our error to the login errors.
*
* @param WP_Error $error
*
* @return WP_Error
*/
public function add_error(WP_Error $error)
{
if (!isset($_GET[self::ERROR_CODE])) {
return $error;
}
$error->add(self::ERROR_CODE, 'The error message displayed on the login screen.');
return $error;
}
/**
* Add our error code to the handled login error codes.
*
* @param array $error_codes
*
* @return array
*/
public function add_error_code(array $error_codes)
{
$error_codes[] = self::ERROR_CODE;
return $error_codes;
}
}
<?php
/**
* Manager that interacts with the WordPress plugin API.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
class PluginAPIManager
{
/**
* Adds a callback to a specific hook of the WordPress plugin API.
*
* @uses add_filter()
*
* @param string $hook_name
* @param callable $callback
* @param int $priority
* @param int $accepted_args
*/
public function add_callback($hook_name, $callback, $priority = 10, $accepted_args = 1)
{
add_filter($hook_name, $callback, $priority, $accepted_args);
}
/**
* Executes all the callbacks registered with the given hook.
*
* @uses do_action()
*
* @param string $hook_name
*/
public function execute()
{
$args = func_get_args();
return call_user_func_array('do_action', $args);
}
/**
* Filters the given value by applying all the changes from the callbacks
* registered with the given hook. Returns the filtered value.
*
* @uses apply_filters()
*
* @param string $hook_name
* @param mixed $value
*
* @return mixed
*/
public function filter()
{
$args = func_get_args();
return call_user_func_array('apply_filters', $args);
}
/**
* Get the name of the hook that WordPress plugin API is executing. Returns
* false if it isn't executing a hook.
*
* @uses current_filter()
*
* @return string|bool
*/
public function get_current_hook()
{
return current_filter();
}
/**
* Checks the WordPress plugin API to see if the given hook has
* the given callback. The priority of the callback will be returned
* or false. If no callback is given will return true or false if
* there's any callbacks registered to the hook.
*
* @uses has_filter()
*
* @param string $hook_name
* @param mixed $callback
*
* @return bool|int
*/
public function has_callback($hook_name, $callback = false)
{
return has_filter($hook_name, $callback);
}
/**
* Removes the given callback from the given hook. The WordPress plugin API only
* removes the hook if the callback and priority match a registered hook.
*
* @uses remove_filter()
*
* @param string $hook_name
* @param callable $callback
* @param int $priority
*
* @return bool
*/
public function remove_callback($hook_name, $callback, $priority = 10)
{
return remove_filter($hook_name, $callback, $priority);
}
}
<?php
require 'class-event-manager-standalone.php';
require 'interface-subscriber-hooks.php';
require 'class-login-error-subscriber.php';
$event_manager = new EventManager();
$event_manager->add_subscriber(new LoginErrorSubscriber());
<?php
/**
* An event subscriber who can use the WordPress event manager to
* trigger additional event.
*
* @author Carl Alexander <carlalexander@helthe.co>
*/
interface EventManagerAwareSubscriberInterface extends SubscriberInterface
{
/**
* Set the WordPress event manager for the subscriber.
*
* @param EventManager $event_manager
*/
public function set_event_manager(EventManager $event_manager);
}
<?php
/**
* An event subscriber who can use the WordPress plugin API manager to
* trigger additional event.
*
* @author Carl Alexander <carlalexander@helthe.co>
*/
interface PluginAPIManagerAwareSubscriberInterface extends SubscriberInterface
{
/**
* Set the WordPress Plugin API manager for the subscriber.
*
* @param PluginAPIManager $plugin_api_manager
*/
public function set_plugin_api_manager(PluginAPIManager $plugin_api_manager);
}
<?php
/**
* A Subscriber knows what specific WordPress events it wants to listen to.
*
* When an EventManager adds a Subscriber, it gets all the WordPress events that
* it wants to listen to. It then adds the subscriber as a listener for each of them.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
interface SubscriberInterface
{
/**
* Returns an array of events that this subscriber wants to listen to.
*
* The array key is the event name. The value can be:
*
* * The method name
* * An array with the method name and priority
* * An array with the method name, priority and number of accepted arguments
*
* For instance:
*
* * array('event_name' => 'method_name')
* * array('event_name' => array('method_name', $priority))
* * array('event_name' => array('method_name', $priority, $accepted_args))
*
* @return array
*/
public static function get_subscribed_events();
}
<?php
/**
* A Subscriber knows what specific WordPress plugin API hooks it wants to register to.
*
* When an EventManager adds a Subscriber, it gets all the hooks that it wants to
* register to. It then registers the subscriber as a callback with the WordPress
* plugin API for each of them.
*
* @author Carl Alexander <contact@carlalexander.ca>
*/
interface SubscriberInterface
{
/**
* Returns an array of hooks that this subscriber wants to register with
* the WordPress plugin API.
*
* The array key is the name of the hook. The value can be:
*
* * The method name
* * An array with the method name and priority
* * An array with the method name, priority and number of accepted arguments
*
* For instance:
*
* * array('hook_name' => 'method_name')
* * array('hook_name' => array('method_name', $priority))
* * array('hook_name' => array('method_name', $priority, $accepted_args))
*
* @return array
*/
public static function get_subscribed_hooks();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment