/** * Optimize website by aggregating css and js * */ public function process($sHtml) { JCH_DEBUG ? JchPlatformProfiler::mark('beforeProcess plgSystem (JCH Optimize)') : null; loadJchOptimizeClass(array('JchOptimizeBase', 'JchOptimizeParser', 'JchOptimizeFileRetriever', 'JchOptimizeLinkBuilder', 'JchOptimizeHelper')); JCH_DEBUG ? JchPlatformProfiler::mark('afterLoadClass plgSystem (JCH Optimize)') : null; try { $oParser = new JchOptimizeParser($this->params, $sHtml, JchOptimizeFileRetriever::getInstance()); $oLinkBuilder = new JchOptimizeLinkBuilder($oParser); $oLinkBuilder->insertJchLinks(); $sOptimizedHtml = JchOptimizeHelper::minifyHtml($oParser->getHtml(), $this->params); } catch (Exception $ex) { JchOptimizeLogger::log($ex->getMessage(), $this->params); $sOptimizedHtml = $sHtml; } spl_autoload_unregister('loadJchOptimizeClass'); JCH_DEBUG ? JchPlatformProfiler::mark('afterProcess plgSystem (JCH Optimize)') : null; return $sOptimizedHtml; }
/** * Get local path of file from the url if internal * If external or php file, the url is returned * * @param string $sUrl Url of file * @return string File path */ public static function getFilePath($sUrl) { //JCH_DEBUG ? JchPlatformProfiler::mark('beforeGetFilePath - ' . $sUrl . ' plgSystem (JCH Optimize)') : null; $sUriBase = JchPlatformUri::base(); $sUriPath = JchPlatformUri::base(TRUE); $oUri = clone JchPlatformUri::getInstance(); $aUrl = parse_url($sUrl); if (JchOptimizeHelper::isInternal($sUrl) && preg_match('#\\.(?>css|js|png|gif|jpe?g)$#i', $aUrl['path'])) { $sUrl = preg_replace(array('#^' . preg_quote($sUriBase, '#') . '#', '#^' . preg_quote($sUriPath, '#') . '/#', '#\\?.*?$#'), '', $sUrl); //JCH_DEBUG ? JchPlatformProfiler::mark('afterGetFilePath - ' . $sUrl . ' plgSystem (JCH Optimize)') : null; return JchPlatformPaths::absolutePath($sUrl); } else { switch (TRUE) { case preg_match('#://#', $sUrl): break; case substr($sUrl, 0, 2) == '//': $sUrl = $oUri->toString(array('scheme')) . substr($sUrl, 2); break; case substr($sUrl, 0, 1) == '/': $sUrl = $oUri->toString(array('scheme', 'user', 'pass', 'host', 'port')) . $sUrl; break; default: $sUrl = $sUriBase . $sUrl; break; } //JCH_DEBUG ? JchPlatformProfiler::mark('afterGetFilePath - ' . $sUrl . ' plgSystem (JCH Optimize)') : null; return html_entity_decode($sUrl); } }
/** * Get local path of file from the url if internal * If external or php file, the url is returned * * @param string $sUrl Url of file * @return string File path */ public static function getFilePath($sUrl) { // global $_PROFILER; //JCH_DEBUG ? $_PROFILER->mark('beforeGetFilePath - ' . $sUrl . ' plgSystem (JCH Optimize)') : null; $sUriBase = str_replace('/administrator/', '', JUri::base()); $sUriPath = str_replace('/administrator', '', JUri::base(TRUE)); $oUri = clone JUri::getInstance($sUriBase); if (JchOptimizeHelper::isInternal($sUrl) && !preg_match('#\\.php#i', $sUrl)) { $sUrl = preg_replace(array('#^' . preg_quote($sUriBase, '#') . '#', '#^' . preg_quote($sUriPath, '#') . '/#', '#\\?.*?$#'), '', $sUrl); //JCH_DEBUG ? $_PROFILER->mark('afterGetFilePath - ' . $sUrl . ' plgSystem (JCH Optimize)') : null; return JPATH_ROOT . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $sUrl); } else { switch (TRUE) { case preg_match('#://#', $sUrl): break; case substr($sUrl, 0, 2) == '//': $sUrl = $oUri->toString(array('scheme')) . substr($sUrl, 2); break; case substr($sUrl, 0, 1) == '/': $sUrl = $oUri->toString(array('scheme', 'host')) . $sUrl; break; default: $sUrl = $sUriBase . $sUrl; break; } //JCH_DEBUG ? $_PROFILER->mark('afterGetFilePath - ' . $sUrl . ' plgSystem (JCH Optimize)') : null; return html_entity_decode($sUrl); } }
/** * */ public function garbageCron() { JCH_DEBUG ? JchPlatformProfiler::start('GarbageCron') : null; $url = JchPlatformPaths::ajaxUrl('garbagecron'); JchOptimizeHelper::postAsync($url, $this->params, array('async' => '1')); JCH_DEBUG ? JchPlatformProfiler::stop('GarbageCron', TRUE) : null; }
/** * Optimize website by aggregating css and js * */ public function process($sHtml) { JCH_DEBUG ? JchPlatformProfiler::start('Process', TRUE) : null; JCH_DEBUG ? JchPlatformProfiler::start('LoadClass') : null; loadJchOptimizeClass(array('JchOptimizeBase', 'JchOptimizeParser', 'JchOptimizeFileRetriever', 'JchOptimizeLinkBuilder', 'JchOptimizeHelper')); JCH_DEBUG ? JchPlatformProfiler::stop('LoadClass', TRUE) : null; try { $oParser = new JchOptimizeParser($this->params, $sHtml, JchOptimizeFileRetriever::getInstance()); $oLinkBuilder = new JchOptimizeLinkBuilder($oParser); $oLinkBuilder->insertJchLinks(); $oParser->runCookieLessDomain(); $oParser->lazyLoadImages(); $this->params->set('isXhtml', $oLinkBuilder->isXhtml()); $this->params->set('isHtml5', $oParser->isHtml5()); $sOptimizedHtml = JchOptimizeHelper::minifyHtml($oParser->getHtml(), $this->params); } catch (Exception $ex) { JchOptimizeLogger::log($ex->getMessage(), $this->params); $sOptimizedHtml = $sHtml; } spl_autoload_unregister('loadJchOptimizeClass'); JCH_DEBUG ? JchPlatformProfiler::stop('Process', TRUE) : null; JCH_DEBUG ? JchPlatformProfiler::attachProfiler($sOptimizedHtml) : null; if (version_compare(PHP_VERSION, '7', '>=')) { ini_set('pcre.jit', $this->jit); } return $sOptimizedHtml; }
/** * Fetches HTML to be sent to browser * * @return string */ public function getHtml() { $sHtml = preg_replace($this->getHeadRegex(), JchOptimizeHelper::cleanReplacement($this->sHeadHtml), $this->sHtml, 1); if (is_null($sHtml) || $sHtml == '') { throw new Exception('Error occured while trying to get html'); } return $sHtml; }
/** * * @param type $sPath */ public static function path2Url($sPath) { $oUri = clone JchPlatformUri::getInstance(); $sBaseFolder = JchOptimizeHelper::getBaseFolder(); $abspath = str_replace(DIRECTORY_SEPARATOR, '/', ABSPATH); $sPath = str_replace(DIRECTORY_SEPARATOR, '/', $sPath); $sUriPath = $oUri->toString(array('scheme', 'user', 'pass', 'host', 'port')) . $sBaseFolder . str_replace($abspath, '', $sPath); return $sUriPath; }
/** * * @param type $function */ public static function ajaxUrl($function) { $url = JUri::getInstance()->toString(array('scheme', 'user', 'pass', 'host', 'port')); $url .= JchOptimizeHelper::getBaseFolder(); if (version_compare(JVERSION, '3.0', '<')) { $url .= 'plugins/system/jch_optimize/ajax.php?action=' . $function; } else { $url .= 'index.php?option=com_ajax&plugin=' . $function . '&format=raw'; } return $url; }
/** * * @param type $uri * @return type */ private function __construct($uri) { $this->oUri = clone JUri::getInstance($uri); if ($uri != 'SERVER') { $parts = JchOptimizeHelper::parseUrl($uri); $this->oUri->setScheme(!empty($parts['scheme']) ? $parts['scheme'] : null); $this->oUri->setUser(!empty($parts['user']) ? $parts['user'] : null); $this->oUri->setPass(!empty($parts['pass']) ? $parts['pass'] : null); $this->oUri->setHost(!empty($parts['host']) ? $parts['host'] : null); $this->oUri->setPort(!empty($parts['port']) ? $parts['port'] : null); $this->oUri->setPath(!empty($parts['path']) ? $parts['path'] : null); $this->oUri->setQuery(!empty($parts['query']) ? $parts['query'] : null); $this->oUri->setFragment(!empty($parts['fragment']) ? $parts['fragment'] : null); } return $this->oUri; }
function jch_buffer_end() { while ($level = ob_get_level()) { if (JchOptimizeHelper::validateHtml($sHtml = ob_get_contents())) { $sOptimizedHtml = jchoptimize($sHtml); ob_clean(); echo $sOptimizedHtml; break; } ob_end_flush(); //buffer not flushed for some reason. if ($level == ob_get_level()) { break; } } }
/** * Optimize website by aggregating css and js * */ public function process($sHtml) { JCH_DEBUG ? JchPlatformProfiler::start('Process', TRUE) : null; JCH_DEBUG ? JchPlatformProfiler::start('LoadClass') : null; loadJchOptimizeClass(array('JchOptimizeBase', 'JchOptimizeParser', 'JchOptimizeFileRetriever', 'JchOptimizeLinkBuilder', 'JchOptimizeHelper')); JCH_DEBUG ? JchPlatformProfiler::stop('LoadClass', TRUE) : null; try { $oParser = new JchOptimizeParser($this->params, $sHtml, JchOptimizeFileRetriever::getInstance()); $oLinkBuilder = new JchOptimizeLinkBuilder($oParser); $oLinkBuilder->insertJchLinks(); $this->params->set('xhtml', $oLinkBuilder->isXhtml()); $sOptimizedHtml = JchOptimizeHelper::minifyHtml($oParser->getHtml(), $this->params); } catch (Exception $ex) { JchOptimizeLogger::log($ex->getMessage(), $this->params); $sOptimizedHtml = $sHtml; } spl_autoload_unregister('loadJchOptimizeClass'); JCH_DEBUG ? JchPlatformProfiler::stop('Process', TRUE) : null; JCH_DEBUG ? JchPlatformProfiler::attachProfiler($sOptimizedHtml) : null; return $sOptimizedHtml; }
/** * Callback function to correct urls in aggregated css files * * @param array $aMatches Array of all matches * @return string Correct url of images from aggregated css file */ public function _correctUrlCB($aMatches, $aUrl) { if (empty($aMatches[1]) || preg_match('#^(?:\\(|/\\*)#', $aMatches[0])) { return $aMatches[0]; } $sImageUrl = $aMatches[1]; $sCssFileUrl = empty($aUrl['url']) ? '' : $aUrl['url']; if (JchOptimizeUrl::isHttpScheme($sImageUrl)) { if ((JchOptimizeUrl::isInternal($sCssFileUrl) || $sCssFileUrl == '') && JchOptimizeUrl::isInternal($sImageUrl)) { $sImageUrl = JchOptimizeUrl::toRootRelative($sImageUrl, $sCssFileUrl); $oImageUri = clone JchPlatformUri::getInstance($sImageUrl); $aStaticFiles = $this->params->get('pro_staticfiles', array('css', 'js', 'jpe?g', 'gif', 'png', 'ico', 'bmp', 'pdf')); unset($aStaticFiles[0]); $sStaticFiles = implode('|', $aStaticFiles); $aFontFiles = $this->fontFiles(); $sFontFiles = implode('|', $aFontFiles); if (preg_match('#\\.(?>' . $sStaticFiles . ')#', $oImageUri->getPath())) { $sImageUrl = JchOptimizeHelper::cookieLessDomain($this->params, $oImageUri->toString(array('path'))); } elseif ($this->params->get('pro_cookielessdomain_enable', '0') && preg_match('#\\.(?>' . $sFontFiles . ')#', $oImageUri->getPath())) { $oUri = clone JchPlatformUri::getInstance(); $sImageUrl = '//' . $oUri->toString(array('host', 'port')) . $oImageUri->toString(array('path')); } } else { if (!JchOptimizeUrl::isAbsolute($sImageUrl)) { $sImageUrl = JchOptimizeUrl::toAbsolute($sImageUrl, $sCssFileUrl); } } } $sImageUrl = preg_match('#(?<!\\\\)[\\s\'"(),]#', $sImageUrl) ? '"' . $sImageUrl . '"' : $sImageUrl; return $sImageUrl; }
/** * * @param type $sUrl * @return type */ public static function prepareFileValues($sFile, $sType = '', $iLen = 27) { if ($sType != 'value') { $oFile = JchPlatformUri::getInstance($sFile); if (JchOptimizeHelper::isInternal($sFile)) { $sFile = $oFile->getPath(); } else { $sFile = $oFile->toString(array('scheme', 'user', 'pass', 'host', 'port', 'path')); } if ($sType == 'key') { return $sFile; } } $sEps = ''; if (strlen($sFile) > $iLen) { $sFile = substr($sFile, -$iLen); $sFile = preg_replace('#^[^/]*+/#', '/', $sFile); $sEps = '...'; } return $sEps . $sFile; }
/** * * @param type $url * @param array $params */ public static function postAsync($url, $params, array $posts) { foreach ($posts as $key => &$val) { if (is_array($val)) { $val = implode(',', $val); } $post_params[] = $key . '=' . urlencode($val); } $post_string = implode('&', $post_params); $parts = JchOptimizeHelper::parseUrl($url); if (isset($parts['scheme']) && $parts['scheme'] == 'https') { $protocol = 'ssl://'; $default_port = 443; } else { $protocol = ''; $default_port = 80; } $fp = @fsockopen($protocol . $parts['host'], isset($parts['port']) ? $parts['port'] : $default_port, $errno, $errstr, 1); if (!$fp) { JchOptimizeLogger::log($errno . ': ' . $errstr, $params); } else { $out = "POST " . $parts['path'] . '?' . $parts['query'] . " HTTP/1.1\r\n"; $out .= "Host: " . $parts['host'] . "\r\n"; $out .= "Content-Type: application/x-www-form-urlencoded\r\n"; $out .= "Content-Length: " . strlen($post_string) . "\r\n"; $out .= "Connection: Close\r\n\r\n"; if (isset($post_string)) { $out .= $post_string; } fwrite($fp, $out); fclose($fp); } }
/** * * @return string */ public function getLazyLoadRegex($admin = FALSE) { $sRegex = '#(?><?[^<]*+(?:<script\\b[^>]*+>(?><?[^<]*+)*?</script>)?)*?' . '\\K(?:(<img(?!(?>\\s*+[^\\s>]*+)*?\\s*+(?>data-(?:src|original)'; $aExcludeClass = JchOptimizeHelper::getArray($this->params->get('pro_excludeLazyLoadClass', array())); if (!empty($aExcludeClass)) { $aExcludeClass = array_map(function ($sValue) { return '\\b' . preg_quote($sValue) . '\\b'; }, $aExcludeClass); $sExcludeClass = implode('|', $aExcludeClass); $sRegex .= '|class\\s*+=\\s*+[\'"]?[^\'">]*?(?>' . $sExcludeClass . ')'; } $sRegex .= '))'; if ($admin) { $sRegex .= '(?:(?=(?>\\s*+[^\\s>]*+)*?\\s*+class\\s*+=\\s*+[\'"]?([^\'">]*+)))?'; } $sRegex .= '(?>\\s*+[^\\s>]*+)*?\\s*+)(src\\s*+=\\s*+(?![\'"]?[^\'"> ]*?(?:data:image'; $aExcludesFiles = JchOptimizeHelper::getArray($this->params->get('pro_excludeLazyLoad', array())); $aExcludesFolders = JchOptimizeHelper::getArray($this->params->get('pro_excludeLazyLoadFolders', array())); $aExcludes = array_merge($aExcludesFiles, $aExcludesFolders); if (!empty($aExcludes)) { $aExcludes = array_map(function ($sValue) { return preg_quote($sValue); }, $aExcludes); $sExcludes = implode('|', $aExcludes); $sRegex .= '|' . $sExcludes; } $sRegex .= '))[\'"]?((?(?<=[\'"])[^\'"]*+|[^\\s>]*+))[\'"]?)([^>]*+>)|\\K$)#i'; return $sRegex; }
/** * Callback function to correct urls in aggregated css files * * @param array $aMatches Array of all matches * @return string Correct url of images from aggregated css file */ public function _correctUrlCB($aMatches) { //JCH_DEBUG ? JchPlatformProfiler::mark('beforeCorrectUrl plgSystem (JCH Optimize)') : null; if (preg_match('#^(?:\\(|/(?:/|\\*))#', $aMatches[0])) { return $aMatches[0]; } if ($aMatches[0] == '') { return ' '; } $sUriBase = JchPlatformUri::base(TRUE); $sImageUrl = $aMatches[1]; $sCssFileUrl = isset($this->aUrl['url']) ? $this->aUrl['url'] : '/'; if (preg_match('#^data:#', $sImageUrl)) { return $sImageUrl; } if (!preg_match('#^/|://#', $sImageUrl)) { $aCssUrlArray = explode('/', $sCssFileUrl); array_pop($aCssUrlArray); $sCssRootPath = implode('/', $aCssUrlArray) . '/'; $sImagePath = $sCssRootPath . $sImageUrl; $oImageUri = clone JchPlatformUri::getInstance($sImagePath); $sUriPath = preg_replace('#^' . preg_quote($sUriBase, '#') . '/#', '', $oImageUri->getPath()); $oImageUri->setPath($sUriBase . '/' . $sUriPath); $sImageUrl = $oImageUri->toString(); } if (JchOptimizeHelper::isInternal($sCssFileUrl) && JchOptimizeHelper::isInternal($sImageUrl)) { $oImageUri = clone JchPlatformUri::getInstance($sImageUrl); $aStaticFiles = $this->staticFiles(); $sStaticFiles = implode('|', $aStaticFiles); $aFontFiles = $this->fontFiles(); $sFontFiles = implode('|', $aFontFiles); if (preg_match('#\\.(?>' . $sStaticFiles . ')#', $oImageUri->getPath())) { $sImageUrl = JchOptimizeHelper::cookieLessDomain($this->params) . $oImageUri->toString(array('path')); } elseif (preg_match('#\\.php#', $oImageUri->getPath())) { $sImageUrl = $oImageUri->toString(array('path', 'query', 'fragment')); } elseif ($this->params->get('pro_cookielessdomain', '') && preg_match('#\\.(?>' . $sFontFiles . ')#', $oImageUri->getPath())) { $oUri = clone JchPlatformUri::getInstance(); $sImageUrl = '//' . $oUri->toString(array('host', 'port')) . $oImageUri->toString(array('path')); } else { $sImageUrl = $oImageUri->toString(array('path')); } } //JCH_DEBUG ? JchPlatformProfiler::mark('afterCorrectUrl plgSystem (JCH Optimize)') : null; $sImageUrl = preg_match('#(?<!\\\\)[\\s\'"(),]#', $sImageUrl) ? '"' . $sImageUrl . '"' : $sImageUrl; return $sImageUrl; }
/** * Generates regex for excluding components set in plugin params * * @param string $param * @return string */ protected function getExComp($sExComParam) { $aComponents = JchOptimizeHelper::getArray($sExComParam); $aExComp = array(); if (!empty($aComponents)) { $aExComp = array_map(function($sValue) { return $sValue . '/'; }, $aComponents); } return $aExComp; }
/** * Returns url of aggregated file * * @param string $sFile Aggregated file name * @param string $sType css or js * @param mixed $bGz True (or 1) if gzip set and enabled * @param number $sTime Expire header time * @return string Url of aggregated file */ protected function buildUrl($sId, $sType) { $sPath = JchPlatformPaths::assetPath(); $iTime = (int) $this->params->get('lifetime', '30'); $bGz = $this->isGZ(); if ($this->params->get('htaccess', 0) == 1) { $sUrl = JchOptimizeHelper::cookieLessDomain($this->params) . $sPath . JchPlatformPaths::rewriteBase() . ($bGz ? 'gz/' : 'nz/') . $iTime . '/JCHI/' . $sId . '.' . $sType; } else { $oUri = clone JchPlatformUri::getInstance(); $oUri->setPath($sPath . '2/jscss.php'); $aVar = array(); $aVar['f'] = $sId; $aVar['type'] = $sType; $aVar['gz'] = $bGz ? 'gz' : 'nz'; $aVar['d'] = $iTime; $aVar['i'] = 'JCHI'; $oUri->setQuery($aVar); $sUrl = htmlentities($oUri->toString(array('path', 'query'))); } return $sUrl; }
/** * Aggregate contents of CSS and JS files * * @param array $aUrlArray Array of links of files * @param string $sType CSS or js * @return string Aggregarted contents * @throws Exception */ public function combineFiles($aUrlArray, $sType, $oCssParser, $bCssAsync = FALSE) { global $_PROFILER; JCH_DEBUG ? $_PROFILER->mark('beforeCombineFiles - ' . $sType . ' plgSystem (JCH Optimize)') : null; $sContents = ''; $bAsync = false; $sAsyncUrl = ''; $oFileRetriever = JchOptimizeFileRetriever::getInstance($this->params); foreach ($aUrlArray as $aUrl) { $sContent = ''; if (isset($aUrl['url'])) { if ($sType == 'js' && $sAsyncUrl != '') { $sContents .= $this->addCommentedUrl('js', $sAsyncUrl) . 'loadScript("' . $sAsyncUrl . '", function(){}); DELIMITER'; $sAsyncUrl = ''; } $sPath = $aUrl['path']; if ($sType == 'js' && $this->loadAsync($aUrl['url'])) { $sAsyncUrl = $aUrl['url']; $bAsync = true; continue; } else { if (!JchOptimizeHelper::fileExists($sPath)) { if ($this->params->get('log', 0)) { JchOptimizeLogger::log(JText::_('File not found: ' . $sPath)); } $sFileContents = 'COMMENT_START File does not exist COMMENT_END'; } else { JCH_DEBUG ? $_PROFILER->mark('beforegetFileContents - ' . $sPath . ' plgSystem (JCH Optimize)') : null; $sFileContents = $oFileRetriever->getFileContents($sPath); JCH_DEBUG ? $_PROFILER->mark('afterGetFileContents - ' . $sPath . ' plgSystem (JCH Optimize)') : null; } if ($sFileContents === FALSE) { throw new Exception(JText::_('Failed getting file contents from ' . $sPath)); } $sContent .= $sFileContents; unset($sFileContents); } } else { if ($sType == 'js' && $sAsyncUrl != '') { $sContents .= $this->addCommentedUrl('js', $sAsyncUrl) . 'loadScript("' . $sAsyncUrl . '", function(){' . $this->sLnEnd . $aUrl['content'] . $this->sLnEnd . '}); DELIMITER'; $sAsyncUrl = ''; } else { $sContent .= $aUrl['content']; } } if ($sType == 'css') { unset($oCssParser->sCssUrl); $oCssParser->aUrl = $aUrl; $sImportContent = preg_replace('#@import\\s(?:url\\()?[\'"]([^\'"]+)[\'"](?:\\))?#', '@import url($1)', $sContent); if (is_null($sImportContent)) { if ($this->params->get('log', 0)) { JchOptimizeLogger::log(JText::_('Error occured trying to parse for @imports in ' . $aUrl['url'])); } $sImportContent = $sContent; } $sContent = $sImportContent; $sContent = $oCssParser->correctUrl($sContent); $sContent = $this->replaceImports($sContent, $aUrl); $sContent = $oCssParser->handleMediaQueries($sContent); } if ($sType == 'js' && $sContent != '') { $sContent = $this->addSemiColon($sContent); } $sContent = $this->MinifyContent($sContent, $sType, $aUrl); $sContents .= $this->addCommentedUrl($sType, $aUrl) . $sContent . 'DELIMITER'; unset($sContent); } if ($bAsync) { $sContents = $this->getLoadScript() . $sContents; if ($sAsyncUrl != '') { $sContents .= $this->addCommentedUrl('js', $sAsyncUrl) . 'loadScript("' . $sAsyncUrl . '", function(){}); DELIMITER'; $sAsyncUrl = ''; } } JCH_DEBUG ? $_PROFILER->mark('afterCombineFiles - ' . $sType . ' plgSystem (JCH Optimize)') : null; return $sContents; }
/** * Generates sprite image and return background positions for image replaced with sprite * * @param array $aMatches Array of css declarations and image url to be included in sprite * @param object $oSpriteGen Object of sprite generator * @return array */ public function generateSprite($aMatches, $oSpriteGen) { $aDeclaration = $aMatches[0]; $aImages = $aMatches[1]; $oSpriteGen->CreateSprite($aImages); $aSpriteCss = $oSpriteGen->GetCssBackground(); $aPatterns = array(); $aPatterns[0] = '#background-image:#'; // Background image declaration regex $aPatterns[1] = '#(background:[^;}]*)\\b' . '((?:top|bottom|left|right|center|-?[0-9]+(?:%|[c-x]{2})?)' . '\\s(?:top|bottom|left|right|center|-?[0-9]+(?:%|[c-x]{2})?))([^;}]*[;}])#'; $aPatterns[2] = '#url\\((?=[^\\)]+\\.(?:png|gif|jpe?g))[^\\)]+\\)#'; //Background image regex $aPatterns[3] = '#background-position:[^;}]+;?#'; //Background position declaration regex $sSpriteName = $oSpriteGen->GetSpriteFilename(); $aSearch = array(); for ($i = 0; $i < count($aSpriteCss); $i++) { if (isset($aSpriteCss[$i])) { $aSearch['needles'][] = $aDeclaration[$i]; $spritepath = JchOptimizeHelper::cookieLessDomain($this->params) . JchPlatformPaths::spriteDir(TRUE) . $sSpriteName; $aReplacements = array(); $aReplacements[0] = 'background:'; $aReplacements[1] = '$1$3'; $aReplacements[2] = 'url(' . $spritepath . ') ' . $aSpriteCss[$i]; $aReplacements[3] = ''; $sReplacement = preg_replace($aPatterns, $aReplacements, $aDeclaration[$i]); if (is_null($sReplacement)) { throw new Exception(JchPlatformUtility::translate('Error finding replacements for sprite background positions')); } $aSearch['replacements'][] = $sReplacement; } } return $aSearch; }
/** * * @param type $aUrl * @param type $sType * @param type $oFileRetriever * @return type * @throws Exception */ public function cacheContent($aUrl, $sType, $oFileRetriever, $oCssParser) { $sContent = ''; if (isset($aUrl['url'])) { $sPath = JchOptimizeHelper::getFilePath($aUrl['url']); $sContent .= $oFileRetriever->getFileContents($sPath); } else { if ($this->sAsyncUrl == '') { $sContent .= $aUrl['content']; } } $sContent = $this->sLnEnd . $sContent; if ($sType == 'css') { unset($oCssParser->sCssUrl); $oCssParser->aUrl = $aUrl; $sImportContent = preg_replace('#@import\\s(?:url\\()?[\'"]([^\'"]+)[\'"](?:\\))?#', '@import url($1)', $sContent); if (is_null($sImportContent)) { JchOptimizeLogger::log(sprintf(JchPlatformUtility::translate('Error occured trying to parse for @imports in %s'), $aUrl['url']), $this->params); $sImportContent = $sContent; } $sContent = $sImportContent; $sContent = $oCssParser->correctUrl($sContent); $sContent = $this->replaceImports($sContent, $aUrl); $sContent = $oCssParser->handleMediaQueries($sContent); if (function_exists('mb_convert_encoding')) { $sContent = mb_convert_encoding($sContent, 'utf-8'); } } if ($sType == 'js' && trim($sContent) != '') { $sContent = $this->addErrorHandler($sContent, $aUrl); } $sContent = $this->minifyContent($sContent, $sType, $aUrl); $sContent = $this->prepareContents($sContent); return $sContent; }
/** * Callback function to correct urls in aggregated css files * * @param array $aMatches Array of all matches * @return string Correct url of images from aggregated css file */ public function _correctUrlCB($aMatches, $aUrl) { if (!isset($aMatches[1]) || $aMatches[1] == '' || preg_match('#^(?:\\(|/(?:/|\\*))#', $aMatches[0])) { return $aMatches[0]; } $sUriBase = JchPlatformUri::base(TRUE); $sImageUrl = $aMatches[1]; $sCssFileUrl = isset($aUrl['url']) ? $aUrl['url'] : '/'; if (!preg_match('#^data:#', $sImageUrl)) { if (!preg_match('#^/|://#', $sImageUrl)) { $aCssUrlArray = explode('/', $sCssFileUrl); array_pop($aCssUrlArray); $sCssRootPath = implode('/', $aCssUrlArray) . '/'; $sImagePath = $sCssRootPath . $sImageUrl; $oImageUri = clone JchPlatformUri::getInstance($sImagePath); if (JchOptimizeHelper::isInternal($sCssFileUrl)) { $sUriPath = preg_replace('#^' . preg_quote($sUriBase, '#') . '/#', '', $oImageUri->getPath()); $oImageUri->setPath($sUriBase . '/' . $sUriPath); $sImageUrl = $oImageUri->toString(); } else { $oImageUri->setPath($oImageUri->getPath()); $sImageUrl = ($oImageUri->toString(array('scheme')) ? '' : '//') . $oImageUri->toString(); } } if (JchOptimizeHelper::isInternal($sCssFileUrl) && JchOptimizeHelper::isInternal($sImageUrl)) { $oImageUri = clone JchPlatformUri::getInstance($sImageUrl); $aStaticFiles = $this->params->get('pro_staticfiles', array('css', 'js', 'jpe?g', 'gif', 'png', 'ico', 'bmp', 'pdf')); $sStaticFiles = implode('|', $aStaticFiles); $aFontFiles = $this->fontFiles(); $sFontFiles = implode('|', $aFontFiles); if (preg_match('#\\.(?>' . $sStaticFiles . ')#', $oImageUri->getPath())) { $sImageUrl = JchOptimizeHelper::cookieLessDomain($this->params, $oImageUri->toString(array('path'))); } elseif (preg_match('#\\.php#', $oImageUri->getPath())) { $sImageUrl = $oImageUri->toString(array('path', 'query', 'fragment')); } elseif ($this->params->get('pro_cookielessdomain_enable', '0') && preg_match('#\\.(?>' . $sFontFiles . ')#', $oImageUri->getPath())) { $oUri = clone JchPlatformUri::getInstance(); $sImageUrl = '//' . $oUri->toString(array('host', 'port')) . $oImageUri->toString(array('path')); } else { $sImageUrl = $oImageUri->toString(array('path')); } } } $sImageUrl = preg_match('#(?<!\\\\)[\\s\'"(),]#', $sImageUrl) ? '"' . $sImageUrl . '"' : $sImageUrl; return $sImageUrl; }
/** * Determines if file requires http protocol to get contents (Not allowed) * * @param string $sUrl * @return boolean */ public function isHttpAdapterAvailable($sUrl) { return !(preg_match('#^(?:http|//)#i', $sUrl) && !JchOptimizeHelper::isInternal($sUrl) || $this->isPHPFile($sUrl)); }
/** * Determines if file requires http protocol to get contents (Not allowed) * * @param string $sUrl * @return boolean */ protected function isUrlFopenAllowed($sUrl) { return preg_match('#(?:.*\\.php)#', $sUrl) === 1 || !JchOptimizeHelper::isInternal($sUrl); }
/** * Returns url of aggregated file * * @param string $sFile Aggregated file name * @param string $sType css or js * @param mixed $bGz True (or 1) if gzip set and enabled * @param number $sTime Expire header time * @return string Url of aggregated file */ protected function buildUrl($sId, $sType, $iTime, $bGz = false) { $oUri = clone JUri::getInstance(JUri::base()); $sJbase = JUri::base(true); $sPath = $sJbase . '/plugins/system/jch_optimize/assets'; $sBaseFolder = $sJbase == '/' ? $sJbase : $sJbase . '/'; $iUrlRewriteMode = $this->params->get('htaccess', 2); if ($iUrlRewriteMode == 1 || JchOptimizeHelper::modRewriteEnabled() && $iUrlRewriteMode != 0) { $sUrl = $sPath . $sBaseFolder . ($bGz ? 'gz/' : 'nz/') . $iTime . '/' . $sId . '.' . $sType; } else { $oUri->setPath($sPath . '2/jscss.php'); $aVar = array(); $aVar['f'] = $sId; $aVar['type'] = $sType; if ($bGz) { $aVar['gz'] = 'gz'; } $aVar['d'] = $iTime; $oUri->setQuery($aVar); $sUrl = htmlentities($oUri->toString(array('path', 'query'))); } return $sUrl; }
/** * Determines if js file should be loaded asynchronously. Would be aggregated otherwise. * * @param type $sPath File path * @return boolean */ protected function loadAsync($sUrl = '') { return JchOptimizeHelper::findExcludes(JchOptimizeHelper::getArray($this->params->get('pro_loadFilesAsync', '')), $sUrl); }
/** * * @param type $sExcludeParams * @param type $sField * @return type */ public function prepareFieldOptions($sType, $sExcludeParams, $sGroup = '') { if ($sType == 'lazyload') { $sGroup = 'file'; $aFieldOptions = $this->getLazyLoad(); } elseif ($sType == 'images') { $sGroup = $sType; $aM = explode('_', $sExcludeParams); $aFieldOptions = $this->getImages($aM[1]); } else { $aFieldOptions = $this->getOptions($sType, $sGroup . 's'); } $aOptions = array(); $oParams = $this->params; $aExcludes = JchOptimizeHelper::getArray($oParams->get($sExcludeParams, array())); foreach ($aExcludes as $sExclude) { $aOptions[$sExclude] = $this->{'prepare' . ucfirst($sGroup) . 'Values'}($sExclude); } return array_unique(array_merge($aFieldOptions, $aOptions)); return $aFieldOptions; }
/** * * @return type */ protected function cookieLessDomain($sType) { if ($this->params->get('pro_cookielessdomain_enable', '0') && in_array($sType, $this->params->get('pro_staticfiles', array('css', 'js', 'jpe?g', 'gif', 'png', 'ico', 'bmp', 'pdf')))) { return JchOptimizeHelper::cookieLessDomain($this->params, JchPlatformPaths::assetPath(TRUE)); } return JchPlatformPaths::assetPath(); }
/** * Determines if file requires http protocol to get contents (Not allowed) * * @param string $sUrl * @return boolean */ protected function isHttpAdapterAvailable($sUrl) { return preg_match('#^(?:http|//)#i', $sUrl) && !JchOptimizeHelper::isInternal($sUrl) || preg_match('#\\.php|^(?!.*?\\.(?:js|css)).++#i', $sUrl); }
/** * Callback function to correct urls in aggregated css files * * @param array $aMatches Array of all matches * @return string Correct url of images from aggregated css file */ protected function _correctUrlCB($aMatches) { $sUriBase = str_replace('/administrator', '', JUri::base(TRUE)); $sImageUrl = $aMatches[1]; $sCssFileUrl = isset($this->aUrl['url']) ? $this->aUrl['url'] : '/'; if (!preg_match('#^/|://|^data:#', $sImageUrl)) { $aCssUrlArray = explode('/', $sCssFileUrl); array_pop($aCssUrlArray); $sCssRootPath = implode('/', $aCssUrlArray) . '/'; $sImagePath = $sCssRootPath . $sImageUrl; $oUri = JURI::getInstance($sImagePath); $sUriPath = preg_replace('#^' . preg_quote($sUriBase, '#') . '/#', '', $oUri->getPath()); $oUri->setPath($sUriBase . '/' . $sUriPath); $sImageUrl = $oUri->toString(); } if (JchOptimizeHelper::isInternal($sCssFileUrl)) { if (JchOptimizeHelper::isInternal($sImageUrl)) { $oUri = JURI::getInstance($sImageUrl); $sImageUrl = $oUri->toString(array('path', 'query', 'fragment')); } } return 'url(' . $sImageUrl . ')'; }