%PDF- %PDF-
Direktori : /home1/lightco1/luminero.com.au/plugins/system/jsnmobilize/libraries/joomlashine/compress/ |
Current File : //home1/lightco1/luminero.com.au/plugins/system/jsnmobilize/libraries/joomlashine/compress/css.php |
<?php /** * @version $Id$ * @package JSNExtension * @subpackage TPLFramework * @author JoomlaShine Team <support@joomlashine.com> * @copyright Copyright (C) 2012 JoomlaShine.com. All Rights Reserved. * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html * * Websites: http://www.joomlashine.com * Technical Support: Feedback - http://www.joomlashine.com/contact-us/get-support.html */ // No direct access to this file defined('_JEXEC') or die('Restricted access'); // Import necessary Joomla libraries jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); /** * CSS Compression engine * * @package TPLFramework * @subpackage Plugin * @since 1.0.0 */ abstract class JSNMobilizeCompressCss { /** * Method to parse all link to css files from the html markup * and compress it * * @param string $htmlMarkup HTML Content to response to browser * @return void */ public static function compress ($htmlMarkup) { // Get object for working with URI $uri = JUri::getInstance(); // Generate link prefix if current scheme is HTTPS $prefix = ''; if ($uri->getScheme() == 'https') { $prefix = $uri->toString(array('scheme', 'host', 'port')); } // Initialize variables $groupIndex = 0; $groupType = 'screen'; $groupFiles = array(); $compress = array(); // Sometime, stylesheet file need to be stored in the original location and file name $document = JFactory::getDocument(); $leaveAlone = preg_split('/[\r\n]+/', $document->params->get('compressionExclude')); // We already know that the file galleria.classic.css must be excluded $leaveAlone[] = 'galleria.classic.css'; // Parse link tags foreach (explode('>', $htmlMarkup[0]) AS $line) { $attributes = JSNMobilizeCompressHelper::parseAttributes($line); // Set default media attribute $attributes['media'] = ! isset($attributes['media']) ? '' : strtolower($attributes['media']); // Skip if not have attibute href if ( ! isset($attributes['href'])) { continue; } // Add to result list if this is external file if ( ! ($isInternal = JUri::isInternal($attributes['href'])) OR strpos($attributes['href'], '//') === 0) { $compress[] = array( 'href' => $attributes['href'], 'media' => $attributes['media'] ); continue; } // Add to result list if this is dynamic generation content $questionPos = false; if (($questionPos = strpos($attributes['href'], '?')) !== false) { $isDynamic = (substr($attributes['href'], $questionPos - 4, 4) == '.php'); $path = JSNMobilizeCompressHelper::getFilePath(substr($attributes['href'], 0, $questionPos)); // Check if this is a dynamic generation content if ( ! $isDynamic AND $isInternal) { $isDynamic = ! is_file($path); } if ($isDynamic) { $compress[] = array( 'href' => $attributes['href'], 'media' => $attributes['media'] ); continue; } } // Check if reserving stylesheet file name is required $stylesheetName = basename($questionPos !== false ? $path : $attributes['href']); if (in_array($stylesheetName, $leaveAlone)) { $attributes['media'] .= '|reserve|' . $stylesheetName; } // Create new compression group when media attribute different with group type if ($attributes['media'] != $groupType) { // Add collected files to compress list if (isset($groupFiles[$groupIndex]) AND ! empty($groupFiles[$groupIndex])) { $compress[] = array( 'files' => $groupFiles[$groupIndex], 'media' => $groupType ); } // Increase index number of the group $groupIndex++; $groupType = $attributes['media']; } // Initial group if ( ! isset($groupFiles[$groupIndex])) { $groupFiles[$groupIndex] = array(); } $href = $attributes['href']; $queryStringIndex = strpos($href, '?'); if ($queryStringIndex !== false) { $href = substr($href, 0, $queryStringIndex); } // Add file to the group $groupFiles[$groupIndex][] = $href; } // Add collected files to result list if (isset($groupFiles[$groupIndex]) AND ! empty($groupFiles[$groupIndex])) { $compress[] = array( 'files' => $groupFiles[$groupIndex], 'media' => $groupType ); } // Initial compress result $compressResult = array(); // Get template details $templateName = JFactory::getApplication()->getTemplate(); $cacheDirectory = "cache"; // Generate path to cache directory if ( ! preg_match('#^(/|\\|[a-z]:)#i', $cacheDirectory)) { $compressPath = JPATH_ROOT . '/' . rtrim($cacheDirectory, '\\/'); } else { $compressPath = rtrim($cacheDirectory, '\\/'); } $compressPath = $compressPath . '/' . $templateName . '/'; // Create directory if not exists if ( ! is_dir($compressPath)) { JFolder::create($compressPath); } // Loop to each compress element to compress file foreach ($compress AS $group) { // Ignore compress when group is a external file if (isset($group['href'])) { $link = '<link rel="stylesheet" href="' . $group['href'] . '" '; if (isset($group['media']) AND ! empty($group['media'])) { $link.= 'media="' . $group['media'] . '" '; } $link.= '/>'; $compressResult[] = $link; continue; } // Check if reserving stylesheet file name is required if (isset($group['media']) AND preg_match('/^([^\|]*)\|reserve\|.+$/', $group['media'], $m)) { $link = '<link rel="stylesheet" href="' . $group['files'][0] . '" '; if (isset($m[1]) AND ! empty($m[1])) { $link.= 'media="' . $m[1] . '" '; } $link.= '/>'; $compressResult[] = $link; continue; } // Generate compress file name $compressFile = md5(implode('', $group['files'])) . '.css'; $lastModified = 0; // Check last modified time for each file in the group foreach ($group['files'] AS $file) { $path = JSNMobilizeCompressHelper::getFilePath($file); $lastModified = (is_file($path) && filemtime($path) > $lastModified) ? filemtime($path) : $lastModified; } // Compress group when expired if ( ! is_file($compressPath . $compressFile) OR filemtime($compressPath . $compressFile) < $lastModified) { // Preset compression buffer $buffer = ''; // Preset remote file array $remoteFiles = array(); // Preset some variables to hold compression status $processedFiles = array(); $maxFileSize = 1024 * (int) $document->params->get('maxCompressionSize'); $currentSize = 0; // Read content of each file and write it to the cache file foreach ($group['files'] AS $file) { $filePath = JSNMobilizeCompressHelper::getFilePath($file); // Skip when cannot access to file if ( ! is_file($filePath) OR ! is_readable($filePath)) { continue; } // Do compression $result = trim(self::_loadFileInto($buffer, $filePath, $maxFileSize, $currentSize, $remoteFiles)); if (empty($result)) { // Store processed file $processedFiles[] = $filePath; } else { // Write buffer to cache file JFile::write($compressPath . $compressFile, $buffer); // Rename created cache file $newFileName = md5(implode('', $processedFiles)) . '.css'; JFile::move($compressPath . $compressFile, $compressPath . $newFileName); // Add compressed file to the remote file import list $remoteFiles[] = str_replace(str_replace('\\', '/', JPATH_ROOT), JUri::root(true), str_replace('\\', '/', $compressPath)) . $newFileName; // Reset compression buffer $buffer = $result; // Reset compression status variables $currentSize = strlen($result); $processedFiles = array($filePath); } } // Write buffer to cache file JFile::write($compressPath . $compressFile, $buffer); if ( ! empty($remoteFiles)) { for ($n = count($remoteFiles), $i = $n - 1; $i >= 0; $i--) { JSNMobilizeCompressHelper::prependIntoFile("@import url({$remoteFiles[$i]});" . ($i + 1 < $n ? "\n" : "\n\n"), $compressPath . $compressFile); } } } // Add compressed file to the compress result list $compressUrl = str_replace(str_replace('\\', '/', JPATH_ROOT), JUri::root(true), str_replace('\\', '/', $compressPath)) . $compressFile; $link = '<link rel="stylesheet" href="' . $prefix . $compressUrl . '" '; if (isset($group['media']) AND ! empty($group['media'])) { $link .= 'media="' . preg_replace('/\|reserve\|(.+)$/', '', $group['media']) . '" '; } $link .= '/>'; $compressResult[] = $link; } return implode("\r\n", $compressResult); } /** * Load content from a file and append into existing opened file * * @param string $buffer Compression buffer. * @param string $sourcePath Path to source file. * @param integer $maxFileSize Maximum allowed file size. * @param integer &$currentFileSize Current file size. * @param array &$remoteFilesImport Array of remotely imported file. * * @return mixed Compressed content if max file size is reached. */ private static function _loadFileInto(&$buffer, $sourcePath, $maxFileSize, &$currentFileSize, &$remoteFilesImport) { // Read source file $source = JFile::read($sourcePath); // Rewrite all relative URLs if (preg_match_all('/(@import\s+|[^:,;\}\r\n]*)([^,;\}\r\n]*)url\s*\(([^\)]+)\)([^,;\}\r\n]*[,;\}])/i', $source, $matches, PREG_SET_ORDER)) { foreach ($matches AS $match) { $fileUrl = JSNMobilizeCompressHelper::getRelativeFilePath(dirname($sourcePath), trim($match[3], '"\'')); if (trim($match[1]) != '@import') { $fileUrl = ltrim(str_replace('\\', '/', $fileUrl), '/'); if (strpos($match[3], '://') === false && strpos($match[3], '//') !== 0) { $source = str_replace($match[0], $match[1] . $match[2] . 'url(/' . $fileUrl . ')' . $match[4], $source); } } elseif ( ! preg_match('#^https?://#', $match[3])) { // Get file path $filePath = getenv('DOCUMENT_ROOT') . $fileUrl; // Compress file being imported $imports[] = self::_loadFileInto($buffer, $filePath, $maxFileSize, $currentFileSize, $remoteFilesImport); // Remove @import file inclusion for local file $source = str_replace($match[0], '', $source); } else { // Store @import file inclusion for remote file $remoteFilesImport[] = $match[3]; } } } // Strip all tab, return and new-line characters $source = preg_replace('/[\t\r\n]/', '', $source); // Prepend path to source file $source = ($currentFileSize == 0 ? '' : "\n\n") . '/* FILE: ' . str_replace(str_replace('\\', '/', JPATH_ROOT), '', str_replace('\\', '/', $sourcePath)) . ' */' . "\n{$source}"; // Get length of processed content $length = strlen($source); // Update current file size $currentFileSize += $length; // Check if max file size is reached if ($length > $maxFileSize OR $currentFileSize > $maxFileSize) { return (isset($imports) ? implode($imports) : '') . $source; } // Append processed content to buffer $buffer .= $source; return ''; } }