<commit_before><?php

namespace Gotron;

use ReflectionClass,
    Gotron\Dispatch\Error,
	Gotron\Dispatch\Response;

class Controller {

    public $view_path = null;

    public $params = array();

    public $parameters = array();

    public $options = array('view' => 'index', 'layout' => 'layout', 'cache' => false, 'status' => 200);

    public $headers = array();

    public $request = null;

    /**
     * Empty filters
     *
     * @var string
     */
    protected $before_filter = array();
    protected $after_filter = array();

    /**
     * Stores whether the controller has already rendered
     *
     * @var string
     */
    private $rendered = false;

    public $response = null;

	/**
	 * Renders the view
	 *
     *  Calls the render method on the view
	 *
	 * @param array $parameters 
	 * @param string $view 
	 * @return string
	 */
    public function render(array $parameters, $options = array()) {
        $this->rendered = true;
        $this->parse_options($options);
        $this->view_type = static::get_view_type($parameters);
        $layout = $this->options['layout'];
        if ($this->view_type == "php") {
            $this->view_path = $this->fileize_view_path($this->options['view']);
        }
        else if($this->view_type == "json") {
            $parameters = $parameters['json'];
            $layout = false;
        }
        $view_name = ucfirst($this->view_type) . "View";
        if(class_exists(__NAMESPACE__ . "\\View\\$view_name")) {
            if($layout === false) {
                $view = call_user_func(__NAMESPACE__ . "\\View\\$view_name::render", $parameters, $this->view_path);
            }
            else {
                $main_view = call_user_func(__NAMESPACE__ . "\\View\\$view_name::render", $parameters, $this->view_path);
                $layout_path = $this->get_layout($layout);
                $view = call_user_func(__NAMESPACE__ . "\\View\\$view_name::render", $parameters, $layout_path, false, $main_view);
            }

			$this->response = Response::build_from_view($view, $this->options['status'], ['headers' => $this->headers]);
        }
        else {
            throw new Exception("$view has not been defined");
        }
    }

    /**
     * Parse the list of options sent to the controller
     *
     * @param array $options
     * @return void
     */
    protected function parse_options(array $options) {
        foreach($options as $key => $value) {
            if(array_key_exists($key, $this->options)) {
                $this->options[$key] = $value;
            }
        }
    }

	/**
	 * Gets the type of view from the parameters array
	 *
	 * @param string $parameters 
	 * @return string
	 */
    protected function get_view_type($parameters) {
        if (array_key_exists('type', $parameters)) {
            return $parameters['type'];
        }
        else if (array_key_exists('json', $parameters)) {
            return 'json';
        }
        else{
            return 'php';
        }
    }

	/**
	 * Returns the lowercase controller name removing 'controller'
	 *
	 * @return string
	 */
    protected function controller_name() {
		if(isset($this->class_name)) {
			$denamespaced = $this->class_name;
		}
		else {
			$reflector = new ReflectionClass($this);
			$namespace = $reflector->getNamespaceName();
	        $class = get_called_class();
			$denamespaced = str_replace($namespace . '\\', "", $class);
		}
        return str_replace(array("_controller"), "", Helper::uncamelize($denamespaced));
    }

	/**
	 * Returns the base view directory for the controller
	 *
	 * @return string
	 */
    protected function standard_view_path() {
        return realpath(file_join(Config::get('root_directory'), Config::get('view_directory'), $this->controller_name()));
    }

    protected static function get_layout($layout = "layout") {
        return realpath(file_join(Config::get('root_directory'), Config::get('view_directory'), "layouts", "{$layout}.php"));
    }

	/**
	 * Turns the string $view into a full path
	 *
	 * @param string $page
	 * @return string
	 */
    protected function fileize_view_path($page) {
        return file_join($this->standard_view_path(), "{$page}.php");
    }

	/**
	 * Calls the method with the before and after functions called at the right time<commit_msg>Added ability to set context for a controller view<commit_after><?php

namespace Gotron;

use ReflectionClass,
    Gotron\Dispatch\Error,
	Gotron\Dispatch\Response;

class Controller {

    public $view_path = null;

    public $params = array();

    public $parameters = array();

    public $options = array('view' => 'index', 'layout' => 'layout', 'cache' => false, 'status' => 200, 'context' => null);

    public $headers = array();

    public $request = null;

    /**
     * Empty filters
     *
     * @var string
     */
    protected $before_filter = array();
    protected $after_filter = array();

    /**
     * Stores whether the controller has already rendered
     *
     * @var string
     */
    private $rendered = false;

    public $response = null;

	/**
	 * Renders the view
	 *
     *  Calls the render method on the view
	 *
	 * @param array $parameters 
	 * @param string $view 
	 * @return string
	 */
    public function render(array $parameters, $options = array()) {
        $this->rendered = true;
        $this->parse_options($options);
        $this->view_type = static::get_view_type($parameters);
        $layout = $this->options['layout'];
        if ($this->view_type == "php") {
            $this->view_path = $this->fileize_view_path($this->options['view']);
        }
        else if($this->view_type == "json") {
            $parameters = $parameters['json'];
            $layout = false;
        }
        $view_name = ucfirst($this->view_type) . "View";
        if(class_exists(__NAMESPACE__ . "\\View\\$view_name")) {
            if($layout === false) {
                $view = call_user_func(__NAMESPACE__ . "\\View\\$view_name::render", $parameters, $this->view_path);
            }
            else {
                $main_view = call_user_func(__NAMESPACE__ . "\\View\\$view_name::render", $parameters, $this->view_path);
                $layout_path = $this->get_layout($layout);
                $view = call_user_func(__NAMESPACE__ . "\\View\\$view_name::render", $parameters, $layout_path, false, $main_view);
            }

			$this->response = Response::build_from_view($view, $this->options['status'], ['headers' => $this->headers]);
        }
        else {
            throw new Exception("$view has not been defined");
        }
    }

    /**
     * Parse the list of options sent to the controller
     *
     * @param array $options
     * @return void
     */
    protected function parse_options(array $options) {
        foreach($options as $key => $value) {
            if(array_key_exists($key, $this->options)) {
                $this->options[$key] = $value;
            }
        }
    }

	/**
	 * Gets the type of view from the parameters array
	 *
	 * @param string $parameters 
	 * @return string
	 */
    protected function get_view_type($parameters) {
        if (array_key_exists('type', $parameters)) {
            return $parameters['type'];
        }
        else if (array_key_exists('json', $parameters)) {
            return 'json';
        }
        else{
            return 'php';
        }
    }

	/**
	 * Returns the lowercase controller name removing 'controller'
	 *
	 * @return string
	 */
    protected function controller_name() {
		if(isset($this->class_name)) {
			$denamespaced = $this->class_name;
		}
		else {
			$reflector = new ReflectionClass($this);
			$namespace = $reflector->getNamespaceName();
	        $class = get_called_class();
			$denamespaced = str_replace($namespace . '\\', "", $class);
		}
        return str_replace(array("_controller"), "", Helper::uncamelize($denamespaced));
    }

	/**
	 * Returns the base view directory for the controller
	 *
	 * @return string
	 */
    protected function standard_view_path() {
        $context = is_null($this->options['context']) ? $this->controller_name() : $this->options['context'];
        return realpath(file_join(Config::get('root_directory'), Config::get('view_directory'), $context));
    }

    protected static function get_layout($layout = "layout") {
        return realpath(file_join(Config::get('root_directory'), Config::get('view_directory'), "layouts", "{$layout}.php"));
    }

	/**
	 * Turns the string $view into a full path
	 *
	 * @param string $page
	 * @return string
	 */
    protected function fileize_view_path($page) {
        return file_join($this->standard_view_path(), "{$page}.php");
    }

	/**
	 * Calls the method with the before and after functions called at the right time
{'fraction_non_alphanumeric': 0.14875938993853857, 'fraction_numerical': 0.0006829046209879354, 'mean_word_length': 2.536016096579477, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 64, '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': '4300535', 'n_tokens_mistral': 2644, 'n_tokens_neox': 2485, 'n_words': 589}