Location: PHPKode > projects > GroundOS > groundos/logic/router/router.class.php
<?PHP
/**
 * /logic/router/router.class.php
 *
 * Routes URL requests to the proper place
 * 
 * @package AgaresCore4
 * @author Agares Media <hide@address.com>
 * @copyright Copyright (c) 2007, 2008 Agares Media.  All rights reserved.
 */

/**
 * router() Class
 *
 * Routes URL requests to the proper place
 * @package AgaresCore4
 */
class router extends rootclass {
	
	public function __construct() { // Constructor
		//
	}	
	
	// The destructor warns if headers have already been sent.
	public function __destruct() { // Destructor
		if(headers_sent($file, $line)){
		    $this->debug("Warning - Headers were already sent in $file on line $line...");
		}
	}		
	
	/**
	 * reroute() Method
	 * 
	 * This method simply sends a 301 redirect, so headers cannot already have been sent or else the method will fail.
	 * The user will be redirected to the URL specified in $location
	 * 
	 * @access public
	 * @param string $location The fully qualified URI to redirect to
	 * @return void
	 */
	public function reroute($location) {
		try {
			if(!headers_sent($file, $line)) {		
				header("HTTP/1.1 301 Moved Permanently");
				header("Location: $location");
			} else {
				throw new Exception("Cannot redirect to $location - Headers were already sent in $file on line $line...");
			}
		} catch(Exception $e) {
			$this->errorReport($e);
		}				
	}
	
	/**
	 * get() Method
	 * 
	 * Get the command, santitized for SQL use if necessary.  The .htaccess file forces all URI's to be parsed so that
	 * all requests above the root directory are contained in the GET variable "command".  For example:
	 * 
	 * This URI request: http://www.example.com/admin/
	 * Becomes this URI request after the .htaccess rules are applied: http://www.example.com/index.php?command=admin
	 *  
	 * @access public
	 * @return string Returns the command, santitized for SQL use if necessary
	 */
	public function get() { 
		try {
			if(isset($_GET['command'])) {
				$command = $this->clean($_GET['command']);
				return $command;
			}
		} catch(Exception $e) {
			$this->errorReport($e);
		}
	}
	
	/**
	 * process() Method
	 * 
	 * Note: This method is called in /index.php and there is no real reason that anyone should directly invoke this
	 * method.  If you're looking to route a window to a specific location, use the reroute() method instead.
	 * 
	 * Takes the command and processes the result, loads the appropriate app or URL, depending on the case.  When you 
	 * access an Application from a URI such as http://www.example.com/admin/ you are calling the default logic
	 * and view files for that application.  Specifically, the AC4 router will load /applications/admin/logic/index.php
	 * followed by /applications/admin/views/index.php
	 * 
	 * Aside from the default logic and view files, there can be an infinite number of logic/view combinations for each
	 * application.  For example, the admin application has a logic/view pair to display the Applications Menu.  To access
	 * the App Menu directly, you would visit this URL: http://www.example.com/admin/appmenu/ which in turn loads this
	 * logic file: /applications/admin/logic/appmenu.php and this view file: /applications/admin/views/appmenu.php
	 *  
	 * When a page cannot be found, it will always generate a 404 error.  If the global $debug variable is set to true, 
	 * it will also give a full detailed error report.  When $debug is set to false, it will still trigger a 404 HTTP 
	 * error, and in addition it will load the 404 error page that is specified in /data/html/404.html  If you want a 
	 * custom error page, simply edit that file.
	 * 
	 * @access public
	 * @return void
	 * @see reroute()
	 */
	public function process() { 
		try {
			global $defaultapp, $defaultloc, $debug;
			$command = $this->get();
			$history = NULL;
			$count = 0;
			
			// This if block simply checks to see if the URL ends with a forward slash, if so, it removes it and reloads the page.
			if(substr($command, -1)== "/") {
				if (isset($_SERVER['HTTPS'])) { // Used so that we automatically support SSL secured URLs
					$httpProtocal = 'https';
				} else {
					$httpProtocal = 'http';
				}
				$newUrl= substr("$httpProtocal://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 0, -1);
				if(!headers_sent($file, $line)) {
					header("HTTP/1.0 307 Temporary redirect"); // 307 keeps the post data if any, but requires user confirmation to resubmit post data
					header("Location: $newUrl");
				} else {
					throw new Exception("Cannot redirect to $location - Headers were already sent in $file on line $line...");
				}					
				exit();
			}
			
			$commandArray = explode("/", $command, 25); // Max 25 arguments to help mitigate DOS attacks and memory issues
			
			// This loop determines if we're dealing with an app or not.
			$possibleApp = true; // By default, we'll assume the request is for an app.  In the foreach loop below, we'll determine the truth
			foreach($commandArray as $checkIfRealFile) { // In this loop, we'll determine if we're dealing with an app, 
				$history.= $checkIfRealFile . '/';
				$count++;
				if (file_exists('./applications/'.$history) && $count >= 2) {
					$possibleApp = false; // This means the URL is a true URL, and not a command to be processed, so lets give the user the actual URL they requested.
				}
			}
			
			// Kind of a backwards way to find out whether or not we're on the homepage, however using NULL, "", '', or even ' ' didn't work when trying to determine if $commandArray[0] was blank
			if ('./applications/'.$commandArray[0].'/logic/index.php' == './applications//logic/index.php' || './applications/'.$commandArray[0].'/logic/index.php' == './applications/index.php/logic/index.php') {
				$possibleApp = false; //
				global $localpath, $homedir, $body_output, $bodymarkup, $headtop_output, $headbottom_output, $router, $database;
				require('./applications/'.$defaultapp.'/config.php'); // This loads the application's settings
				require('./applications/'.$defaultapp.'/logic/'.$defaultloc.'.php'); // This executes the app's logic
				require('./applications/'.$defaultapp.'/views/'.$defaultloc.'.php'); // This opens the view associated with the logic.				
			}
			
			
			if ($possibleApp == true && !file_exists('./applications/'.$commandArray[0].'/logic/')) { // Throws a fatal error if there is no application installed that matches the argument 0
				throw new Exception('The Application: '. $commandArray[0] . ' could not be found.  Try reupload the application to the /applications/ folder and try again.');
			}
			if ($possibleApp == true && !file_exists('./applications/'.$commandArray[0].'/logic/index.php')) { // All apps must have a index.php, if not, then its a fatal error.  This file implements the logic in /applications/yourapp/classes.php
				throw new Exception('The Application: '. $commandArray[0] . ' does not have an executable file located in its directory.  Try reupload the application to the /applications/ folder and try again.');
			}

			if ($possibleApp == true) {
				if(!isset($commandArray[1]) || !file_exists('./applications/'.$commandArray[0].'/logic/'.$commandArray[1].'.php')) {$filename = 'index';} else {$filename = $commandArray[1];} // This logic code will treat  $commandArray[1] to point to specific logic/view partners within the app.  If no suitable logic file is found, then the default logic file for the application will handle the request.
				// First lets load/declare all of our global variables.
				global $localpath, $homedir, $body_output, $bodymarkup, $headtop_output, $headbottom_output, $router, $database;
				$this->debug('Router enacted.  Routing to '.$commandArray[0]);
				require('./applications/'.$commandArray[0].'/config.php'); // This loads the application's settings
				require('./applications/'.$commandArray[0].'/logic/'.$filename.'.php'); // This executes the app's logic
				require('./applications/'.$commandArray[0].'/views/'.$filename.'.php'); // This opens the view associated with the logic.
			} else {
				// 
			}
			return $commandArray;
		} catch(Exception $e) {
			if($debug==true) {
				// For debugging purposes, its useful if we spit out the variable $commandArray
				echo '<h1>404 Page not found.</h1><br /><br />';
				echo 'Turn off debugging to disable the following error report:<br /><br />';
				echo 'process() METHOD DETAILED ERROR REPORT:<br /><br />Router Array:<br /><pre>';
				print_r($commandArray);
				echo '</pre><br /><br />';
				$this->errorReport($e);
			} else {
				global $homedir;
				header("HTTP/1.0 404 Not Found");
				include('./data/html/404.html');
			}
		}
	}	
	
	
}
?>
Return current item: GroundOS