[wp-hackers] Re: [wp-trac] Re: [WordPress Trac] #3875: Proposal
for a new plugin architecture
jacobsantos at branson.com
jacobsantos at branson.com
Tue Jul 31 20:51:01 GMT 2007
Use Cases (What I expect and not what happens, I will need to do unit
testing for that part):
The below two will create an additional property on the class to keep
track of the of the unique id for removal and insertion. This depends on
the code being accurate, in the handling of the $function_to_add array.
I tried to reference the array, but I'm starting to think that I should
have the '&' in the function instead to make it easier.
For array($this, 'method_name'):
Quote (http://us2.php.net/manual/en/language.references.spot.php):
"In an object method, $this is always a reference to the caller object."
On PHP 4: Should give desired result because it is being passed by
reference anyway.
On PHP 5: Should work as expected..
For array(&$this, 'method_name'):
The redundancy is from some reason for PHP 4, is lost to me, as I didn't
bother to learn class references until PHP 5 when it was no longer a
requirement for classes.
See above. This should be the preferred method, since it won't hurt and
won't break on wrong information in manual or some PHP 4 bug. For the
documentation page.
For array($object, 'method_name');
For PHP 4: Bug on plugin author's part and won't give desired result. It
will create additional copies and won't delete the original. This could
be fixed, but I'm not up for that now. There is a possible way to fix
this, but it would require unit testing to be sure. It should also be
faster, since it wouldn't be creating copies. The fix would only be for
this use case though and I'm not sure it if it worth fixing a bug on the
plugin author's fault.
For PHP 5: Should work as expected.
For array(&$object, 'method_name'):
For PHP 4: Should work as expected.
For PHP 5: Should work as expected.
For array('class_name', 'method_name'):
Perhaps the second fastest, just by how much workload and checking is
done. We don't bother with the checking that the above four do, which
will append a number to the classname and method name when the objects
are different.
This is not needed for static method calling as it doesn't and won't
depend on $this. It would be a bug on the part of the plugin author if
they expect to be able to use $this in their method afterwards. I don't
expect this to be used often enough, but it should still be supported.
For regular function passing:
Would work as expected and should only be slightly slower than what it
is now.
However, only unit testing, code coverage, and profiling will give the
complete and accurate picture. The use cases can easily be made into
tests for running the current code and future code against.
The diff is below:
Index: plugin.php
===================================================================
--- plugin.php (revision 5825)
+++ plugin.php (working copy)
@@ -19,7 +19,10 @@
global $wp_filter, $merged_filters;
// So the format is wp_filter['tag']['array of priorities']['array
of functions serialized']['array of ['array (functions, accepted_args)]']
- $wp_filter[$tag][$priority][serialize($function_to_add)] =
array('function' => $function_to_add, 'accepted_args' => $accepted_args);
+ $fn_idx = _wp_filter_build_unique_id($tag, &$function_to_add,
$priority);
+
+ $wp_filter[$tag][$priority][$fn_idx] = array('function' =>
$function_to_add, 'accepted_args' => $accepted_args);
+ //$wp_filter[$tag][$priority][serialize($function_to_add)] =
array('function' => $function_to_add, 'accepted_args' => $accepted_args);
unset( $merged_filters[ $tag ] );
return true;
}
@@ -97,7 +100,7 @@
* @return boolean Whether the function is removed.
*/
function remove_filter($tag, $function_to_remove, $priority = 10,
$accepted_args = 1) {
- $function_to_remove = serialize($function_to_remove);
+ $function_to_remove = _wp_filter_build_unique_id($tag,
&$function_to_remove, $priority);
$r =
isset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]);
@@ -280,4 +283,51 @@
add_action('deactivate_' . $file, $function);
}
+function _wp_filter_build_unique_id($tag, $function_to_add, $priority = 10)
+{
+ global $wp_filter;
+ // If function then just skip all of the tests and not overwrite
the following.
+ $fn_idx = $function_to_add;
+
+ // Only test if using an array to call a class and method.
+ // Else bypass all of the following checks.
+ if(is_array($function_to_add))
+ {
+ list($obj,$fn) = $function_to_add;
+
+ // Expect most use cases for $obj to be objects and not strings
+ if(is_object($obj))
+ {
+ // We are going to use $classname more than once, store it
+ $classname = get_class($obj);
+ $fn_idx = $classname.$fn;
+
+ if(!is_null($function_to_add[0]->wp_filter_id))
+ {
+ $fn_idx .= $function_to_add[0]->wp_filter_id;
+ }
+
+ // Compare the two object references to see if they are the
same object.
+ // This is slow however as it will check each property and
method for similar, much
+ // like an array comparsion. Should work similar to PHP 4
and PHP 5.
+ if($function_to_add[0] ==
$wp_filter[$tag][$priority][$fn_idx]['function'][0]) {
+ return $fn_idx;
+ } else {
+ $i = count($wp_filter[$tag][$priority]);
+ $function_to_add[0]->wp_filter_id = $i;
+ $fn_idx .= $function_to_add[0]->wp_filter_id;
+ }
+ }
+ // Must mean that it is using static calling.
+ // We can also assume that if they are using static calling
+ // it doesn't matter if they have two or more variables that
they are trying
+ // to add to the same hooks. The bug would be theirs, we can
only assume
+ // that they know enough when doing static method call binding
to know what
+ // to expect.
+ else
+ $fn_idx = $obj.fn;
+ }
+ return $fn_idx;
+}
+
?>
More information about the wp-hackers
mailing list