<commit_before><?php

/**
 * @package	PHP MVC Framework
 * @author 	<NAME>
 * @version 1.0
 */

namespace PHPMVC\Foundation;

use PHPMVC\DB\DB;
use PHPMVC\Foundation\Exception\NotFoundException;
use PHPMVC\Foundation\Model\Model;
use PHPMVC\Foundation\Model\ModelQueryBuilder;
use PHPMVC\Foundation\Router;

class Application
{
    private $action = null;
	private $controller = null;
    private $db = null;
    private $error = null;
    private $errorBacktrace = null;
	private $parameters = array();
    private $router = null;
    private static $config = null;
    private static $configPath = null;
    
	public function __construct($__config)
	{
        self::$config = $__config;
        self::$configPath = $__config['ROOT'] . '/config';
        
        // display 503: maintenance if the application is in maintenance mode.
		if ($this->underMaintenance()) {
			(new __DefaultController())->viewMaintenance();
			exit(0);
		}
        
        if (!$__config['DEBUG']) {
            error_reporting(E_ALL & ~E_NOTICE);
            
            ini_set('display_errors', 'Off');
            
            if (!set_exception_handler([$this, 'handleException']) === false) {
                echo 'Could not set exception handler.';
                die(__FILE__ . ':' . __LINE__);
            }
            
            if (!set_error_handler([$this, 'handleError']) === false) {
                throw new \Exception('Could not set error handler.');
            }
            
            register_shutdown_function([$this, 'shutdownFunction']);
        }
    
        session_start();
        
        $routesPath = self::$configPath . '/routes.json';
        
        if (file_exists($routesPath)) {
            $jsonString = file_get_contents($routesPath);
            $routes = json_decode($jsonString, true);
            $this->router = new Router($__config['NAME'], $routes);
        }
        
		if (!$this->matchRoute()) {
            $message = '404: Not found.';
            
            if (!class_exists($this->controller)) {
                $message = "The controller with the class '{$this->controller}' does not exist.";
            }
            
			throw new NotFoundException($message);
		}
        
        $this->controller = new $this->controller();
		
        // setup user handling in Controller class.
        if (isset($__config['USR_CLASS']) && isset($__config['USR_SESSION_KEY'])) {
            Controller::setUserClass(
                $__config['USR_CLASS'],
                $__config['USR_SESSION_KEY']
            );
        }
        
		// setup database connection if config is set.
        if (isset(self::$config['DB_DRIVER'])) {
            $this->db = new DB(self::$config);
            Controller::setDB($this->db);
            Model::setDB($this->db);
            ModelQueryBuilder::setDB($this->db);
        }
        
        $reflection = new \ReflectionMethod($this->controller, $this->action);
        if ($reflection->isPublic()) {
            call_user_func_array([$this->controller, $this->action], $this->parameters);
        } else {
            $this->controller->viewError(404);
		}
	}
	
    public function handleError($errorNo, $errorStr, $errorFile, $errorLine, $errorContext)
    {
        $this->error = [
            'file' => $errorFile,
            'line' => $errorLine,
            'message' => $errorStr,
            'type' => E_ERROR
        ];
        
        $errorBacktrace = debug_backtrace();
        $errorBacktrace = array_splice($errorBacktrace, 0, 1);
        $this->errorBacktrace = $errorBacktrace;
    }
    
    public function handleException(\Exception $exception)
    {
        $controller = new \PHPMVC\Foundation\__DefaultController();
        $exceptionClass = get_class($exception);
        
        if ($exceptionClass === NotFoundException::class) {<commit_msg>Throwing exception upon page not found instead of directly displaying error message<commit_after><?php

/**
 * @package	PHP MVC Framework
 * @author 	<NAME>
 * @version 1.0
 */

namespace PHPMVC\Foundation;

use PHPMVC\DB\DB;
use PHPMVC\Foundation\Exception\NotFoundException;
use PHPMVC\Foundation\Model\Model;
use PHPMVC\Foundation\Model\ModelQueryBuilder;
use PHPMVC\Foundation\Router;

class Application
{
    private $action = null;
	private $controller = null;
    private $db = null;
    private $error = null;
    private $errorBacktrace = null;
	private $parameters = array();
    private $router = null;
    private static $config = null;
    private static $configPath = null;
    
	public function __construct($__config)
	{
        self::$config = $__config;
        self::$configPath = $__config['ROOT'] . '/config';
        
        // display 503: maintenance if the application is in maintenance mode.
		if ($this->underMaintenance()) {
			(new __DefaultController())->viewMaintenance();
			exit(0);
		}
        
        if (!$__config['DEBUG']) {
            error_reporting(E_ALL & ~E_NOTICE);
            
            ini_set('display_errors', 'Off');
            
            if (!set_exception_handler([$this, 'handleException']) === false) {
                echo 'Could not set exception handler.';
                die(__FILE__ . ':' . __LINE__);
            }
            
            if (!set_error_handler([$this, 'handleError']) === false) {
                throw new \Exception('Could not set error handler.');
            }
            
            register_shutdown_function([$this, 'shutdownFunction']);
        }
    
        session_start();
        
        $routesPath = self::$configPath . '/routes.json';
        
        if (file_exists($routesPath)) {
            $jsonString = file_get_contents($routesPath);
            $routes = json_decode($jsonString, true);
            $this->router = new Router($__config['NAME'], $routes);
        }
        
		if (!$this->matchRoute()) {
            $message = '404: Not found.';
            
            if (!class_exists($this->controller)) {
                $message = "The controller with the class '{$this->controller}' does not exist.";
            }
            
			throw new NotFoundException($message);
		}
        
        $this->controller = new $this->controller();
		
        // setup user handling in Controller class.
        if (isset($__config['USR_CLASS']) && isset($__config['USR_SESSION_KEY'])) {
            Controller::setUserClass(
                $__config['USR_CLASS'],
                $__config['USR_SESSION_KEY']
            );
        }
        
		// setup database connection if config is set.
        if (isset(self::$config['DB_DRIVER'])) {
            $this->db = new DB(self::$config);
            Controller::setDB($this->db);
            Model::setDB($this->db);
            ModelQueryBuilder::setDB($this->db);
        }
        
        $reflection = new \ReflectionMethod($this->controller, $this->action);
        if ($reflection->isPublic()) {
            call_user_func_array([$this->controller, $this->action], $this->parameters);
        } else {
            throw new NotFoundException("The method '{$this->action}' within the class '{$this->controller}' is not publically accessible.");
		}
	}
	
    public function handleError($errorNo, $errorStr, $errorFile, $errorLine, $errorContext)
    {
        $this->error = [
            'file' => $errorFile,
            'line' => $errorLine,
            'message' => $errorStr,
            'type' => E_ERROR
        ];
        
        $errorBacktrace = debug_backtrace();
        $errorBacktrace = array_splice($errorBacktrace, 0, 1);
        $this->errorBacktrace = $errorBacktrace;
    }
    
    public function handleException(\Exception $exception)
    {
        $controller = new \PHPMVC\Foundation\__DefaultController();
        $exceptionClass = get_class($exception);
        
        if ($exceptionClass === NotFoundException::class) {
{'fraction_non_alphanumeric': 0.13623077900622696, 'fraction_numerical': 0.003177023764137756, 'mean_word_length': 2.1467413034786085, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 57, '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': '1530599', 'n_tokens_mistral': 2203, 'n_tokens_neox': 2165, 'n_words': 461}