PHP Classes

File: JLaso/SlimRoutingManager/RoutingCacheManager.php

Recommend this page to a friend!
  Classes of Joseluis Laso   Slim Routing Manager   JLaso/SlimRoutingManager/RoutingCacheManager.php   Download  
File: JLaso/SlimRoutingManager/RoutingCacheManager.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Slim Routing Manager
Read routes from controller class annotations
Author: By
Last change: Update of JLaso/SlimRoutingManager/RoutingCacheManager.php
Date: 5 months ago
Size: 7,822 bytes
 

Contents

Class file image Download
<?php

namespace JLaso\SlimRoutingManager;

use \
Slim\Slim;

class
RoutingCacheManager
{

    protected
$cacheDir;
    protected
$rootDir;

   
/**
     * @param array $options
     */
   
function __construct($options = array())
    {
       
$tmp = preg_split('|/vendor/|', __DIR__);
       
$this->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 = <<<EOD
<?php


/**
 * Generated with RoutingCacheManager
 *
 * on
{$date}
 */

\$app = Slim\Slim::getInstance();

{$content}

EOD;
       
$fileName = $this->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);
            }
        }
    }


}