The TryingToScale PHP framework.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

205 lines
5.5 KiB

<?php
declare(strict_types=1);
/**
* @author Robert Strutts <Robert@TryingToScale.com>
* @copyright Copyright (c) 2022, Robert Strutts.
* @license https://mit-license.org/
*/
namespace tts;
use Exception;
/**
*
* @todo Ensure tts JS error reporting works
* @todo
* @todo Make Cached Sessions
* @todo Force Database methods to try Cache First and Save Cache Data
*/
class app {
private $file;
private $class;
private $method;
private $params;
private function get_first_chunks(string $input): string {
$parts = explode('/', $input);
$last = array_pop($parts);
$parts = array(implode('/', $parts), $last);
return $parts[0];
}
private function get_last_part(string $input): string {
$reversedParts = explode('/', strrev($input), 2);
return strrev($reversedParts[0]);
}
/**
* Do not declare a return type here, as it will Error out!!
*/
public function __construct() {
$full_route = \bs_tts\site_helper::get_route();
$no_hmtl = str_replace(".html", "", $full_route);
// Find the Route
$route = $this->get_first_chunks($no_hmtl);
// Find the Method
$the_method = $this->get_last_part($no_hmtl);
$params = \bs_tts\site_helper::get_params();
// Now load Route
$is_from_the_controller = true; // TRUE for from Constructor...
$this->router($route, $the_method, $params, $is_from_the_controller);
}
private function get_ctrl_dir(): string {
$ctrl = (\tts\console_app::is_cli()) ? "cli_" : "";
return (\bs_tts\site_helper::get_testing()) ? "test_" : $ctrl;
}
/**
* Gets route and checks if valid
* @param string $route
* @param string $method
* @param bool $is_controller
* @retval action
*/
public function router(?string $route, ?string $method, $params, bool $is_controller = false) {
$ROOT = \bs_tts\site_helper::get_root();
$file = "";
$class = "";
if (\tts\request::is_empty($route)) {
$uri = '/app/' . \main_tts\configure::get('tts', 'default_project');
} else {
$uri = $route;
}
$filtered_uri = \tts\security::filter_uri($uri);
$safe_folders = \bs_tts\requires::filter_dir_path(
$this->get_first_chunks($filtered_uri)
);
if (\bs_tts\requires::is_dangerous($safe_folders)) {
$this->local404();
}
$safe_folders = rtrim($safe_folders, '/');
if (empty($ROOT)) {
$this->local404();
}
$safe_file = \bs_tts\requires::filter_dir_path(
$this->get_last_part($filtered_uri)
);
if (\bs_tts\requires::is_dangerous($safe_file)) {
$this->local404();
}
$test = $this->get_ctrl_dir();
$dir = \bs_tts\requires::safer_dir_exists($ROOT . \bs_tts\site_helper::get_project() . "{$test}controllers/" . $safe_folders);
//check for default site controller first
if ($dir === false) {
$this->local404();
} else {
$file = \bs_tts\requires::safer_file_exists(basename($safe_file) . '_ctrl.php', $dir);
if ($file !== false) {
$class = \tts\security::filter_class($safe_folders) . "\\" . \tts\security::filter_class($safe_file . "_ctrl");
} else {
$this->local404();
}
}
if (\tts\request::is_empty($method)) {
$method = ""; // Clear out :null if exists
}
if (substr($method, 0, 2) == '__') {
$method = ""; // Stop any magical methods being called
}
if ($is_controller === true) {
$this->file = $file;
$this->class = $class;
$this->method = $method;
$this->params = $params;
} else {
return $this->action($file, $class, $method, $params);
}
}
private function local404() {
\tts\page_not_found::tts_error404();
}
private function handle_my_errors($controller, string $method_name): void {
// if (! method_exists($controller, "skip_default_error_handler_for_" . $method_name)) {
// require_once \main_tts\TTS_FRAMEWORK . 'bootstrap/errors.php';
// }
}
/**
* Do controller action
* @param string $file
* @param string $class
* @param string $method
* @retval type
*/
private function action(string $file, string $class, string $method, $params) {
$safer_file = \bs_tts\requires::safer_file_exists($file);
if (! $safer_file) {
$this->local404();
}
if (empty($class)) {
$this->local404();
}
$use_api = \tts\request::is_api();
$test = $this->get_ctrl_dir();
$project_folder = \bs_tts\site_helper::get_project();
$call_class = "\\prj\\" . rtrim($project_folder, "/") . '\\' . $test . 'controllers\\' . $class;
$controller = new $call_class();
if ($use_api) {
if (empty($method)) {
$method = "index";
}
$method .= "_api";
if (method_exists($controller, $method)) {
$this->handle_my_errors($controller, $method);
return $controller->$method($params);
} else {
\tts\page_not_found::tts_error404_cli();
}
} else {
if (!empty($method) && method_exists($controller, $method)) {
$this->handle_my_errors($controller, $method);
return $controller->$method($params);
} else {
if (empty($method) && method_exists($controller, 'index')) {
$this->handle_my_errors($controller, 'index');
return $controller->index($params);
} else {
$this->local404();
}
}
}
}
/**
* Does load controller by calling action
*/
public function load_controller() {
return $this->action($this->file, $this->class, $this->method, $this->params);
}
} // end of app