ProcessWire icon indicating copy to clipboard operation
ProcessWire copied to clipboard

WireArray::each() with namespace

Open kixe opened this issue 8 years ago • 2 comments

If passing a function as string (function name) to method each(), the string has to include the functions namespace. Would be nice to have a hint in the method description. It took me a while to get this. http://php.net/manual/en/function.is-callable.php#107105

function foo($item) {
 // some stuff
}
$wirearray->each('\ProcessWire\foo'); // works if namespace is declared
$wirearray->each(__NAMESPACE__.'\foo'); // works anyway
$wirearray->each('foo'); // works ONLY if no namespace is declared

Would be genious if the function would add NAMESPACE automatically as the constant return an empty string if no namespace is declared. http://php.net/manual/en/language.namespaces.nsconstants.php

possible solution: change Class WireArray Line 1757ff:

    public function each($func = null) {
        $result = null; // return value, if it's detected that one is desired
        $namespace = (__NAMESPACE__)? __NAMESPACE__.'\\':'';
        if(is_callable($namespace.$func)) {
            $func = $namespace.$func;
            $funcInfo = new \ReflectionFunction($func);

kixe avatar Jun 09 '16 04:06 kixe

If specifying a function, the $func argument should be an actual callable closure/function. Whereas string arguments are meant to map to a property of items in the WireArray or a formatting {string}. Though can see how is_callable() can work with strings too… but unless I'm forgetting something (always possible), that's not the usage we intended here. Can't remove it now of course, if people are using it that way. But maybe it's a good thing if a namespace is required there to prevent mixup with the intended $func as string usages (property name or formatting string).

ryancramerdesign avatar Jun 10 '16 14:06 ryancramerdesign

Since both methods is_callable() and ReflectionFunction::__construct() accepting strings as functions I can see an enhancement. The namespace will only be added if a callable function (as string) is detected.

If a property and a method having the same name there will be a conflict anyway using each() in PW 2.x This solution should work in any case:

    public function each($func = null) {
        $result = null; // return value, if it's detected that one is desired
        $namespace = (__NAMESPACE__)? __NAMESPACE__.'\\':'';
        if(is_callable($func) || is_callable($namespace.$func)) {
            if (!is_callable($func)) $func = $namespace.$func;
            $funcInfo = new \ReflectionFunction($func);

kixe avatar Jun 11 '16 11:06 kixe