diff --git a/api/src/Link.php b/api/src/Link.php index da84892067..e7d660de9e 100644 --- a/api/src/Link.php +++ b/api/src/Link.php @@ -751,45 +751,7 @@ class Link extends Link\Storage echo "Options: "; _debug_array($options); } - // See etemplate's nextmatch widget, following was copied from there - // allow static callbacks - if(strpos($method,'::') !== false) - { - // workaround for php < 5.3: do NOT call it static, but allow application code to specify static callbacks - if (version_compare(PHP_VERSION,'5.3','<')) list($class,$method) = explode('::',$method); - } - else - { - list($app,$class,$method) = explode('.',$method); - } - if ($class) - { - if (!$app && !is_object($GLOBALS[$class])) - { - $GLOBALS[$class] = new $class(); - } - if (is_object($GLOBALS[$class])) // use existing instance (put there by a previous CreateObject) - { - $obj = $GLOBALS[$class]; - } - else - { - $obj = CreateObject($app.'.'.$class); - } - } - if(is_callable($method)) // php5.3+ call - { - $result = call_user_func($method,$pattern,$options); - } - elseif(is_object($obj) && method_exists($obj,$method)) - { - $result = $obj->$method($pattern,$options); - } - else - { - // if there is no object or no method, give a more explaining error message - throw new Exception\AssertionFailed("Object has no method '$reg[query]'!"); - } + $result = self::exec($method, $pattern, $options); if (!isset($options['total'])) { @@ -848,7 +810,7 @@ class Link extends Link\Storage } $method = $reg['title']; - if (true) $title = ExecMethod($method,$id); + if (true) $title = self::exec($method,$id); if ($id && is_null($title)) // $app,$id has been deleted ==> unlink all links to it { @@ -909,7 +871,7 @@ class Link extends Link\Storage { for ($n = 0; ($ids = array_slice($ids_to_query,$n*self::MAX_TITLES_QUERY,self::MAX_TITLES_QUERY)); ++$n) { - foreach(ExecMethod(self::$app_register[$app]['titles'],$ids) as $id => $t) + foreach(self::exec(self::$app_register[$app]['titles'],$ids) as $id => $t) { $title =& self::get_cache($app,$id); $titles[$id] = $title = $t; @@ -1533,7 +1495,7 @@ class Link extends Link\Storage $method = $args['method']; unset($args['method']); //error_log(__METHOD__."() calling $method(".array2string($args).')'); - ExecMethod($method, $args); + self::exec($method, $args); } } @@ -1649,7 +1611,7 @@ class Link extends Link\Storage { throw new Exception\WrongParameter(__METHOD__."('$id')"); } - $ret = call_user_func_array('ExecMethod2', $data); + $ret = call_user_func_array('self::exec', $data); if (is_resource($ret)) fseek($ret, 0); @@ -1703,7 +1665,7 @@ class Link extends Link\Storage } else { - $ret = ExecMethod2($method,$id,$required,$rel_path,$user); + $ret = self::exec($method,$id,$required,$rel_path,$user); $err = "(from $method)"; } //error_log(__METHOD__."('$app',$id,$required,'$rel_path',$user) returning $err ".array2string($ret)); @@ -1716,7 +1678,7 @@ class Link extends Link\Storage { if(($method = self::get_registry($app,'file_access'))) { - $cache |= ExecMethod2($method,$id,$required,$rel_path) ? $required|Acl::READ : 0; + $cache |= self::exec($method,$id,$required,$rel_path) ? $required|Acl::READ : 0; } else { @@ -1727,5 +1689,41 @@ class Link extends Link\Storage //else error_log(__METHOD__."($app,$id,$required,$rel_path) using cached value $cache --> ".($cache & $required ? 'true' : 'false')); return !!($cache & $required); } + + /** + * Execute a static method or $app.$class.$method string with given arguments + * + * In case of a non-static method as shared instance of the class is used. + * This is a replacement for global ExecMethod(2) functions. + * + * @param callable|string $method "$app.$class.$method" or static method + * @param mixed args variable number of arguments + */ + protected static function exec($method) + { + static $objs = array(); + + $params = func_get_args(); + array_shift($params); + + // static methods or callables can be called directly + if (is_callable($method)) + { + return call_user_func_array($method, $params); + } + + list($app, $class, $m) = $parts = explode('.', $method); + if (count($parts) != 3) throw Api\Exception\WrongParameter("Wrong dot-delimited method string '$method'!"); + + if (!isset($objs[$class])) + { + if (!class_exists($class)) + { + require_once EGW_INCLUDE_ROOT.'/'.$app.'/inc/class.'.$class.'.inc.php'; + } + $objs[$class] = new $class; + } + return call_user_func_array(array($objs[$class], $m), $params); + } } Link::init_static(); diff --git a/api/src/loader/deprecated_factory.php b/api/src/loader/deprecated_factory.php index 673eaa57f7..62c5a58854 100755 --- a/api/src/loader/deprecated_factory.php +++ b/api/src/loader/deprecated_factory.php @@ -17,7 +17,7 @@ use EGroupware\Api; * Load a class and include the class file if not done so already. * * This function is used to create an instance of a class, and if the class file has not been included it will do so. - * $GLOBALS['egw']->acl =& CreateObject('phpgwapi.acl'); + * $GLOBALS['egw']->acl = CreateObject('phpgwapi.acl'); * * @author RalfBecker@outdoor-training.de * @param $classname name of class @@ -97,7 +97,6 @@ function CreateObject($class) /** * Execute a function with multiple arguments - * We take object $GLOBALS[classname] from class if exists * * @param string app.class.method method to execute * @example ExecObject('etemplates.so_sql.search',$criteria,$key_only,...); @@ -106,25 +105,17 @@ function CreateObject($class) */ function &ExecMethod2($acm) { - // class::method is php5.2.3+ - if (strpos($acm,'::') !== false && version_compare(PHP_VERSION,'5.2.3','<')) - { - list($class,$method) = explode('::',$acm); - $acm = array($class,$method); - } if (!is_callable($acm)) { list(,$class,$method) = explode('.',$acm); - if (!is_object($obj =& $GLOBALS[$class])) + + if (class_exists($class)) { - if (class_exists($class)) - { - $obj = new $class; - } - else - { - $obj = CreateObject($acm); - } + $obj = new $class; + } + else + { + $obj = CreateObject($acm); } if (!method_exists($obj,$method)) @@ -162,29 +153,26 @@ function ExecMethod($method, $functionparam = '_UNDEF_', $loglevel = 3, $classpa if (!is_callable($method) && $partscount == 2) { list($appname,$classname,$functionname) = explode(".", $method); - if (!is_object($GLOBALS[$classname])) + + if ($classparams != '_UNDEF_' && ($classparams || $classparams != 'True')) { - // please note: no reference assignment (=&) here, as $GLOBALS is a reference itself!!! - if ($classparams != '_UNDEF_' && ($classparams || $classparams != 'True')) - { - $GLOBALS[$classname] = CreateObject($appname.'.'.$classname, $classparams); - } - elseif (class_exists($classname)) - { - $GLOBALS[$classname] = new $classname; - } - else - { - $GLOBALS[$classname] = CreateObject($appname.'.'.$classname); - } + $obj = CreateObject($appname.'.'.$classname, $classparams); + } + elseif (class_exists($classname)) + { + $obj = new $classname; + } + else + { + $obj = CreateObject($appname.'.'.$classname); } - if (!method_exists($GLOBALS[$classname],$functionname)) + if (!method_exists($obj, $functionname)) { error_log("ExecMethod('$method', ...) No methode '$functionname' in class '$classname'! ".function_backtrace()); return false; } - $method = array($GLOBALS[$classname],$functionname); + $method = array($obj, $functionname); } if (is_callable($method)) {