main
Robert 5 months ago
parent 818aebc99c
commit 32567ea58e
  1. 6
      Zephir/aes-loader/hydraterbootloader/hydraterbootloader/loader.zep
  2. 213
      src/bootstrap/errors.php
  3. 1
      src/bootstrap/main.php
  4. 16
      src/classes/enums/view_type.php
  5. 14
      src/classes/extras_booter.php
  6. 5
      src/classes/services/log.php
  7. 14
      src/classes/tag_matches.php
  8. 6
      src/classes/view.php
  9. 2
      src/views/on_error/dev_error.php

@ -93,13 +93,12 @@ class Loader
let cacheDir = this->getCacheDir();
let hash = hash("sha256", filePath);
let tmpPath = cacheDir . "/aesphp_" . hash . ".php";
let tmpPath = cacheDir . "/ap_" . hash;
if useInclude && file_exists(tmpPath) && !forceRefresh {
let expired = this->isExpired(tmpPath, 28800); // 8 hours = 28800 seconds
if !expired {
require tmpPath;
return;
return require tmpPath;
} else {
unlink(tmpPath); // Remove expired cache
}
@ -119,6 +118,7 @@ class Loader
}
return require tmpPath;
} else {
let plaintext = str_replace(["<?php", "?>"], ["",""], plaintext);
return eval(plaintext);
}
}

@ -6,9 +6,104 @@ define('WORD_WRAP_CHRS', 80); // Letters before Line Wrap on Errors
// Configuration
if (! defined('BaseDir')) {
define('BaseDir', ""); // To avoid defination errors
define('LOG_FILE', false);
} else {
define('LOG_FILE', BaseDir . '/protected/logs/error_log.txt');
define('LOG_FILE', BaseDir . '/protected/logs/errors.log.txt');
}
function fallback_dev(): bool {
if (! defined("ENVIRONMENT")) {
return false; // Force (false) which means Live on unknown state
}
return (ENVIRONMENT === 'development') ? true : false;
}
function fallback_get_config(string $key, string $item, $default_when_not_found = false) {
if (! method_exists("\CodeHydrater\bootstrap\configure", "has")) {
return $default_when_not_found;
}
$value = $default_when_not_found; // Init defaults
if (configure::has($key, $item)) {
$value = configure::get($key, $item);
if ($value === null) {
return $default_when_not_found;
}
}
return $value;
}
function should_be_broken(string $msg = ""): bool {
$clear = fallback_get_config("CodeHydrater", "clear_screen_on_prod_errors");
if (fallback_get_config("CodeHydrater", "if_live_with_error_show_broken_page") === true) {
broken_error($msg, $clear);
return true;
} else {
broken_error($msg, false); // Don't Clear
}
return false;
}
function fallback_mini_view_prod(string $msg, string $file = "prod_error.php") {
if (fallback_get_config("CodeHydrater", "clear_screen_on_prod_errors") === false) {
return $msg; // Return Error Message on False and do not clear the Screen
}
echo fallback_mini_view($msg, $file);
}
function fallback_mini_view_dev(string $msg, string $file = "dev_error.php") {
if (fallback_get_config("CodeHydrater", "clear_screen_on_dev_errors") === false) {
return $msg; // Return Error Message on False and do not clear the Screen
}
echo fallback_mini_view($msg, $file);
}
function fallback_mini_view(string $msg, string $file = "dev_error.php"): string {
@ob_end_clean(); // Wipe all HTML content before this....
if (!headers_sent()) {
header('Content-Type: text/html; charset=utf-8', true, 200);
}
views::ob_start();
$saved_ob_level = ob_get_level();
$mini = new \stdClass();
$mini->page_output = $msg;
if (fallback_requires($file, false, $mini) === false) {
fallback_requires("views/on_error/" . $file, true, $mini);
}
// If you really must close all of your output buffers except one, this'll do it:
while (ob_get_level() > $saved_ob_level) {
ob_end_flush();
}
return @ob_get_clean();
}
function fallback_logger(string $logMessage, string $file = LOG_FILE) {
if (method_exists("CodeHydrater\services\log", "write")) {
$logger = new \CodeHydrater\services\log("errors");
$written = $logger->write($logMessage);
if ($written === false) {
// Open a connection to the system logger
openlog("PHP App", LOG_PID | LOG_ODELAY, LOG_LOCAL0);
// Write a message
syslog(LOG_INFO, $logMessage);
// Close the connection
closelog();
}
} else {
$Message = date('[Y-m-d H:i:s]') . $logMessage;
file_put_contents($file, $Message, FILE_APPEND);
}
}
/**
@ -29,13 +124,23 @@ function formatMessage($message, $type = 'error') {
} else {
// Web HTML formatting
$styles = [
'error' => 'color:red;',
'warning' => 'color:orange;',
'notice' => 'color:blue;'
'error' => 'uk-alert-danger',
'warning' => 'uk-alert-warning',
'notice' => 'uk-alert-primary'
];
$style = $styles[$type] ?? $styles['error'];
$message = wordwrap($message, WORD_WRAP_CHRS, "<br>\n");
return "<div style='{$style}padding:10px;border:1px solid #f99;margin:10px;'>$message</div>";
$assets = "/assets/uikit/css/uikit.gradient.min.css";
if (file_exists(BaseDir. "/public/" . $assets)) {
$msg = '<link rel="stylesheet" href="' . $assets . '" type="text/css" media="all" />';
$msg .= "<div class=\"uk-alert $style\">";
} else {
$msg = "<div style=\"color: red;padding:10px;border:1px solid #f99;margin:10px;\"";
}
$msg .= $message;
$msg .= "</div>";
return $msg;
}
}
@ -71,26 +176,18 @@ set_error_handler(function($errno, $errstr, $errfile, $errline) {
$errorType = $errorInfo[0];
$errorCategory = $errorInfo[1];
$logMessage = date('[Y-m-d H:i:s]') . " [$errorType] $errstr in $errfile on line $errline" . PHP_EOL;
$logMessage = " [$errorType] $errstr in $errfile on line $errline" . PHP_EOL;
$displayMessage = "$errorType: $errstr in $errfile on line $errline";
// Log to file
if (LOG_FILE !== false) {
file_put_contents(LOG_FILE, $logMessage, FILE_APPEND);
}
fallback_logger($logMessage);
// Display in development environment
if (fallback_dev()) {
echo formatMessage($displayMessage, $errorCategory);
echo fallback_mini_view_dev(formatMessage($displayMessage, $errorCategory));
// Prevent PHP's default error handler
return true;
}
if (is_on_error_page() === true) {
if (fallback_requires('prod_error.php') === false) {
fallback_requires('views/on_error/prod_error.php', true);
}
exit(1); // Prevent HTML Looping!!!
}
should_be_broken($displayMessage);
return true;
});
@ -99,21 +196,22 @@ set_exception_handler(function($e) {
if (method_exists("errors", "get_handle_exceptions") && ! errors::get_handle_exceptions()) {
return false;
}
$logMessage = date('[Y-m-d H:i:s]') . " [EXCEPTION] " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . PHP_EOL;
$logMessage = " [EXCEPTION] " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . PHP_EOL;
$displayMessage = "UNCAUGHT EXCEPTION: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine();
if (LOG_FILE !== false) {
file_put_contents(LOG_FILE, $logMessage, FILE_APPEND);
}
fallback_logger($logMessage);
// Are we developing...? if so, show details on error
if (fallback_dev()) {
echo formatMessage($displayMessage, 'error');
echo fallback_mini_view_dev(formatMessage($displayMessage, 'error'));
} else {
if (should_be_broken($displayMessage) === false) {
// In production, show user-friendly message
echo PHP_SAPI === 'cli'
? "An error occurred. Our team has been notified." . PHP_EOL
: "An error occurred. Our team has been notified.";
}
}
});
// Handle fatal errors
@ -123,31 +221,28 @@ register_shutdown_function(function() {
}
$error = error_get_last();
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
$logMessage = date('[Y-m-d H:i:s]') . " [FATAL] {$error['message']} in {$error['file']} on line {$error['line']}" . PHP_EOL;
$logMessage = " [FATAL] {$error['message']} in {$error['file']} on line {$error['line']}" . PHP_EOL;
$displayMessage = "FATAL ERROR: {$error['message']} in {$error['file']} on line {$error['line']}";
if (LOG_FILE !== false) {
file_put_contents(LOG_FILE, $logMessage, FILE_APPEND);
}
fallback_logger($logMessage);
// If developing, show error
if (fallback_dev()) {
echo formatMessage($displayMessage, 'error');
echo fallback_mini_view_dev(formatMessage($displayMessage, 'error'));
} else {
should_be_broken($displayMessage);
}
}
});
function fallback_is_live(): bool {
return is_live(); // from main.php
}
/**
* Displays Error page
* @param type $ex error message
*/
function broken_error($ex = ''): void {
function broken_error(string $ex = "", bool $clear = false): void {
if (fallback_is_cli()) {
echo $ex;
exit(1);
return;
}
$use_api = fallback_is_api();
@ -155,24 +250,14 @@ function broken_error($ex = ''): void {
$internal_error = "An unexpected error occured.";
$status_code = 500;
fallback_json_error($internal_error, $status_code);
return;
}
if (fallback_is_live()) {
// Try really Hard to display Prod Error Page
$exists = fallback_requires('prod_error.php');
if (! $exists) {
$exists = fallback_requires('views/on_error/prod_error.php', true);
}
if ($exists === false) {
echo "<h1>Sorry, we had an error...</h1><p>We apologize for any inconvenience this may cause.</p>";
}
} else {
if ($ex === "") {
echo "<h2>Unknown Issue...</h2>";
$error_message = "<h1>Sorry, we had an error...</h1><p>We apologize for any inconvenience this may cause.</p>";
if ($clear === false) {
echo $error_message;
} else {
echo $ex;
}
echo "<h1>Error Page</h1><p>Please go back to another page...</p>";
echo fallback_mini_view_prod($error_message);
}
}
@ -188,7 +273,6 @@ function fallback_json_error(string $data, int $status_code): void {
header('Content-Type: application/json; charset=utf-8', true, intval($status_code));
}
echo json_encode($data);
exit;
}
function fallback_is_api(): bool {
@ -224,20 +308,14 @@ function fallback_is_cli() {
}
function fallback_get_uri(): ?string {
return strtok($_SERVER['REQUEST_URI']);
}
function fallback_dev(): bool {
if (! defined("ENVIRONMENT")) {
return false; // Force Live on unknown state
}
if (ENVIRONMENT === 'development') {
return true;
$uri = strtok($_SERVER['REQUEST_URI'], "?");
if ($uri === false) {
return "";
}
return false;
return $uri;
}
function fallback_requires(string $file, bool $fw = false): bool {
function fallback_requires(string $file, bool $fw = false, $local = null): bool {
$exists = method_exists("\CodeHydrater\bootstrap\requires", "secure_include");
if ($exists) {
if ($fw === false) {
@ -261,19 +339,6 @@ function fallback_requires(string $file, bool $fw = false): bool {
return false; // You have failed me for the last time! LOL
}
/**
* Check if already on Error Page
* @return bool
*/
function is_on_error_page(): bool {
if (fallback_is_cli()) {
exit(1);
} else {
return (stripos(fallback_get_uri(), "error.html") !== false);
}
}
// Test the error handler (uncomment to test)
// trigger_error("This is a test warning", E_USER_WARNING);
// throw new Exception("This is a test exception");

@ -293,6 +293,7 @@ registry::get('loader')->add_namespace("Project", CodeHydrater_PROJECT);
load_all::init(CodeHydrater_PROJECT);
// Keep these blocks of code here not anywhere before it...
if (! defined('ENVIRONMENT')) {
if (is_live() === false) {
define('ENVIRONMENT', 'development');

@ -0,0 +1,16 @@
<?php
declare(strict_types = 1);
/**
* @author Robert Strutts <Bob_586@Yahoo.com>
* @copyright (c) 2025, Robert Strutts
* @license MIT
*/
namespace CodeHydrater\enums;
enum view_type: string {
case LIQUID = ".tpl";
case TWIG = ".twig";
case PHP = ".php";
}

@ -12,19 +12,23 @@ namespace CodeHydrater;
use HydraterBootloader\LicenseVerifier;
const PublicPEM = BaseDir."/keydata/public.pem";
const AESKeysFile = BaseDir."/src/aeskeys.php";
const LicenseFile = BaseDir."/keydata/license.json";
const PublicPEM = BaseDir."/protected/keydata/public.pem";
const AESKeysFile = BaseDir."/protected/src/aeskeys.php";
const LicenseFile = BaseDir."/protected/keydata/license.json";
class extras_booter {
public static function tryToEnableFeature(string $featureName) {
public static function tryToEnableFeature(string $featureName, bool $include = true, $refresh = false) {
if (! class_exists("HydraterBootloader\LicenseVerifier")) {
return false;
}
$verifier = new LicenseVerifier();
return $verifier->tryEnabledItem(LicenseFile, AESKeysFile, $featureName, PublicPEM);
try {
return $verifier->tryEnabledItem(LicenseFile, AESKeysFile, $featureName, PublicPEM, $include, $refresh);
} catch (\Exception $e) {
return false;
}
}
}
// tryToEnableFeature("testing");

@ -99,7 +99,10 @@ final class log {
}
$dt = new \DateTime();
$now = $dt->format('g:i A \o\n l jS F Y');
fwrite($this->handle, $now . ' - ' . print_r($message, true) . "\n");
$written = fwrite($this->handle, $now . ' - ' . print_r($message, true) . "\n");
if ($written === false) {
return false;
}
return true;
}

@ -3,12 +3,12 @@
declare(strict_types=1);
/**
* @author Robert Strutts <Robert@TryingToScale.com>
* @author Robert Strutts
* @copyright Copyright (c) 2022, Robert Strutts.
* @license MIT
*/
namespace tts;
namespace CodeHydrater;
final class tag_matches {
@ -23,16 +23,16 @@ const tags_to_check = array('div', 'span', 'form', 'i*', 'a*', 'h1', 'p*');
public static function check_tags(string $page): array {
$alert = '';
$output = '';
$l_page = \bs_tts\common::string_to_lowercase($page);
$l_page = bootstrap\common::string_to_lowercase($page);
unset($page);
$assets = \bs_tts\site_helper::get_asset("uikit/css/uikit.gradient.min.css");
$assets = "/assets/uikit/css/uikit.gradient.min.css";
$ui = '<link rel="stylesheet" href="' . $assets . '/uikit/css/uikit.gradient.min.css" type="text/css" media="all" />';
$ui .= '<div class="uk-alert uk-alert-danger"><b>';
$ui_end = '</b></div>';
foreach (self::tags_to_check as $tag_name) {
if (\bs_tts\common::is_string_found($tag_name, '*')) {
if (bootstrap\common::is_string_found($tag_name, '*')) {
$tag_name = str_replace('*', '', $tag_name);
$otag = "<{$tag_name}>"; // Open Tag
$open = substr_count($l_page, $otag); // Count open tags in page
@ -50,11 +50,11 @@ public static function check_tags(string $page): array {
if ($total_still_open > 0) {
$msg = "{$total_still_open} possibly MISSING closing {$tag_name} !!!";
$alert .= "console.log('{$msg}');\r\n";
$output .= (\main_tts\is_live()) ? "<!-- {$msg} -->\r\n" : "{$ui}{$msg}{$ui_end}\r\n";
$output .= (bootstrap\is_live()) ? "<!-- {$msg} -->\r\n" : "{$ui}{$msg}{$ui_end}\r\n";
} elseif ($total_still_open < 0) {
$msg = abs($total_still_open) . " possibly MISSING opening {$tag_name} !!!";
$alert .= "console.log('{$msg}');\r\n";
$output .= (\main_tts\is_live()) ? "<!-- {$msg} -->\r\n" : "{$ui}{$msg}{$ui_end}\r\n";
$output .= (bootstrap\is_live()) ? "<!-- {$msg} -->\r\n" : "{$ui}{$msg}{$ui_end}\r\n";
}
}
return array('output' => $output, 'alert' => $alert);

@ -208,8 +208,8 @@ final class view {
$page_output .= ob_get_clean();
try {
if (bootstrap\common::get_bool(bootstrap\configure::get('tts', 'check_HTML_tags')) === true) {
$tags = \tts\tag_matches::check_tags($page_output);
if (bootstrap\common::get_bool(bootstrap\configure::get('CodeHydrater', 'check_HTML_tags')) === true) {
$tags = \CodeHydrater\tag_matches::check_tags($page_output);
if (! empty($tags['output'])) {
$page_output .= $tags['output'];
$page_output .= '<script type="text/javascript">'.$tags['alert'].'</script>';
@ -219,7 +219,7 @@ final class view {
}
}
} catch (exceptions\Bool_Exception $e) {
if (bootstrap\configure::get('tts', 'live') === false) {
if (bootstrap\configure::get('CodeHydrater', 'live') === false) {
$page_output .= assets::alert('SET Config for tts: check_HTML_tags');
}
}

@ -14,7 +14,7 @@
<link rel="shortcut icon" href="/assets/favicon/favicon.ico">
</head>
<body id="my-page">
<h1>Development errors:</h1>
<div id="wrap">
<div id="autosavemessage"></div>
<?= $local->page_output; ?>

Loading…
Cancel
Save