Skip to content

Instantly share code, notes, and snippets.

@rmccue
Forked from kovshenin/plugin-file.php
Created January 17, 2012 12:27
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rmccue/1626492 to your computer and use it in GitHub Desktop.
Save rmccue/1626492 to your computer and use it in GitHub Desktop.
Improved class concept
<?php
/*****
All new versions will be posted at
https://github.com/rmccue/Rotor_WPPlugin
Please use that repository instead of this Gist.
******/
/*
Plugin Name: WP_Plugin class test
Description: A better test!
Author: Ryan McCue
Version: 1.0
Author URI: http://ryanmccue.info/
*/
class WP_Plugin {
public function __construct() {
$self = new ReflectionClass($this);
foreach ($self->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
$params = $method->getNumberOfParameters();
$hooks = array('filter' => array(), 'action' => array());
if (strpos($method->name, 'filter_') === 0) {
$hook = substr($method->name, 7);
$hooks['action'][$hook] = 10;
}
elseif (strpos($method->name, 'action_') === 0) {
$hook = substr($method->name, 7);
$hooks['action'][$hook] = 10;
}
else {
$doc = $method->getDocComment();
if (empty($doc) || (strpos($doc, '@wordpress-filter') === false && strpos($doc, '@wordpress-action') === false)) {
continue;
}
preg_match_all('#^\s+\*\s*@wordpress-(action|filter)\s+([\w-]+)(\s*\d+)?#im', $doc, $matches, PREG_SET_ORDER);
var_dump($matches);
if (empty($matches)) {
continue;
}
foreach ($matches as $match) {
$type = $match[1];
$hook = $match[2];
$priority = 10;
if (!empty($match[3])) {
$priority = (int) $match[3];
}
$hooks[$type][$hook] = $priority;
}
}
var_dump(__LINE__, $hooks);
foreach ($hooks['filter'] as $hook => $priority) {
add_filter($hook, array($this, $method->name), $priority, $params);
}
foreach ($hooks['action'] as $hook => $priority) {
add_action($hook, array($this, $method->name), $priority, $params);
}
}
}
}
// Here's an example of a plugin that would benefit from the above
class Some_Plugin extends WP_Plugin {
// Will filter the_title
public function filter_the_title( $title ) {
return $title . '123';
}
// Will filter the_content
public function filter_the_content( $content ) {
return $content . ' Add more content.';
}
// Will run during wp_footer
public function action_wp_footer() {
echo "I'm in the footer!";
}
/**
* @wordpress-action init
* @wordpress-action admin_init 25
*/
public function my_init() {
echo "I'm in the footer!";
}
}
$some_plugin = new Some_Plugin();
@GaryJones
Copy link

One trouble with using methods that are named in a certain way, is that you can't have two methods hooked to the same hook with the same priority - for example, scripts() and styles() methods hooked to wp_enqueue_scripts that you may want to be individually unhookable or only conditionally hook able depending if a user wants to not use plugin styles, etc.

@rmccue
Copy link
Author

rmccue commented Jan 20, 2012

@toscho:

BTW I prefer real instances because it is easier to extend such classes. Yes, PHP now inherits static methods too, but you still cannot rely on it.

Yes you can, PHP has always inherited static methods. The only problem with it was that self was always bound to the class it was defined in. With late static binding, you can use static instead, but that sucks.

You'll notice in my add_filter/add_action methods for the static class, it works around this for PHP <5.3

@GaryJones:

you can't have two methods [...] that you may want to be individually unhookable or only conditionally hook able depending if a user wants to not use plugin styles, etc

That's one place where you definitely need code, so I agree with Mark's sentiment on making hooking itself easier.

@peterchester
Copy link

@mikeschinkel

We recently made a library management class for our premium plugins since they often share code. We went off the assumption that we'll want to use the latest version since we can't load the same class name at different versions.

https://gist.github.com/2134425

@easterncoder
Copy link

I find myself hating the process of having to declare add_action, etc far away from the method they're calling and so I search big old google and found this.

Was surprised to find that your style of declaring method names so that the action, priority, etc can be parsed for add_action, etc is similar to what I did years before. I guess great minds think alike. I used said method for one of our company's internal WP plugins and it's still running now.

What I do not like about it is the fact that your method names will always look ugly.

I then saw your approach of using Reflection to get the doc comment which is smart and I almost went that route. Two reasons however prevented me from doing so

  1. It's easy to break. Some coder might mess it up and the code will still run without errors since it's only a comment.
  2. Optimizers like eAccelerator can mess it up as well as previously noted in one of the comments.

But that inspired me to think further and asked... what if it's not a comment? What if it's actual code that is declared in the method itself? I thought why not use static variables. A static variable named a certain way so we can easily find it with Reflection the same way you did with the doc comment.

Here's what I came up with:
https://github.com/easterncoder/wp_autohooks

Would love to hear any feedback.

(I can go to sleep in peach now)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment