/**
* Class loader method
*
* Additional arguments may be supplied and are passed to the sub-class.
* Additional include paths are also able to be specified for third-party use
*
* @param string $key The name of helper method to load, (prefix).(class).function
* prefix and class are optional and can be used to load custom
* html helpers.
* @param array $methodArgs The arguments to pass forward to the method being called
*
* @return mixed Result of HTMLHelper::call($function, $args)
*
* @since 1.5
* @throws \InvalidArgumentException
*/
public static final function _(string $key, ...$methodArgs)
{
list($key, $prefix, $file, $func) = static::extract($key);
if (\array_key_exists($key, static::$registry)) {
$function = static::$registry[$key];
return static::call($function, $methodArgs);
}
/*
* Support fetching services from the registry if a custom class prefix was not given (a three segment key),
* the service comes from a class other than this one, and a service has been registered for the file.
*/
if ($prefix === 'JHtml' && $file !== '' && static::getServiceRegistry()->hasService($file)) {
$service = static::getServiceRegistry()->getService($file);
$toCall = array($service, $func);
if (!\is_callable($toCall)) {
throw new \InvalidArgumentException(sprintf('%s::%s not found.', $file, $func), 500);
}
static::register($key, $toCall);
return static::call($toCall, $methodArgs);
}
$className = $prefix . ucfirst($file);
if (!class_exists($className)) {
$path = Path::find(static::$includePaths, strtolower($file) . '.php');
if (!$path) {
throw new \InvalidArgumentException(sprintf('%s %s not found.', $prefix, $file), 500);
}
\JLoader::register($className, $path);
if (!class_exists($className)) {
throw new \InvalidArgumentException(sprintf('%s not found.', $className), 500);
}
}
// If calling a method from this class, do not allow access to internal methods
if ($className === __CLASS__) {
if (!(new \ReflectionMethod($className, $func))->isPublic()) {
throw new \InvalidArgumentException('Access to internal class methods is not allowed.');
}
}
$toCall = array($className, $func);
if (!\is_callable($toCall)) {
throw new \InvalidArgumentException(sprintf('%s::%s not found.', $className, $func), 500);
}
static::register($key, $toCall);
return static::call($toCall, $methodArgs);
}