Exemplo n.º 1
0
        /**
         * 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;
        }
Exemplo n.º 2
0
 /**
  * 
  */
 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;
 }
Exemplo n.º 4
0
 /**
  * Minify the markeup given in the constructor
  *
  * @return string
  */
 public function process()
 {
     JCH_DEBUG ? \JchPlatformProfiler::mark('beforeProcess plgSystem (JCH Optimize)') : null;
     if ($this->_isXhtml === null) {
         $this->_isXhtml = preg_match('#^\\s*+<!DOCTYPE[^X]++XHTML#i', $this->_html);
     }
     if ($this->_isHtml5 === null) {
         $this->_isHtml5 = preg_match('#^\\s*+<!DOCTYPE html>#i', $this->_html);
     }
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterTestHtml plgSystem (JCH Optimize)') : null;
     //Replace comments (not containing IE conditional comments)
     $this->_html = preg_replace('#(?>(?:<(?!!))?[^<]*+(?:<(?:script|style)\\b[^>]*+>(?><?[^<]*+)*?<\\/(?:script|style)>|<!--\\[(?>\\]?[^\\]]*+)*?\\]--!?>|' . '<!DOCTYPE[^>]++>)?)*?\\K(?:<!--(?>-?[^-\\[]*+)*?--!?>|[^<]*+\\K$)#i', '', $this->_html);
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterReplaceComments plgSystem (JCH Optimize)') : null;
     //Reduce whitespace outside all elements to one space
     $this->_html = preg_replace('#(?>>?[^>]*+>(?>[^>]*+\\S[^>]*+>)*?)*?\\K(?:(?<=>)\\s++(?=<)|[^<]*+$\\K)#', ' ', $this->_html);
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterReduceWs plgSystem (JCH Optimize)') : null;
     //block/undisplayed elements
     $b = 'address|article|aside|audio|body|blockquote|canvas|dd|div|dl' . '|fieldset|figcaption|figure|footer|form|h[1-6]|head|header|hgroup|html|noscript|ol|output|p' . '|pre|section|style|table|title|tfoot|ul|video';
     //self closing block/undisplayed elements
     $b2 = 'base|meta|link|hr';
     //inline elements
     $i = 'b|big|i|small|tt' . '|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var' . '|a|bdo|br|map|object|q|script|span|sub|sup' . '|button|label|select|textarea';
     //self closing inline elements
     $i2 = 'img|input';
     // remove ws around block elements preserving space around inline elements
     $this->_html = preg_replace("#(?>\\s*+(?:<(?:(?>{$i})\\b[^>]*+>|(?:/(?>{$i})\\b>|(?>{$i2})\\b[^>]*+>)\\s*+)|<[^>]*+>)|[^<]++)*?\\K" . "(?:\\s++(?=<(?>{$b}|{$b2})\\b)|(?:</(?>{$b})\\b>|<(?>{$b2})\\b[^>]*+>)\\K\\s++(?!<(?>{$i}|{$i2})\\b)|\$)#i", '', $this->_html);
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterRemoveWsAroundBlocks plgSystem (JCH Optimize)') : null;
     //Minify scripts
     $this->_html = preg_replace_callback('#(?><?[^<]*+)*?\\K(?:(<(script|style)\\b[^>]*+>)((?>(?:<(?!/\\g{2}))?[^<]++)+?)(<\\/\\g{2}>)|$)#i', array($this, '_minifyCB'), $this->_html);
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterMinifyScripts plgSystem (JCH Optimize)') : null;
     //elements to escape
     $e = 'pre|script|style|textarea';
     //Regex for escape elements
     $p = "<pre\\b[^>]*+>(?><?[^<]*+)*?</pre>";
     $sc = "<script\\b[^>]*+>(?><?[^<]*+)*?</script>";
     $st = "<style\\b[^>]*+>(?><?[^<]*+)*?</style>";
     $t = "<textarea\\b[^>]*+>(?><?[^<]*+)*?</textarea>";
     //Replace runs of whitespace inside elements with single space escaping pre, textarea, scripts and style elements
     $this->_html = preg_replace("#(?>[^<]*+(?:{$p}|{$sc}|{$st}|{$t}|<[^>]++>[^<]*+))*?(?:(?:<(?!{$e})[^>]*+>)?(?>\\s?[^\\s<]*+)*?\\K\\s{2,}|\\K\$)#i", ' ', $this->_html);
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterReplaceRunsOfWs plgSystem (JCH Optimize)') : null;
     //Remove additional ws around attributes
     $this->_html = preg_replace('#(?><?[^<]*+)*?(?:<[a-z0-9]++\\K\\s++|\\G[^\\>=]++=(?(?=\\s*+["\'])\\s*+["\'][^"\']*+["\']|[^\\s]++)\\K\\s++|$\\K)#i', ' ', $this->_html);
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterRemoveWsAroundAttributes plgSystem (JCH Optimize)') : null;
     if ($this->_isHtml5) {
         $ns1 = '"[^"\'`=<>\\s]*+(?:[\'`=<>\\s]|(?<=\\\\)")(?>(?:(?<=\\\\)")?[^"]*+)*?(?<!\\\\)"';
         $ns2 = "'[^'\"`=<>\\s]*+(?:[\"`=<>\\s]|(?<=\\\\)')(?>(?:(?<=\\\\)')?[^']*+)*?(?<!\\\\)'";
         //Remove quotes from selected attributes
         $this->_html = preg_replace("#(?:(?=[^>]*+>)|<[a-z0-9]++ )" . "(?>[=]?[^=>]*+(?:=(?:{$ns1}|{$ns2})|>(?><?[^<]*+)*?(?:<[a-z0-9]++ |\$))?)*?" . "(?:=\\K([\"'])([^\"'`=<>\\s]++)\\g{1}[ ]?|\\K\$)#i", '$2 ', $this->_html);
     }
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterRemoveQuotes plgSystem (JCH Optimize)') : null;
     //remove redundant attributes
     $this->_html = preg_replace('#(?><?[^<]*+)*?<(?:(?:script|style|link)|/html>)(?>[ ]?[^ >]*+)*?\\K(?: type=["\']?text/(?:javascript|css)|[^<]*+\\K$)#i', '', $this->_html);
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterRemoveAttributes plgSystem (JCH Optimize)') : null;
     //Remove last whitespace in open tag
     $this->_html = preg_replace('#(?><?[^<]*+)*?(?:<[a-z0-9]++(?>\\s*+[^\\s>]++)*?\\K(?:\\s++(?=>)|(?<=["\'])\\s++(?=/>))|$\\K)#i', '', $this->_html);
     //                JCH_DEBUG ? \JchPlatformProfiler::mark('afterRemoveLastWs plgSystem (JCH Optimize)') : null;
     return trim($this->_html);
 }
Exemplo n.º 5
0
 /**
  * 
  * @param type $sHtml
  */
 public static function attachProfiler(&$sHtml)
 {
     if (!is_super_admin()) {
         return;
     }
     $items = JchPlatformProfiler::mark(TRUE);
     $node = self::getAdminBarNodeBegin() . $items . self::getAdminBarNodeEnd();
     $script = '<script type="application/javascript">' . 'var ul = document.getElementById("wp-admin-bar-root-default");' . 'ul.insertAdjacentHTML(\'beforeend\', \'' . $node . '\');' . '</script>';
     $sHtml = str_replace('</body>', $script . '</body>', $sHtml);
 }
Exemplo n.º 6
0
 /**
  * Grabs background images with no-repeat attribute from css and merge them in one file called a sprite.
  * Css is updated with sprite url and correct background positions for affected images.
  * Sprite saved in {Joomla! base}/images/jch-optimize/
  *
  * @param string $sCss       Aggregated css file before sprite generation
  * @return string           Css updated with sprite information on success. Original css on failure
  */
 public function getSprite($sCss)
 {
     JCH_DEBUG ? JchPlatformProfiler::mark('beforeGetSprite plgSystem (JCH Optimize)') : null;
     $sImageLibrary = $this->getImageLibrary();
     $aMatches = $this->processCssUrls($sCss);
     if (empty($aMatches) || $sImageLibrary === FALSE) {
         return $sCss;
     }
     $this->params->set('sprite-path', JchPlatformPaths::spriteDir());
     $aSearch = $this->generateSprite($aMatches, new CssSpriteGen($sImageLibrary, $this->params));
     JCH_DEBUG ? JchPlatformProfiler::mark('afterGetSprite plgSystem (JCH Optimize)') : null;
     return $aSearch;
 }
Exemplo n.º 7
0
 public function getOriginalHtml()
 {
     JCH_DEBUG ? JchPlatformProfiler::mark('beforeGetHtml') : null;
     $url = home_url() . '/?jchbackend=1';
     try {
         $oFileRetriever = JchOptimizeFileRetriever::getInstance();
         $response = $oFileRetriever->getFileContents($url);
         if ($oFileRetriever->response_code != 200) {
             throw new Exception(JchPlatformUtility::translate('Failed fetching front end HTML with response code ' . $oFileRetriever->response_code));
         }
         JCH_DEBUG ? JchPlatformProfiler::mark('afterGetHtml') : null;
         return $response;
     } catch (Exception $e) {
         JchOptimizeLogger::log($url . ': ' . $e->getMessage(), $this->params);
         JCH_DEBUG ? JchPlatformProfiler::mark('afterGetHtml)') : null;
         throw new RunTimeException(_('Load or refresh the front-end site first then refresh this page ' . 'to populate the multi select exclude lists.'));
     }
 }
Exemplo n.º 8
0
 /**
  * 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;
 }
Exemplo n.º 9
0
 /**
  * 
  * @param type $oObj
  * @param type $sCss
  * @return type
  */
 public function generateAdminLinks($oObj, $sCss)
 {
     JCH_DEBUG ? JchPlatformProfiler::start('GenerateAdminLinks') : null;
     $params = clone $this->params;
     $params->set('javascript', '1');
     $params->set('css', '1');
     $params->set('excludeAllExtensions', '0');
     $params->set('css_minify', '0');
     $params->set('debug', '0');
     $params->set('bottom_js', '2');
     $sHtml = $oObj->getOriginalHtml();
     $oParser = new JchOptimizeParser($params, $sHtml, JchOptimizeFileRetriever::getInstance());
     $aLinks = $oParser->getReplacedFiles();
     if ($sCss == '' && !empty($aLinks['css'][0])) {
         $oCombiner = new JchOptimizeCombiner($params, $this->bBackend);
         $oCssParser = new JchOptimizeCssParser($params, $this->bBackend);
         $oCombiner->combineFiles($aLinks['css'][0], 'css', $oCssParser);
         $sCss = $oCombiner->css;
     }
     $oSpriteGenerator = new JchOptimizeSpriteGenerator($params);
     $aLinks['images'] = $oSpriteGenerator->processCssUrls($sCss, TRUE);
     JCH_DEBUG ? JchPlatformProfiler::stop('GenerateAdminLinks', TRUE) : null;
     return $aLinks;
 }
Exemplo n.º 10
0
 /**
  * If parameter is set will minify HTML before sending to browser; 
  * Inline CSS and JS will also be minified if respective parameters are set
  * 
  * @return string                       Optimized HTML
  * @throws Exception
  */
 public static function minifyHtml($sHtml, $oParams)
 {
     JCH_DEBUG ? JchPlatformProfiler::mark('beforeMinifyHtml plgSystem (JCH Optimize)') : null;
     $aOptions = array();
     if ($oParams->get('css_minify', 0)) {
         $aOptions['cssMinifier'] = array('JchOptimize\\CSS_Optimize', 'process');
     }
     if ($oParams->get('js_minify', 0)) {
         $aOptions['jsMinifier'] = array('JchOptimize\\JS_Optimize', 'minify');
     }
     $aOptions['minify_level'] = $oParams->get('html_minify_level', 2);
     if ($oParams->get('html_minify', 0)) {
         $sHtmlMin = HTML_Optimize::minify($sHtml, $aOptions);
         if ($sHtmlMin == '') {
             JchOptimizeLogger::log(JchPlatformUtility::translate('Error while minifying HTML'), $oParams);
             $sHtmlMin = $sHtml;
         }
         $sHtml = $sHtmlMin;
     }
     JCH_DEBUG ? JchPlatformProfiler::mark('afterMinifyHtml plgSystem (JCH Optimize)') : null;
     return $sHtml;
 }
Exemplo n.º 11
0
 /**
  * 
  * @param type $sContent
  * @param type $sUrl
  */
 protected function minifyContent($sContent, $sType, $aUrl)
 {
     if ($this->params->get($sType . '_minify', 0) && preg_match('#\\s++#', trim($sContent))) {
         $sUrl = isset($aUrl['url']) ? $aUrl['url'] : ($sType == 'css' ? 'Style' : 'Script') . ' Declaration';
         JCH_DEBUG ? JchPlatformProfiler::mark('beforeMinifyContent - "' . $sUrl . '" plgSystem (JCH Optimize)') : null;
         $sMinifiedContent = trim($sType == 'css' ? CSS_Optimize::process($sContent) : JS_Optimize::minify($sContent));
         if (is_null($sMinifiedContent) || $sMinifiedContent == '') {
             JchOptimizeLogger::log(sprintf(JchPlatformUtility::translate('Error occurred trying to minify: %s'), $aUrl['url']), $this->params);
             $sMinifiedContent = $sContent;
         }
         JCH_DEBUG ? JchPlatformProfiler::mark('afterMinifyContent - "' . $sUrl . '" plgSystem (JCH Optimize)') : null;
         return $sMinifiedContent;
     }
     return $sContent;
 }
Exemplo n.º 12
0
 /**
  * 
  * @return type
  */
 public function lazyLoadImages()
 {
     if ($this->params->get('pro_lazyload', '0')) {
         JCH_DEBUG ? JchPlatformProfiler::start('LazyLoadImages') : null;
         $sLazyLoadBodyHtml = preg_replace($this->getLazyLoadRegex(), '$1src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="$3" ' . 'data-jchll="true"$4<noscript>$1$2$4</noscript>', $this->getBodyHtml());
         if (is_null($sLazyLoadBodyHtml)) {
             JchOptimizeLogger::log('Lazy load images function failed', $this->params);
             return;
         }
         if (preg_match($this->getBodyRegex(), $sLazyLoadBodyHtml, $aBodyMatches) === FALSE || empty($aBodyMatches)) {
             JchOptimizeLogger::log('Failed retrieving body in lazy load images function', $this->params);
             return;
         }
         $this->sBodyHtml = $aBodyMatches[0];
         JCH_DEBUG ? JchPlatformProfiler::stop('LazyLoadImages', TRUE) : null;
     }
 }
Exemplo n.º 13
0
 public function parseUserAgent($userAgent)
 {
     JCH_DEBUG ? JchPlatformProfiler::start('ParseUserAgent') : null;
     //Chrome
     if (preg_match('#^(?:(?=[^(]*+\\([^AM)]*+(Android|Macintosh)))?(?>(?:Mozilla|AppleWebKit|Safari)/[\\d. ]*+(?:\\([^)]*+\\)(?:[^()]*+\\))*\\s*+)?|Chrome/(\\d++\\.\\d++)[\\d. ]*+|Mobile\\s*+){4,5}$|' . '^(?=[^(]*+\\([^A)]*+Android)(?=(?>V?[^V]*+)*?Version/)(?>(?:Mozilla|AppleWebKit|Safari|Version)/[\\d. ]*+(?:\\([^)]*+\\)(?:[^()]*+\\))*\\s*+)?|Chrome/(\\d++\\.\\d++)[\\d. ]*+|Mobile\\s*+){5,6}$|' . '^(?>(?:Mozilla|AppleWebKit|Safari|Chrome)/[\\d. ]*+(?:\\([^)]*+\\)(?:[^()]*+\\))*\\s*+)?|Chromium/(\\d++\\.\\d++)[\\d. ]*+|(?:Fedora|Ubuntu)/?[\\d. ]*+){5,6}#', $userAgent, $version)) {
         if (!empty($version[2])) {
             $this->browser = 'Chrome';
             $this->version = (double) $version[2];
         } elseif (!empty($version[3])) {
             $this->browser = 'Android WebView';
             $this->version = (double) $version[3];
         } elseif (!empty($version[4])) {
             $this->browser = 'Chromium';
             $this->version = (double) $version[4];
         }
         if (!empty($version[1]) || $this->browser == 'Android WebView') {
             if ($this->version >= 40) {
                 $this->fontHash = 'c0fbf0f0/woff2';
             } elseif ($this->version >= 36) {
                 $this->fontHash = 'd70f5a27/woff2';
             } elseif ($this->version >= 31) {
                 $this->fontHash = '1578596c/woff';
             } else {
                 $this->fontHash = '34c6462b/woff';
             }
         } else {
             if ($this->version >= 40) {
                 $this->fontHash = 'd858f13e/woff2';
             } elseif ($this->version >= 36) {
                 $this->fontHash = 'c9ad59db/woff2';
             } else {
                 $this->fontHash = '1dc159a2/woff';
             }
         }
     } elseif (preg_match('#^(?=(?>F?[^F]*+)*?Firefox/(\\d++\\.\\d++))(?:(?=[^(]*+\\((?>[AiM]?[^AiM)]*+)*?(Android|(?:Macintosh|iP(?:[oa]d|hone)))))?(?>(?:Mozilla|MyWebkit|Gecko|Firefox|Navigator|TenFourFox)/[\\d. ]*+(?:\\([^)]*+\\)(?:[^()]*+\\))*\\s*+)?|[^/]++){3,4}$#', $userAgent, $version)) {
         $this->browser = 'Firefox';
         $this->version = (double) $version[1];
         if (!empty($version[2]) && $version[2] == 'Android') {
             if ($this->version >= 35) {
                 $this->fontHash = '9a0a6e1c/woff2/woff';
             } elseif ($this->version >= 3.6) {
                 $this->fontHash = '34c6462b/woff';
             }
         } elseif (!empty($version[2])) {
             if ($this->version >= 35) {
                 $this->fontHash = '34b7815d/woff2/woff';
             } elseif ($this->version >= 3.6) {
                 $this->fontHash = '1578596c/woff';
             } else {
                 $this->fontHash = '269b5aae/ttf';
             }
         } else {
             if ($this->version >= 35) {
                 $this->fontHash = '0dc68147/woff2/woff';
             } elseif ($this->version >= 3.6) {
                 $this->fontHash = '1dc159a2/woff';
             }
         }
     } elseif (preg_match('#^(?=(?>V?[^V]*+)*?Version/(\\d++\\.\\d++))(?:(?=[^(]*+\\([^O)]*+Opera\\s*+Mini/(\\d++\\.\\d++)))?(?>(?:Opera|Presto|Version)/[\\d. ]*+(?:\\([^)]*+\\)(?:[^()]*+\\))*\\s*+)?|[^/]++){3}$|' . '^(?=(?>O?[^O]*+)*?OPR/(\\d++\\.\\d++))(?:(?=[^(]*+\\([^M)]*+(Macintosh)))?(?>(?:Mozilla|AppleWebKit|Chrome|Safari|OPR)/[\\d. ]*+(?:\\([^)]*+\\)(?:[^()]*+\\))*\\s*+)?|[^/]++){5}$#', $userAgent, $version)) {
         if (!empty($version[2])) {
             $this->browser = 'Opera Mini';
             $this->version = (double) $version[2];
         } else {
             $this->browser = 'Opera';
             $this->version = (double) (!empty($version[1]) ? $version[1] : $version[3]);
         }
         if (!empty($version[4]) && $version[4] == 'Macintosh') {
             if ($this->version >= 23) {
                 $this->fontHash = 'c0fbf0f0/woff2';
             } elseif ($this->version >= 11.1) {
                 $this->fontHash = '1578596c/woff';
             } else {
                 $this->fontHash = '269b5aae/ttf';
             }
         } else {
             if ($this->version >= 23) {
                 $this->fontHash = 'd858f13e/woff2';
             } elseif ($this->version >= 11.1) {
                 $this->fontHash = '1dc159a2/woff';
             }
         }
     } elseif (preg_match('#^(?:(?=[^(]*+\\(\\s*+(?:Macintosh|iP(?:[oa]d|hone))[^O)]++OS\\s*+X?\\s*+(\\d++[_.]\\d*+)))?(?:(?=(?>[CV]?[^CV]*+)*?(CriOS|Version)/(\\d++\\.\\d++)))?(?>(?:Mozilla|AppleWebKit|Version|Mobile|Safari|CriOS|OPiOS)/[\\d.\\w]*+\\s*+(?:\\([^)]*+\\)(?:[^()]*+\\))*\\s*+)?){4,5}$#', $userAgent, $version)) {
         if (!empty($version[2]) && $version[2] == 'CriOS') {
             $this->browser = 'Chrome';
         } else {
             $this->browser = 'Safari';
         }
         if (!empty($version[3])) {
             $this->version = (double) $version[3];
         }
         if (!empty($version[1])) {
             $os_version = (double) str_replace('_', '.', $version[1]);
             // OS version
             if ($this->version >= 5 || $this->version == 0.0) {
                 $this->fontHash = '1578596c/woff';
             } elseif ($this->version < 5 && $os_version <= 4.2) {
                 $this->fontHash = 'd7745f9b/svg';
             } elseif ($this->version < 5 && $os_version > 4.2) {
                 $this->fontHash = '269b5aae/ttf';
             }
         }
     } elseif (preg_match('#^Mozilla/5\\.0\\s*+\\(\\s*+Windows\\s++(?:NT|Phone)[^T)]*+Trident[^r)]*+rv:(\\d++)\\.[^)]*+\\)\\s*+like\\s++Gecko\\s*+|' . '^Mozilla/[\\d. ]*+\\(compatible;\\s*+MSIE (\\d++)\\.#', $userAgent, $version)) {
         $this->browser = 'IE';
         $this->version = (double) (!empty($version[1]) ? $version[1] : $version[2]);
         if ($this->version >= 9) {
             $this->fontHash = '1dc159a2/woff';
         } else {
             $this->fontHash = 'ea09403b/eot';
         }
     } elseif (preg_match('#^(?>(?:Mozilla|AppleWebKit|Safari|Chrome)/[\\d. ]*+(?:\\([^)]*+\\)(?:[^()]*+\\))*\\s*+)?)++Edge/(\\d++\\.\\d++)[\\d. ]*+#', $userAgent, $version)) {
         $this->browser = 'Edge';
         $this->version = (double) (!empty($version[1]) ? $version[1] : $this->version);
         $this->fontHash = '1dc159a2/woff';
     }
     JCH_DEBUG ? JchPlatformProfiler::stop('ParseUserAgent', TRUE) : null;
 }
Exemplo n.º 14
0
 /**
  * If parameter is set will minify HTML before sending to browser; 
  * Inline CSS and JS will also be minified if respective parameters are set
  * 
  * @return string                       Optimized HTML
  * @throws Exception
  */
 public static function minifyHtml($sHtml, $oParams)
 {
     JCH_DEBUG ? JchPlatformProfiler::start('MinifyHtml') : null;
     if ($oParams->get('html_minify', 0)) {
         $aOptions = array();
         if ($oParams->get('css_minify', 0)) {
             $aOptions['cssMinifier'] = array('JchOptimize\\CSS_Optimize', 'optimize');
         }
         if ($oParams->get('js_minify', 0)) {
             $aOptions['jsMinifier'] = array('JchOptimize\\JS_Optimize', 'optimize');
         }
         $aOptions['minifyLevel'] = $oParams->get('html_minify_level', 2);
         $aOptions['isXhtml'] = (bool) $oParams->get('isXhtml', false);
         $aOptions['isHtml5'] = (bool) $oParams->get('isHtml5', false);
         $sHtmlMin = HTML_Optimize::optimize($sHtml, $aOptions);
         if ($sHtmlMin == '') {
             JchOptimizeLogger::log('Error while minifying HTML', $oParams);
             $sHtmlMin = $sHtml;
         }
         $sHtml = $sHtmlMin;
         JCH_DEBUG ? JchPlatformProfiler::stop('MinifyHtml', TRUE) : null;
     }
     return $sHtml;
 }
Exemplo n.º 15
0
 /**
  * 
  * @param type $oObj
  * @param type $sCss
  * @return type
  */
 public function generateAdminLinks($oObj, $sCss)
 {
     JCH_DEBUG ? JchPlatformProfiler::start('GenerateAdminLinks') : null;
     $params = clone $this->params;
     $params->set('javascript', '1');
     $params->set('css', '1');
     $params->set('excludeAllExtensions', '0');
     $params->set('css_minify', '0');
     $params->set('debug', '0');
     $params->set('bottom_js', '2');
     ##<procode>##
     $params->set('pro_phpAndExternal', '1');
     $params->set('pro_inlineScripts', '1');
     $params->set('pro_lazyload', '0');
     ##</procode>##
     $sHtml = $oObj->getOriginalHtml();
     $oParser = new JchOptimizeParser($params, $sHtml, JchOptimizeFileRetriever::getInstance());
     $aLinks = $oParser->getReplacedFiles();
     if ($sCss == '' && !empty($aLinks['css'][0])) {
         $oCombiner = new JchOptimizeCombiner($params, $this->bBackend);
         $oCssParser = new JchOptimizeCssParser($params, $this->bBackend);
         $oCombiner->combineFiles($aLinks['css'][0], 'css', $oCssParser);
         $sCss = $oCombiner->css;
     }
     $oSpriteGenerator = new JchOptimizeSpriteGenerator($params);
     $aLinks['images'] = $oSpriteGenerator->processCssUrls($sCss, TRUE);
     ##<procode>##
     $sRegex = $oParser->getLazyLoadRegex();
     preg_match_all($sRegex, $oParser->getBodyHtml(), $aMatches);
     $aLinks['lazyload'] = $aMatches[1];
     ##</procode>##
     JCH_DEBUG ? JchPlatformProfiler::stop('GenerateAdminLinks', TRUE) : null;
     return $aLinks;
 }
Exemplo n.º 16
0
 /**
  * 
  * @param type $sRegex
  * @param type $sType
  * @param type $sSection
  * @param type $aCBArgs
  * @throws Exception
  */
 protected function searchArea($sRegex, $sSection, $aCBArgs)
 {
     JCH_DEBUG ? JchPlatformProfiler::start('SearchArea - ' . $sSection) : null;
     $obj = $this;
     $sProcessedHtml = preg_replace_callback($sRegex, function ($aMatches) use($obj, $aCBArgs) {
         return $obj->replaceScripts($aMatches, $aCBArgs);
     }, $this->{'s' . ucfirst($sSection) . 'Html'});
     if (is_null($sProcessedHtml)) {
         throw new Exception(sprintf('Error while parsing for links in %1$s', $sSection));
     }
     $this->{'s' . ucfirst($sSection) . 'Html'} = $sProcessedHtml;
     JCH_DEBUG ? JchPlatformProfiler::stop('SearchArea - ' . $sSection, TRUE) : null;
 }
Exemplo n.º 17
0
 /**
  * 
  */
 protected function getImagesWithoutAttributes()
 {
         if($this->params->get('img_attributes_enable', '0'))
         {
                 JCH_DEBUG ? JchPlatformProfiler::start('GetImagesWithoutAttributes') : null;
                 
                 $rx = '#(?><?[^<]*+)*?\K(?:<img\s++(?!(?=(?>[^\s>]*+\s++)*?width\s*+=\s*+["\'][^\'">a-z]++[\'"])'
                         . '(?=(?>[^\s>]*+\s++)*?height\s*+=\s*+["\'][^\'">a-z]++[\'"]))'
                         . '(?=(?>[^\s>]*+\s++)*?src\s*+=(?:\s*+"([^">]*+)"|\s*+\'([^\'>]*+)\'|([^\s>]++)))[^>]*+>|$)#i';
                 
                 preg_match_all($rx, $this->getBodyHtml(), $m, PREG_PATTERN_ORDER);
              
                 $this->aLinks['img'] = array_map(function($a){return array_slice($a, 0, -1);}, $m);
                 
                 JCH_DEBUG ? JchPlatformProfiler::stop('GetImagesWithoutAttributes', true) : null;
         }
 }
Exemplo n.º 18
0
 /**
  * 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)
 {
     $sContents = '';
     $sLifetime = (int) $this->params->get('lifetime', '30') * 24 * 60 * 60;
     $this->bAsync = FALSE;
     $this->sAsyncUrl = '';
     $oFileRetriever = JchOptimizeFileRetriever::getInstance();
     foreach ($aUrlArray as $aUrl) {
         $sUrl = $this->prepareFileUrl($aUrl, $sType);
         JCH_DEBUG ? JchPlatformProfiler::start('CombineFile - ' . $sUrl) : null;
         if ($sType == 'js') {
             $sJsContents = $this->handleAsyncUrls($aUrl);
             if ($sJsContents === FALSE) {
                 continue;
             }
             $sContents .= $sJsContents;
             unset($sJsContents);
         }
         if (isset($aUrl['id']) && $aUrl['id'] != '') {
             $function = array($this, 'cacheContent');
             $args = array($aUrl, $sType, $oFileRetriever, $oCssParser, TRUE);
             $sCachedContent = JchPlatformCache::getCallbackCache($aUrl['id'], $sLifetime, $function, $args);
             $this->{$sType} .= $sCachedContent;
             if (!isset($aUrl['url']) && $this->sAsyncUrl != '' && $sType == 'js') {
                 $this->sAsyncUrl = '';
             }
             if ($this->sAsyncUrl == '') {
                 $sContents .= $this->addCommentedUrl($sType, $aUrl) . '[[JCH_' . $aUrl['id'] . ']]' . $this->sLnEnd . 'DELIMITER';
             }
         } else {
             $sContent = $this->cacheContent($aUrl, $sType, $oFileRetriever, $oCssParser, FALSE);
             $sContents .= $this->addCommentedUrl($sType, $aUrl) . $sContent . '|"LINE_END"|';
         }
         JCH_DEBUG ? JchPlatformProfiler::stop('CombineFile - ' . $sUrl, TRUE) : null;
     }
     if ($this->bAsync) {
         $sContents = $this->getLoadScript() . $sContents;
         if ($this->sAsyncUrl != '') {
             $sContents .= $this->addCommentedUrl('js', $this->sAsyncUrl) . 'loadScript("' . $this->sAsyncUrl . '", function(){});  DELIMITER';
             $this->sAsyncUrl = '';
         }
     }
     return $sContents;
 }
Exemplo n.º 19
0
 /**
  * Insert url of aggregated file in html
  *
  * @param string $sNewLink   Url of aggregated file
  */
 protected function replaceLinks($sId, $sType)
 {
     JCH_DEBUG ? JchPlatformProfiler::start('ReplaceLinks - ' . $sType) : null;
     $sSearchArea = $this->oParser->getHeadHtml();
     $sSearchArea .= $this->oParser->getBodyHtml();
     $sLink = $this->{'getNew' . ucfirst($sType) . 'Link'}();
     $sUrl = $this->buildUrl($sId, $sType);
     $sNewLink = str_replace('URL', $sUrl, $sLink);
     if ($sType == 'js' && $this->params->get('bottom_js', '0') == '1') {
         $sNewLink = str_replace('JCHI', '0', $sNewLink);
         $sSearchArea = str_replace('</body>', $sNewLink, $sSearchArea);
         $this->oParser->sHtml = str_replace('</body>', $sNewLink, $this->oParser->sHtml);
     } elseif ($this->params->get('bottom_js', '0')) {
         $sNewLink = str_replace('JCHI', '0', $sNewLink);
         $sSearchArea = str_replace('</title>', $sNewLink, $sSearchArea);
     } else {
         $sSearchArea = preg_replace_callback('#<JCH_' . strtoupper($sType) . '([^>]++)>#', function ($aM) use($sNewLink) {
             return str_replace('JCHI', $aM[1], $sNewLink);
         }, $sSearchArea);
     }
     $this->oParser->setSearchArea(preg_replace($this->oParser->getBodyRegex(), '', $sSearchArea, 1), 'head');
     $this->oParser->setSearchArea(preg_replace($this->oParser->getHeadRegex(), '', $sSearchArea, 1), 'body');
     JCH_DEBUG ? JchPlatformProfiler::stop('ReplaceLinks - ' . $sType, TRUE) : null;
 }
Exemplo n.º 20
0
 /**
  * Uses regex to find css declarations containing background images to include in sprite
  * 
  * @param string $sCss  Aggregated css file
  * @return array        Array of css declarations and image urls to replace with sprite
  */
 public function processCssUrls($sCss, $bBackend = FALSE)
 {
     JCH_DEBUG ? JchPlatformProfiler::start('ProcessCssUrls') : null;
     $params = $this->params;
     $aRegexStart = array();
     $aRegexStart[0] = '
                     #(?:{
                             (?=\\s*+(?>[^}\\s:]++[\\s:]++)*?url\\(
                                     (?=[^)]+\\.(?:png|gif|jpe?g))
                             ([^)]+)\\))';
     $aRegexStart[1] = '
                     (?=\\s*+(?>[^}\\s:]++[\\s:]++)*?no-repeat)';
     $aRegexStart[2] = '
                     (?(?=\\s*(?>[^};]++[;\\s]++)*?background(?:-position)?\\s*+:\\s*+(?:[^;}\\s]++[^}\\S]++)*?
                             (?<p>(?:[tblrc](?:op|ottom|eft|ight|enter)|-?[0-9]+(?:%|[c-x]{2})?))(?:\\s+(?&p))?)
                                     (?=\\s*(?>[^};]++[;\\s]++)*?background(?:-position)?\\s*+:\\s*+(?>[^;}\\s]++[\\s]++)*?
                                             (?:left|top|0(?:%|[c-x]{2})?)\\s+(?:left|top|0(?:%|[c-x]{2})?)
                                     )
                     )';
     $sRegexMiddle = '   
                     [^{}]++} )';
     $sRegexEnd = '#isx';
     $aIncludeImages = JchOptimizeHelper::getArray($params->get('csg_include_images'));
     $aExcludeImages = JchOptimizeHelper::getArray($params->get('csg_exclude_images'));
     $sIncImagesRegex = '';
     if (!empty($aIncludeImages[0])) {
         foreach ($aIncludeImages as &$sImage) {
             $sImage = preg_quote($sImage, '#');
         }
         $sIncImagesRegex .= '
                             |(?:{
                                     (?=\\s*+(?>[^}\\s:]++[\\s:]++)*?url';
         $sIncImagesRegex .= ' (?=[^)]* [/(](?:' . implode('|', $aIncludeImages) . ')\\))';
         $sIncImagesRegex .= '\\(([^)]+)\\)
                                     )
                                     [^{}]++ })';
     }
     $sExImagesRegex = '';
     if (!empty($aExcludeImages[0])) {
         $sExImagesRegex .= '(?=\\s*+(?>[^}\\s:]++[\\s:]++)*?url\\(
                                                     [^)]++  (?<!';
         foreach ($aExcludeImages as &$sImage) {
             $sImage = preg_quote($sImage, '#');
         }
         $sExImagesRegex .= implode('|', $aExcludeImages) . ')\\)
                                                     )';
     }
     $sRegexStart = implode('', $aRegexStart);
     $sRegex = $sRegexStart . $sExImagesRegex . $sRegexMiddle . $sIncImagesRegex . $sRegexEnd;
     if (preg_match_all($sRegex, $sCss, $aMatches) === FALSE) {
         throw new Exception('Error occurred matching for images to sprite');
     }
     if (isset($aMatches[3])) {
         $total = count($aMatches[1]);
         for ($i = 0; $i < $total; $i++) {
             $aMatches[1][$i] = trim($aMatches[1][$i]) ? $aMatches[1][$i] : $aMatches[3][$i];
         }
     }
     if ($bBackend) {
         $aImages = array();
         $aImagesMatches = array();
         $aImgRegex = array();
         $aImgRegex[0] = $aRegexStart[0];
         $aImgRegex[2] = $aRegexStart[1];
         $aImgRegex[4] = $sRegexMiddle;
         $aImgRegex[5] = $sRegexEnd;
         $sImgRegex = implode('', $aImgRegex);
         if (preg_match_all($sImgRegex, $sCss, $aImagesMatches) === FALSE) {
             throw new Exception('Error occurred matching for images to include');
         }
         $aImagesMatches[0] = array_diff($aImagesMatches[0], $aMatches[0]);
         $aImagesMatches[1] = array_diff($aImagesMatches[1], $aMatches[1]);
         $oImageLibrary = $this->getImageLibrary();
         if ($oImageLibrary === FALSE) {
             return array();
         }
         $oCssSpriteGen = new CssSpriteGen($oImageLibrary, $this->params, $bBackend);
         $aImages['include'] = $oCssSpriteGen->CreateSprite($aImagesMatches[1]);
         $aImages['exclude'] = $oCssSpriteGen->CreateSprite($aMatches[1]);
         return $aImages;
     }
     JCH_DEBUG ? JchPlatformProfiler::stop('ProcessCssUrls', TRUE) : null;
     return $aMatches;
 }
Exemplo n.º 21
0
 /**
  * 
  * @staticvar string $sCssRuleRegex
  * @param type $sContent
  * @param type $sHtml
  */
 public function optimizeCssDelivery($sContents, $sHtml)
 {
     JCH_DEBUG ? JchPlatformProfiler::start('OptimizeCssDelivery') : null;
     $sHtmlTruncated = '';
     preg_replace_callback('#<(?:[a-z0-9]++)(?:[^>]*+)>(?><?[^<]*+)*?(?=<[a-z0-9])#i', function ($aM) use(&$sHtmlTruncated) {
         $sHtmlTruncated .= $aM[0];
         return;
     }, $sHtml, (int) $this->params->get('pro_optimizeCssDelivery', '200'));
     $sHtmlTruncated = preg_replace('#\\s*=\\s*["\']([^"\']++)["\']#i', '=" $1 "', $sHtmlTruncated);
     $sHtmlTruncated = preg_replace_callback('#(<(?>[^<>]++|(?1))*+>)|((?<=>)(?=[^<>\\S]*+[^<>\\s])[^<>]++)#', function ($m) {
         if (isset($m[1]) && $m[1] != '') {
             return $m[0];
         }
         if (isset($m[2]) && $m[2] != '') {
             return ' ';
         }
     }, $sHtmlTruncated);
     $obj = $this;
     $oDom = new DOMDocument();
     libxml_use_internal_errors(TRUE);
     $oDom->loadHtml($sHtmlTruncated);
     libxml_clear_errors();
     $oXPath = new DOMXPath($oDom);
     $sCriticalCss = '';
     $sContents = preg_replace_callback('#' . self::cssRulesRegex() . '#', function ($aMatches) use($obj, $oXPath, $sHtmlTruncated, &$sCriticalCss) {
         return $obj->extractCriticalCss($aMatches, $oXPath, $sHtmlTruncated, $sCriticalCss);
     }, $sContents);
     $sCriticalCss = preg_replace('#@[^{]*+{[^\\S}]*+}#', '', $sCriticalCss);
     $sCriticalCss = preg_replace('#@[^{]*+{[^\\S}]*+}#', '', $sCriticalCss);
     $sCriticalCss = preg_replace('#/\\*\\*\\*!+[^!]+!\\*\\*\\*+/[^\\S]*+(?=\\/\\*\\*\\*!|$)#', '', $sCriticalCss);
     $sCriticalCss = preg_replace('#\\s*[\\r\\n]{2,}\\s*#', "\n\n", $sCriticalCss);
     $aContents = array('font-face' => trim($sContents), 'criticalcss' => trim($sCriticalCss));
     JCH_DEBUG ? JchPlatformProfiler::stop('OptimizeCssDelivery', TRUE) : null;
     return $aContents;
 }
Exemplo n.º 22
0
 /**
  * 
  * @return type
  */
 public function lazyLoadImages()
 {
     if ($this->params->get('pro_lazyload', '0')) {
         JCH_DEBUG ? JchPlatformProfiler::start('LazyLoadImages') : null;
         $sLazyLoadBodyHtml = preg_replace($this->getLazyLoadRegex(), 'data-src="$1" src="' . JchOptimizeHelper::cookieLessDomain($this->params) . JchPlatformPaths::imageFolder() . 'placeholder.gif" data-jchll="true"', $this->getBodyHtml());
         if (is_null($sLazyLoadBodyHtml)) {
             JchOptimizeLogger::log(JchPlatformUtility::translate('Lazy load images function failed'), $this->params);
             return;
         }
         if (preg_match($this->getBodyRegex(), $sLazyLoadBodyHtml, $aBodyMatches) === FALSE || empty($aBodyMatches)) {
             JchOptimizeLogger::log(JchPlatformUtility::translate('Failed retrieving body in lazy load images function'), $this->params);
             return;
         }
         $this->sBodyHtml = $aBodyMatches[0];
         JCH_DEBUG ? JchPlatformProfiler::stop('LazyLoadImages', TRUE) : null;
     }
 }
Exemplo n.º 23
0
 /**
  * 
  * @param type $sRegex
  * @param type $sType
  * @param type $sSection
  * @param type $aCBArgs
  * @throws Exception
  */
 protected function searchArea($sRegex, $sSection, $aCBArgs)
 {
     JCH_DEBUG ? JchPlatformProfiler::mark('beforeSearchArea - ' . $sSection . ' plgSystem (JCH Optimize)') : null;
     $obj = $this;
     $sProcessedHtml = preg_replace_callback($sRegex, function ($aMatches) use($obj, $aCBArgs) {
         return $obj->replaceScripts($aMatches, $aCBArgs);
     }, $this->{'s' . ucfirst($sSection) . 'Html'});
     if (is_null($sProcessedHtml)) {
         throw new Exception(sprintf(JchPlatformUtility::translate('Error while parsing for links in %1$s'), $sSection));
     }
     $this->{'s' . ucfirst($sSection) . 'Html'} = $sProcessedHtml;
     JCH_DEBUG ? JchPlatformProfiler::mark('afterSearchArea - ' . $sSection . ' plgSystem (JCH Optimize)') : null;
 }
Exemplo n.º 24
0
 /**
  * Create and cache aggregated file if it doesn't exists, file will have
  * lifetime set in global configurations.
  *
  * @param array $aFunction    Name of function used to aggregate files
  * @param array $aArgs        Arguments used by function above
  * @param string $sId         Generated id to identify cached file
  * @return boolean           True on success
  */
 public function loadCache($aFunction, $aArgs, $sId)
 {
     JCH_DEBUG ? JchPlatformProfiler::mark('beforeLoadCache plgSystem (JCH Optimize)') : null;
     $iLifeTime = (int) $this->params->get('lifetime', '30') * 24 * 60 * 60;
     $bCached = JchPlatformCache::getCallbackCache($sId, $iLifeTime, $aFunction, $aArgs);
     JCH_DEBUG ? JchPlatformProfiler::mark('afterLoadCache plgSystem (JCH Optimize)') : null;
     return $bCached;
 }