public static function grab($func, $args = NULL) { if (preg_match('/(.+)\\h*(->|::)\\h*(.+)/s', $func, $parts)) { // Convert string to executable PHP callback if (!class_exists($parts[1])) { self::error(500, ['Invalid Class', $parts[1] . ' class does not exist']); } if ($parts[2] == '->') { $ref = new ReflectionClass($parts[1]); $parts[1] = method_exists($parts[1], '__construct') ? $ref->newinstanceargs($args) : $ref->newinstance(); } $func = array($parts[1], $parts[3]); } return $func; }
/** * Grab the real route handler behind the string expression * @return string|array * @param $func string * @param $args array **/ function grab($func, $args = NULL) { if (preg_match('/(.+)\\h*(->|::)\\h*(.+)/s', $func, $parts)) { // Convert string to executable PHP callback if (!class_exists($parts[1])) { user_error(sprintf(self::E_Class, $parts[1]), E_USER_ERROR); } if ($parts[2] == '->') { if (is_subclass_of($parts[1], 'Prefab')) { $parts[1] = call_user_func($parts[1] . '::instance'); } else { $ref = new ReflectionClass($parts[1]); $parts[1] = method_exists($parts[1], '__construct') ? $ref->newinstanceargs($args) : $ref->newinstance(); } } $func = array($parts[1], $parts[3]); } return $func; }
/** * Execute callback/hooks (supports 'class->method' format) * @return mixed|FALSE * @param $func callback * @param $args mixed * @param $hooks string **/ function call($func, $args = NULL, $hooks = '') { if (!is_array($args)) { $args = array($args); } // Execute function; abort if callback/hook returns FALSE if (is_string($func) && preg_match('/(.+)\\h*(->|::)\\h*(.+)/s', $func, $parts)) { // Convert string to executable PHP callback if (!class_exists($parts[1])) { user_error(sprintf(self::E_Class, $parts[1])); } if ($this->hive['PSEUDO'] && $this->hive['VERB'] == 'POST' && strtolower($parts[3]) == 'post' && preg_match('/!(put|delete)/', implode(',', array_keys($_GET)), $hook) && method_exists($parts[1], $parts[3])) { // ReST implementation for non-capable HTTP clients $this->hive['BODY'] = http_build_query($_POST); $parts[3] = $hook[1]; } if ($parts[2] == '->') { if (is_subclass_of($parts[1], 'Prefab')) { $parts[1] = call_user_func($parts[1] . '::instance'); } else { $ref = new ReflectionClass($parts[1]); $parts[1] = method_exists($parts[1], '__construct') ? $ref->newinstanceargs($args) : $ref->newinstance(); } } $func = array($parts[1], $parts[3]); } if (!is_callable($func)) { // No route handler if ($hooks == 'beforeroute,afterroute') { $allowed = array(); if (isset($parts[1])) { $allowed = array_intersect(array_map('strtoupper', get_class_methods($parts[1])), explode('|', self::VERBS)); } header('Allow: ' . implode(',', $allowed)); $this->error(405); } else { user_error(sprintf(self::E_Method, is_string($func) ? $func : $this->stringify($func))); } } $obj = FALSE; if (is_array($func)) { $hooks = $this->split($hooks); $obj = TRUE; } // Execute pre-route hook if any if ($obj && $hooks && in_array($hook = 'beforeroute', $hooks) && method_exists($func[0], $hook) && call_user_func_array(array($func[0], $hook), $args) === FALSE) { return FALSE; } // Execute callback $out = call_user_func_array($func, $args ?: array()); if ($out === FALSE) { return FALSE; } // Execute post-route hook if any if ($obj && $hooks && in_array($hook = 'afterroute', $hooks) && method_exists($func[0], $hook) && call_user_func_array(array($func[0], $hook), $args) === FALSE) { return FALSE; } return $out; }