rootDir = $tmp[0] . "/"; if(!isset($options['cache'])){ $options['cache'] = $tmp[0] . '/cache/routing'; } @mkdir($options['cache'], 0777, true); $this->cacheDir = $options['cache']; if(isset($options['controller'])){ if(is_array($options['controller'])){ $controllers = $options['controller']; }else{ $controllers = array($options['controller']); } }else{ $controllers = array($tmp[0] . '/app/controller'); } if(count($controllers)){ foreach($controllers as $controllerPath){ $this->loadPath(realpath($controllerPath)); } } } /******************* * * * CACHE FUNCTIONS * * * *******************/ /** * gets the full path and the name of cache file * * @param $class * * @return string */ protected function cacheFile($class) { return $this->cacheDir . '/' . $class . '.php'; } /** * This method writes the cache content into cache file * * @param $class * @param $content * * @return string */ protected function writeCache($class, $content) { $date = date("Y-m-d h:i:s"); $content = <<cacheFile($class); file_put_contents($fileName, $content); return $fileName; } /** * Generates new file and return cachefile name * @param $classFile * * @return string */ protected function updateAndGetCacheFileName($classFile) { $className = $this->className($classFile); if($this->hasChanged($classFile)){ $content = $this->processClass($classFile); $this->writeCache($className, $content); $this->setDateFromClassFile($classFile); } return $this->cacheFile($className); } /** * Return cachefile contents * * @param $classFile * * @return string */ protected function getCache($classFile) { return file_get_contents($this->updateAndGetCacheFileName($classFile)); } /** * Process the cachefile, in PHP require is enough * * @param $classFile * * @throws \Exception */ protected function processCache($classFile) { require_once($this->updateAndGetCacheFileName($classFile)); } /** * Indicates if the classfile has a diferent modify time that cache file * * @param $classFile * * @return bool */ protected function hasChanged($classFile) { $className = $this->className($classFile); $cacheFile = $this->cacheFile($className); $cacheDate = file_exists($cacheFile) ? filemtime($cacheFile) : 0; $fileDate = filemtime($classFile); return ($fileDate != $cacheDate); } /******************* * * * CLASS FUNCTIONS * * * *******************/ /** * Sets the modify time of cache file according to classfile * * @param $classFile */ protected function setDateFromClassFile($classFile) { $className = $this->className($classFile); $cacheFile = $this->cacheFile($className); $fileDate = filemtime($classFile); touch($cacheFile, $fileDate); } /** * Extracts the className through the classfile name * * @param $classFile * * @return mixed * @throws \Exception */ protected function className($classFile) { $classFile = str_replace($this->rootDir, "", $classFile); $className = str_replace(array(".php", "/"), array("", "_"), $classFile); return $className; } /** * @param $classFile * * @return string * @throws \Exception */ protected function processClass($classFile) { $className = ''; $content = file_get_contents($classFile); $result = ''; preg_match_all('/class\s+(\w*)\s*(extends\s+)?([^{])*/s', $content, $mclass, PREG_SET_ORDER); $className = $mclass[0][1]; if (!$className){ throw new \Exception(sprintf('class not found in %s', $classFile)); } preg_match_all('|(/\*\*[^{]*?{)|', $content, $match, PREG_PATTERN_ORDER); foreach ($match[0] as $k => $m) { $function = '?'; $comments = ''; if (!substr_count($m, 'class')) { $function = substr_count($m, 'function') ? 'yes' : 'no'; if ($function == 'yes') { preg_match_all('/(\/\*\*.*\*\/)/s', $m, $mc, PREG_PATTERN_ORDER); $comments = nl2br($mc[0][0]); preg_match_all('/\*\/\s+(public\s+)?(static\s+)?function\s+([^\(]*)\(/s', $m, $mf, PREG_SET_ORDER); $functionName = $mf[0][3]; preg_match_all("/\*\s+@Route\s*\('([^']*)'\)/s", $comments, $params, PREG_SET_ORDER); $route = $params[0][1]; preg_match_all("/\*\s+@Method\s*\('([^']*)'\)/s", $comments, $params, PREG_SET_ORDER); $method = isset($params[0][1]) ? strtoupper($params[0][1]) : 'GET'; preg_match_all("/\*\s+@Name\s*\('([^']*)'\)/s", $comments, $params, PREG_SET_ORDER); $name = strtolower($params[0][1]); $result .= sprintf( '$app->map("%s", "%s::___%s")->via("%s")->name("%s");' . PHP_EOL, $route, $className, $functionName, str_replace(',','","',$method), $name ); } } } return $result; } /****************** * * * PATH FUNCTIONS * * * ******************/ /** * Main method to invoke the routing system * * @param $phpFile */ protected function loadRoute($phpFile) { require_once $phpFile; $this->processCache($phpFile); } /** * Reads the contents of this dir and returns only dirs * that have first letter capitalized * * @return array */ protected static function readdir($dir) { $entries = array(); foreach (scandir($dir) as $entry) { if(($entry != '.') && ($entry != '..')){ $current = "$dir/$entry"; if($current != $dir){ if(is_dir($current)){ $aux = self::readdir($current); $entries = array_merge($entries, $aux); }else{ if(preg_match("/\w*?Controller.php/", $entry)){ $entries[] = $current; } } } } } return $entries; } /** * Load all Controller classes in an entire path * * @param $path */ protected function loadPath($path) { $controllers = self::readdir($path); if(count($controllers)){ foreach($controllers as $controller){ $this->loadRoute($controller); } } } }