I made a late checkin on the 1.4 branch today.
The problem was with Hooks.php, the event-handling mechanism for
optional functionality and third-party extensions. wfRunHooks(), the
interface for mainline code to raise events for hooks to handle, was
using PHP's variable-argument syntax so you could give different
parameter sets to different events:
wfRunHooks('Event1', $param1, $param2, $param3); # three params
wfRunHooks('Event2', $param4, $param5); # just two params
The problem with this is that the var args syntax silently changes
pass-by-reference semantics to pass-by-value semantics. So events that
should allow modifying parameters do not. For example:
$wgEventHooks['Event3'][] = 'MyEvent3Handler';
# ...
function MyEvent3Handler(&$str) {
$str .= " and so on.";
return true;
}
# ...
$somestring = "Eggs, bananas, bacon";
# NOTE: OLD CALLING FORMAT
if (wfRunHooks('Event3', &$somestring)) {
echo $somestring; # prints "Eggs, bananas, bacon"
}
After some consulting with PHP gurus, the best solution I could come up
with was to pack the params in an array when passing them to
wfRunHooks(). Now the last few lines are:
if (wfRunHooks('Event3', array(&$somestring))) {
echo $somestring; # prints "Eggs, bananas, bacon and so on."
}
Adding a reference to an array keeps its "reference-ness".
I wanted to make sure that the hooks technology was at least worth
experimenting with in the 1.4 branch, and that the interface (from both
sides) was relatively stable. Hooks need to be able to modify their
parameters to be useful, so I made these changes.
I've done pretty extensive testing of all the points in 1.4 where
wfRunHooks() is called, and it seems to be stable.
~Evan
--
Evan Prodromou
evan(a)bad.dynu.ca