<commit_before><?php

SG::loadClass('SG_Renderer');

/**
 * Class responsible for locating controllers and rendering views.
 */
class SG_Dispatcher {

    public static $defaultTemplate = 'html/page';

    public static $defaultView = 'default';

    private $_app;

    public function __construct($app = null) {
        $this->_app = ($app ? $app : SG_App::singleton());
    }

    /**
     * Given a path, renders the page and generates an SG_Response
     * instance for it.
     * @param $path String A path in the app.
     * @return Object An SG_Response instance.
     */
    public function &getResponse($path) {

        $originalPath = trim($path);
        $navItem = $this->_app->find($path);

        $info = $this->getControllerInfo($navItem);
        $path = $navItem->getFullPath();

        if (!$info) $info = array();

        if (empty($info['controller']) || empty($info['action'])) {

            $parts = explode('/', $path);

            if (empty($info['controller'])) {
                $info['controller'] = array_shift($parts);
            }

            if (empty($info['action'])) {
                $info['action'] = array_shift($parts);
            }

            if (empty($info['args'])) {
                $info['args'] = $parts;
            }
        }

        $response = new SG_Response();

        if (empty($info['action'])) {

            // No action specified == index, but we need to make sure the
            // path ends with a '/'.
            if (substr($originalPath, strlen($originalPath) - 1, 1) != '/') {
                $response->redirect($this->_app->makeUrl('/' . $path . '/'));
                return $response;
            }

        }

        $controller = $this->createController($info, $response);

        if (!$controller) {
            $controller = $this->createDefaultController($info, $response);
        }

        $data = $this->execute(
            $response,
            $controller,
            empty($info['action']) ? 'index' : $info['action'],
            empty($info['args']) ? array() : $info['args']
        );

        // For e.g. 301 redirects we don't need to bother rendering
        if (!$response->shouldContinueProcessing()) {
            return $response;
        }

        $template = $controller->template;
        $view = $controller->view;

        $this->render(
            isset($info['controller']) ? $info['controller'] : '',
            $template, $view, $data, $response
        );

        return $response;
    }

    /**
     * Given the controller info array from an SG_Nav_Item, instantiates the
     * appropriate controller instance.
     * @return Object An SG_Controller if found, otherwise NULL.
     */
    protected function &createController(&$info, $response) {

        $controller = null;

        if (empty($info['controller'])) {
            return $controller;
        }

        $name = preg_replace('/Controller$/', '', $info['controller']);
        $controllerFile = $this->_app->getFile('controllers/' . $name . '.php');

        if (!$controllerFile) {
            return $controller;
        }

        require_once($controllerFile);

        $className = $name . 'Controller';

        if (!class_exists($className)) {
            $response->notFound();
            app_error("Found controller file, but class $className does not exist.");
            $info['action'] = 'error';
        } else {
            $controller = new $className($this->_app, $response);
            $this->configureController($controller, $info);
        }

        return $controller;

    }

    protected function &createDefaultController($info, $response) {
        require_once($this->_app->getOption('OCTOPUS_DIR') . 'controllers/Default.php');

        $controller = new DefaultController($this->_app, $response);
        $controller->requestedController = $info['controller'];
        $this->configureController($controller, $info);

        return $controller;
    }

    private function configureController($controller, $info) {

        $controller->template = (isset($info['template']) ? $info['template'] : self::$defaultTemplate);

        if (isset($info['view'])) {
            $controller->view = $info['view'];
        } else if (isset($info['action'])) {
            $controller->view = $info['action'];
        } else {
            $controller->view = self::$defaultView;
        }

    }

    /**
     * Given a nav item, figure out what controller it should use, what action
     * should be called, and what args should be passed.
     */
    private function getControllerInfo($navItem) {

        $controllers = $this->_app->getControllers(true);
        $parts = explode('/', $navItem->getFullPath());

        // Find the most specific controller we can
        $controller = '';
        $found = false;
        while(($p = array_shift($parts))) {

            if (!$p) {
                continue;
            }

            $controller .= ($controller ? '_' : '') . camel_case($p, true);

            if (in_array($controller, $controllers)) {
                // Found it!
                $found = true;
                break;
            }
        }

        if (!$found) {
            return false;
        }

        $action = array_shift($parts);
        if (!$action) $action = 'index';<commit_msg>- Remove SG_Dispatcher's dependence on SG_Nav_Item<commit_after><?php

SG::loadClass('SG_Renderer');

/**
 * Class responsible for locating controllers and rendering views.
 */
class SG_Dispatcher {

    public static $defaultTemplate = 'html/page';

    public static $defaultView = 'default';

    private $_app;

    public function __construct($app = null) {
        $this->_app = ($app ? $app : SG_App::singleton());
    }

    /**
     * Given a path, renders the page and generates an SG_Response
     * instance for it.
     * @param $path String A path in the app.
     * @return Object An SG_Response instance.
     */
    public function &getResponse($path) {

        $originalPath = trim($path);
        $path = trim($path, '/');

        $info = $this->getControllerInfo($path);

        if (!$info) $info = array();

        if (empty($info['controller']) || empty($info['action'])) {

            $parts = explode('/', $path);

            if (empty($info['controller'])) {
                $info['controller'] = array_shift($parts);
            }

            if (empty($info['action'])) {
                $info['action'] = array_shift($parts);
            }

            if (empty($info['args'])) {
                $info['args'] = $parts;
            }
        }

        $response = new SG_Response();

        if (empty($info['action'])) {

            // No action specified == index, but we need to make sure the
            // path ends with a '/'.
            if (substr($originalPath, strlen($originalPath) - 1, 1) != '/') {
                $response->redirect($this->_app->makeUrl('/' . $path . '/'));
                return $response;
            }

        }

        $controller = $this->createController($info, $response);

        if (!$controller) {
            $controller = $this->createDefaultController($info, $response);
        }

        $data = $this->execute(
            $response,
            $controller,
            empty($info['action']) ? 'index' : $info['action'],
            empty($info['args']) ? array() : $info['args']
        );

        // For e.g. 301 redirects we don't need to bother rendering
        if (!$response->shouldContinueProcessing()) {
            return $response;
        }

        $template = $controller->template;
        $view = $controller->view;

        $this->render(
            isset($info['controller']) ? $info['controller'] : '',
            $template, $view, $data, $response
        );

        return $response;
    }

    /**
     * Given the controller info array from an SG_Nav_Item, instantiates the
     * appropriate controller instance.
     * @return Object An SG_Controller if found, otherwise NULL.
     */
    protected function &createController(&$info, $response) {

        $controller = null;

        if (empty($info['controller'])) {
            return $controller;
        }

        $name = preg_replace('/Controller$/', '', $info['controller']);
        $controllerFile = $this->_app->getFile('controllers/' . $name . '.php');

        if (!$controllerFile) {
            return $controller;
        }

        require_once($controllerFile);

        $className = $name . 'Controller';

        if (!class_exists($className)) {
            $response->notFound();
            app_error("Found controller file, but class $className does not exist.");
            $info['action'] = 'error';
        } else {
            $controller = new $className($this->_app, $response);
            $this->configureController($controller, $info);
        }

        return $controller;

    }

    protected function &createDefaultController($info, $response) {
        require_once($this->_app->getOption('OCTOPUS_DIR') . 'controllers/Default.php');

        $controller = new DefaultController($this->_app, $response);
        $controller->requestedController = $info['controller'];
        $this->configureController($controller, $info);

        return $controller;
    }

    private function configureController($controller, $info) {

        $controller->template = (isset($info['template']) ? $info['template'] : self::$defaultTemplate);

        if (isset($info['view'])) {
            $controller->view = $info['view'];
        } else if (isset($info['action'])) {
            $controller->view = $info['action'];
        } else {
            $controller->view = self::$defaultView;
        }

    }

    /**
     * Given a path, figure out what controller it should use, what action
     * should be called, and what args should be passed.
     */
    private function getControllerInfo($path) {

        $controllers = $this->_app->getControllers(true);
        $parts = explode('/', $path);

        // Find the most specific controller we can
        $controller = '';
        $found = false;
        while(($p = array_shift($parts))) {

            if (!$p) {
                continue;
            }

            $controller .= ($controller ? '_' : '') . camel_case($p, true);

            if (in_array($controller, $controllers)) {
                // Found it!
                $found = true;
                break;
            }
        }

        if (!$found) {
            return false;
        }

        $action = array_shift($parts);
        if (!$action) $action = 'index';
{'fraction_non_alphanumeric': 0.15437505886785344, 'fraction_numerical': 0.0009418856550814731, 'mean_word_length': 2.0019790783149563, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 63, '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': '4368513', 'n_tokens_mistral': 2868, 'n_tokens_neox': 2724, 'n_words': 671}