[wp-hackers] overriding pluggable.php functions

Will Norris will at willnorris.com
Sat Jan 10 06:13:31 GMT 2009


On Jan 9, 2009, at 7:12 PM, Dougal Campbell wrote:

> Will Norris wrote:
>> [...] So I've been thinking about how it would work if  
>> pluggable.php were instead made up of functions like:
>>
>> if (!function_exists('wp_authenticate')) {
>>    function wp_authenticate($username, $password) {
>>        return _wp_authenticate($username, $password) {
>>    }
>> }
>>
>> function _wp_authenticate($username, $password) {
>>    /* all the normal authentication logic */
>> }
>>
>> So basically, the functions which can be replaced by plugins don't  
>> actually include any logic whatsoever, they simply call "private"  
>> counterparts.  This way, I can override wp_authenticate, but can  
>> still fall back by calling _wp_authenticate myself. [...]
>
> *headslap, because I didn't think of it myself*
>
> +1 on this idea.
>
> Sometime back, I had run into a a similar problem, wanting to  
> override a pluggable function, but still be able to fall back to the  
> original code. Of course, I went with the quick-and-dirty solution  
> of just copying the original function. But I knew it was an ugly  
> solution, because it wasn't future-proof.
>
> This is the kind of elegant solution that's needed. It's basically  
> the procedural programming equivalent of being able to call a  
> super() method in OOP. :)

I actually chatted with Peter Westwood in #wordpress-dev today and he  
suggested using filters instead... there is certainly an elegance to  
this.  pluggable.php was designed to *replace* functionality, not  
*add* it.  There is already a great mechanism in wordpress to add  
functionality... filters and actions.  So imagine something along the  
lines of...

   if (!function_exists('wp_authenticate')) {
     function wp_authenticate($username, $password) {
       return apply_filters('authenticate', null, $username, password);
     }
   }

   add_filter('authenticate', '_wp_authenticate', 10, 3);
   function _wp_authenticate($user, $username, $password) {
     /* all the normal authentication logic */
   }



Now I could do something like the following in my plugin...

   add_filter('authenticate', 'my_authenticate', 9, 3);
   function my_authenticate($user, $username, $password) {
     if ( /* some check*/) {
       /* custom authenticate logic here */

       // just remove the default authentication filter
       remove_filter('authenticate', '_wp_authenticate');

       // or remove them all
       remove_all_filters('authenticate');
     }
     return $user;
   }


This way we get all the power and flexibility that comes from the  
hooks system.  You do have to think about other plugins that may be  
implementing the same hook, but that's no different than is being done  
today.  Perhaps in the example above, the /* some check */ statement  
should include something along the lines of checking that $user is  
null?  I don't know.  What do you others think?

-will





More information about the wp-hackers mailing list