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.
 
 

253 lines
7.6 KiB

<?php
declare(strict_types=1);
/**
* @author Robert Strutts <Robert@TryingToScale.com>
* @copyright Copyright (c) 2022, Robert Strutts.
* @license https://mit-license.org/
*/
/**
* @todo Add Template Service here instead of hardcoded
* Ref to Liquid.
*/
namespace tts;
final class view {
public $white_space_control = false;
public $page_output;
private $vars = [];
private $project_dir;
private $files = [];
private $template = false;
private $use_template_engine = false;
private $template_type = 'tpl';
protected $tempalte_engine = null;
public function __construct() {
$this->project_dir = \bs_tts\site_helper::get_project();
}
private function get_file(string $view_file, string $default): string {
$file_ext = \bs_tts\common::get_string_right($view_file, 4);
if (! \bs_tts\common::is_string_found($file_ext, '.')) {
$view_file .= '.php';
}
$file = (empty($default)) ? "{$this->project_dir}/views/{$view_file}" : "{$this->project_dir}/views/{$default}/{$view_file}";
$path = \bs_tts\site_helper::get_root();
$vf = $path . $file;
if ( \bs_tts\requires::safer_file_exists($vf) !== false) {
return $file;
}
return '';
}
/**
* Alias to set_view
*/
public function include(string $file): void {
$this->set_view($file);
}
/**
* Alias to set_view
*/
public function add_view(string $file): void {
$this->set_view($file);
}
private function find_view_path(string $view_file) {
$found = false;
$default_paths = \main_tts\configure::get('view_mode', 'default_paths');
$get = \tts\misc::request_var('render');
if (in_array($get, $default_paths)) {
if (($key = array_search($get, $default_paths)) !== false) {
unset($default_paths[$key]); // Remove as we'll make it first later...
}
array_unshift($default_paths, $get); // Make First in Array!
}
foreach ($default_paths as $default) {
$file = $this->get_file($view_file, $default);
if ( ! empty($file) ) {
$found = true;
break;
}
}
return ($found) ? $file : false;
}
private function find_template_path($tpl_file) {
$file = "{$this->project_dir}/views/includes/{$tpl_file}";
$path = \bs_tts\site_helper::get_root();
$vf = $path . $file;
return \bs_tts\requires::safer_file_exists($vf);
}
/**
* Use View File
* @param string $view_file
* @param string $render_path
* @throws Exception
*/
public function set_view(string $view_file = null): void {
if ($view_file === null) {
return;
}
$file_ext = \bs_tts\common::get_string_right($view_file, 4);
if (! \bs_tts\common::is_string_found($file_ext, '.')) {
$file_ext = '.php';
} else if ($file_ext !== '.php') {
$this->use_template_engine = true;
$this->template_type = str_replace('.', '', $file_ext);
}
if ($file_ext === '.php') {
$file = $this->find_view_path($view_file);
} else {
$file = $this->find_template_path($view_file);
}
if ($file === false) {
echo "No view file exists for: {$view_file}!";
throw new \Exception("View File does not exist: " . $view_file);
} else {
$this->files[] = array('file'=>$file, 'path'=>"project", 'file_type'=>$file_ext);
}
}
public function clear_template(): void {
$this->template = false;
}
/**
* Use Template with view
* @param string $render_page
* @return bool was found
*/
public function set_template(string $render_page): bool {
if (! empty($render_page)) {
$render_page = str_replace('.php', '', $render_page);
$templ = "{$this->project_dir}/templates/{$render_page}";
if (\bs_tts\requires::safer_file_exists(\bs_tts\site_helper::get_root() . $templ. '.php') !== false) {
$this->template = $templ;
// echo $this->template;
return true;
}
}
$this->template = false;
return false;
}
private function clear_ob(int $saved_ob_level): void {
while (ob_get_level() > $saved_ob_level) {
ob_end_flush();
}
}
/**
* Sets a variable in this view with the given name and value
*
* @param mixed $name Name of the variable to set in the view, or an array of key/value pairs where each key is the variable and each value is the value to set.
* @param mixed $value Value of the variable to set in the view.
*/
public function set($name, $value = null): void {
if (is_array($name)) {
foreach ($name as $var_name => $value) {
$this->vars[$var_name] = $value;
}
} else {
$this->vars[$name] = $value;
}
}
/**
* Alias to fetch with Built-in echo
* @param type $local
* @param string $file
*/
public function render($local, string $file = null) {
echo $this->fetch($local, $file);
}
/**
* Outputs view
* @param type $local = $this
* @param $file (optional view file)
*/
public function fetch($local, string $file = null): string {
$page_output = ob_get_clean(); // Get echos before View
\main_tts\views::ob_start();
$saved_ob_level = ob_get_level();
$this->set_view($file);
unset($file);
if (!is_object($local)) {
$local = $this; // FALL Back, please use fetch($this);
}
if ($this->use_template_engine) {
$this->tempalte_engine = \main_tts\registry::get('di')->get_service('templates', [$this->template_type]);
if ($this->white_space_control) {
$this->tempalte_engine->whitespace_control();
}
}
if (count($this->files) > 0) {
foreach ($this->files as $view_file) {
if ($view_file['file_type'] == '.php') {
\bs_tts\requires::secure_include($view_file['file'], $view_file['path'], $local, $this->vars); // Include the file
} else {
$template_file = str_replace('.tpl', '', $view_file['file']);
$this->tempalte_engine->parse_file($template_file);
$assigns = $this->vars['template_assigns'] ?? [];
$filters = $this->vars['template_filters'] ?? null;
$registers = $this->vars['template_registers'] ?? [];
$assigns['production'] =(\main_tts\is_live());
echo $this->tempalte_engine->render($assigns, $filters, $registers);
}
}
}
$this->clear_ob($saved_ob_level);
$page_output .= ob_get_clean();
try {
if (\bs_tts\common::get_bool(\main_tts\configure::get('tts', 'check_HTML_tags')) === true) {
$tags = \tts\tag_matches::check_tags($page_output);
if (! empty($tags['output'])) {
$page_output .= $tags['output'];
$page_output .= '<script type="text/javascript">'.$tags['alert'].'</script>';
foreach($this->files as $bad) {
$page_output .= "<script type=\"text/javascript\">console.log'In view file:{$bad['file']}');\r\n</script>";
}
}
}
} catch (\tts\exceptions\Bool_Exception $e) {
if (\main_tts\configure::get('tts', 'live') === false) {
$page_output .= \tts\assets::alert('SET Config for tts: check_HTML_tags');
}
}
if ($this->template !== false && \bs_tts\requires::safer_file_exists(\bs_tts\site_helper::get_root() . $this->template . ".php") !== false) {
\main_tts\views::ob_start();
$saved_ob_level = ob_get_level();
$local->page_output = $page_output;
\bs_tts\requires::secure_include($this->template, 'project', $local, $this->vars);
$this->clear_ob($saved_ob_level);
$page_output = ob_get_clean();
}
// Reset Files to zero, as they were outputed....
unset($this->files);
$this->files = [];
return $page_output;
}
}