|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
c960657 Smarty Regular
Joined: 07 May 2003 Posts: 75 Location: Copenhagen, Denmark
|
Posted: Thu Jun 15, 2006 12:13 pm Post subject: Problems registering multiple pre-/post-/outputfilters |
|
|
I have several classes implementing the methods with the same name, e.g. Foo::filter() and Bar::filter().
If I register both using $smarty->register_outputfilter(array('Foo', 'filter')) and $smarty->register_outputfilter(array('Bar', 'filter')), only Bar::filter() is applied. This is because the method name is used as the key in the $smarty->plugins['outputfilter'][$key] array.
I'm not sure, what the key is used for. One way to fix this would be to just use a unique key generated using uniqid() or similar when the callable is an array. However, I suggest generating a string of the form 'Bar::filter', because this would allow these filters to be unregistered as well (currently filters implemented as class methods cannot be unregistered).
I haven't found a built-in PHP function that converts a callable to a nice string, so in order to do this you need to treat each of the three cases separately ($functionName, array($object, $methodName) and array($className, $methodName)). |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Thu Jun 15, 2006 5:06 pm Post subject: |
|
|
Hi c960657.
Hmmm. That's a pickle.
The key is used mainly for unregistering. This presents some legacy issues. Consider registering an outputfilter (or any filter type) using an array callback:
[php:1:06fb119a00]$smarty->register_outputfilter( array( 'Foo', 'bar' ) );[/php:1:06fb119a00]
The key becomes the function name (as you already said) and so to unregister it:
[php:1:06fb119a00]$smarty->unregister_outputfilter( 'bar' );[/php:1:06fb119a00]
the unregister_*() methods only take a function name, which is unfortunate because anyone relying on this (meaning anyone currently using it) will be SOL if we change the implementation to address this bug.
A long time-ago I had privately proposed a generalized register()/unregister() pair looking to deprecate the zillions of register_*/unregister_* functions that smarty currently sports. Outside of a new mecahnism, I can't see how to address this without major BC issues.
You have good ideas about these sorts of issues so I'd be happy to hear any you might have |
|
Back to top |
|
c960657 Smarty Regular
Joined: 07 May 2003 Posts: 75 Location: Copenhagen, Denmark
|
Posted: Fri Jun 16, 2006 4:19 pm Post subject: |
|
|
Hi boots,
boots wrote: |
the unregister_*() methods only take a function name, which is unfortunate because anyone relying on this (meaning anyone currently using it) will be SOL if we change the implementation to address this bug.
|
One way to make register_*() and unregister_*() symmetrical while still allowing unregister_outputfilter('filter') to unregister ('Foo', 'filter') is something like this (not tested):
[php:1:0049d2b049]function register_prefilter($function)
{
$_name = $this->_get_callable_name($function);
$this->_plugins['prefilter'][$_name] = array($function, null, null, false);
}
/**
* Unregisters a prefilter function
*
* @param string $function name of PHP function
*/
function unregister_prefilter($function)
{
$_name = $this->_get_callable_name($function);
if (isset($this->_plugins['prefilter'][$_name])) {
unset($this->_plugins['prefilter'][$function]);
} elseif (is_string($function)) {
// BC compatibily
foreach ($this->_plugins['prefilter'] as $n => $_function) {
if (is_array($_function) && $_function[1] == $_name) {
// should we trigger a warning
unset($this->_plugins['prefilter'][$n]);
break;
}
}
}
}
// Returns a canonical string representation of a callable
function _get_callable_name($function)
if (is_array($function) && sizeof($function) == 2) {
if (is_string($function[0])) {
$_name = implode('::', $function);
} else {
$_name = get_class($function[0]) . '::' . $function[1];
}
} elseif (is_string($function)) {
$_name = $function;
} else {
$this->trigger_error('Invalid argument');
}
// PHP class and function names are case-insensitive
return strtolower($_name);
}[/php:1:0049d2b049]
It's not pretty, but I don't think it is very ugly either |
|
Back to top |
|
El Hombre Gris Smarty Rookie
Joined: 21 Apr 2006 Posts: 23
|
Posted: Thu Jun 22, 2006 1:55 pm Post subject: |
|
|
If you just need to register a filter from static member functions without risking to overwrite some other filter, and you won't need to unregister them, you can use create_function():
Code: | $smarty->register_outputfilter(create_function('$tpl_output, &$smarty', 'return Foo::filter($tpl_output, $smarty);')); |
This will create an "anonymous" function (not really anonymous, it has a unique name automatically generated) which will call the static member function. |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Thu Jun 22, 2006 3:14 pm Post subject: |
|
|
El Hombre Gris wrote: | If you just need to register a filter from static member functions without risking to overwrite some other filter, and you won't need to unregister them, you can use create_function():
Code: | $smarty->register_outputfilter(create_function('$tpl_output, &$smarty', 'return Foo::filter($tpl_output, $smarty);')); |
This will create an "anonymous" function (not really anonymous, it has a unique name automatically generated) which will call the static member function. |
Clever, as always, Mr Grey |
|
Back to top |
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|