Skip to content

Instantly share code, notes, and snippets.

@nikolov-tmw
Created April 23, 2024 18:03
Show Gist options
  • Save nikolov-tmw/34b827a7199fd5ced930952361bc0ab4 to your computer and use it in GitHub Desktop.
Save nikolov-tmw/34b827a7199fd5ced930952361bc0ab4 to your computer and use it in GitHub Desktop.
Maybe-kinda-late-initializing classes in WordPress?
<?php
trait Hookable {
public static function get_instance() {
static $instance = null;
if ( is_null( $instance ) ) {
$instance = new static();
}
return $instance;
}
public static function add_filter( $hook, $priority = 10, $accepted_args = 1 ) {
// You could transform $method to whatever suits your style
// Right now it could end up like "the_content_filter", but if you prefer
// camelCase for method names, you could convert $hook to camelCase and
// add Filter to it so that $method would end up like "theContentFilter"
$method = $hook . '_filter';
// method_exists seems to work regardless of a method's visibility or static/regular type
if ( ! method_exists( static::class, $method ) ) {
// maybe show/log an error message here that this would not work
// due to absence of $method on the current class
return;
}
add_filter( $hook, function() use( $method ) {
$instance = static::get_instance();
return call_user_func_array( [ $instance, $method ], func_get_args() );
}, $priority, $accepted_args );
}
public static function add_action( $hook, $priority = 10, $accepted_args = 1 ) {
// You could transform $method to whatever suits your style
// Right now it could end up like "the_content_action", but if you prefer
// camelCase for method names, you could convert $hook to camelCase and
// add Filter to it so that $method would end up like "theContentAction"
$method = $hook . '_action';
// method_exists seems to work regardless of a method's visibility or static/regular type
if ( ! method_exists( static::class, $method ) ) {
// maybe show/log an error message here that this would not work
// due to absence of $method on the current class
return;
}
add_action( $hook, function() use( $method ) {
$instance = static::get_instance();
call_user_func_array( [ $instance, $method ], func_get_args() );
}, $priority, $accepted_args );
}
}
<?php
/* Your plugin headers here, if this is a plugin */
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
require_once __DIR__ . '/hookable-trait.php';
require_once __DIR__ . '/MySampleClass.php';
// Register the hooks for the class without instantiating it by using a static method
MySampleClass::register_hooks();
<?php
class MySampleClass {
use Hookable;
public static function register_hooks() {
static::add_action( 'wp_footer' );
static::add_filter( 'the_content', 100 );
static::add_filter( 'admin_title', 100, 2 );
}
public function wp_footer_action() {
echo '<h1>This is wp_footer_action()!</h1>';
}
public function the_content_filter( $content ) {
$content .= '<h3>I added this from a filter!</h3>';
return $content;
}
public function admin_title_filter( $admin_title, $title ) {
return $admin_title . ' <==== Test, also received $title: ' . $title;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment