All pastes #912988 Raw Edit

Untitled

public text v1 · immutable
·published 2008-02-21 19:34 UTC
rendered paste body
<?php

class Dispatcher
{
    
    public function dispatch()
    {
        
        $log = empty(Config::$logRouting) ? false : fopen(Config::$logRouting, 'r+');
        
        static $isLoaded, $urlParam;
        if (!$isLoaded)
        {
            $routes = Routes::$routes;
            
            $urlParams = isset($_GET['_url']) ? $_GET['_url'] : '';
            $urlSegments = explode('/', trim($urlParams,'/'));
            
            $urlSegCount = count($urlSegments);
            
        }
        
        $routed = false;
        
        foreach ($routes as $i=>$routeParams)
        {
            
            $route = trim($routeParams[0], '/');
            $params = $defaults = $routeParams[1];
            
            $routeSegments = explode('/', $route);
            
            // we count a lot, so we cache the size of the route segments
            $routeSegCount = count($routeSegments);
            
            // if we have more segments in the url than in the route, then we have a * situation.
            if ($routeSegCount < $urlSegCount)
            {
                // if we don't have an even number of leftover url segments, all is lost.
                if(end($routeSegments) !== '*')
                {
                    $log && fputs($log, '<pre>Route '.$i.': We don\'t have a * for the extra url segments</pre>');
                    continue; // we have failed
                }
                // Re-init this when i care...i don't know if i should care about the end of the url
                // elseif(($urlSegCount-$routeSegCount)%2 !== 0)
                // {
                //    return false;
                //}
                $segmentCount = $routeSegCount;
            }
            else
            {
                $segmentCount = $urlSegCount;
            }
            
            // run through and match the route, segment by segment, in search of flaws
            for ($i=0; $i<$segmentCount; $i++)
            {
                
                if ($routeSegments[$i]===$urlSegments[$i] ||                 // if it's not a var or a glob, match the literal strings
                    ($routeSegments[$i]==='*' && $i+1===$segmentCount))     // * only as the LAST SEGMENT
                {
                    continue; // THIS IS A LITERAL MATCH AND SUCCESS.
                }
                elseif ($routeSegments[$i][0]===':')                        // check for :foo, if so...then it's good
                {
                    $key = substr($routeSegments[$i], 1);
                    $params[$key] = empty($urlSegments[$i]) ? $defaults[$key] : $urlSegments[$i];
                }
                else
                {
                    $log && fputs($log, '<pre>Route '.$i.': Literal string match for "'.$routeSegments[$i].'" against "'.$urlSegments[$i].'" failed</pre>');
                    continue 2;                                             // You have failed us
                }
                
            }
            
            // we need to run through the rest of the segments, if the url is shorter, and test for defaults
            for (; $i<$routeSegCount; $i++)
            {
                // If we have an unfulfilled (we're in this loop, so we ran out of user params, remember?) *, just make sure we're at the end
                if ($routeSegments[$i]==='*' && $i+1!==$segmentCount)
                {
                    $log && fputs($log, '<pre>Route '.$i.': Ran out of parameters</pre>');
                    continue 2; // next in foreach
                }
                
                // Check if this segment starts with :, and since we're in "unset params" mode, if it isn't, we have a problem
                if ($routeSegments[$i][0]!==':')
                {
                    $log && fputs($log, '<pre>Route '.$i.': A route segment literal cannot be matched after input has run out</pre>');
                    continue 2; // next in foreach
                }
                
                $key = substr($routeSegments[$i], 1); // We need to check that the var has a default, and we need the array key it will exist under
                if (!isset($defaults[$key]))
                {
                    $log && fputs($log, '<pre>Route '.$i.': No default specified for extra parameter</pre>');
                    continue 2; // next in foreach
                }
            }
            
            $routed = true;
            // we ran the gauntlet!
            break;
            
        } // endforeach routes
        
        if (!$routed)
        {
            throw new Exception('Route not found!');
        }
        
        if (empty($params['controller']) || !class_exists($params['controller'].'_Controller'))
        {
            $controller = ($params['controller'] = Config::$defaultController).'_Controller';
        }
        else
        {
            $controller = $params['controller'].'_Controller';
        }
        
        if (empty($params['action']) || !method_exists($controller, $params['action']))
        {
            $action = $params['action'] = Config::$defaultAction;
        }
        else
        {
            $action = $params['action'];
        }
        
        $controllerInstance = new $controller($params);
        
        $controllerInstance->$action();
        
    }
     
}

?>