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.
IOcornerstone/src/Framework/HtmlDocument.php

528 lines
14 KiB

<?php
declare(strict_types=1);
/**
* @author Robert Strutts
* @copyright (c) 2026, Robert Strutts
* @license MIT
*/
namespace IOcornerstone\Framework;
use IOcornerstone\Framework\{
Assets,
Configure,
Common
};
/**
* Description of htmlDocument
*
* @author Robert Strutts
*/
class HtmlDocument
{
private $title = '';
private $author = '';
private $description = '';
private $keywords = '';
private $robots = '';
private $head = '';
private $header = '';
private $body = '';
private $footer = '';
private $jsOnReady = '';
private $styles = '';
private $scripts = '';
private $mainStyles = '';
private $mainScripts = '';
private $activeCrumb = '';
private $breadcrumb = [];
public function __construct()
{
$this->title = Configure::get('html', 'title') ?? '';
$this->author = Configure::get('html', 'author') ?? '';
$this->footer = Configure::get('html', 'footer') ?? '';
$this->keywords = Configure::get('html', 'keywords') ?? '';
$this->description = Configure::get('html', 'description') ?? '';
$this->robots = Configure::get('html', 'robots');
$css = Configure::get('html', 'css');
if (Common::getCount($css) > 0) {
foreach ($css as $file => $path) {
if (is_array($file))
continue;
if (is_array($path)) {
if (isset($path['path'])) {
$pathType = $path['path'];
unset($path['path']);
} else {
$pathType = "project";
}
$this->addCss($file, $pathType, $path);
} else {
$this->addCss($file, $path);
}
}
}
$js = Configure::get('html', 'javascript');
if (Common::getCount($js) > 0) {
foreach ($js as $file => $path) {
if (is_array($file))
continue;
if (is_array($path)) {
if (isset($path['path'])) {
$pathType = $path['path'];
unset($path['path']);
} else {
$pathType = "project";
}
$this->addJs($file, $pathType, $path);
} else {
$this->addJs($file, $path);
}
}
}
}
public function clearCss(): void
{
$this->styles = '';
}
public function clearJs(): void
{
$this->scripts = '';
}
/**
* Set both Title and Header for HTML
* @param string $title
*/
public function setTitleAndHeader(string $title): void
{
$this->title = $title;
$this->header = $title;
}
/**
* Set Author for HTML
* @param string $title
*/
public function setAuthor(string $author): void
{
$this->author = $author;
}
public function addToTitle(string $title): void
{
$this->title .= $title;
}
public function beforeTitle(string $title): void
{
$this->title = $title . $this->title;
}
/**
* Set Title for HTML
* @param string $title
*/
public function setTitle(string $title): void
{
$this->title = $title;
}
/**
* Set Header for HTML
* @param string $header
*/
public function setHeader(string $header): void
{
$this->header = $header;
}
public function setHead(string $head): void
{
$this->head = $head;
}
/**
* Set Footer for HTML
* @param string $footer
*/
public function setFooter(string $footer): void
{
// $this->add_css('footer.css', 'project');
$this->footer = $footer;
}
/**
* Set Description for HTML
* @param string $description
*/
public function setDescription(string $description): void
{
$this->description = $description;
}
/**
* Set Keywords for HTML
* @param string $keywords
*/
public function setKeywords(string $keywords): void
{
$this->keywords = $keywords;
}
/**
* Set Robots for HTML
* @param string $robot
*/
public function setRobots(string $robot): void
{
$this->robots = $robot;
}
public function setBody(string $body): void
{
$this->body = $body;
}
/**
* Set Active BreadCrumb in HTML
* @param string $active
*/
public function setActiveCrumb(string $active): void
{
$this->activeCrumb = $active;
}
/**
* Set BreadCrumbs using array (HyperLink => Name of Crumb)
* @param array $crumbs Array(href => name)
*/
public function setBreadcrumbs(array $crumbs): void
{
$this->breadcrumb = $crumbs;
}
private function doAction(string $file, string $which, string $scope, array $a): void
{
switch ($which) {
case 'main_css':
$this->addMainCss($file, $scope, $a);
break;
case 'css':
$this->addCss($file, $scope, $a);
break;
case 'main_js':
$this->addMainJs($file, $scope, $a);
break;
case 'js':
$this->addJs($file, $scope, $a);
break;
}
}
public function setAssetsFromArray(array $files, string $which, string $scope = 'project', array $options = []): void
{
if (Common::hasKeys($files)) {
foreach ($files as $file => $a) {
$this->doAction($file, $which, $scope, $a);
}
} else {
foreach ($files as $file) {
$this->doAction($file, $which, $scope, $options);
}
}
}
private function missingFile(string $file, string $scope, string $kind)
{
$failed = strtoupper($kind) . " filename of {$file} - {$scope} Asset Failed to Load!";
$this->addToJavascript("console.log(\"%c {$failed}\", \"color: red\")");
$comment = "<!-- {$failed} -->";
if ($kind === "css") {
$this->styles .= $comment;
} else if ($kind === "main_css") {
$this->mainStyles .= $comment;
} else if ($kind === "js") {
$this->scripts .= $comment;
} else if ($kind === "main_js") {
$this->mainScripts .= $comment;
}
}
/**
* Add CSS stylesheet to HTML under main CSS
* @param string $file
* @param string $scope (project, framework, cdn)
* @return bool was successful
*/
public function addCss(string $file, string $scope = 'project', array $a = array()): bool
{
$css = Assets::wrapAsset($file, $scope);
if ($css === false) {
$this->missingFile($file, $scope, "css");
return false;
}
$this->styles .= Assets::wrapCss($file, $scope, $a);
return true;
}
/**
* Add JS JavaScript to HTML under main JS
* @param string $file
* @param string $scope (project, framework, cdn)
* @return bool was successful
*/
public function addJs(string $file, string $scope = 'project', array $a = array()): bool
{
$js = Assets::wrapAsset($file, $scope);
if ($js === false) {
$this->jsLog($file . " - {$scope} Asset Failed to Load!");
return false;
}
$this->scripts .= Assets::wrapJs($file, $scope, $a);
return true;
}
/**
* Add CSS stylesheet to HTML towards top of HTML for CSS
* @param string $file
* @param string $scope (project, framework, cdn)
* @return bool was successful
*/
public function addMainCss(string $file, string $scope = 'project', array $a = array()): bool
{
$css = Assets::wrapAsset($file, $scope);
if ($css === false) {
$this->jsLog($file . " - {$scope} Asset Failed to Load!");
return false;
}
$this->mainStyles .= Assets::wrapCss($file, $scope, $a);
return true;
}
/**
* Add JavaScript to HTML towards top of HTML for JS
* @param string $file
* @param string $scope (project, framework, cdn)
* @return bool was successful
*/
public function addMainJs(string $file, string $scope = 'project', array $a = array()): bool
{
$js = Assets::wrapAsset($file, $scope);
if ($js === false) {
$this->jsLog($file . " - {$scope} Asset Failed to Load!");
return false;
}
$this->mainScripts .= Assets::wrapJs($file, $scope, $a);
return true;
}
/**
* Adds JavaScript code to called after JQuery is ready.
* @param string $code
*/
//public function add_js_onready(string $code): void {
// $this->js_onready .= \px_inline_js(\px_jquery_load($code));
//}
/**
* Log to JavaScript Console under Chrome Browser
* @param string $log
*/
public function jsLog(string $log): void
{
$this->addToJavascript("console.log('{$log}');");
}
/**
* Place JavaScript in HTML
* @param string $js
*/
public function addToJavascript(string $js): void
{
if (!empty($js)) {
$this->scripts .= Assets::inlineJs($js);
}
}
public function addToCss(string $css): void
{
if (!empty($css)) {
$this->styles .= Assets::inlineCss($css);
}
}
/**
* Use CSS/JS for Database SSP
public function datatables_code(): void {
$this->addCss('datatables/datatables.min.css', 'cl');
$this->addJs('datatables/datatables_no_jquery.min.js', 'cl');
}
*
*/
/**
* Used by Template file to render HTML Author
* @return string HTML Author
*/
public function getAuthor(): string
{
return $this->author;
}
/**
* Used by Template file to render HTML TITLE
* @return string HTML TITLE
*/
public function getTitle(): string
{
return $this->title;
}
/**
* Used by Template file to render HTML Header
* @return string HTML Header
*/
public function getHeader(): string
{
return $this->header;
}
public function getBody(): string
{
return $this->body;
}
/**
* Used by Template file to render HTML Footer
* @return string HTML Footer
*/
public function getFooter(): string
{
return $this->footer;
}
/**
* Used by Template file to render HTML Meta data for Description
* @return string HTML Meta Description
*/
public function getDescription(): string
{
return $this->description;
}
/**
* Used by Template file to render HTML Meta data for Keywords
* @return string HTML Meta Keywords
*/
public function getKeywords(): string
{
return $this->keywords;
}
/**
* Used by Template file to render HTML Meta data for Robots
* @return string HTML Meta Robots
*/
public function getRobots(): ?string
{
return $this->robots;
}
/**
* Used by Template file to render HTML CSS
* @return string HTML CSS
*/
public function getStyles(): string
{
return $this->styles;
}
/**
* Used by Template file to render HTML JavaScripts
* @return string HTML JS
*/
public function getScripts(): string
{
return $this->scripts;
}
/**
* Used by Template file to render HTML main CSS @Top
* @return string HTML CSS
*/
public function getMainStyles(): string
{
return $this->mainStyles;
}
/**
* Used by Template file to render HTML main JS @Top
* @return string HTML JavaScript
*/
public function getMainScripts(): string
{
return $this->mainScripts;
}
/**
* Used by Template file to render HTML JS after main JS
* @return string HTML JS
*/
public function getJsOnReady(): string
{
return $this->jsOnReady;
}
/**
* Used by Template file to render HTML Active BreadCrumb
* @return string HTML Active BreadCrumb
*/
public function getActiveCrumb(): string
{
return $this->activeCrumb;
}
/**
* Used by Template file to render HTML BreadCrumbs
* @return string HTML BreadCrumbs
*/
public function getBreadcrumbs(): array
{
return $this->breadcrumb;
}
public function getHead(): string
{
return $this->head;
}
public function getBreadcrumbsAuto(bool $showHomeSVG = false): string
{
if (!count($this->breadcrumb) && empty($this->activeCrumb)) {
return "";
}
$out = "<nav><ul class=\"breadcrumb\">" . PHP_EOL;
if ($showHomeSVG) {
$out .= '<svg class="homecrumb" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"></path></svg>';
}
foreach ($this->breadcrumb as $link => $crumb) {
$out .= "<li><a href=\"$link\">$crumb</a></li>" . PHP_EOL;
}
if (!empty($this->activeCrumb)) {
$out .= "<li>" . $this->activeCrumb . "</li>" . PHP_EOL;
}
$out .= "</ul></nav>" . PHP_EOL;
return $out;
}
}