Hi there,
I'd say I'm a WordPres Ninja Brown Belt - not the highest skilled ninja, but definitely not a newbie. I've come across something that I could use some help on. I'll keep trying to figure it out myself, but if anyone can offer suggestions, I'd appreciate it.
Here's the (I think) minimal code to reproduce:
1. Add two filters to the same hook. Make it so that the first one you add has a later priority than the second.
add_filter('foo','foo2',13,2);
add_filter('foo','foo3',12,2);
2. Define foo2 and foo3 (note, dump is just a debug trace for myself which I've included below for reference):
function foo2($var,$args){
$smarty = $args[0];
dump("2: (start)",$smarty,$var);
if ($var == 'why'){
$smarty->internal = 'foo2';
bar($smarty);
}
dump("2: (end)",$smarty,$var);
return $var;
}
function foo3($var,$args){
$smarty = $args[0];
dump("3: (start)",$smarty,$var);
if ($var == 'why'){
$smarty->internal = 'foo3';
bar($smarty);
}
dump("3: (end)",$smarty,$var);
return $var;
}
function bar(&$smarty){
$smarty->foo('var2');
}
function dump($foo,&$smarty,$_var){
echo "<pre>";
echo "In foo$foo: \n";
print_r('internal: '.$smarty->internal."\n");
print_r('var: '.$_var."\n");
echo "</pre>";
}
3. Define the class wtf():
class wtf{
var $internal;
function wtf(){
}
function foo($var){
$var = apply_filters('foo',$var,array(&$this));
return $this->internal;
}
}
4. Add the testing shortcode:
add_shortcode('tester','trying');
function trying($content){
$smarty = new wtf();
$smarty->internal = 'internal';
$blah = $smarty->foo('why');
return $blah;
}
Note that foo2 and foo3 both set the $smarty->internal variable. That's the thing that I'm ultimately interested in and it's what's returned by the function $smarty->foo(). Because foo2 is prioritized to happen after foo3, I __expect/desire__ the value of $blah to be 'foo2'.
The behaviour is complicated by the fact that foo2 and foo3 both call the bar() function, which in turn calls $smarty->foo(), which in turn applies the same foo filters. (Yes, there's a reason I'm doing all of this, I'll explain it below).
When all of the above code is executed, the value of $blah does not end up being the desired 'foo2', but instead it is 'foo3'.
I would expect the filters to be applied in this order:
foo3('why') - (see $smarty->foo('why') in the trying() function)
- foo3('var2') - (see $smarty->foo('var2') in the bar() function)
- foo2('var2')
foo2('why') - the next filter I added
- foo3('var2')
- foo2('var2')
However, what ends up happening is the foo2('why') filter never gets applied. I can't figure out why. I think it gets removed from the wp_filters array somehow within the apply_filters() function because of the quasi-recursion.
WHY I'M TRYING TO DO THIS
-------------------------
The variable is named $smarty for a reason. I'm using the Smarty templating engine for a series of plugins I'm creating. I've extended the Smarty class with a Smarty_Instance class to allow a call to filters. The Smarty_Instance::fetch function looks like:
function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false){
$resource_name = apply_filters('Smarty_Instance_resource_name',$resource_name,array(&$this));
return parent::fetch($resource_name,$cache_id,$compile_id,$display);
}
This allows me to add display customizations to plugin templates without touching them. The use case I've used most often is to have a plugin change the template_directory of the $smarty object to be a directory within its structure, as opposed to the directory within the original plugin (that's what $smarty->internal in the above code represents).
The quasi-recursion comes when a template gets content by fetching another template, thus calling the filters again. But, it __SHOULD__ be acceptable because it's calling it with different $resource_name values (corresponds to $var in the above code).
I'm sure this belongs in the Advanced forum, but I'm not a moderator, so I can't post there. If appropriate, I'll trust someone will move it there.
Do any of you black belts out there have any ideas on what's going on and/or a way to avoid the problem?
I hope I've explained this accordingly. I'm happy to clarify anything if it'll help.
Thanks for any help that comes back to me.