<commit_before><?
/**
 * Created by PhpStorm.
 * User: agbetunsin
 * Date: 1/22/14
 * Time: 3:07 PM
 */

namespace Lean;
use ICanBoogie\Inflector;

class Router {

  // instance of application controller class
  protected $controller;

  // array of non RESTful routes, mapped to the controller methods to invoke
  protected $routes = array();

  private $path;
  private $request;
  private $controllerMethodPrefix;
  private $params = array();
  private $inflector;

  private $urlPatterns = array(
    'REST' => '#^/?(?<resource>\w+)(/(?<identifier>[a-z0-9]+)(/(?<sub_resource>\w+))?)?$#'
  );

  // bool flag to indicate whether a route was resolved or not
  private $_resolved = false;

  protected function init(){}

  public static function instance(){
    return new static;
  }

  protected function __construct(){

    $this->inflector = Inflector::get();

    if ( !class_exists('\Controller') )
      throw new ControllerException("No Controller class found in ".LEAN_APP_ROOT);
    
    $this->controller = \Controller::instance();

    $this->request = $_SERVER['REQUEST_METHOD'];

    $this->path = $_SERVER['PATH_INFO'];

    if (!$this->path && isset($_GET['path'])) $this->path = $_GET['path'];

    $this->init();

    $this->route();

    $this->controller->respond();

  }

  private function parseInputData(){
    $input = json_decode(file_get_contents("php://input"), true);
    if (is_array($input))
      $this->controller->extendPostData($input);
  }

  private function route(){

    switch ($this->request) {
      case 'POST':
        $this->controllerMethodPrefix = 'create';
        $this->parseInputData();
        break;
      case 'PATCH':
      case 'PUT':
        $this->controllerMethodPrefix = 'update';
        $this->parseInputData();
        break;
      case 'DELETE':
        $this->controllerMethodPrefix = 'destroy';
        break;
      case 'GET':
      case 'OPTIONS':
      case 'HEAD':
      default:
        $this->controllerMethodPrefix = 'get'; // instead of read
    }

    if ($this->path == '') {
      $this->_resolved = true;
      return $this->controller->index();
    }

    try {
      $this->match();
    }

    catch (\Exception $e) {
      try {
        if (($e instanceof RouterException) || ($e instanceof ControllerException) || ($e instanceof ModelException)) $this->matchRestRoutes();
        else echo $e->getMessage(); // application / internal server error
      }
      catch (\Exception $ex) {
        #if ($ex instanceof ControllerException) ; // $this->notImplement($ex); // or ->notFound()
        #else 
        echo $ex->getMessage(); // application / internal server error
      }
    }

    //if (!$this->_resolved) $this->notFound();

  }

  private function match(){

    # If non REST routes are defined in $this->routes

    if (!empty($this->routes)){
      
      foreach ($this->routes as $routePattern => $controllerMethod) {

        list($method, $pattern) = explode(' ', $routePattern);

        if ($method != $this->request) continue;
        if (!preg_match("#^/?{$pattern}$#i", $this->path)) continue;

        # $pattern = str_replace(':id','(?<id>[0-9]+)', $pattern);
        $pattern = preg_replace('#:([a-z_]+)#i','(?<$0>[a-z0-9\._]+)', $pattern);
        preg_match("#^/?{$pattern}$#", $this->path, $matches);

        if (count($matches) > 1) 
          $this->controller->setParams($matches);

        if (!method_exists($this->controller, $controllerMethod))
          throw new ControllerException("$controllerMethod is not defined in app/controller.php", 1);

        $this->_resolved = true;

        return $this->controller->$controllerMethod();

      }

    }

    if ($this->_resolved !== true)
        
        $this->matchRestRoutes();
  }

  private function usePluralMethod(){
    return (!isset($this->params['id']) && !empty($this->params))
      || (empty($this->params) && $this->request == 'GET');
  }

  private function matchRestRoutes(){
    
    preg_match($this->urlPatterns['REST'], $this->path, $matches);<commit_msg>Fixed non-rest route matching error<commit_after><?
/**
 * Created by PhpStorm.
 * User: agbetunsin
 * Date: 1/22/14
 * Time: 3:07 PM
 */

namespace Lean;
use ICanBoogie\Inflector;

class Router {

  // instance of application controller class
  protected $controller;

  // array of non RESTful routes, mapped to the controller methods to invoke
  protected $routes = array();

  private $path;
  private $request;
  private $controllerMethodPrefix;
  private $params = array();
  private $inflector;

  private $urlPatterns = array(
    'REST' => '#^/?(?<resource>\w+)(/(?<identifier>[a-z0-9]+)(/(?<sub_resource>\w+))?)?$#'
  );

  // bool flag to indicate whether a route was resolved or not
  private $_resolved = false;

  protected function init(){}

  public static function instance(){
    return new static;
  }

  protected function __construct(){

    $this->inflector = Inflector::get();

    if ( !class_exists('\Controller') )
      throw new ControllerException("No Controller class found in ".LEAN_APP_ROOT);
    
    $this->controller = \Controller::instance();

    $this->request = $_SERVER['REQUEST_METHOD'];

    $this->path = $_SERVER['PATH_INFO'];

    if (!$this->path && isset($_GET['path'])) $this->path = $_GET['path'];

    $this->init();

    $this->route();

    $this->controller->respond();

  }

  private function parseInputData(){
    $input = json_decode(file_get_contents("php://input"), true);
    if (is_array($input))
      $this->controller->extendPostData($input);
  }

  private function route(){

    switch ($this->request) {
      case 'POST':
        $this->controllerMethodPrefix = 'create';
        $this->parseInputData();
        break;
      case 'PATCH':
      case 'PUT':
        $this->controllerMethodPrefix = 'update';
        $this->parseInputData();
        break;
      case 'DELETE':
        $this->controllerMethodPrefix = 'destroy';
        break;
      case 'GET':
      case 'OPTIONS':
      case 'HEAD':
      default:
        $this->controllerMethodPrefix = 'get'; // instead of read
    }

    if ($this->path == '') {
      $this->_resolved = true;
      return $this->controller->index();
    }

    try {
      $this->match();
    }

    catch (\Exception $e) {
      try {
        if (($e instanceof RouterException) || ($e instanceof ControllerException) || ($e instanceof ModelException)) $this->matchRestRoutes();
        else echo $e->getMessage(); // application / internal server error
      }
      catch (\Exception $ex) {
        #if ($ex instanceof ControllerException) ; // $this->notImplement($ex); // or ->notFound()
        #else 
        echo $ex->getMessage(); // application / internal server error
      }
    }

    //if (!$this->_resolved) $this->notFound();

  }

  private function match(){

    # If non REST routes are defined in $this->routes

    if (!empty($this->routes)){
      
      foreach ($this->routes as $routePattern => $controllerMethod) {

        list($method, $pattern) = explode(' ', $routePattern);

        if ($method != $this->request) continue;
        
        if (!preg_match("#^/?{$pattern}$#i", $this->path)) {

          $pattern = preg_replace('#:([a-z_]+)#i','(?<$1>[a-z0-9\._]+)', $pattern);
          preg_match("#^/?{$pattern}$#", $this->path, $matches);

          if (!$matches) continue;

          if (count($matches) > 1) 
            $this->controller->setParams($matches);

        }

        if (!method_exists($this->controller, $controllerMethod))
          throw new ControllerException("$controllerMethod is not defined in app/controller.php", 1);

        $this->_resolved = true;

        return $this->controller->$controllerMethod();

      }

    }

    if ($this->_resolved !== true)
        
      $this->matchRestRoutes();
  }

  private function usePluralMethod(){
    return (!isset($this->params['id']) && !empty($this->params))
      || (empty($this->params) && $this->request == 'GET');
  }

  private function matchRestRoutes(){
    
    preg_match($this->urlPatterns['REST'], $this->path, $matches);
{'fraction_non_alphanumeric': 0.1750401185038884, 'fraction_numerical': 0.003950129613627947, 'mean_word_length': 2.8379914732354337, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 120, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5961431', 'n_tokens_mistral': 2440, 'n_tokens_neox': 2355, 'n_words': 564}