improvements streamCSSBigFile

This commit is contained in:
Fernando Ontiveros
2025-04-25 16:20:18 +00:00
parent e6ce83a1e4
commit 6a5e44a04c
2 changed files with 72 additions and 74 deletions

View File

@@ -408,19 +408,20 @@ class Bootstrap
} }
/** /**
* Parsing the URI * Parses the given URI and sets system constants based on the parsed values.
* *
* @author Fernando Ontiveros Lira <fernando@colosa.com> * @param string $uri The URI to parse.
* @access public * @param array $arrayFriendlyUri An optional array for friendly URIs.
* @param string $urlLink
* @param array $arrayFriendlyUri
* *
* @return string * @return string
*/ */
public static function parseURI($uri, array $arrayFriendlyUri = null) public static function parseURI($uri, array $arrayFriendlyUri = [])
{ {
$aRequestUri = explode('/', $uri); // Split the URI into segments
$args = self::parseNormalUri($aRequestUri, $arrayFriendlyUri); $requestUriSegments = explode('/', $uri);
// Parse the URI segments into
$args = self::parseNormalUri($requestUriSegments, $arrayFriendlyUri);
if (! empty($args)) { if (! empty($args)) {
define("SYS_LANG", $args ['SYS_LANG']); define("SYS_LANG", $args ['SYS_LANG']);
@@ -428,7 +429,7 @@ class Bootstrap
define('SYS_COLLECTION', $args ['SYS_COLLECTION']); define('SYS_COLLECTION', $args ['SYS_COLLECTION']);
define('SYS_TARGET', $args ['SYS_TARGET']); define('SYS_TARGET', $args ['SYS_TARGET']);
if (array_key_exists('API_VERSION', $args)) { if (isset($args['API_VERSION'])) {
define('API_VERSION', $args['API_VERSION']); define('API_VERSION', $args['API_VERSION']);
} }
} }
@@ -853,34 +854,34 @@ class Bootstrap
} }
/** /**
* Dynamically generates and streams a CSS file by aggregating smaller CSS files. * streaming a big JS file with small js files
*
* This function is designed to serve CSS content dynamically based on different skins or themes.
* It reads configuration files to determine which CSS files to include, handles caching headers,
* and performs browser-specific logic to ensure compatibility.
* *
* @author Fernando Ontiveros Lira <fernando@colosa.com> * @author Fernando Ontiveros Lira <fernando@colosa.com>
* @access public * @access public
* @param string $filename The name of the file, used to determine the skin and variant. * @param string $file
* @return string The aggregated and minified CSS content. * @return string
*/ */
public static function streamCSSBigFile($filename) public static function streamCSSBigFile($filename)
{ {
// Set the content type to CSS and prevent MIME type sniffing
header('Content-Type: text/css'); header('Content-Type: text/css');
header('X-Content-Type-Options: nosniff'); header('X-Content-Type-Options: nosniff');
// Parse the filename to extract skin name and variant //First get Skin info
$filenameParts = explode("-", $filename); $filenameParts = explode("-", $filename);
$skinName = !empty($filenameParts[0]) ? $filenameParts[0] : 'base'; $skinName = empty($filenameParts[0]) ? 'base' : $filenameParts[0];
$skinVariant = isset($filenameParts[1]) ? strtolower($filenameParts[1]) : 'skin'; $skinVariant = "skin";
// Normalize skin names if (isset($filenameParts[1])) {
if (in_array($skinName, ['jscolors', 'xmlcolors'])) { $skinVariant = strtolower($filenameParts[1]);
$skinName = 'classic';
} }
// Determine the configuration file path based on the skin name
$configurationFile = ''; $configurationFile = '';
if ($skinName == "jscolors") {
$skinName = "classic";
}
if ($skinName == "xmlcolors") {
$skinName = "classic";
}
if ($skinName == "classic") { if ($skinName == "classic") {
$configurationFile = Bootstrap::ExpandPath("skinEngine") . 'base' . PATH_SEP . 'config.xml'; $configurationFile = Bootstrap::ExpandPath("skinEngine") . 'base' . PATH_SEP . 'config.xml';
} else { } else {
@@ -894,49 +895,50 @@ class Bootstrap
$configurationFile = Bootstrap::ExpandPath("skinEngine") . $skinName . PATH_SEP . 'config.xml'; $configurationFile = Bootstrap::ExpandPath("skinEngine") . $skinName . PATH_SEP . 'config.xml';
} }
} }
// Fallback to base configuration if the specific one doesn't exist
if (!file_exists($configurationFile)) { if (!file_exists($configurationFile)) {
$configurationFile = Bootstrap::ExpandPath("skinEngine") . 'base' . PATH_SEP . 'config.xml'; $configurationFile = Bootstrap::ExpandPath("skinEngine") . 'base' . PATH_SEP . 'config.xml';
} }
// Set caching headers $mtime = date('U');
$mtime = time();
$gmt_mtime = gmdate("D, d M Y H:i:s", $mtime) . " GMT"; $gmt_mtime = gmdate("D, d M Y H:i:s", $mtime) . " GMT";
$etag = '"' . Bootstrap::encryptOld($mtime . $filename) . '"';
$expires = gmdate("D, d M Y H:i:s", $mtime + 30 * 24 * 60 * 60) . " GMT"; // 1 month
header('Pragma: cache'); header('Pragma: cache');
header('ETag: ' . $etag); header('ETag: "' . Bootstrap::encryptOld($mtime . $filename) . '"');
header('Last-Modified: ' . $gmt_mtime); header("Last-Modified: " . $gmt_mtime);
header('Cache-Control: public'); header('Cache-Control: public');
header('Expires: ' . $expires); header("Expires: " . gmdate("D, d M Y H:i:s", time() + 30 * 60 * 60 * 24) . " GMT"); //1 month
//header("Expires: " . gmdate("D, d M Y H:i:s", time () + 60*60*24 ) . " GMT"); //1 day - tempor
// Handle conditional requests for caching if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$ifModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'] ?? null; if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime) {
$ifNoneMatch = $_SERVER['HTTP_IF_NONE_MATCH'] ?? null; header('HTTP/1.1 304 Not Modified');
exit();
if (($ifModifiedSince && $ifModifiedSince === $gmt_mtime) || }
($ifNoneMatch && str_replace('"', '', stripslashes($ifNoneMatch)) === Bootstrap::encryptOld($mtime . $filename))) {
header('HTTP/1.1 304 Not Modified');
exit();
} }
// Read and parse the configuration XML file if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
if (str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == Bootstrap::encryptOld($mtime . $filename)) {
header("HTTP/1.1 304 Not Modified");
exit();
}
}
//Read Configuration File
$xmlConfiguration = file_get_contents($configurationFile); $xmlConfiguration = file_get_contents($configurationFile);
$xmlConfigurationObj = Bootstrap::xmlParser($xmlConfiguration); $xmlConfigurationObj = Bootstrap::xmlParser($xmlConfiguration);
$baseSkinDirectory = dirname($configurationFile); $baseSkinDirectory = dirname($configurationFile);
$directorySize = Bootstrap::getDirectorySize($baseSkinDirectory); $directorySize = Bootstrap::getDirectorySize($baseSkinDirectory);
$mtime = $directorySize['maxmtime']; $mtime = $directorySize['maxmtime'];
// Prepare the CSS output with a header comment //if userAgent (BROWSER) is MSIE we need special headers to avoid MSIE behaivor.
$outputHeader = "/* Autogenerated CSS file by gulliver framework ** \n"; //$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
$outputHeader = "/* Autogenerated CSS file by gulliver framework \n";
$outputHeader .= " Skin: $filename\n"; $outputHeader .= " Skin: $filename\n";
$mtimeNow = date('U'); $mtimeNow = date('U');
$gmt_mtimeNow = gmdate("D, d M Y H:i:s", $mtimeNow) . " GMT"; $gmt_mtimeNow = gmdate("D, d M Y H:i:s", $mtimeNow) . " GMT";
$outputHeader .= " Date: $gmt_mtimeNow*/\n"; $outputHeader .= " Date: $gmt_mtimeNow*/\n";
$output = ""; $output = "";
// Include base CSS files based on the skin variant //Base files
switch (strtolower($skinVariant)) { switch (strtolower($skinVariant)) {
case "extjs": case "extjs":
//Base //Base
@@ -951,7 +953,7 @@ class Bootstrap
break; break;
} }
// Get browser information for compatibility checks //Get Browser Info
$infoBrowser = Bootstrap::get_current_browser(); $infoBrowser = Bootstrap::get_current_browser();
$browserName = $infoBrowser['browser_working']; $browserName = $infoBrowser['browser_working'];
if (isset($infoBrowser[$browserName . '_data'])) { if (isset($infoBrowser[$browserName . '_data'])) {
@@ -960,7 +962,7 @@ class Bootstrap
} }
} }
// Parse the configuration to get the list of CSS files to include //Read Configuration File
$xmlConfiguration = file_get_contents($configurationFile); $xmlConfiguration = file_get_contents($configurationFile);
$xmlConfigurationObj = Bootstrap::xmlParser($xmlConfiguration); $xmlConfigurationObj = Bootstrap::xmlParser($xmlConfiguration);
@@ -971,8 +973,6 @@ class Bootstrap
if (isset($skinFilesArray['__ATTRIBUTES__'])) { if (isset($skinFilesArray['__ATTRIBUTES__'])) {
$skinFilesArray = array($skinFilesArray); $skinFilesArray = array($skinFilesArray);
} }
// Iterate over each CSS file and include it if compatible with the current browser
foreach ($skinFilesArray as $keyFile => $cssFileInfo) { foreach ($skinFilesArray as $keyFile => $cssFileInfo) {
$enabledBrowsers = explode(",", $cssFileInfo['__ATTRIBUTES__']['enabledBrowsers']); $enabledBrowsers = explode(",", $cssFileInfo['__ATTRIBUTES__']['enabledBrowsers']);
$disabledBrowsers = explode(",", $cssFileInfo['__ATTRIBUTES__']['disabledBrowsers']); $disabledBrowsers = explode(",", $cssFileInfo['__ATTRIBUTES__']['disabledBrowsers']);
@@ -1000,14 +1000,8 @@ class Bootstrap
} }
} }
// Minify the CSS by removing comments and unnecessary whitespace //Remove comments..
$regex = array( $regex = array("`^([\t\s]+)`ism" => '', "`^\/\*(.+?)\*\/`ism" => "", "`([\n;]+)\/\*(.+?)\*\/`ism" => "$1", "`([\n;\s]+)//(.+?)[\n\r]`ism" => "$1\n", "`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism" => "\n");
"`^([\t\s]+)`ism" => '',
"`^\/\*(.+?)\*\/`ism" => "",
"`([\n;]+)\/\*(.+?)\*\/`ism" => "$1",
"`([\n;\s]+)//(.+?)[\n\r]`ism" => "$1\n",
"`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism" => "\n"
);
$output = preg_replace(array_keys($regex), $regex, $output); $output = preg_replace(array_keys($regex), $regex, $output);
$output = $outputHeader . $output; $output = $outputHeader . $output;

View File

@@ -380,16 +380,20 @@ if (!defined('PATH_DB') || !file_exists(PATH_DB)) {
app()->useStoragePath(realpath(PATH_DATA)); app()->useStoragePath(realpath(PATH_DATA));
app()->make(Kernel::class)->bootstrap(); app()->make(Kernel::class)->bootstrap();
restore_error_handler(); restore_error_handler();
//Overwrite with the Processmaker env.ini configuration used in production environments //Overwrite with the Processmaker env.ini configuration used in production environments
//@todo: move env.ini configuration to .env //@todo: move env.ini configuration to .env
ini_set('display_errors', $config['display_errors']); //ini_set('display_errors', $config['display_errors']);
ini_set('error_reporting', $config['error_reporting']); //ini_set('error_reporting', $config['error_reporting']);
ini_set('display_errors', true);
ini_set('error_reporting', true);
ini_set('short_open_tag', 'On'); ini_set('short_open_tag', 'On');
ini_set('default_charset', "UTF-8"); ini_set('default_charset', "UTF-8");
ini_set('soap.wsdl_cache_enabled', $config['wsdl_cache']); ini_set('soap.wsdl_cache_enabled', $config['wsdl_cache']);
ini_set('date.timezone', TIME_ZONE); //Set Time Zone ini_set('date.timezone', TIME_ZONE); //Set Time Zone
date_default_timezone_set(TIME_ZONE); date_default_timezone_set(TIME_ZONE);
config(['app.timezone' => TIME_ZONE]); config(['app.timezone' => TIME_ZONE]);