/** * Instance Collector * * @return object Collector */ public static function collector() { if (!self::$Collector instanceof Collector) { self::$Collector = new Collector(Server::getHeaders()); } return self::$Collector; }
/** * Clean The uri double slashed to single slashed * eg : http://domain.com//do//this////uri///// to http://domain.com/do/this to prevent much 404 error * ;/domain.com | :/domain.com | ://domain.com | ;//domain.com to //domain.com * and replace backslashed to slashed * * @param string $uri the url to clean * @param boolan $replace_space true if you want use replace sache with (+) - plus characters * @param boolean $use_http true if use http as prefix is possible when url use start as (//) * @return string $result as clean uri */ public static function cleanSlashUri($uri, $replace_space = false, $use_http = false) { // if non string stop here return original if (!is_string($uri) || !$uri) { return $uri; } static $result, $tmpuri = null; // if uri is same and has result , then will be return as before if ($result !== null && $tmpuri === $uri) { return $result; } // determine $tmpuri as $uri variables $tmpuri = $uri; $query = ''; if (strpos($uri, '?')) { $explode = explode('?', $uri); $uri = $explode[0]; if (count($explode) > 1) { array_shift($explode); } $query = '?' . implode('?', $explode); } // clean request uri backslashed replaces, remember on windows request uri backslash ( \ ) , is not functions!! $slashed = preg_replace('/(\\\\)+/', '/', trim($uri)); // clean the protocol;// | protocol// // or ;// | :// ( this will be only start with ; or : or double slash not single slash (/) or start with etc. ) // hate the loop ! so save it as array variable , this value same as allowed_protocols() $regex = array('/\\/{3,}/', '/^(:|;)*\\/\\/|^(:|;)\\/+/'); $protocol = array('/', '//'); $result = preg_replace($regex, $protocol, $slashed); // closure object as callback $tolowerfix = function ($n) { $n[0] = str_replace(';', ':', strtolower($n[0])); $n[0] = preg_replace('/^(.*)\\/\\//', '$1://', $n[0]); return preg_replace('/\\:{1,}/', ':', $n[0]); }; /** * replace unsafe protocols if use ; or multiple : or ; * eg : http:::::::/www.domain.com | http;//www.domain.com will be http://www.domain.com * http;/domain.com | http:/domain.com will be http://domain.com * replace only safe protocol , and make it lower */ $regex = '/^(http|https|ftp|ftps|mailto|news|irc|gopher|nntp|feed|telnet|mms|rtsp|svn|tel|fax|xmpp|rtmp)((;|:)*\\/?\\/?)/i'; $result = preg_replace_callback($regex, array($tolowerfix, '__invoke'), $result); // end // clean double slash on url after domain $remslash = function ($c) { return preg_replace('/((.*)\\:)\\/(\\/)?/', '$1/$3', $c[1]) . preg_replace('/(\\/\\/)+/', '/', $c[4]); }; $regex = '/^(((.*):)?\\/\\/?)?(.*)/'; $result = preg_replace_callback($regex, array($remslash, '__invoke'), $result); // end $result = preg_replace('/^(\\/\\/)?(mailto|xmpp)(\\:)(\\/\\/)?(.*)?/', '$2$3$5', $result); if ($result[strlen($result) - 1] === '/') { $result = rtrim($result, '/'); } if ($replace_space) { $result = str_replace(' ', '+', $result); } if ($use_http === true && preg_match('/^\\/\\//', $result)) { $result = Server::httpProtocol() . ':' . $result; } return $result = $result . $query; }
/** * Checking current request File as Root path * * @return string base directory of root path */ public static function currentRootpath() { static $root; if (!$root) { $root = static::cleanSlashed(dirname(Server::get('SCRIPT_FILENAME'))); } return $root; }
/** * Parse x_Routes * * Matches any x_routes that may exist in the x_routes definition * @access private */ protected function parse() { // remove not found self::removeNotFound(); // Turn the segment array into a URI string $uri = implode('/', Url::allSegment()); // Get HTTP verb $http_verb = strtoupper(trim(Server::get('REQUEST_METHOD', 'CLI'))); if (!isset($this->x_routes['main'])) { $this->x_routes['main'] = array(); } if (!isset($this->x_routes['default'])) { $this->x_routes['default'] = array(); } $default_array = array('main' => $this->x_routes['main'], 'default' => $this->x_routes['default']); // sort it again $this->x_routes = array_merge($default_array, $this->x_routes); unset($default_array); // freed foreach ($this->x_routes as $routeKey => $route) { if (empty($route)) { continue; } // Is there a literal match? If so we're done if (isset($route[$uri]) && !preg_match('/[\\)\\(]/', $uri) && strpos($uri, ':any') === false && strpos($uri, ':num') === false && is_callable($route[$uri]['function']) && $route[$uri]['method'] == $http_verb) { $this->x_current_route = array('name' => $routeKey, 'route' => $uri); return $this->setRequest($route[$uri]['function']); } // Loop through the route array looking for wildcards foreach ($route as $key => $Rval) { if (!is_array($Rval)) { continue; } // $keyTmp = $key; // Convert wildcards to RegEx $key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key); if (strpos($key, '/') === 0) { $key = "/" . substr($key, 1); } elseif ($key && preg_match('/(^\\(\\?[iUXxms]\\))/', $key)) { // parentesis $key = preg_replace_callback('/(^\\(\\?[iUXxms]\\))(.*)/', function ($match) { return $match[1] . (strpos($match[2], '/') === 0 ? substr($match[2], 1) : $match[2]); }, $key); } else { $key = "/{$key}"; } // fix :any or [^/]+ on first statements $key = preg_replace('/^(\\/|\\(\\?[iUXxms]\\))(\\(+)?(\\[\\^\\/\\]\\+)(\\)+)/', "\$1(.?\$3)", $key); // Does the RegEx match? if (preg_match('#^' . $key . '$#', '/' . $uri, $matches)) { // Are we using callbacks to process back-references? if (is_callable($Rval['function'])) { if ($Rval['method'] == 'ALL' || in_array($http_verb, explode('|', $Rval['method']))) { $this->x_current_route = array('name' => $routeKey, 'route' => $key); return $this->setRequest($Rval['function']); } } } } } // set Not Found empty($uri) || self::setNotfound(); // If we got this far it means we didn't encounter a // matching route so we'll set the site default route return $this->setRequest(); }
/** * Parse Request URL * * @return string Request URI parsed */ protected function parseRequestUri() { // static cached static $return = null; if ($return !== null) { return $return; } if (!Server::get('REQUEST_URI') && !Server::get('SCRIPT_NAME')) { $return = ''; return $return; } // add Request URI // $requri = Path::cleanSlashed(Request::getHost().'/'.Server::get('REQUEST_URI')); $requri = Server::get('REQUEST_URI'); $requri = substr($requri, 0, 1) == '/' ? $requri : "/{$requri}"; $requri = rtrim(Request::getHost(), '/') . $requri; $uri = parse_url('http://' . $requri); $query = isset($uri['query']) ? $uri['query'] : ''; $uri = isset($uri['path']) ? $uri['path'] : ''; $script_name = Server::get('SCRIPT_NAME'); if (isset($script_name[0])) { /** * Set New URL Path */ if (strpos($uri, $script_name) === 0) { $uri = substr($uri, strlen($script_name)); } elseif (strpos($uri, dirname($script_name)) === 0) { $uri = substr($uri, strlen(dirname($script_name))); } } // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct // URI is found, and also fixes the QUERY_STRING server var and $_GET array. if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0) { $query = explode('?', $query, 2); $uri = $query[0]; $_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : ''; } else { $_SERVER['QUERY_STRING'] = $query; } // replace server attributes Server::replace($_SERVER); // parse the string parse_str($_SERVER['QUERY_STRING'], $_GET); // replace get Get::replace($_GET); if ($uri === '/' || $uri === '') { $return = '/'; } else { $return = Path::removeRelativeDirectory($uri); } return $return; }
/** * Initialize application * * @return object $instance current singleton instance object */ public static function create() { static $has_call = null; $instance = static::singleton(); if (!$has_call) { $has_call = true; // for CLI used if (defined('STDIN')) { chdir(dirname(Server::get('SCRIPT_FILENAME', getcwd()))); } } return $instance; }
/** * Get Path Info (virtual path) * * @return string */ public static function getPathInfo() { return Server::get('PATH_INFO'); }