Fixed Cookie Sessions to close before Response Body...in Kernel.

main
Robert 3 weeks ago
parent b7b18a924d
commit 9b2d9f9390
  1. 3
      src/Bootstrap.php
  2. 99
      src/Framework/Assets.php
  3. 2
      src/Framework/ErrorHandler.php
  4. 167
      src/Framework/HtmlDocument.php
  5. 3
      src/Framework/Http/Kernel.php
  6. 5
      src/Framework/Services/Sessions/CookieSessionHandler.php
  7. 8
      src/Framework/SessionManagement.php
  8. 49
      src/Framework/SiteHelper.php

@ -11,6 +11,7 @@ declare(strict_types=1);
use IOcornerstone\Psr4AutoloaderClass; use IOcornerstone\Psr4AutoloaderClass;
use IOcornerstone\Framework\{ use IOcornerstone\Framework\{
Registry as Reg, Registry as Reg,
SiteHelper,
Console, Console,
Configure, Configure,
CliDefaults, CliDefaults,
@ -46,6 +47,8 @@ $loader->addNamespace("Psr\Http\Server", [
PSR . 'http-server-handler' . DIRECTORY_SEPARATOR . 'src' PSR . 'http-server-handler' . DIRECTORY_SEPARATOR . 'src'
]); ]);
SiteHelper::setupHTTP();
function dd($var = 'nothing', endDump $end = endDump::EXIT_AND_STOP) function dd($var = 'nothing', endDump $end = endDump::EXIT_AND_STOP)
{ {
Common::dump($var, $end); Common::dump($var, $end);

@ -1,12 +1,13 @@
<?php <?php
declare(strict_types = 1); declare(strict_types=1);
/** /**
* @author Robert Strutts * @author Robert Strutts
* @copyright (c) 2026, Robert Strutts * @copyright (c) 2026, Robert Strutts
* @license MIT * @license MIT
*/ */
namespace IOcornerstone\Framework; namespace IOcornerstone\Framework;
use IOcornerstone\Framework\{ use IOcornerstone\Framework\{
@ -17,13 +18,20 @@ use IOcornerstone\Framework\{
class Assets class Assets
{ {
public static function getVer(string $filename): string { private static $files = [];
public static function getAssetFiles(): array{
return self::$files;
}
public static function getVer(string $filename): string
{
if (self::attemptsRootDir($filename)) { if (self::attemptsRootDir($filename)) {
return ""; return "";
} }
$safe_file = Security::filterUri($filename); $safe_file = Security::filterUri($filename);
if (! file_exists($safe_file)) { if (!file_exists($safe_file)) {
return "?ver=false"; return "?ver=false";
} }
return "?ver=" . date('Y.m.d_H.i.s', filemtime($safe_file)); return "?ver=" . date('Y.m.d_H.i.s', filemtime($safe_file));
@ -34,9 +42,10 @@ class Assets
* @param string|null $path * @param string|null $path
* @return bool * @return bool
*/ */
private static function attemptsRootDir(?string $path): bool { private static function attemptsRootDir(?string $path): bool
{
// up from src and back up to public // up from src and back up to public
$open_base_dir_path = BaseDir. '/public/'; $open_base_dir_path = BaseDir . '/public/';
if ($path === null || $path === '') { if ($path === null || $path === '') {
return false; return false;
@ -50,8 +59,8 @@ class Assets
return false; return false;
} }
public static function getAjaxFiles(string $ajax_folder): string
public static function getAjaxFiles(string $ajax_folder): string { {
if (self::attemptsRootDir($ajax_folder)) { if (self::attemptsRootDir($ajax_folder)) {
return ""; return "";
} }
@ -59,29 +68,32 @@ class Assets
$ret = "var assets_files = [];" . PHP_EOL; $ret = "var assets_files = [];" . PHP_EOL;
$js = glob($safe_folder . "*.{js,css}", GLOB_BRACE); $js = glob($safe_folder . "*.{js,css}", GLOB_BRACE);
foreach($js as $file) { foreach ($js as $file) {
$ret .= 'assets_files.push({ filename: "' . basename($file) . '", ts: "' . self::getVer($file) . '" });' . PHP_EOL; $ret .= 'assets_files.push({ filename: "' . basename($file) . '", ts: "' . self::getVer($file) . '" });' . PHP_EOL;
} }
return $ret; return $ret;
} }
public static function loadallCss(array $files, string $scope='project'): string { public static function loadallCss(array $files, string $scope = 'project'): string
{
$ret = ''; $ret = '';
foreach($files as $file=>$a_media) { foreach ($files as $file => $a_media) {
$ret .= self::wrapCss($file, $scope, $a_media); $ret .= self::wrapCss($file, $scope, $a_media);
} }
return $ret; return $ret;
} }
public static function loadallJs(array $files, string $scope='project'): string { public static function loadallJs(array $files, string $scope = 'project'): string
{
$ret = ''; $ret = '';
foreach($files as $file=>$a) { foreach ($files as $file => $a) {
$ret .= self::wrapJs($file, $scope, $a); $ret .= self::wrapJs($file, $scope, $a);
} }
return $ret; return $ret;
} }
public static function image(string $file, string $scope = '', array $a = array()): string { public static function image(string $file, string $scope = '', array $a = array()): string
{
$more = ''; $more = '';
if (count($a)) { if (count($a)) {
foreach ($a as $k => $v) { foreach ($a as $k => $v) {
@ -95,8 +107,9 @@ class Assets
return "<img src=\"{$file}\" {$more}/>\r\n"; return "<img src=\"{$file}\" {$more}/>\r\n";
} }
public static function alert($msg) { public static function alert($msg)
return self::inlineJs('alert("'.$msg.'");'); {
return self::inlineJs('alert("' . $msg . '");');
} }
/** /**
@ -105,7 +118,8 @@ class Assets
* @param string $scope (project/framework/cdn) * @param string $scope (project/framework/cdn)
* @retval boolean|string false is not found, else Asset REF * @retval boolean|string false is not found, else Asset REF
*/ */
public static function wrapAsset(string $file, string $scope = 'project') { public static function wrapAsset(string $file, string $scope = 'project')
{
$scope = StringFacade::strtolower($scope); $scope = StringFacade::strtolower($scope);
if ($scope === 'cdn') { if ($scope === 'cdn') {
$proto = $_SERVER['SERVER_PROTOCOL']; $proto = $_SERVER['SERVER_PROTOCOL'];
@ -128,13 +142,15 @@ class Assets
} }
return $file; return $file;
} }
/** /**
* Fetch Version of file if exists * Fetch Version of file if exists
* @param string $file * @param string $file
* @param string $scope * @param string $scope
* @return string|bool * @return string|bool
*/ */
private static function projectPaths(string $file, string $scope = 'project'): string | bool { private static function projectPaths(string $file, string $scope = 'project'): string|bool
{
$scope = stringFacade::strtolower($scope); $scope = stringFacade::strtolower($scope);
if ($scope === 'cdn') { if ($scope === 'cdn') {
return ""; return "";
@ -146,7 +162,24 @@ class Assets
return ""; return "";
} }
$check = self::isMinified($path, $file); $check = self::isMinified($path, $file);
return ($check !==false) ? self::getVer($path . $check) : false; $version = ($check !== false) ? self::getVer($path . $check) : false;
if ($version === false) {
return false;
}
if (self::hasFile($file)) {
return false;
}
return $version;
}
private static function hasFile(string $file): bool
{
if (in_array($file, static::$files)) {
return true;
}
static::$files[] = $file;
return false;
} }
/** /**
@ -155,7 +188,8 @@ class Assets
* @param string $media - default of all media * @param string $media - default of all media
* @retval string * @retval string
*/ */
public static function wrapCss(string $file, string $scope = 'project', array $a_media = array()): string { public static function wrapCss(string $file, string $scope = 'project', array $a_media = array()): string
{
$more = ''; $more = '';
if (count($a_media)) { if (count($a_media)) {
foreach ($a_media as $k => $v) { foreach ($a_media as $k => $v) {
@ -178,11 +212,12 @@ class Assets
* @param type $file - external JS file. * @param type $file - external JS file.
* @retval string of script src=file * @retval string of script src=file
*/ */
public static function wrapJs(string $file, string $scope = 'project', array $a = array()): string { public static function wrapJs(string $file, string $scope = 'project', array $a = array()): string
{
$more = ''; $more = '';
if (count($a)) { if (count($a)) {
foreach ($a as $k => $v) { foreach ($a as $k => $v) {
$more .= (isset($k) && $k !=0 ) ? " {$k}=\"{$v}\"" : " {$v}"; $more .= (isset($k) && $k != 0) ? " {$k}=\"{$v}\"" : " {$v}";
} }
} }
@ -200,7 +235,8 @@ class Assets
* @param type $code string of code to inline into page. * @param type $code string of code to inline into page.
* @retval type * @retval type
*/ */
public static function inlineJs(string $code): string { public static function inlineJs(string $code): string
{
return "<script type=\"text/javascript\">\r\n//<![CDATA[\r\n {$code}\r\n //]]> \r\n </script>\r\n"; return "<script type=\"text/javascript\">\r\n//<![CDATA[\r\n {$code}\r\n //]]> \r\n </script>\r\n";
} }
@ -209,11 +245,13 @@ class Assets
* @param string $code to do once JQuery is Ready * @param string $code to do once JQuery is Ready
* @retval string wrapped in ready code... * @retval string wrapped in ready code...
*/ */
public static function jqueryLoad(string $code): string { public static function jqueryLoad(string $code): string
{
return "\r\n$(function() { \r\n \t {$code} \r\n }); \r\n"; return "\r\n$(function() { \r\n \t {$code} \r\n }); \r\n";
} }
public static function isMinified(string $path, string $file) { public static function isMinified(string $path, string $file)
{
if (self::attemptsRootDir($path)) { if (self::attemptsRootDir($path)) {
return false; return false;
} }
@ -223,7 +261,7 @@ class Assets
if (str_contains($safe_file, '.auto.js')) { if (str_contains($safe_file, '.auto.js')) {
$production = (isLive()); $production = (isLive());
$safe_file = str_replace('.auto.js', '', $safe_file); $safe_file = str_replace('.auto.js', '', $safe_file);
if ( $production && file_exists($safe_path . $safe_file . '.min.js') ) { if ($production && file_exists($safe_path . $safe_file . '.min.js')) {
return $safe_file . '.min.js'; return $safe_file . '.min.js';
} }
return (file_exists($safe_path . $safe_file . '.js')) ? $safe_file . '.js' : false; return (file_exists($safe_path . $safe_file . '.js')) ? $safe_file . '.js' : false;
@ -232,12 +270,12 @@ class Assets
if (str_contains($safe_file, '.auto.css')) { if (str_contains($safe_file, '.auto.css')) {
$production = (isLive()); $production = (isLive());
$safe_file = str_replace('.auto.css', '', $safe_file); $safe_file = str_replace('.auto.css', '', $safe_file);
if ( $production && file_exists($safe_path . $safe_file . '.min.css') ) { if ($production && file_exists($safe_path . $safe_file . '.min.css')) {
return $safe_file . '.min.css'; return $safe_file . '.min.css';
} }
return (file_exists($safe_path . $safe_file . '.css')) ? $safe_file . '.css' : false; return (file_exists($safe_path . $safe_file . '.css')) ? $safe_file . '.css' : false;
} }
return ( file_exists($safe_path . $safe_file) ) ? $safe_file : false; return (file_exists($safe_path . $safe_file)) ? $safe_file : false;
} }
/** /**
@ -245,7 +283,8 @@ class Assets
* @param string url - site to do redirect on * @param string url - site to do redirect on
* @reval none * @reval none
*/ */
public static function gotoUrl(string $url): void { public static function gotoUrl(string $url): void
{
echo '<META http-equiv="refresh" content="0;URL=' . $url . '">'; echo '<META http-equiv="refresh" content="0;URL=' . $url . '">';
exit; exit;
} }
@ -255,7 +294,8 @@ class Assets
* @param string $url - site to do redirect for * @param string $url - site to do redirect for
* @retval none - exits once done * @retval none - exits once done
*/ */
public static function redirectUrl(string $url): void { public static function redirectUrl(string $url): void
{
$url = str_replace(array('&amp;', "\n", "\r"), array('&', '', ''), $url); $url = str_replace(array('&amp;', "\n", "\r"), array('&', '', ''), $url);
if (!headers_sent()) { if (!headers_sent()) {
header('Location: ' . $url); header('Location: ' . $url);
@ -264,5 +304,4 @@ class Assets
} }
exit; exit;
} }
} }

@ -115,7 +115,9 @@ final class ErrorHandler
return true; return true;
} }
if (! headers_sent()) {
http_response_code(500); http_response_code(500);
}
if ($this->debug) { if ($this->debug) {
$this->renderDebug($e); $this->renderDebug($e);

@ -1,12 +1,13 @@
<?php <?php
declare(strict_types = 1); declare(strict_types=1);
/** /**
* @author Robert Strutts * @author Robert Strutts
* @copyright (c) 2026, Robert Strutts * @copyright (c) 2026, Robert Strutts
* @license MIT * @license MIT
*/ */
namespace IOcornerstone\Framework; namespace IOcornerstone\Framework;
use IOcornerstone\Framework\{ use IOcornerstone\Framework\{
@ -22,6 +23,7 @@ use IOcornerstone\Framework\{
*/ */
class HtmlDocument class HtmlDocument
{ {
private $title = ''; private $title = '';
private $author = ''; private $author = '';
private $description = ''; private $description = '';
@ -37,9 +39,10 @@ class HtmlDocument
private $mainStyles = ''; private $mainStyles = '';
private $mainScripts = ''; private $mainScripts = '';
private $activeCrumb = ''; private $activeCrumb = '';
private $breadcrumb = array(); private $breadcrumb = [];
public function __construct() { public function __construct()
{
$this->title = Configure::get('html', 'title') ?? ''; $this->title = Configure::get('html', 'title') ?? '';
$this->author = Configure::get('html', 'author') ?? ''; $this->author = Configure::get('html', 'author') ?? '';
$this->footer = Configure::get('html', 'footer') ?? ''; $this->footer = Configure::get('html', 'footer') ?? '';
@ -48,8 +51,9 @@ class HtmlDocument
$this->robots = Configure::get('html', 'robots'); $this->robots = Configure::get('html', 'robots');
$css = Configure::get('html', 'css'); $css = Configure::get('html', 'css');
if (Common::getCount($css) > 0) { if (Common::getCount($css) > 0) {
foreach($css as $file=>$path) { foreach ($css as $file => $path) {
if (is_array($file)) continue; if (is_array($file))
continue;
if (is_array($path)) { if (is_array($path)) {
if (isset($path['path'])) { if (isset($path['path'])) {
$pathType = $path['path']; $pathType = $path['path'];
@ -64,9 +68,10 @@ class HtmlDocument
} }
} }
$js = Configure::get('html', 'javascript'); $js = Configure::get('html', 'javascript');
if (Common::getCount($js) >0) { if (Common::getCount($js) > 0) {
foreach($js as $file=>$path) { foreach ($js as $file => $path) {
if (is_array($file)) continue; if (is_array($file))
continue;
if (is_array($path)) { if (is_array($path)) {
if (isset($path['path'])) { if (isset($path['path'])) {
$pathType = $path['path']; $pathType = $path['path'];
@ -82,11 +87,13 @@ class HtmlDocument
} }
} }
public function clearCss(): void { public function clearCss(): void
{
$this->styles = ''; $this->styles = '';
} }
public function clearJs(): void { public function clearJs(): void
{
$this->scripts = ''; $this->scripts = '';
} }
@ -94,7 +101,8 @@ class HtmlDocument
* Set both Title and Header for HTML * Set both Title and Header for HTML
* @param string $title * @param string $title
*/ */
public function setTitleAndHeader(string $title): void { public function setTitleAndHeader(string $title): void
{
$this->title = $title; $this->title = $title;
$this->header = $title; $this->header = $title;
} }
@ -103,7 +111,8 @@ class HtmlDocument
* Set Author for HTML * Set Author for HTML
* @param string $title * @param string $title
*/ */
public function setAuthor(string $author): void { public function setAuthor(string $author): void
{
$this->author = $author; $this->author = $author;
} }
@ -111,7 +120,8 @@ class HtmlDocument
* Set Title for HTML * Set Title for HTML
* @param string $title * @param string $title
*/ */
public function setTitle(string $title): void { public function setTitle(string $title): void
{
$this->title = $title; $this->title = $title;
} }
@ -119,11 +129,13 @@ class HtmlDocument
* Set Header for HTML * Set Header for HTML
* @param string $header * @param string $header
*/ */
public function setHeader(string $header): void { public function setHeader(string $header): void
{
$this->header = $header; $this->header = $header;
} }
public function setHead(string $head): void { public function setHead(string $head): void
{
$this->head = $head; $this->head = $head;
} }
@ -131,7 +143,8 @@ class HtmlDocument
* Set Footer for HTML * Set Footer for HTML
* @param string $footer * @param string $footer
*/ */
public function setFooter(string $footer): void { public function setFooter(string $footer): void
{
// $this->add_css('footer.css', 'project'); // $this->add_css('footer.css', 'project');
$this->footer = $footer; $this->footer = $footer;
} }
@ -140,7 +153,8 @@ class HtmlDocument
* Set Description for HTML * Set Description for HTML
* @param string $description * @param string $description
*/ */
public function setDescription(string $description): void { public function setDescription(string $description): void
{
$this->description = $description; $this->description = $description;
} }
@ -148,7 +162,8 @@ class HtmlDocument
* Set Keywords for HTML * Set Keywords for HTML
* @param string $keywords * @param string $keywords
*/ */
public function setKeywords(string $keywords): void { public function setKeywords(string $keywords): void
{
$this->keywords = $keywords; $this->keywords = $keywords;
} }
@ -156,11 +171,13 @@ class HtmlDocument
* Set Robots for HTML * Set Robots for HTML
* @param string $robot * @param string $robot
*/ */
public function setRobots(string $robot): void { public function setRobots(string $robot): void
{
$this->robots = $robot; $this->robots = $robot;
} }
public function setBody(string $body): void { public function setBody(string $body): void
{
$this->body = $body; $this->body = $body;
} }
@ -168,7 +185,8 @@ class HtmlDocument
* Set Active BreadCrumb in HTML * Set Active BreadCrumb in HTML
* @param string $active * @param string $active
*/ */
public function setActiveCrumb(string $active): void { public function setActiveCrumb(string $active): void
{
$this->activeCrumb = $active; $this->activeCrumb = $active;
} }
@ -176,13 +194,15 @@ class HtmlDocument
* Set BreadCrumbs using array (HyperLink => Name of Crumb) * Set BreadCrumbs using array (HyperLink => Name of Crumb)
* @param array $crumbs Array(href => name) * @param array $crumbs Array(href => name)
*/ */
public function setBreadcrumbs(array $crumbs): void { public function setBreadcrumbs(array $crumbs): void
{
$this->breadcrumb = $crumbs; $this->breadcrumb = $crumbs;
} }
public function setAssetsFromArray(array $files, string $which, string $scope = 'project'): void { public function setAssetsFromArray(array $files, string $which, string $scope = 'project'): void
foreach($files as $file => $a) { {
switch($which) { foreach ($files as $file => $a) {
switch ($which) {
case 'main_css': case 'main_css':
$this->addMainCss($file, $scope, $a); $this->addMainCss($file, $scope, $a);
break; break;
@ -199,7 +219,8 @@ class HtmlDocument
} }
} }
private function missingFile(string $file, string $scope, string $kind) { private function missingFile(string $file, string $scope, string $kind)
{
$failed = strtoupper($kind) . " filename of {$file} - {$scope} Asset Failed to Load!"; $failed = strtoupper($kind) . " filename of {$file} - {$scope} Asset Failed to Load!";
$this->addToJavascript("console.log(\"%c {$failed}\", \"color: red\")"); $this->addToJavascript("console.log(\"%c {$failed}\", \"color: red\")");
$comment = "<!-- {$failed} -->"; $comment = "<!-- {$failed} -->";
@ -220,7 +241,8 @@ class HtmlDocument
* @param string $scope (project, framework, cdn) * @param string $scope (project, framework, cdn)
* @return bool was successful * @return bool was successful
*/ */
public function addCss(string $file, string $scope = 'project', array $a = array()): bool { public function addCss(string $file, string $scope = 'project', array $a = array()): bool
{
$css = Assets::wrapAsset($file, $scope); $css = Assets::wrapAsset($file, $scope);
if ($css === false) { if ($css === false) {
$this->missingFile($file, $scope, "css"); $this->missingFile($file, $scope, "css");
@ -236,10 +258,11 @@ class HtmlDocument
* @param string $scope (project, framework, cdn) * @param string $scope (project, framework, cdn)
* @return bool was successful * @return bool was successful
*/ */
public function addJs(string $file, string $scope = 'project', array $a = array()): bool { public function addJs(string $file, string $scope = 'project', array $a = array()): bool
{
$js = Assets::wrapAsset($file, $scope); $js = Assets::wrapAsset($file, $scope);
if ($js === false) { if ($js === false) {
$this->js_log($file . " - {$scope} Asset Failed to Load!"); $this->jsLog($file . " - {$scope} Asset Failed to Load!");
return false; return false;
} }
$this->scripts .= Assets::wrapJs($file, $scope, $a); $this->scripts .= Assets::wrapJs($file, $scope, $a);
@ -252,10 +275,11 @@ class HtmlDocument
* @param string $scope (project, framework, cdn) * @param string $scope (project, framework, cdn)
* @return bool was successful * @return bool was successful
*/ */
public function addMainCss(string $file, string $scope = 'project', array $a = array()): bool { public function addMainCss(string $file, string $scope = 'project', array $a = array()): bool
{
$css = Assets::wrapAsset($file, $scope); $css = Assets::wrapAsset($file, $scope);
if ($css === false) { if ($css === false) {
$this->js_log($file . " - {$scope} Asset Failed to Load!"); $this->jsLog($file . " - {$scope} Asset Failed to Load!");
return false; return false;
} }
$this->mainStyles .= Assets::wrapCss($file, $scope, $a); $this->mainStyles .= Assets::wrapCss($file, $scope, $a);
@ -268,10 +292,11 @@ class HtmlDocument
* @param string $scope (project, framework, cdn) * @param string $scope (project, framework, cdn)
* @return bool was successful * @return bool was successful
*/ */
public function addMainJs(string $file, string $scope = 'project', array $a = array()): bool { public function addMainJs(string $file, string $scope = 'project', array $a = array()): bool
{
$js = Assets::wrapAsset($file, $scope); $js = Assets::wrapAsset($file, $scope);
if ($js === false) { if ($js === false) {
$this->js_log($file . " - {$scope} Asset Failed to Load!"); $this->jsLog($file . " - {$scope} Asset Failed to Load!");
return false; return false;
} }
$this->mainScripts .= Assets::wrapJs($file, $scope, $a); $this->mainScripts .= Assets::wrapJs($file, $scope, $a);
@ -290,7 +315,8 @@ class HtmlDocument
* Log to JavaScript Console under Chrome Browser * Log to JavaScript Console under Chrome Browser
* @param string $log * @param string $log
*/ */
public function jsLog(string $log): void { public function jsLog(string $log): void
{
$this->addToJavascript("console.log('{$log}');"); $this->addToJavascript("console.log('{$log}');");
} }
@ -298,8 +324,9 @@ class HtmlDocument
* Place JavaScript in HTML * Place JavaScript in HTML
* @param string $js * @param string $js
*/ */
public function addToJavascript(string $js): void { public function addToJavascript(string $js): void
if (! empty($js)) { {
if (!empty($js)) {
$this->scripts .= Assets::inlineJs($js); $this->scripts .= Assets::inlineJs($js);
} }
} }
@ -317,7 +344,8 @@ class HtmlDocument
* Used by Template file to render HTML Author * Used by Template file to render HTML Author
* @return string HTML Author * @return string HTML Author
*/ */
public function getAuthor(): string { public function getAuthor(): string
{
return $this->author; return $this->author;
} }
@ -325,7 +353,8 @@ class HtmlDocument
* Used by Template file to render HTML TITLE * Used by Template file to render HTML TITLE
* @return string HTML TITLE * @return string HTML TITLE
*/ */
public function getTitle(): string { public function getTitle(): string
{
return $this->title; return $this->title;
} }
@ -333,11 +362,13 @@ class HtmlDocument
* Used by Template file to render HTML Header * Used by Template file to render HTML Header
* @return string HTML Header * @return string HTML Header
*/ */
public function getHeader(): string { public function getHeader(): string
{
return $this->header; return $this->header;
} }
public function getBody(): string { public function getBody(): string
{
return $this->body; return $this->body;
} }
@ -345,7 +376,8 @@ class HtmlDocument
* Used by Template file to render HTML Footer * Used by Template file to render HTML Footer
* @return string HTML Footer * @return string HTML Footer
*/ */
public function getFooter(): string { public function getFooter(): string
{
return $this->footer; return $this->footer;
} }
@ -353,7 +385,8 @@ class HtmlDocument
* Used by Template file to render HTML Meta data for Description * Used by Template file to render HTML Meta data for Description
* @return string HTML Meta Description * @return string HTML Meta Description
*/ */
public function getDescription(): string { public function getDescription(): string
{
return $this->description; return $this->description;
} }
@ -361,7 +394,8 @@ class HtmlDocument
* Used by Template file to render HTML Meta data for Keywords * Used by Template file to render HTML Meta data for Keywords
* @return string HTML Meta Keywords * @return string HTML Meta Keywords
*/ */
public function getKeywords(): string { public function getKeywords(): string
{
return $this->keywords; return $this->keywords;
} }
@ -369,7 +403,8 @@ class HtmlDocument
* Used by Template file to render HTML Meta data for Robots * Used by Template file to render HTML Meta data for Robots
* @return string HTML Meta Robots * @return string HTML Meta Robots
*/ */
public function getRobots(): ?string { public function getRobots(): ?string
{
return $this->robots; return $this->robots;
} }
@ -377,7 +412,8 @@ class HtmlDocument
* Used by Template file to render HTML CSS * Used by Template file to render HTML CSS
* @return string HTML CSS * @return string HTML CSS
*/ */
public function getStyles(): string { public function getStyles(): string
{
return $this->styles; return $this->styles;
} }
@ -385,7 +421,8 @@ class HtmlDocument
* Used by Template file to render HTML JavaScripts * Used by Template file to render HTML JavaScripts
* @return string HTML JS * @return string HTML JS
*/ */
public function getScripts(): string { public function getScripts(): string
{
return $this->scripts; return $this->scripts;
} }
@ -393,7 +430,8 @@ class HtmlDocument
* Used by Template file to render HTML main CSS @Top * Used by Template file to render HTML main CSS @Top
* @return string HTML CSS * @return string HTML CSS
*/ */
public function getMainStyles(): string { public function getMainStyles(): string
{
return $this->mainStyles; return $this->mainStyles;
} }
@ -401,7 +439,8 @@ class HtmlDocument
* Used by Template file to render HTML main JS @Top * Used by Template file to render HTML main JS @Top
* @return string HTML JavaScript * @return string HTML JavaScript
*/ */
public function getMainScripts(): string { public function getMainScripts(): string
{
return $this->mainScripts; return $this->mainScripts;
} }
@ -409,15 +448,17 @@ class HtmlDocument
* Used by Template file to render HTML JS after main JS * Used by Template file to render HTML JS after main JS
* @return string HTML JS * @return string HTML JS
*/ */
public function getJsOnReady(): string { public function getJsOnReady(): string
{
return $this->jsOnReady; return $this->jsOnReady;
} }
/** /**
* Used by Template file to render HTML Active BreadCrumb * Used by Template file to render HTML Active BreadCrumb
* @return string HTML Active BreadCrumb * @return string HTML Active BreadCrumb
*/ */
public function getActiveCrumb(): string { public function getActiveCrumb(): string
{
return $this->activeCrumb; return $this->activeCrumb;
} }
@ -425,11 +466,31 @@ class HtmlDocument
* Used by Template file to render HTML BreadCrumbs * Used by Template file to render HTML BreadCrumbs
* @return string HTML BreadCrumbs * @return string HTML BreadCrumbs
*/ */
public function getBreadcrumbs(): array { public function getBreadcrumbs(): array
{
return $this->breadcrumb; return $this->breadcrumb;
} }
public function getHead(): string { public function getHead(): string
{
return $this->head; return $this->head;
} }
public function getBreadcrumbsAuto(): string
{
if (! count($this->breadcrumb) && empty($this->activeCrumb)) {
return "";
}
$out = "<nav><ul class=\"breadcrumb\">" . PHP_EOL;
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;
}
} }

@ -130,6 +130,9 @@ class Kernel {
header("$name: $value", false); header("$name: $value", false);
} }
} }
if (function_exists('session_status') && session_status() == PHP_SESSION_ACTIVE) {
session_write_close();
}
echo $response->getBody(); echo $response->getBody();
} }

@ -39,10 +39,7 @@ class CookieSessionHandler implements \SessionHandlerInterface {
if (isset($options['cookie_secure'])) { if (isset($options['cookie_secure'])) {
self::$cookieSecure = $options['cookie_secure']; self::$cookieSecure = $options['cookie_secure'];
} else { } else {
/** $use_secure = (USE_SECURE);
* @todo Fix this...use_secure
*/
$use_secure = true;
if ($use_secure === false) { if ($use_secure === false) {
self::$cookieSecure = false; self::$cookieSecure = false;
} }

@ -45,7 +45,7 @@ final class SessionManagement
'files' => new FileSes($enc, $options), 'files' => new FileSes($enc, $options),
default => new CookieSes($enc, $options), default => new CookieSes($enc, $options),
}; };
session_set_save_handler($handler, true); session_set_save_handler($handler);
self::makeSessionStarted(); self::makeSessionStarted();
} }
@ -56,12 +56,8 @@ final class SessionManagement
session_name($name); session_name($name);
} }
/**
* @todo Fix ForceSecure....to detect mode
*/
if (! headers_sent()) { if (! headers_sent()) {
$use_secure = 1; // (site_helper::get_use_secure()) ? 1 : 0; $use_secure = (USE_SECURE) ? 1 : 0;
$use_secure = ($force_secure) ? 1 : $use_secure; $use_secure = ($force_secure) ? 1 : $use_secure;
session_start([ session_start([
'cookie_lifetime' => 0, // until browser is closed 'cookie_lifetime' => 0, // until browser is closed

@ -1,12 +1,13 @@
<?php <?php
declare(strict_types = 1); declare(strict_types=1);
/** /**
* @author Robert Strutts * @author Robert Strutts
* @copyright (c) 2026, Robert Strutts * @copyright (c) 2026, Robert Strutts
* @license MIT * @license MIT
*/ */
namespace IOcornerstone\Framework; namespace IOcornerstone\Framework;
use IOcornerstone\Framework\Security; use IOcornerstone\Framework\Security;
@ -19,13 +20,33 @@ use IOcornerstone\Framework\Security;
*/ */
final class SiteHelper final class SiteHelper
{ {
private static $local_site_domains = ['localhost']; private static $local_site_domains = ['localhost'];
private static $Private_IPs_allowed = ['127.0.0.1', '::1']; private static $Private_IPs_allowed = ['127.0.0.1', '::1'];
private static $Public_IPs_allowed = []; private static $Public_IPs_allowed = [];
public static function setLocalSiteDomains(string|array $domain_name): void { public static function setupHTTP(): void
{
define("PROJECT_ASSETS_DIR", BaseDir . DIRECTORY_SEPARATOR . "public" . DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR);
$server_port = $_SERVER['SERVER_PORT'] ?? 80;
$secure_port_on = $_SERVER['HTTPS'] ?? "off";
$use_secure = ($server_port == "443" || $secure_port_on == "on");
$protocol = ($use_secure) ? "https://" : "http://";
$domain_name = $_SERVER['HTTP_HOST'] ?? "";
define("HTTP_PROT", $protocol);
define("USE_SECURE", $use_secure);
define("PROJECT_BASE_REF", $protocol . $domain_name);
define("PROJECT_ASSETS_BASE_REF", PROJECT_BASE_REF . "/assets");
define("ASSETS_DIR", PROJECT_ASSETS_DIR);
define('ASSETS_BASE_REF', PROJECT_ASSETS_BASE_REF);
}
public static function setLocalSiteDomains(string|array $domain_name): void
{
if (is_array($domain_name)) { if (is_array($domain_name)) {
foreach($domain_name as $domain) { foreach ($domain_name as $domain) {
self::$local_site_domains[] = $domain; self::$local_site_domains[] = $domain;
} }
} elseif (is_string($domain_name)) { } elseif (is_string($domain_name)) {
@ -33,9 +54,10 @@ final class SiteHelper
} }
} }
public static function setAllowedPrivateIPs(string|array $IP_addresses): void { public static function setAllowedPrivateIPs(string|array $IP_addresses): void
{
if (is_array($IP_addresses)) { if (is_array($IP_addresses)) {
foreach($IP_addresses as $IP) { foreach ($IP_addresses as $IP) {
$s_ip = Security::getValidIp($IP); $s_ip = Security::getValidIp($IP);
if ($s_ip === false) { if ($s_ip === false) {
continue; continue;
@ -51,9 +73,10 @@ final class SiteHelper
} }
} }
public static function setAllowedPublicIPs(string|array $IP_addresses): void { public static function setAllowedPublicIPs(string|array $IP_addresses): void
{
if (is_array($IP_addresses)) { if (is_array($IP_addresses)) {
foreach($IP_addresses as $IP) { foreach ($IP_addresses as $IP) {
$s_ip = Security::getValidPublicIp($IP); $s_ip = Security::getValidPublicIp($IP);
if ($s_ip === false) { if ($s_ip === false) {
continue; continue;
@ -69,16 +92,19 @@ final class SiteHelper
} }
} }
public static function isServerName_A_PrivateDomain(): bool { public static function isServerName_A_PrivateDomain(): bool
{
$white_list = array_merge(self::$local_site_domains, self::$Private_IPs_allowed); $white_list = array_merge(self::$local_site_domains, self::$Private_IPs_allowed);
return (Security::isServerNameOnDomainList($white_list)); return (Security::isServerNameOnDomainList($white_list));
} }
public static function remoteNotAllowedForceLive(): bool { public static function remoteNotAllowedForceLive(): bool
return (! self::is_allowed()); {
return (!self::is_allowed());
} }
public static function is_allowed(): bool { public static function is_allowed(): bool
{
$remote_ip = Security::getClientIpAddress(); $remote_ip = Security::getClientIpAddress();
if (in_array($remote_ip, self::$Public_IPs_allowed)) { if (in_array($remote_ip, self::$Public_IPs_allowed)) {
return true; return true;
@ -88,5 +114,4 @@ final class SiteHelper
} }
return false; return false;
} }
} }

Loading…
Cancel
Save