summaryrefslogtreecommitdiff
path: root/lpf/lib/Router.class.php
diff options
context:
space:
mode:
Diffstat (limited to 'lpf/lib/Router.class.php')
-rw-r--r--lpf/lib/Router.class.php110
1 files changed, 110 insertions, 0 deletions
diff --git a/lpf/lib/Router.class.php b/lpf/lib/Router.class.php
new file mode 100644
index 0000000..238e3f8
--- /dev/null
+++ b/lpf/lib/Router.class.php
@@ -0,0 +1,110 @@
+<?php
+
+require_once('Controller.class.php');
+
+class Router {
+ /**
+ * Array mapping URIs to controllers.
+ * A controller may register itself either by using
+ * Router::register($URI, $controller[, $function]);
+ * or by adding itself to the $ROUTER global.
+ *
+ * The default here just gives us a 404 handler.
+ */
+ private $routes = array('/*' => 'Http404');
+
+ /**
+ * Instantiate a router that looks for controllers in $controllerpath.
+ */
+ public function Router($controllerpath) {
+ // create a $ROUTES global that can be used to set up our
+ // $this->routes.
+ global $ROUTES;
+ $ROUTES = $this->routes;
+
+ // Split $controllerpath into directories, and load the
+ // controllers in each.
+ $dirs = explode(PATH_SEPARATOR, $controllerpath);
+ foreach ($dirs as $dir) {
+ // Find all files in $dir with the ext `.class.php'
+ $files = glob($dir.'/*.class.php');
+ foreach ($files as $file) {
+ // and include them
+ require_once($file);
+ }
+ }
+
+ $this->routes = $ROUTES;
+ unset($ROUTES);
+ }
+
+ /**
+ * Route the page at the relative URL $page to the appropriate
+ * controller, and call the appropriate function.
+ */
+ public function route($page) {
+ $parts = explode('/', $page);
+ $length = count($parts); // the # of segments in $controllerpart
+
+ // if $page ends in "/", strip that off
+ if ($parts[$length-1]=='') {
+ array_pop($parts);
+ $length--;
+ }
+
+ $controllerpart = implode('/', $parts);
+
+ // Keep shortening $controllerpart until it matches something in
+ // $this->routes. The shortest it will ever become is '/*'.
+ // If no key exists for '/*', that's an infinite loop.
+ // Fortunately, the default value of $this->routes directs '/*'
+ // to the Http404 controller.
+ while(!isset($this->routes[$controllerpart])) {
+ $some_parts = array_slice($parts, 0, $length);
+ $controllerpart = implode('/', $some_parts).'/*';
+ $length--;
+ }
+ $length++;
+
+ // Figure what function to call on what controller
+ // Grammar Nazi Warning: `what' or `which'?
+ $controller = $this->routes[$controllerpart];
+ if (strpos($controller, '->')===false) {
+ // imply function
+ $function = $parts[$length];
+ } else {
+ preg_match('/(.*)->(.*)/', $controller, $matches);
+ $controller = $matches[1];
+ $function = $matches[2];
+ }
+
+ // Default to the `index' function, provided by all controllers
+ if ($function=='') {
+ $function = 'index';
+ }
+
+ // We will pass these arrays to the function.
+ $routed = array_slice($parts, 0, $length);
+ $remainder = array_slice($parts, $length);
+
+ // Finally, run the controller
+ $obj = new $controller();
+ if (in_array($function, get_class_methods($obj))) {
+ call_user_func(array($obj, $function),
+ $routed, $remainder);
+ } else {
+ $obj->http404($routed, $remainder);
+ }
+ }
+
+ /**
+ * This is to allow controllers to register themselves to the router.
+ * If $function=='', then the function will be determined by the segment
+ * to the right of the last segment in $path
+ */
+ public static function register($path, $controller, $function='') {
+ $str = $controller.(($function=='')?'':'->'.$function);
+ global $ROUTES;
+ $ROUTES[$path] = $str;
+ }
+} \ No newline at end of file