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

@@ -27,8 +27,8 @@ class Bootstrap
self::$startingTime = microtime(true); self::$startingTime = microtime(true);
// Determine session lifetime // Determine session lifetime
$sessionLifetime = isset($config['session.gc_maxlifetime']) $sessionLifetime = isset($config['session.gc_maxlifetime'])
? $config['session.gc_maxlifetime'] ? $config['session.gc_maxlifetime']
: ini_get('session.gc_maxlifetime'); : ini_get('session.gc_maxlifetime');
// Default to 1440 seconds (24 minutes) if lifetime is not set // Default to 1440 seconds (24 minutes) if lifetime is not set
@@ -64,13 +64,13 @@ class Bootstrap
$isSafari = preg_match("/safari/i", $userAgent) && !preg_match("/chrome/i", $userAgent); $isSafari = preg_match("/safari/i", $userAgent) && !preg_match("/chrome/i", $userAgent);
// Set cookie lifetime based on browser and configuration // Set cookie lifetime based on browser and configuration
if (($isIE && $config['ie_cookie_lifetime'] != 1) || if (($isIE && $config['ie_cookie_lifetime'] != 1) ||
($isSafari && $config['safari_cookie_lifetime'] != 1)) { ($isSafari && $config['safari_cookie_lifetime'] != 1)) {
return; // Do not set cookie lifetime if conditions are not met return; // Do not set cookie lifetime if conditions are not met
} }
ini_set('session.cookie_lifetime', $sessionLifetime); ini_set('session.cookie_lifetime', $sessionLifetime);
} }
/** /**
* @deprecated 3.2.2, We keep this function only for backwards compatibility because is used in the plugin manager * @deprecated 3.2.2, We keep this function only for backwards compatibility because is used in the plugin manager
@@ -302,7 +302,7 @@ class Bootstrap
//if (DEBUG_TIME_LOG) { // to do: remove comment //if (DEBUG_TIME_LOG) { // to do: remove comment
self::logTimeByPage(); self::logTimeByPage();
//} //}
$browserCacheFilesUid = G::browserCacheFilesGetUid(); $browserCacheFilesUid = G::browserCacheFilesGetUid();
@@ -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 = time();
$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('ETag: ' . $etag);
header('Last-Modified: ' . $gmt_mtime);
header('Cache-Control: public');
header('Expires: ' . $expires);
// Handle conditional requests for caching
$ifModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'] ?? null;
$ifNoneMatch = $_SERVER['HTTP_IF_NONE_MATCH'] ?? null;
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 $mtime = date('U');
$gmt_mtime = gmdate("D, d M Y H:i:s", $mtime) . " GMT";
header('Pragma: cache');
header('ETag: "' . Bootstrap::encryptOld($mtime . $filename) . '"');
header("Last-Modified: " . $gmt_mtime);
header('Cache-Control: public');
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
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime) {
header('HTTP/1.1 304 Not Modified');
exit();
}
}
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;
@@ -2731,7 +2725,7 @@ class Bootstrap
/** /**
* Returns an array containing the values of the current execution context. * Returns an array containing the values of the current execution context.
* *
* @global object $RBAC * @global object $RBAC
* @param array $extraParams * @param array $extraParams
* @return array * @return array

View File

@@ -181,7 +181,7 @@ $_SERVER['SERVER_ADDR'] = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR
//to do: make different environments. sys //to do: make different environments. sys
//check if it is a installation instance //check if it is a installation instance
if (!defined('PATH_C')) { // to do: review if (!defined('PATH_C')) { // to do: review
// is a intallation instance, so we need to define PATH_C and PATH_LANGUAGECONT constants temporarily // is a intallation instance, so we need to define PATH_C and PATH_LANGUAGECONT constants temporarily
define('PATH_C', (rtrim(Bootstrap::sys_get_temp_dir(), PATH_SEP) . PATH_SEP)); define('PATH_C', (rtrim(Bootstrap::sys_get_temp_dir(), PATH_SEP) . PATH_SEP));
@@ -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]);
@@ -745,7 +749,7 @@ if (!defined('EXECUTE_BY_CRON')) {
// Default to 1440 seconds (24 minutes) if lifetime is not set // Default to 1440 seconds (24 minutes) if lifetime is not set
if (is_null($sessionLifetime)) { if (is_null($sessionLifetime)) {
$sessionLifetime = 1440; $sessionLifetime = 1440;
} }
$cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + $sessionLifetime, 'httponly' => true]); $cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + $sessionLifetime, 'httponly' => true]);
setcookie(session_name(), session_id(), $cookieOptions); setcookie(session_name(), session_id(), $cookieOptions);
} }
@@ -795,7 +799,7 @@ if (!defined('EXECUTE_BY_CRON')) {
$noLoginFolders[] = 'services'; $noLoginFolders[] = 'services';
$noLoginFolders[] = 'tracker'; $noLoginFolders[] = 'tracker';
$noLoginFolders[] = 'InstallerModule'; $noLoginFolders[] = 'InstallerModule';
$data = new stdClass(); $data = new stdClass();
$data->noLoginFiles = &$noLoginFiles; $data->noLoginFiles = &$noLoginFiles;
$data->noLoginFolders = &$noLoginFolders; $data->noLoginFolders = &$noLoginFolders;