This is a heavy regex-based removal of whitespace, unnecessary comments and tokens, and some CSS value minimization, where practical. Many steps have been taken to avoid breaking comment-based hacks, including the ie5/mac filter (and its inversion), but expect tricky hacks involving comment tokens in 'content' value strings to break minimization badly. A test suite is available. Note: This replaces a lot of spaces with line breaks. It's rumored (https://github.com/yui/yuicompressor/blob/master/README.md#global-options) that some source control tools and old browsers don't like very long lines. Compressed files with shorter lines are also easier to diff. If this is unacceptable please use CSSmin instead.
Deprecation: Use CSSmin (tubalmartin/cssmin)
Author: Stephen Clay (steve@mrclay.org)
Author: http://code.google.com/u/1stvamp/ (Issue 64 patch)
示例#1
0
文件: CSS.php 项目: sajawa/lib
 /**
  * Minify a CSS string
  * 
  * @param string $css
  * 
  * @param array $options (currently ignored)
  * 
  * @return string
  */
 public static function process($css, $options = array())
 {
     static $instance;
     if (!$instance) {
         $instance = new Minify_CSS_Compressor($options);
     }
     return $instance->_process($css);
 }
 protected function _process($css)
 {
     $css = parent::_process($css);
     $css = preg_replace('`\\s*`', '', $css);
     $css = preg_replace('`;}`', '}', $css);
     return $css;
 }
示例#3
0
文件: CSS.php 项目: rswiders/core
 /**
  * Minify a CSS string
  * 
  * @param string $css
  * 
  * @param array $options available options:
  * 
  * 'preserveComments': (default true) multi-line comments that begin
  * with "/*!" will be preserved with newlines before and after to
  * enhance readability.
  *
  * 'removeCharsets': (default true) remove all @charset at-rules
  * 
  * 'prependRelativePath': (default null) if given, this string will be
  * prepended to all relative URIs in import/url declarations
  * 
  * 'currentDir': (default null) if given, this is assumed to be the
  * directory of the current CSS file. Using this, minify will rewrite
  * all relative URIs in import/url declarations to correctly point to
  * the desired files. For this to work, the files *must* exist and be
  * visible by the PHP process.
  *
  * 'symlinks': (default = array()) If the CSS file is stored in 
  * a symlink-ed directory, provide an array of link paths to
  * target paths, where the link paths are within the document root. Because 
  * paths need to be normalized for this to work, use "//" to substitute 
  * the doc root in the link paths (the array keys). E.g.:
  * <code>
  * array('//symlink' => '/real/target/path') // unix
  * array('//static' => 'D:\\staticStorage')  // Windows
  * </code>
  *
  * 'docRoot': (default = $_SERVER['DOCUMENT_ROOT'])
  * see Minify_CSS_UriRewriter::rewrite
  * 
  * @return string
  */
 public static function minify($css, $options = array())
 {
     $options = array_merge(array('compress' => true, 'removeCharsets' => true, 'preserveComments' => true, 'currentDir' => null, 'docRoot' => $_SERVER['DOCUMENT_ROOT'], 'prependRelativePath' => null, 'symlinks' => array()), $options);
     if ($options['removeCharsets']) {
         $css = preg_replace('/@charset[^;]+;\\s*/', '', $css);
     }
     if ($options['compress']) {
         if (!$options['preserveComments']) {
             require_once 'Compressor.php';
             $css = Minify_CSS_Compressor::process($css, $options);
         } else {
             require_once 'CommentPreserver.php';
             require_once 'Compressor.php';
             $css = Minify_CommentPreserver::process($css, array('Minify_CSS_Compressor', 'process'), array($options));
         }
     }
     if (!$options['currentDir'] && !$options['prependRelativePath']) {
         return $css;
     }
     require_once 'UriRewriter.php';
     if ($options['currentDir']) {
         return Minify_CSS_UriRewriter::rewrite($css, $options['currentDir'], $options['docRoot'], $options['symlinks']);
     } else {
         return Minify_CSS_UriRewriter::prepend($css, $options['prependRelativePath']);
     }
 }
示例#4
0
 /**
  * Minify a CSS string
  * 
  * @param string $css
  * 
  * @param array $options available options:
  * 
  * 'preserveComments': (default true) multi-line comments that begin
  * with "/*!" will be preserved with newlines before and after to
  * enhance readability.
  * 
  * 'prependRelativePath': (default null) if given, this string will be
  * prepended to all relative URIs in import/url declarations
  * 
  * 'currentDir': (default null) if given, this is assumed to be the
  * directory of the current CSS file. Using this, minify will rewrite
  * all relative URIs in import/url declarations to correctly point to
  * the desired files. For this to work, the files *must* exist and be
  * visible by the PHP process.
  *
  * 'symlinks': (default = array()) If the CSS file is stored in 
  * a symlink-ed directory, provide an array of link paths to
  * target paths, where the link paths are within the document root. Because 
  * paths need to be normalized for this to work, use "//" to substitute 
  * the doc root in the link paths (the array keys). E.g.:
  * <code>
  * array('//symlink' => '/real/target/path') // unix
  * array('//static' => 'D:\\staticStorage')  // Windows
  * </code>
  * 
  * @return string
  */
 static public function minify($css, $options = array()) 
 {
     require_once 'Minify/CSS/Compressor.php';
     if (isset($options['preserveComments']) 
         && !$options['preserveComments']) {
         $css = Minify_CSS_Compressor::process($css, $options);
     } else {
         require_once 'Minify/CommentPreserver.php';
         $css = Minify_CommentPreserver::process(
             $css
             ,array('Minify_CSS_Compressor', 'process')
             ,array($options)
         );
     }
     if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
         return $css;
     }
     require_once 'Minify/CSS/UriRewriter.php';
     if (isset($options['currentDir'])) {
         return Minify_CSS_UriRewriter::rewrite(
             $css
             ,$options['currentDir']
             ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
             ,isset($options['symlinks']) ? $options['symlinks'] : array()
         );  
     } else {
         return Minify_CSS_UriRewriter::prepend(
             $css
             ,$options['prependRelativePath']
         );
     }
 }
示例#5
0
 protected function _commentCB($m)
 {
     if ($m[1][0] === '!') {
         return '/*' . $m[1] . '*/';
     }
     return parent::_commentCB($m);
 }
 public function doProcessFile($file, $replace = false)
 {
     $optimizedContent = Minify_CSS_Compressor::process(file_get_contents($file));
     if ($replace) {
         return parent::replaceFile($file, $optimizedContent);
     } else {
         return $optimizedContent;
     }
 }
示例#7
0
 private function buildApiCss()
 {
     // copy file
     $this->getFilesystem()->copy(sfConfig::get('sf_web_dir') . '/css/api_sources/button.css', sfConfig::get('sf_web_dir') . '/css/v1/button.css', array('override' => true));
     // replace wildcards
     $this->getFilesystem()->replaceTokens(sfConfig::get('sf_web_dir') . '/css/v1/button.css', '##', '##', array('YIID_WIDGET_HOST' => sfConfig::get('app_settings_widgets_host'), 'YIID_BUTTON_HOST' => sfConfig::get('app_settings_button_url')));
     $lCssMin = Minify_CSS_Compressor::process(file_get_contents(sfConfig::get('sf_web_dir') . '/css/v1/button.css'));
     $lCssMinFile = fopen(sfConfig::get('sf_web_dir') . '/css/v1/button.css', 'w+');
     $lDone = fwrite($lCssMinFile, $lCssMin);
     fclose($lCssMinFile);
 }
示例#8
0
 /**
  * Minify a CSS string
  * 
  * @param string $css
  * 
  * @param array $options available options:
  * 
  * 'preserveComments': (default true) multi-line comments that begin
  * with "/*!" will be preserved with newlines before and after to
  * enhance readability.
  *
  * 'removeCharsets': (default true) remove all @charset at-rules
  * 
  * 'prependRelativePath': (default null) if given, this string will be
  * prepended to all relative URIs in import/url declarations
  * 
  * 'currentDir': (default null) if given, this is assumed to be the
  * directory of the current CSS file. Using this, minify will rewrite
  * all relative URIs in import/url declarations to correctly point to
  * the desired files. For this to work, the files *must* exist and be
  * visible by the PHP process.
  *
  * 'symlinks': (default = array()) If the CSS file is stored in 
  * a symlink-ed directory, provide an array of link paths to
  * target paths, where the link paths are within the document root. Because 
  * paths need to be normalized for this to work, use "//" to substitute 
  * the doc root in the link paths (the array keys). E.g.:
  * <code>
  * array('//symlink' => '/real/target/path') // unix
  * array('//static' => 'D:\\staticStorage')  // Windows
  * </code>
  *
  * 'docRoot': (default = $_SERVER['DOCUMENT_ROOT'])
  * see Minify_CSS_UriRewriter::rewrite
  * 
  * @return string
  */
 public static function minify($css, $options = array())
 {
     $options = array_merge(array('removeCharsets' => true, 'preserveComments' => true), $options);
     if ($options['removeCharsets']) {
         $css = preg_replace('/@charset[^;]+;\\s*/', '', $css);
     }
     if (!$options['preserveComments']) {
         $css = Minify_CSS_Compressor::process($css, $options);
     } else {
         $css = Minify_CommentPreserver::process($css, array('Minify_CSS_Compressor', 'process'), array($options));
     }
     return $css;
 }
示例#9
0
文件: CSS.php 项目: nxtclass/NXTClass
 /**
  * Minify a CSS string
  *
  * @param string $css
  *
  * @param array $options available options:
  *
  * 'preserveComments': (default true) multi-line comments that begin
  * with "/*!" will be preserved with newlines before and after to
  * enhance readability.
  *
  * 'prependRelativePath': (default null) if given, this string will be
  * prepended to all relative URIs in import/url declarations
  *
  * 'currentDir': (default null) if given, this is assumed to be the
  * directory of the current CSS file. Using this, minify will rewrite
  * all relative URIs in import/url declarations to correctly point to
  * the desired files. For this to work, the files *must* exist and be
  * visible by the PHP process.
  *
  * 'symlinks': (default = array()) If the CSS file is stored in
  * a symlink-ed directory, provide an array of link paths to
  * target paths, where the link paths are within the document root. Because
  * paths need to be normalized for this to work, use "//" to substitute
  * the doc root in the link paths (the array keys). E.g.:
  * <code>
  * array('//symlink' => '/real/target/path') // unix
  * array('//static' => 'D:\\staticStorage')  // Windows
  * </code>
  *
  * @return string
  */
 public static function minify($css, $options = array())
 {
     require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS/Compressor.php';
     if (isset($options['preserveComments']) && $options['preserveComments']) {
         require_once W3TC_LIB_MINIFY_DIR . '/Minify/CommentPreserver.php';
         $css = Minify_CommentPreserver::process($css, array('Minify_CSS_Compressor', 'process'), array($options));
     } else {
         $css = Minify_CSS_Compressor::process($css, $options);
     }
     require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS/UriRewriter.php';
     $css = Minify_CSS_UriRewriter::rewrite($css, $options);
     return $css;
 }
示例#10
0
 public function min()
 {
     $this->_options = array_merge(array('remove_charsets' => true, 'preserve_comments' => true, 'current_dir' => null, 'doc_root' => $_SERVER['DOCUMENT_ROOT'], 'prepend_relative_path' => null, 'symlinks' => array()), $this->_options);
     if ($this->_options['remove_charsets']) {
         $this->_css = preg_replace('/@charset[^;]+;\\s*/', '', $this->_css);
     }
     if (!$this->_options['preserve_comments']) {
         $this->_css = Minify_CSS_Compressor::process($this->_css, $this->_options);
     } else {
         $this->_css = Minify_CSS_Comment_Preserver::process($this->_css, array('Minify_CSS_Compressor', 'process'), array($this->_options));
     }
     if (!$this->_options['current_dir'] && !$this->_options['prepend_relative_path']) {
         return $this->_css;
     }
     if ($this->_options['current_dir']) {
         return Minify_CSS_Uri_Rewriter::rewrite($this->_css, $this->_options['current_dir'], $this->_options['doc_root'], $this->_options['symlinks']);
     } else {
         return Minify_CSS_Uri_Rewriter::prepend($this->_css, $this->_options['prepend_relative_path']);
     }
 }
示例#11
0
 /**
  * Execute preprocessor
  *
  * This will take all CSS files from the source dir, minify each one and 
  * then combine them into one file.
  *
  * @param array $options Options for execution
  * @return void
  */
 public function execute($options = array())
 {
     $cssFiles = FileOps::rglob("*.css", 0, $this->getSourceDir());
     if (empty($cssFiles)) {
         return false;
     }
     FileOps::ensurePathExists($this->getDestinationDir());
     // Just get the basename of the main style sheet, this will be written
     // to the destination dir
     $mainStylesheet = basename($options['main_stylesheet']);
     $mainStylesheet = $this->getDestinationDir() . DIRECTORY_SEPARATOR . $mainStylesheet;
     $buffer = array();
     foreach ($cssFiles as $file) {
         $content = file_get_contents($file);
         $newContent = \Minify_CSS_Compressor::process($content);
         $buffer[] = $newContent;
     }
     if ($buffer) {
         file_put_contents($mainStylesheet, implode("\n", $buffer));
     }
 }
示例#12
0
 /**
  * doExecute
  *
  * @return  int
  */
 protected function doExecute()
 {
     $path = $this->getArgument(0);
     $package = $this->getOption('p');
     $folder = $this->console->get('asset.folder', 'asset');
     if ($package = PackageHelper::getPackage($package)) {
         $path = $package->getDir() . '/Resources/asset/' . $path;
     } else {
         $path = WINDWALKER_PUBLIC . '/' . trim($folder, '/') . '/' . $path;
     }
     if (is_file($path)) {
         $files = array(new \SplFileInfo($path));
     } elseif (is_dir($path)) {
         $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \FilesystemIterator::FOLLOW_SYMLINKS));
     } else {
         throw new \InvalidArgumentException('No path');
     }
     /** @var \SplFileInfo $file */
     foreach ($files as $file) {
         $ext = File::getExtension($file->getPathname());
         if (StringHelper::endsWith($file->getBasename(), '.min.' . $ext)) {
             continue;
         }
         if ($ext == 'css') {
             $this->out('[<comment>Compressing</comment>] ' . $file);
             $data = \Minify_CSS_Compressor::process(file_get_contents($file));
             $data = str_replace("\n", ' ', $data);
         } elseif ($ext == 'js') {
             $this->out('[<comment>Compressing</comment>] ' . $file);
             $data = \JSMinPlus::minify(file_get_contents($file));
             $data = str_replace("\n", ';', $data);
         } else {
             continue;
         }
         $newName = $file->getPath() . '/' . File::stripExtension($file->getBasename()) . '.min.' . $ext;
         file_put_contents($newName, $data);
         $this->out('[<info>Compressed</info>] ' . $newName);
     }
 }
 /**
  * @see sfCombineMinifierInterface
  */
 public static function minify($content, array $options = array())
 {
     return Minify_CSS_Compressor::process($content, $options);
 }
示例#14
0
 /**
  * Minify CSS
  *
  * @param  string $s CSS string to minify
  * @return string minified CSS string.
  */
 function _minifyCss($s)
 {
     require_once BX_DIRECTORY_PATH_PLUGINS . 'minify/lib/Minify/CSS/Compressor.php';
     return Minify_CSS_Compressor::process($s);
 }
 public function getStyles()
 {
     if (defined('HTTP_CATALOG')) {
         return $this->styles;
     }
     global $registry;
     $combinedStyles = array();
     $result = array();
     $oc_root = dirname(DIR_APPLICATION);
     $cache = NULL;
     $cachefile = NULL;
     $recache = false;
     $filename = NULL;
     $megaHashes = array();
     if (!defined('DS')) {
         define('DS', DIRECTORY_SEPARATOR);
     }
     //load NitroCache
     require_once $oc_root . DS . 'system' . DS . 'nitro' . DS . 'config.php';
     require_once $oc_root . DS . 'system' . DS . 'nitro' . DS . 'core' . DS . 'core.php';
     $nitroSettings = getNitroPersistence();
     if (empty($nitroSettings['Nitro']['Enabled']) || $nitroSettings['Nitro']['Enabled'] != 'yes' || empty($nitroSettings['Nitro']['Mini']['Enabled']) || empty($nitroSettings['Nitro']['Mini']['CSS']) || $nitroSettings['Nitro']['Mini']['Enabled'] != 'yes' || $nitroSettings['Nitro']['Mini']['CSS'] != 'yes' || function_exists('areWeInIgnoredUrl') && areWeInIgnoredUrl()) {
         return $this->styles;
     }
     if (!file_exists($oc_root . DS . 'assets')) {
         mkdir($oc_root . DS . 'assets');
     }
     if (!file_exists($oc_root . DS . 'assets' . DS . 'style')) {
         mkdir($oc_root . DS . 'assets' . DS . 'style');
     }
     $cssExclude = array();
     $excludedCSS = array();
     $includedCSS = 0;
     if (!empty($nitroSettings['Nitro']['Mini']['CSSExclude'])) {
         $cssExclude = explode("\n", $nitroSettings['Nitro']['Mini']['CSSExclude']);
         foreach ($cssExclude as $k => $stylename) {
             $cssExclude[$k] = trim($stylename, "\n\r ");
         }
     }
     //extract local fylesystem path
     foreach ($this->styles as $hash => $style) {
         $url_info = parse_url($style['href']);
         if (!empty($url_info['path'])) {
             $f = trim($url_info['path'], '/');
             if (file_exists($oc_root . DS . $f)) {
                 $this->styles[$hash]['href'] = $f;
             } else {
                 if (empty($nitroSettings['Nitro']['Mini']['CSSExclude'])) {
                     $nitroSettings['Nitro']['Mini']['CSSExclude'] = '';
                 }
                 $cssExclude[] = basename($style['href']);
             }
         } else {
             if (empty($nitroSettings['Nitro']['Mini']['CSSExclude'])) {
                 $nitroSettings['Nitro']['Mini']['CSSExclude'] = '';
             }
             $cssExclude[] = basename($style['href']);
         }
     }
     if (!empty($nitroSettings['Nitro']['Mini']['CSSCombine']) && $nitroSettings['Nitro']['Mini']['CSSCombine'] == 'yes') {
         $cachefile = $oc_root . DS . 'assets' . DS . 'style' . DS . getSSLCachePrefix() . 'styles-combined.cache';
         if (!file_exists($cachefile)) {
             touch($cachefile);
             file_put_contents($cachefile, json_encode(array()));
         }
         $cache = json_decode(file_get_contents($cachefile), true);
         //build combination hash
         foreach ($this->styles as $hash => $style) {
             if (!in_array(basename($style['href']), $cssExclude)) {
                 if (empty($megaHashes[$style['rel'] . $style['media']])) {
                     $megaHashes[$style['rel'] . $style['media']] = '';
                 }
                 $megaHashes[$style['rel'] . $style['media']] .= $hash;
                 $includedCSS++;
             } else {
                 $excludedCSS[$hash] = $style;
             }
         }
         foreach ($megaHashes as $k => $megaHash) {
             $megaHashes[$k] = md5($megaHash);
         }
         // Check the cache if we should recache
         foreach ($this->styles as $hash => $style) {
             if (empty($style)) {
                 continue;
             }
             if (!in_array(basename($style['href']), $cssExclude)) {
                 $filename = $oc_root . DS . trim(str_replace('/', DS, $style['href']), DS);
                 //convert relative url to absolute filesystem specific path (all of this, because of Windows)
                 $comboKey = $megaHashes[$style['rel'] . $style['media']];
                 if (empty($cache[$comboKey]) || !is_array($cache[$comboKey])) {
                     $cache[$comboKey] = array();
                 }
                 if (array_key_exists($filename, $cache[$comboKey])) {
                     if ($cache[$comboKey][$filename] != filemtime($filename)) {
                         $recache = true;
                         break;
                     }
                 } else {
                     $recache = true;
                     break;
                 }
             }
         }
         //end of check
         if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == '1')) {
             $webshopUrl = $registry->get('config')->get('config_ssl');
         } else {
             $webshopUrl = $registry->get('config')->get('config_url');
         }
         $webshopUrl = rtrim(preg_replace('~^https?\\:~i', '', $webshopUrl), '/');
         include_once $oc_root . DS . 'system' . DS . 'nitro' . DS . 'lib' . DS . 'minifier' . DS . 'CSSMin.php';
         foreach ($this->styles as $hash => $style) {
             if (empty($style)) {
                 continue;
             }
             if (!in_array(basename($style['href']), $cssExclude)) {
                 $target = '/assets/style/' . getSSLCachePrefix() . 'nitro-combined-' . $megaHashes[$style['rel'] . $style['media']] . '.css';
                 $targetAbsolutePath = $oc_root . DS . trim(str_replace('/', DS, $target), DS);
                 $filename = $oc_root . DS . trim(str_replace('/', DS, $style['href']), DS);
                 $comboHash = $megaHashes[$style['rel'] . $style['media']];
                 if (empty($combinedStyles[$style['rel'] . $style['media']])) {
                     $combinedStyles[$style['rel'] . $style['media']] = array('rel' => $style['rel'], 'media' => $style['media'], 'content' => '', 'megaHash' => $comboHash);
                 }
                 if ($recache || !file_exists($targetAbsolutePath)) {
                     if (empty($counters[$style['rel'] . $style['media']])) {
                         $counters[$style['rel'] . $style['media']] = 0;
                     }
                     $urlToCurrentDir = $webshopUrl . dirname('/' . trim($style['href'], '/'));
                     /* replace relative urls with absolute ones */
                     $tmpContent = preg_replace('/(url\\()(?![\'\\"]?https?\\:\\/\\/)([\'\\"]?)\\/?/', '$1$2' . $urlToCurrentDir . '/', file_get_contents($filename));
                     //minify
                     $tmpContent = Minify_CSS_Compressor::process($tmpContent);
                     $combinedStyles[$style['rel'] . $style['media']]['content'] .= $tmpContent;
                     unset($tmpContent);
                     $cache[$comboHash][$filename] = filemtime($filename);
                 }
             }
         }
         file_put_contents($cachefile, json_encode($cache));
         foreach ($combinedStyles as $key => $value) {
             $target = '/assets/style/' . getSSLCachePrefix() . 'nitro-combined-' . $megaHashes[$key] . '.css';
             $targetAbsolutePath = $oc_root . DS . trim(str_replace('/', DS, $target), DS);
             if ($recache || !file_exists($targetAbsolutePath)) {
                 file_put_contents($targetAbsolutePath, $value['content']);
             }
             $result[$megaHashes[$key]] = array('rel' => $value['rel'], 'media' => $value['media'], 'href' => trim($target, '/'));
         }
         if ($includedCSS > 0) {
             return array_merge($excludedCSS, $result);
         } else {
             return $excludedCSS;
         }
     } else {
         $cachefile = $oc_root . DS . 'assets' . DS . 'style' . DS . getSSLCachePrefix() . 'styles.cache';
         if (!file_exists($cachefile)) {
             touch($cachefile);
             file_put_contents($cachefile, json_encode(array()));
         }
         $cache = json_decode(file_get_contents($cachefile), true);
         if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == '1')) {
             $webshopUrl = $registry->get('config')->get('config_ssl');
         } else {
             $webshopUrl = $registry->get('config')->get('config_url');
         }
         $webshopUrl = rtrim(preg_replace('~^https?\\:~i', '', $webshopUrl), '/');
         include_once $oc_root . DS . 'system' . DS . 'nitro' . DS . 'lib' . DS . 'minifier' . DS . 'CSSMin.php';
         foreach ($this->styles as $hash => $style) {
             if (empty($style)) {
                 continue;
             }
             $recache = false;
             if (!in_array(trim(basename($style['href']), "\r\n"), $cssExclude)) {
                 $filename = $oc_root . DS . trim(str_replace('/', DS, $style['href']), DS);
                 $basefilename = basename($style['href'], '.css');
                 $target = '/assets/style/' . getSSLCachePrefix() . 'nitro-mini-' . $basefilename . '.css';
                 $targetAbsolutePath = $oc_root . DS . trim(str_replace('/', DS, $target), DS);
                 if (array_key_exists($filename, $cache)) {
                     if ($cache[$filename] != filemtime($filename)) {
                         $recache = true;
                     }
                 } else {
                     $recache = true;
                 }
                 if ($recache || !file_exists($targetAbsolutePath)) {
                     $urlToCurrentDir = $webshopUrl . dirname('/' . trim($style['href'], '/'));
                     /* replace relative urls with absolute ones */
                     $tmpContent = preg_replace('/(url\\()(?![\'\\"]?https?\\:\\/\\/)([\'\\"]?)\\/?/', '$1$2' . $urlToCurrentDir . '/', file_get_contents($filename));
                     //minify
                     $tmpContent = Minify_CSS_Compressor::process($tmpContent);
                     file_put_contents($targetAbsolutePath, $tmpContent);
                     unset($tmpContent);
                     $cache[$filename] = filemtime($filename);
                 }
                 $this->styles[$hash]['href'] = trim($target, '/');
             }
         }
         file_put_contents($cachefile, json_encode($cache));
         return $this->styles;
     }
 }
示例#16
0
 /**
  * Process asset content
  *
  * @param   string  $content
  * @return  string
  */
 public static function process($content)
 {
     // Include the processor
     include_once Kohana::find_file('vendor', 'minify_css_compressor/Compressor');
     return Minify_CSS_Compressor::process($content);
 }
 /**
  * Minify the given $content according to the file type indicated in $filename
  *
  * @param string $filename
  * @param string $content
  * @return string
  */
 protected function minifyFile($filename, $content)
 {
     // if we have a javascript file and jsmin is enabled, minify the content
     $isJS = stripos($filename, '.js');
     require_once 'thirdparty/jsmin/jsmin.php';
     require_once BASE_PATH . '/minify/code/thirdparty/Compressor.php';
     require_once BASE_PATH . '/minify/code/thirdparty/UriRewriter.php';
     increase_time_limit_to();
     if ($isJS) {
         $content = JSMin::minify($content) . ";\n";
     } else {
         $content = Minify_CSS_UriRewriter::rewrite($content, Director::baseFolder() . "/" . dirname($filename), Director::baseFolder());
         $content = Minify_CSS_Compressor::process($content) . "\n";
     }
     return $content;
 }
 public function filterDump(AssetInterface $asset)
 {
     $asset->setContent(\Minify_CSS_Compressor::process($asset->getContent()));
 }
 private function process($content, $type, $compress, $file = null)
 {
     switch ($type) {
         case 'css':
             if (!empty($file)) {
                 $content = preg_replace('#url\\((?!\\s*[\'"]?(data\\:image|/|http([s]*)\\:\\/\\/))\\s*([\'"])?#i', "url(\$3{$this->getPath($file)}", $content);
             }
             $content = trim($compress ? Minify_CSS_Compressor::process($content) : $content);
             break;
         case 'js':
             $content = trim($compress ? JSMin::minify($content) : $content, ';') . ';';
             break;
     }
     return $content;
 }
示例#20
0
 /**
  * Minify a CSS string
  *
  * @param string $css
  *
  * @param array $options (currently ignored)
  *
  * @return string
  */
 public static function process($css, $options = array())
 {
     $obj = new Minify_CSS_Compressor($options);
     return $obj->_process($css);
 }
示例#21
0
 /**
  * merges and minifies the styles
  * @param  array $styles 
  * @param  string $theme  
  * @return string         HTML
  */
 public static function styles($styles, $theme = NULL)
 {
     if ($theme === NULL) {
         $theme = self::$theme;
     }
     $ret = '';
     if (Kohana::$environment == Kohana::DEVELOPMENT or Core::config('config.minify') == FALSE) {
         foreach ($styles as $file => $type) {
             $file = self::public_path($file, $theme);
             $ret .= HTML::style($file, array('media' => $type));
         }
     } else {
         $files = array();
         foreach ($styles as $file => $type) {
             //not external file we need the public link
             if (!Valid::url($file)) {
                 $files[] = $file;
             } else {
                 $ret .= HTML::style($file, array('media' => $type));
             }
         }
         //name for the minify js file
         $css_minified_name = URL::title('minified-' . str_replace('css', '', implode('-', $files))) . '.css';
         //check if file exists.
         $file_name = self::theme_folder($theme) . '/css/' . $css_minified_name;
         //only generate if file doesnt exists or older than 1 week
         if (!file_exists($file_name) or time() > strtotime('+1 week', filemtime($file_name))) {
             $min = '';
             require_once Kohana::find_file('vendor', 'minify/css', 'php');
             //getting the content from files
             foreach ($files as $file) {
                 if (($version = strpos($file, '?')) > 0) {
                     $file = substr($file, 0, $version);
                 }
                 if (file_exists(self::theme_folder($theme) . '/' . $file)) {
                     $min .= file_get_contents(self::theme_folder($theme) . '/' . $file);
                 }
             }
             File::write($file_name, Minify_CSS_Compressor::process($min));
         }
         $ret .= HTML::style(self::public_path('css/' . $css_minified_name, $theme), array('media' => 'screen'));
     }
     return $ret;
 }
示例#22
0
	public static function optimizecss($tpl)
	{
		$outputpath = JPATH_ROOT . '/' . $tpl->getParam('t3-assets', 't3-assets') . '/css';
		$outputurl = JURI::root(true) . '/' . $tpl->getParam('t3-assets', 't3-assets') . '/css';
		
		if (!JFile::exists($outputpath)){
			JFolder::create($outputpath);
			@chmod($outputpath, 0755);
		}

		if (!is_writeable($outputpath)) {
			return false;
		}

		$doc = JFactory::getDocument();

		//======================= Group css ================= //
		$cssgroups = array();
		$stylesheets = array();
		$ielimit = 4095;
		$selcounts = 0;
		$regex = '/\{.+?\}|,/s'; //selector counter
		$csspath = '';

		foreach ($doc->_styleSheets as $url => $stylesheet) {

			$url = self::fixUrl($url);

			if ($stylesheet['mime'] == 'text/css' && ($csspath = self::cssPath($url))) {
				$stylesheet['path'] = $csspath;
				$stylesheet['data'] = JFile::read($csspath);

				$selcount = preg_match_all($regex, $stylesheet['data'], $matched);
				if(!$selcount) {
					$selcount = 1; //just for sure
				}

				//if we found an @import rule or reach IE limit css selector count, break into the new group
				if (preg_match('#@import\s+.+#', $stylesheet['data']) || $selcounts + $selcount >= $ielimit) {
					if(count($stylesheets)){
						$cssgroup = array();
						$groupname = array();
						foreach ( $stylesheets as $gurl => $gsheet ) {
							$cssgroup[$gurl] = $gsheet;
							$groupname[] = $gurl;
						}

						$cssgroup['groupname'] = implode('', $groupname);
						$cssgroups[] = $cssgroup;
					}

					$stylesheets = array($url => $stylesheet); // empty - begin a new group
					$selcounts = $selcount;
				} else {

					$stylesheets[$url] = $stylesheet;
					$selcounts += $selcount;
				}

			} else {
				// first get all the stylsheets up to this point, and get them into
				// the items array
				if(count($stylesheets)){
					$cssgroup = array();
					$groupname = array();
					foreach ( $stylesheets as $gurl => $gsheet ) {
						$cssgroup[$gurl] = $gsheet;
						$groupname[] = $gurl;
					}

					$cssgroup['groupname'] = implode('', $groupname);
					$cssgroups[] = $cssgroup;
				}

				//mark ignore current stylesheet
				$cssgroup = array($url => $stylesheet, 'ignore' => true);
				$cssgroups[] = $cssgroup;

				$stylesheets = array(); // empty - begin a new group
			}
		}
		
		if(count($stylesheets)){
			$cssgroup = array();
			$groupname = array();
			foreach ( $stylesheets as $gurl => $gsheet ) {
				$cssgroup[$gurl] = $gsheet;
				$groupname[] = $gurl;
			}

			$cssgroup['groupname'] = implode('', $groupname);
			$cssgroups[] = $cssgroup;
		}
		
		//======================= Group css ================= //

		$output = array();
		foreach ($cssgroups as $cssgroup) {
			if(isset($cssgroup['ignore'])){
				
				unset($cssgroup['ignore']);
				foreach ($cssgroup as $furl => $fsheet) {
					$output[$furl] = $fsheet;
				}

			} else {

				$groupname = 'css-' . substr(md5($cssgroup['groupname']), 0, 5) . '.css';
				$groupfile = $outputpath . '/' . $groupname;
				$grouptime = JFile::exists($groupfile) ? @filemtime($groupfile) : -1;
				$rebuild = $grouptime < 0; //filemtime == -1 => rebuild

				unset($cssgroup['groupname']);
				foreach ($cssgroup as $furl => $fsheet) {
					if(!$rebuild && @filemtime($fsheet['path']) > $grouptime){
						$rebuild = true;
					}
				}

				if($rebuild){

					$cssdata = array();
					foreach ($cssgroup as $furl => $fsheet) {
						$cssdata[] = "\n\n/*===============================";
						$cssdata[] = $furl;
						$cssdata[] = "================================================================================*/";
						
						$cssmin = Minify_CSS_Compressor::process($fsheet['data']);
						$cssmin = T3Path::updateUrl($cssmin, T3Path::relativePath($outputurl, dirname($furl)));

						$cssdata[] = $cssmin;
					}

					$cssdata = implode("\n", $cssdata);
					JFile::write($groupfile, $cssdata);
					@chmod($groupfile, 0644);
				}

				$output[$outputurl . '/' . $groupname] = array(
					'mime' => 'text/css',
					'media' => null,
					'attribs' => array()
					);
			}
		}

		//apply the change make change
		$doc->_styleSheets = $output;
	}
示例#23
0
 /**
  * HideMyWP::global_css_filter()
  * Generate new style from main file 
  * @return
  */
 function global_css_filter()
 {
     global $wp_query;
     $new_style_path = trim($this->opt('new_style_name'), ' /');
     //$this->h->ends_with($_SERVER["REQUEST_URI"], 'main.css') ||   <- For multisite
     if (isset($wp_query->query_vars['style_wrapper']) && $wp_query->query_vars['style_wrapper'] && $this->is_permalink()) {
         if (is_multisite() && isset($wp_query->query_vars['template_wrapper'])) {
             $css_file = str_replace(get_stylesheet(), $wp_query->query_vars['template_wrapper'], get_stylesheet_directory()) . '/style.css';
         } else {
             $css_file = get_stylesheet_directory() . '/style.css';
         }
         status_header(200);
         //$expires = 60*60*24; // 1 day
         $expires = 60 * 60 * 24 * 3;
         //3 day
         header("Pragma: public");
         header("Cache-Control: maxage=" . $expires);
         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT');
         header('Content-type: text/css; charset=UTF-8');
         $css = file_get_contents($css_file);
         if ($this->opt('minify_new_style')) {
             if ($this->opt('minify_new_style') == 'quick') {
                 $to_remove = array('%\\n\\r%', '!/\\*.*?\\*/!s', '/\\n\\s*\\n/', "%(\\s){1,}%");
                 $css = preg_replace($to_remove, ' ', $css);
             } elseif ($this->opt('minify_new_style') == 'safe') {
                 require_once 'lib/class.CSS-minify.php';
                 $css = Minify_CSS_Compressor::process($css, array());
             }
         }
         if ($this->opt('clean_new_style')) {
             if (strpos($css, 'alignright') === false) {
                 //Disable it if it uses import or so on
                 if (is_multisite()) {
                     $opts = get_blog_option(BLOG_ID_CURRENT_SITE, self::slug);
                     $opts['clean_new_style'] = '';
                     update_blog_option(BLOG_ID_CURRENT_SITE, self::slug, $opts);
                 } else {
                     $opts = get_option(self::slug);
                     $opts['clean_new_style'] = '';
                     update_option(self::slug, $opts);
                 }
             } else {
                 $old = array('wp-caption', 'alignright', 'alignleft', 'alignnone', 'aligncenter');
                 $new = array('x-caption', 'x-right', 'x-left', 'x-none', 'x-center');
                 $css = str_replace($old, $new, $css);
             }
             //We replace HTML, too
         }
         // if (is_child_theme())
         //     $css = str_replace('/thematic/', '/parent/', $css);
         echo $css;
         //  if(extension_loaded('zlib'))
         //     ob_end_flush();
         exit;
     }
 }
示例#24
0
 public function getcontent()
 {
     // restore IE hacks
     $this->content = $this->restore_iehacks($this->content);
     // restore comments
     $this->content = $this->restore_comments($this->content);
     // restore noscript
     if (strpos($this->content, '%%NOSCRIPT%%') !== false) {
         $this->content = preg_replace_callback('#%%NOSCRIPT%%(.*?)%%NOSCRIPT%%#is', create_function('$matches', 'return stripslashes(base64_decode($matches[1]));'), $this->content);
     }
     // restore noptimize
     $this->content = $this->restore_noptimize($this->content);
     //Restore the full content
     if (!empty($this->restofcontent)) {
         $this->content .= $this->restofcontent;
         $this->restofcontent = '';
     }
     // Inject the new stylesheets
     $replaceTag = array("<title", "before");
     $replaceTag = apply_filters('autoptimize_filter_css_replacetag', $replaceTag);
     if ($this->inline == true) {
         foreach ($this->csscode as $media => $code) {
             $this->inject_in_html('<style type="text/css" media="' . $media . '">' . $code . '</style>', $replaceTag);
         }
     } else {
         if ($this->defer == true) {
             $deferredCssBlock = "<script>function lCss(url,media) {var d=document;var l=d.createElement('link');l.rel='stylesheet';l.type='text/css';l.href=url;l.media=media; d.getElementsByTagName('head')[0].appendChild(l);}function deferredCSS() {";
             $noScriptCssBlock = "<noscript>";
             $defer_inline_code = $this->defer_inline;
             $defer_inline_code = apply_filters('autoptimize_filter_css_defer_inline', $defer_inline_code);
             if (!empty($defer_inline_code)) {
                 $iCssHash = md5($defer_inline_code);
                 $iCssCache = new autoptimizeCache($iCssHash, 'css');
                 if ($iCssCache->check()) {
                     // we have the optimized inline CSS in cache
                     $defer_inline_code = $iCssCache->retrieve();
                 } else {
                     if (class_exists('Minify_CSS_Compressor')) {
                         $tmp_code = trim(Minify_CSS_Compressor::process($this->defer_inline));
                     } else {
                         if (class_exists('CSSmin')) {
                             $cssmin = new CSSmin();
                             $tmp_code = trim($cssmin->run($defer_inline_code));
                         }
                     }
                     if (!empty($tmp_code)) {
                         $defer_inline_code = $tmp_code;
                         $iCssCache->cache($defer_inline_code, "text/css");
                         unset($tmp_code);
                     }
                 }
                 $code_out = '<style type="text/css" media="all">' . $defer_inline_code . '</style>';
                 $this->inject_in_html($code_out, $replaceTag);
             }
         }
         foreach ($this->url as $media => $url) {
             $url = $this->url_replace_cdn($url);
             //Add the stylesheet either deferred (import at bottom) or normal links in head
             if ($this->defer == true) {
                 $deferredCssBlock .= "lCss('" . $url . "','" . $media . "');";
                 $noScriptCssBlock .= '<link type="text/css" media="' . $media . '" href="' . $url . '" rel="stylesheet" />';
             } else {
                 $this->inject_in_html('<link type="text/css" media="' . $media . '" href="' . $url . '" rel="stylesheet" />', $replaceTag);
             }
         }
         if ($this->defer == true) {
             $deferredCssBlock .= "}if(window.addEventListener){window.addEventListener('DOMContentLoaded',deferredCSS,false);}else{window.onload = deferredCSS;}</script>";
             $noScriptCssBlock .= "</noscript>";
             $this->inject_in_html($noScriptCssBlock, array('<title>', 'before'));
             $this->inject_in_html($deferredCssBlock, array('</body>', 'before'));
         }
     }
     //Return the modified stylesheet
     return $this->content;
 }
 protected function _Consolidate($Files, $Suffix, $Prefix = '')
 {
     $Token = $Prefix . md5(serialize($Files)) . $Suffix;
     $CacheFile = PATH_CACHE . "/Consolidate/{$Token}";
     if (in_array($Token, $this->ChunkedFiles)) {
         return $Token;
     }
     if (!file_exists($CacheFile)) {
         $ConsolidateFile = '';
         $PathRootParts = split(DS, PATH_ROOT);
         $WebRootParts = split(DS, $this->WebRoot);
         $Base = join(DS, array_slice($PathRootParts, 0, -count($WebRootParts)));
         foreach ($Files as $File) {
             $ConsolidateFile .= "/*\n";
             $ConsolidateFile .= "* Consolidate '{$File['fullhref']}'\n";
             $ConsolidateFile .= "*/\n\n";
             $OriginalFile = PATH_ROOT . DS . $File['href'];
             $FileStr = file_get_contents($OriginalFile);
             if ($FileStr && strtolower($Suffix) == '.css') {
                 $FileStr = Minify_CSS_UriRewriter::rewrite($FileStr, dirname($Base . DS . $this->WebRoot . DS . $File['href']), $Base);
                 $FileStr = Minify_CSS_Compressor::process($FileStr);
             }
             $ConsolidateFile .= trim($FileStr);
             if ($FileStr && strtolower($Suffix) == '.js') {
                 if (substr($ConsolidateFile, -1) != ';') {
                     $ConsolidateFile .= ";";
                 }
             }
             $ConsolidateFile .= "\n\n";
         }
         if (!file_exists(dirname($CacheFile))) {
             mkdir(dirname($CacheFile), 0777, TRUE);
         }
         file_put_contents($CacheFile, $ConsolidateFile);
     }
     if (!in_array($Token, $this->ChunkedFiles)) {
         $this->ChunkedFiles[] = $Token;
     }
     return $Token;
 }
示例#26
0
 /**
  * Minify text
  *
  * @access	public
  * @param	string		Text to minify
  * @param	string		Type to minify (css/html). Default is css
  * @return	string		Minified text
  */
 public function minify($text, $type = 'css')
 {
     $type = strtolower($type);
     /* What to do? */
     if ($type == 'css') {
         require_once IPS_PUBLIC_PATH . 'min/lib/Minify/CSS/Compressor.php';
         /*noLibHook*/
         $text = Minify_CSS_Compressor::process($text);
     } else {
         if ($type == 'html') {
             require_once IPS_PUBLIC_PATH . 'min/lib/Minify/HTML.php';
             /*noLibHook*/
             $text = Minify_HTML::minify($text, array('xhtml' => 1));
         }
     }
     return $text;
 }
示例#27
0
function sp_combine_plugin_css_files()
{
    global $sp_plugin_styles, $spDevice;
    if (!is_a($sp_plugin_styles, 'WP_Styles')) {
        $sp_plugin_styles = new WP_Styles();
    }
    # save copy of styles in case of failure writing
    $saved_styles = clone $sp_plugin_styles;
    # check for standard theme or mobile
    if ($spDevice == 'mobile') {
        $option = 'sp_css_concat_mobile';
    } else {
        if ($spDevice == 'tablet') {
            $option = 'sp_css_concat_tablet';
        } else {
            $option = 'sp_css_concat';
        }
    }
    $css_concat = sp_get_option($option);
    if (!is_array($css_concat)) {
        $css_concat = array();
    }
    $css_files_modify = array();
    $css_files = array();
    if (is_array($sp_plugin_styles->queue)) {
        # is there anything in the queue?
        $sp_plugin_styles->all_deps($sp_plugin_styles->queue);
        # preparing the queue taking dependencies into account
        foreach ($css_concat as $css => $value) {
            # going through all the already found css files, checking that they are still required
            if (!in_array(substr($css, 4), $sp_plugin_styles->to_do) && substr($css, 0, 4) == 'css-') {
                # if the css is not queued, rewrite the file
                $css_media = $value['type'];
                $css_files_modify[$css_media] = true;
                unset($css_concat[$css]);
            }
        }
        foreach ($sp_plugin_styles->to_do as $css) {
            $css_src = $sp_plugin_styles->registered[$css]->src;
            $css_media = $sp_plugin_styles->registered[$css]->args;
            # is the css is hosted localy AND is a css file?
            if ((!(strpos($css_src, get_bloginfo('url')) === false) || substr($css_src, 0, 1) === '/' || substr($css_src, 0, 1) === '.') && (substr($css_src, strrpos($css_src, '.'), 4) == '.css' || substr($css_src, strrpos($css_src, '.'), 4) == '.php')) {
                if (!is_array($css_files) || !array_key_exists($css_media, $css_files)) {
                    $css_files[$css_media] = array();
                }
                if (strpos($css_src, get_bloginfo('url')) === false) {
                    $css_relative_url = substr($css_src, 1);
                } else {
                    $css_relative_url = substr($css_src, strlen(get_bloginfo('url')) + 1);
                }
                if (strpos($css_relative_url, '?')) {
                    $css_relative_url = substr($css_relative_url, 0, strpos($css_relative_url, '?'));
                }
                # removing parameters
                $css_m_time = null;
                @($css_m_time = filemtime($css_relative_url));
                # getting the mofified time of the css file. extracting the file's dir
                if ($css_m_time) {
                    # only add the file if it's accessible
                    # check for php theme file indicating main theme file and save whole url vs just relative
                    if (substr($css_src, strrpos($css_src, '.'), 4) == '.php') {
                        array_push($css_files[$css_media], $css_src);
                    } else {
                        array_push($css_files[$css_media], $css_relative_url);
                    }
                    if (!file_exists(SP_COMBINED_CACHE_DIR . SP_COMBINED_CSS_BASE_NAME . $css_media . '.css') || isset($css_concat['css-' . $css]) && ($css_m_time != $css_concat['css-' . $css]['modified'] || $css_concat['css-' . $css]['type'] != $css_media) || !isset($css_concat['css-' . $css])) {
                        # css file is first identified
                        $css_files_modify[$css_media] = true;
                        # the combined file containing this media type css should be changed
                        if (isset($css_concat['css-' . $css]) && $css_concat['css-' . $css]['type'] != $css_media) {
                            # if the media type changed - rewrite both css files
                            $tmp = $css_concat['css-' . $css]['type'];
                            $css_files_modify[$tmp] = true;
                        }
                        if (!is_array($css_concat['css-' . $css])) {
                            $css_concat['css-' . $css] = array();
                        }
                        $css_concat['css-' . $css]['modified'] = $css_m_time;
                        # write the new modified date
                        $css_concat['css-' . $css]['type'] = $css_media;
                    }
                    $sp_plugin_styles->remove($css);
                    # removes the css file from the queue
                }
            }
        }
    }
    foreach ($css_files_modify as $key => $value) {
        $combined_file = fopen(SP_COMBINED_CACHE_DIR . SP_COMBINED_CSS_BASE_NAME . $key . '.css', 'w');
        if ($combined_file) {
            $css_content = '';
            if (is_array($css_files[$key])) {
                foreach ($css_files[$key] as $css_src) {
                    $css_content .= "\n" . sp_get_css_content($css_src) . "\n";
                }
            }
            if (!isset($css_concat['ver'][$key])) {
                $css_concat['ver'][$key] = 0;
            }
            $css_concat['ver'][$key]++;
            # compress the css before writing it out
            require 'sp-api-class-css-compressor.php';
            $css_content = Minify_CSS_Compressor::process($css_content);
            fwrite($combined_file, $css_content);
            fclose($combined_file);
        } else {
            # couldnt open file for writing so revert back to enqueueing all the styles
            if (!empty($saved_styles)) {
                foreach ($saved_styles->queue as $handle) {
                    wp_enqueue_style($handle, $saved_styles->registered[$handle]->src);
                }
            }
            return;
            # enqueued through wp now so bail
        }
    }
    foreach ($css_files as $key => $value) {
        # enqueue the combined css files
        wp_enqueue_style(SP_COMBINED_CSS_BASE_NAME . $key, SP_COMBINED_CACHE_URL . SP_COMBINED_CSS_BASE_NAME . $key . '.css', array(), $css_concat['ver'][$key]);
    }
    sp_update_option($option, $css_concat);
}
示例#28
0
文件: Minify.php 项目: jkphl/squeezr
 /**
  * Minify a CSS text
  *
  * @param string $css			CSS text
  * @param array $options		Optional options
  * @return string				Minified CSS text
  */
 public function minify($css, array $options = array())
 {
     return \Minify_CSS_Compressor::process($css, $options);
 }
示例#29
0
 public static function OutputCombined($tag, $modstamp = 0)
 {
     if (substr($tag, 0, 3) == 'css') {
         self::ProcessCSS();
     } else {
         self::ProcessJS();
     }
     if (self::$memcached) {
         $ret = self::$memcached->get($tag . '-' . $modstamp);
         if ($ret) {
             echo $ret;
             return;
         }
         ob_start();
     }
     if (isset(self::$combined[$tag])) {
         foreach (self::$combined[$tag] as $_f) {
             if ($_f->flags & self::NO_MINIFY || (self::$features & self::FEAT_MINIFY) == 0) {
                 readfile(WEB_ROOT . DIRECTORY_SEPARATOR . $_f->link);
             } else {
                 if ($_f->type == self::TYPE_JS) {
                     try {
                         echo JSMin::minify(file_get_contents(WEB_ROOT . DIRECTORY_SEPARATOR . $_f->link));
                     } catch (Exception $ex) {
                         error_log((string) $ex);
                     }
                 } elseif ($_f->type == self::TYPE_CSS) {
                     try {
                         echo Minify_CSS_Compressor::process(file_get_contents(WEB_ROOT . DIRECTORY_SEPARATOR . $_f->link));
                     } catch (Exception $ex) {
                         error_log((string) $ex);
                     }
                 }
             }
         }
     }
     if (self::$memcached) {
         self::$memcached->set($tag . '-' . $modstamp, ob_get_contents());
         ob_end_flush();
     }
 }
 /**
  * @param $contents
  * @return string
  */
 private function minifyCSS($contents)
 {
     if (!$contents) {
         return "";
     }
     return Minify_CSS_Compressor::process($contents);
 }