Skip to content

Commit

Permalink
Working router functionality. Needs testing
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksanderakero committed Mar 27, 2016
1 parent a362e22 commit 2b3e030
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 6 deletions.
14 changes: 14 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@
/* START SITE STUFF */

/* Routing options */
$conf['prod']['routing']['enabled'] = false;
$conf['test']['routing']['enabled'] = false;
$conf['devel']['routing']['enabled'] = true;

$conf['prod']['routing']['defaultController'] = 'index';
$conf['test']['routing']['defaultController'] = 'index';
$conf['devel']['routing']['defaultController'] = 'index';

$conf['prod']['routing']['defaultAction'] = '';
$conf['test']['routing']['defaultAction'] = '';
$conf['devel']['routing']['defaultAction'] = '';
/* End Routing options */

/* Full path to the content */
$conf['prod']['path']['full'] = ROOT . DS;
$conf['test']['path']['full'] = ROOT . DS;
Expand Down
17 changes: 17 additions & 0 deletions controllers/app_controller.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,21 @@ function displayPageNotImplementedError(){
$this->log->error("Displaying 501 error. Missing Smarty template, request: " . print_r($_REQUEST, true));
APP::$smarty->display('error_pages/501.tpl');
}

public static function factory($name)
{
/** TODO: WTF is this shit, needs to be fixed. For some reason it would not load core classes here. */
if($name == 'App_Controller') {
$classname = $name;
require_once(APP::$conf['path']['core']['controllers'] . 'app_controller.class.php');
} else {
$classname = ucwords($name) . '_Controller';
require_once(APP::$conf['path']['controllers'] . strtolower($name) . '.class.php');
}
return new $classname;
}

public static function getActionName($name) {
return 'process' . ucwords($name);
}
}
2 changes: 1 addition & 1 deletion controllers/permission_controller.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Permission_Controller {
* Overriding standard method with custom action.
*/
function process(){
if( !APP::$auth->isLoggedIn) APP::$request->jump("authorize");
if( !APP::$auth->isLoggedIn) APP::$request->jump("login");
else $this->processWithPermission();
}

Expand Down
45 changes: 40 additions & 5 deletions lib/app_request.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,55 @@ function processUrl() {
$this->path_arr = explode('/', $this->url);
$this->log->debug("Path exploded is: " . json_encode($this->path_arr));
}

function processRequestWithRouting() {
$this->log->debug('Posted url: ' . $this->url);

$router = new APP_Router($this->url);
$router->parse();

$controller = $router->getController();
$action = $router->getAction();

APP::$controller = APP_Controller::factory($controller);
$actionName = APP_Controller::getActionName($action);

$this->log->debug('Controller was set to: ' . get_class(APP::$controller));
$this->log->debug('Action was set to: ' . $actionName);

try {
if($action == '404') {
$this->log->debug('File was not found. Displaying 404 error');
APP::$controller->displayPageNotFoundError();
}
else {
if(method_exists(APP::$controller, $actionName)) {
$this->log->debug('Method exists. Calling ' . get_class(APP::$controller) . "->" . $actionName);
APP::$controller->$actionName();
} else {
$this->log->debug(get_class(APP::$controller) . " does not have function $actionName, redirecting user to correct url: " . $this->path_arr[0]);
$this->jump($this->path_arr[0]);
}
}
} catch (SmartyException $e) {
$this->log->error($e);
APP::$controller->displayPageNotImplementedError();
}
}

function processRequest(){
$this->log->debug("processRequest() method has been called, starting process..");
//TODO: implement url_mapping
if(isset($this->path_arr[0])){
if(isset($this->path_arr[0])){ // 1a. If url exists, continue processing -> OK
$controllerName = strtolower($this->path_arr[0]);
//check if its index
if($controllerName == ''){
if($controllerName == ''){ // 2. If empty entry, set default controller -> OK
$controllerName = 'index';
}
$this->log->debug("Controller name that we will be calling is: " . $controllerName);
//lets find out if we have any controller
$controllerFile = APP::$conf['path']['controllers'] . $controllerName . '.class.php';
if(file_exists($controllerFile)){ //controller exists we try to load it
if(file_exists($controllerFile)){ // 3. controller exists we try to load it
$this->log->debug("Controller file exists on disk, we try to load it!");
require_once($controllerFile);
$controllerClass = ucwords($controllerName) . "_Controller";
Expand All @@ -74,13 +109,13 @@ function processRequest(){
APP::$controller->displayPageNotImplementedError();
}

}else{ //controller does not exists, we display 404 error with parent controller
}else{ // 3b. controller does not exists, we display 404 error with parent controller -> OK
$this->log->debug("Controller does not exist, we load default controller and display 404 error.");
require_once APP::$conf['path']['core']['controllers'] . 'app_controller.class.php';
APP::$controller = new APP_Controller();
APP::$controller->displayPageNotFoundError();
}
}else{
}else{ // 1b. If no url, then 503 -> OK
$this->log->debug("Path Arr is empty.. Something must be wrong, returning 503 error");
//Something went wrong with processing url, we display 503 error.
APP::$smarty->display('error_pages/503.tpl');
Expand Down
76 changes: 76 additions & 0 deletions lib/app_router.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

/**
* Created by IntelliJ IDEA.
* User: Aleksander Akerø
* Date: 27.03.2016
* Time: 05.41
*/
class APP_Router {
private $path;
private $defaultController;
private $defaultAction;

private $controller;
private $action;

public function __construct($path) {
$this->log = Logger::getLogger("com.dalisra.request");

$this->path = $path;
$this->defaultController = APP::$conf['routing']['defaultController'];
$this->defaultAction = APP::$conf['routing']['defaultAction'];
}

public function parse() {
if($this->path == null)
$this->path = '';

// TODO: Possible bug with this removing the GET parameters ...?
$chunks = explode('/', $this->path);

if(strlen($chunks[0]) < 1) {
$this->controller = $this->defaultController;
$this->action = $this->defaultAction;

} else {
$controllerName = array_shift($chunks);
$controllerFile = APP::$conf['path']['controllers'] . $controllerName . '.class.php';
$actionName = array_shift($chunks);

/** Assuming error until proven wrong ...Moahahah! */
$this->controller = 'App_Controller';
$this->action = '404';

if(file_exists($controllerFile)) {
$this->controller = $controllerName;

if(strlen($actionName) > 0 ) $this->action = $actionName;
else $this->action = $this->defaultAction;

} else {
$urlmapper = new App_UrlMapper();
$route = $urlmapper->getMappedRoute($this->path);

if (count($route) > 0) {
$controllerFile = APP::$conf['path']['controllers'] . $route['controller'] . '.class.php';

if (file_exists($controllerFile)) {
$this->controller = $route['controller'];
$this->action = $route['action'];
}
}
}
}
}

public function getController()
{
return $this->controller;
}

public function getAction()
{
return $this->action;
}
}
34 changes: 34 additions & 0 deletions lib/app_urlmapper.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/**
* Created by IntelliJ IDEA.
* User: Aleksander Akerø
* Date: 27.03.2016
* Time: 05.43
*/
class App_UrlMapper {
var $routes = array(
array(
'url' => '/^login/',
'controller' => 'authorize',
'action' => 'login'
),
array(
'url' => '/^logout/',
'controller' => 'authorize',
'action' => 'logout'
)
);

public function getMappedRoute($url) {
$mappedRoute = [];

foreach($this->routes as $route) {
if(preg_match($route['url'], $url)) {
$mappedRoute = $route;
}
}

return $mappedRoute;
}
}

3 comments on commit 2b3e030

@Dalisra
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This starting to get into shape but few things:

  1. App_Router probably is not needed - most of it logic already is implemented in App_Request class witch handles everything with request url, splitting it and stuff.
  2. Router does not need to know what happens if controller does not exist.. It does not need to do anything special for displaying 404 or any other error pages. This code should be handled in request class too.
  3. Not sure what does ^ mean in url in url mapper class. I gues we have to thing how to move this to a configuration file. (Maybe its own configuration file on its site)

@aleksanderakero
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 and 2. I agree that we don't necessarily need the request class. That was just the way I made it while testing the implementation on an a smaller scale, and it was just easier to move the entire class in to this project this way. But I see what, you mean, we could basicly just move the functions in to the Request class.

But what I think works with it is that the logic is simplified now. The processRequest function only does the logic of what happens given a request, and the router helps with giving it the correct parameters as of what the controller, action model and so on is.

  1. This was just how I decided to recognize "known" urls, and is basically regex matching. This quick implementation just has the url rules mapped in an array. And the ^login just states that all url's starting with "login" should match that route.

Also the authorize controller is not a part of the core framework so maybe we should find some more common or relatable routes to put in as default. And yes, the routes could maybe come from a config file, or database or whatever. The UrlMapper was just a proof of consept.

And url-mapper is maybe the wrong name for this class. Maybe that is the one that should be called Router, since it does not provide any url's for linking and so on, it just a route for a given request.

@Dalisra
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prototype kode:

  1. Define Controller and Action variables.
  2. If routing enabled try to load url with routing rules. And decide Controller and Action
  3. If Controller and Action are set, then load them
  4. If Controller and Action are not set, try to find them out the old way, and then load them.
  5. If Controller and Action is still not set, try to find default ones and load them.
  6. If Controller and Action is still not set, try to load App_Controller and dispaly 404.
  7. If controller and Action is still not set, display error message.

Please sign in to comment.