/** * Minifies stylesheet definitions * * @param string $v Stylesheet definitions as string * @return string Minified stylesheet definitions */ public static function minify($css) { /* Protect all datas inside blocks like : * /*<<* / * ... * /*!>>* / * Used to protect copyrights texts */ $matches = array(); preg_match_all("#\\/\\*<{2}\\*\\/(.*)\\/\\*\\!>{2}\\*\\/#Us", $css, $matches); if (isset($matches[1]) && $matches[1]) { $return = ''; $css = explode('/*<<*/', $css); if (trim($css[0]) != '') { $return .= cssmin::min($css[0]); } unset($css[0]); $css = array_values($css); foreach ($matches[1] as $key => $match) { $code = explode('/*!>>*/', $css[$key]); $return .= $match . "\n" . cssmin::min($code[1]); } return $return; } else { return cssmin::min($css); } }
public function doProcessFile($file, $replace = false) { $optimizedContent = cssmin::minify(file_get_contents($file)); if ($replace) { return parent::replaceFile($file, $optimizedContent); } else { return $optimizedContent; } }
public function __construct($file) { global $dataDir; includeFile('thirdparty/cssmin_v.1.0.php'); $this->file = $file; $this->full_path = $dataDir . $file; $this->content = file_get_contents($this->full_path); $this->content = \cssmin::minify($this->content); $this->CSS_Import(); $this->CSS_FixUrls(); }
function addcssfile($file, $minify = true, $imgPath = '/img/') { $output = file_get_contents($file); $image = dirname($file) . $imgPath; $image = str_replace('css/', '', $image); $output = str_replace('img/', $image, $output); $output = str_replace(PATH_UNIX, '', $output); if ($minify == true && MINIFY == true) { $output = cssmin::minify($output); } return $output; }
/** * Apply minification if possible * * @param string $source * @return string */ function optionMinify($source, $context = null, $filename = null) { if ($this->Sprocket->fileExt == 'css') { if (!class_exists('cssmin')) { require_once realpath(dirname(__FILE__) . '/../third-party/' . MINIFY_CSS); } $source = cssmin::minify($source, "preserve-urls"); } if ($this->Sprocket->fileExt == 'js') { if (!class_exists('JSMin')) { require_once realpath(dirname(__FILE__) . '/../third-party/' . MINIFY_JS); } $source = JSMin::minify($source); } return $source; }
/** * Creates a CSS loader component. */ public function createComponentCss() { // prepare files list // FileCollection constructor accepts default resources directory $files = new \WebLoader\FileCollection(WWW_DIR . '/css'); $files->addFiles(array('screen.css', 'bootstrap-3.0.0/less/bootstrap.less', 'bootstrap-3.0.0/less/variables.less', 'jqplot/dist/jquery.jqplot.min.css', 'jqplot.css')); // pass the files collection to the compiler and set output path $compiler = \WebLoader\Compiler::createCssCompiler($files, WWW_DIR . '/webtemp'); // add LESS filter to the compiler $compiler->addFileFilter(new \Webloader\Filter\LessFilter()); // add CSSMin filter to the compiler $compiler->addFilter(function ($code) { return \cssmin::minify($code); }); // nette komponenta pro výpis <link>ů přijímá kompilátor a cestu k adresáři na webu return new \WebLoader\Nette\CssLoader($compiler, $this->template->basePath . '/webtemp'); }
/** * Resetstyle * Implements a reset stylesheet * * Usage: Simply include the plugin in @cssp * Status: Stable * Version: 1.0 * * Version history: * 1.0 Initial Stable Version * 1.1 Added support for custom stylesheets * * @param mixed &$output * @return void */ function resetstyle(&$output) { // Get the reset stylesheet. Use the custom file if it exists if (file_exists('plugins/resetstyle/custom.css')) { $reset_stylesheet = file_get_contents('plugins/resetstyle/custom.css'); } elseif (file_exists('plugins/resetstyle/default.css')) { $reset_stylesheet = file_get_contents('plugins/resetstyle/default.css'); } if (!empty($reset_stylesheet)) { // Compress the styles $reset_stylesheet = cssmin::minify($reset_stylesheet); // Add the reset stylesheet to the output. Done! $output = $reset_stylesheet . $output; } else { global $cssp; $cssp->report_error('Resetstyle plugin couldn\'t find a stylesheet to include'); } }
/** * Return a array structure of a stylesheet definitions. * * <code> * $css_structure = cssmin::toArray(file_get_contents("path/to/target/file.css")); * </code> * * @param string $css Stylesheet definitions as string * @param string $options Options for {@link cssmin::minify()} * @return array Structure of the stylesheet definitions as array */ public static function toArray($css, $options = "") { $r = array(); $css = cssmin::minify($css, $options); preg_match_all("/(.+){(.+:.+);}/U", $css, $items); if (count($items[0]) > 0) { for ($i = 0; $i < ($c = count($items[0])); $i++) { $keys = explode(",", $items[1][$i]); $styles_tmp = explode(";", $items[2][$i]); $styles = array(); foreach ($styles_tmp as $style) { $style_tmp = explode(":", $style); $styles[$style_tmp[0]] = $style_tmp[1]; } $r[] = array("keys" => cssmin_array_clean($keys), "styles" => cssmin_array_clean($styles)); } } return $r; }
/** * Resetstyle * Implements a reset stylesheet * * Usage: Simply include the plugin in @cssp * Status: Stable * Version: 1.0 * * Version history: * 1.0 Initial Stable Version * 1.1 Added support for custom stylesheets * * @param mixed &$output * @return void */ function resetstyle(&$output) { $settings = Plugin::get_settings('resetstyle'); // Get the reset stylesheet. Use the custom file if it exists if (file_exists('plugins/resetstyle/custom.css')) { $reset_stylesheet = file_get_contents('plugins/resetstyle/custom.css'); } elseif (file_exists('plugins/resetstyle/default.css')) { $reset_stylesheet = file_get_contents('plugins/resetstyle/default.css'); } if (!empty($reset_stylesheet)) { // Compress the styles $reset_stylesheet = cssmin::minify($reset_stylesheet); // Force a scrollbar? if (is_array($settings) && in_array('force-scrollbar', $settings)) { $reset_stylesheet .= 'html{overflow-y:scroll}'; } // Add the reset stylesheet to the output. Done! $output = $reset_stylesheet . $output; } else { global $cssp; $cssp->report_error('Resetstyle plugin couldn\'t find a stylesheet to include'); } }
/** * The main entry point method. */ public function main() { if (class_exists('cssmin', false) == false) { require_once $this->cssMinPath; } foreach ($this->filesets as $fs) { try { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); $fullPath = realpath($fs->getDir($this->project)); foreach ($files as $file) { $this->log('Minifying file ' . $file); $target = $this->targetDir . '/' . str_replace($fullPath, '', str_replace('.css', '-min.css', $file)); if (file_exists(dirname($target)) == false) { mkdir(dirname($target), 0700, true); } file_put_contents($target, cssmin::minify(file_get_contents($fullPath . '/' . $file), "remove-last-semicolon,preserve-urls")); } } catch (BuildException $be) { // directory doesn't exist or is not readable if ($this->failonerror) { throw $be; } else { $this->log($be->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN); } } } }
/** * Méthode pour insérer les CSS dans la page (personnalisations propres à la page ou à la session) * * @param void * @return string */ private static function inserer_css_inline() { $string = ''; if(!empty(Layout::$tab_css_inline)) { $string_css_inline = implode(NL,Layout::$tab_css_inline); $string .= '<style type="text/css">'.NL; $string .= (SERVEUR_TYPE == 'PROD') ? cssmin::minify($string_css_inline).NL : $string_css_inline.NL ; $string .= '</style>'.NL; } return $string; }
require 'cssmin.php'; } // 拼接文件,并应用通用规则 foreach ($a_files as $k) { if (empty($type)) { $type = get_extend($k); } $in_str = file_get_contents($k); if ($in_str === false) { $unfound[] = $k; } elseif ($MINIFY) { if ($type == 'js') { $R_files[] = JSMin::minify($in_str); } else { if ($type == 'css') { $R_files[] = cssmin::minify($in_str); } } } else { $R_files[] = $in_str; } } //添加过期头,过期时间1年 header("Expires: " . date("D, j M Y H:i:s", strtotime("now + 10 years")) . " GMT"); header("Cache-Control: max-age=315360000"); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified_time) . ' GMT'); //输出文件类型 header($header[$type]); //拼装文件 $result = join("\n", $R_files); //输出文件
private function compressCss($content) { // remove comments // TODO: check and see if this breaks hacks. Turning it off for now //$content = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $content); // remove tabs, spaces, newlines, etc. //$content = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $content); cssmin::minify($content, array('preserve-urls' => false)); return $content; }
/** * createSprites * * This is the public function to allow the sprites to be built. * * @return $result boolean value indicating whether or not sprites were created */ public function createSprites() { global $mod_strings; if (!$this->isAvailable) { if (!$this->silentRun) { $msg = $mod_strings['LBL_SPRITES_NOT_SUPPORTED']; $GLOBALS['log']->warn($msg); $this->logMessage($msg); } return false; } // add repeatable sprites if (count($this->spriteRepeat)) { $this->spriteSrc = array_merge($this->spriteSrc, $this->spriteRepeat); } foreach ($this->spriteSrc as $name => $dirs) { if (!$this->silentRun) { $msg = string_format($mod_strings['LBL_SPRITES_CREATING_NAMESPACE'], array($name)); $GLOBALS['log']->debug($msg); $this->logMessage($msg); } // setup config for sprite placement algorithm if (substr($name, 0, 6) == 'repeat') { $isRepeat = true; $type = substr($name, 7, 10) == 'horizontal' ? 'horizontal' : 'vertical'; $config = array('type' => $type); } else { $isRepeat = false; $config = array('type' => 'boxed', 'width' => $this->maxWidth, 'height' => $this->maxHeight, 'rowcnt' => $this->rowCnt); } // use separate class to arrange the images $sp = new SpritePlacement($dirs, $config); $sp->processSprites(); //if(! $this->silentRun) // echo " (size {$sp->width()}x{$sp->height()})<br />"; // we need a target image size if ($sp->width() && $sp->height()) { // init sprite image $this->initSpriteImg($sp->width(), $sp->height()); // add sprites based upon determined coordinates foreach ($dirs as $dir => $files) { if (!$this->silentRun) { $msg = string_format($mod_strings['LBL_SPRITES_PROCESSING_DIR'], array($dir)); $GLOBALS['log']->debug($msg); $this->logMessage($msg); } foreach ($files as $file => $info) { if ($im = $this->loadImage($dir, $file, $info['type'])) { // coordinates $dst_x = $sp->spriteMatrix[$dir . '/' . $file]['x']; $dst_y = $sp->spriteMatrix[$dir . '/' . $file]['y']; imagecopy($this->spriteImg, $im, $dst_x, $dst_y, 0, 0, $info['x'], $info['y']); imagedestroy($im); if (!$this->silentRun) { $msg = string_format($mod_strings['LBL_SPRITES_ADDED'], array("{$dir}/{$file}")); $GLOBALS['log']->debug($msg); $this->logMessage($msg); } } } } // dir & filenames if ($isRepeat) { $outputDir = sugar_cached("sprites/Repeatable"); $spriteFileName = "{$name}.png"; $cssFileName = "{$this->fileName}.css"; $metaFileName = "{$this->fileName}.meta.php"; $nameSpace = "Repeatable"; } else { $outputDir = sugar_cached("sprites/{$name}"); $spriteFileName = "{$this->fileName}.png"; $cssFileName = "{$this->fileName}.css"; $metaFileName = "{$this->fileName}.meta.php"; $nameSpace = "{$name}"; } // directory structure if (!is_dir(sugar_cached("sprites/{$nameSpace}"))) { sugar_mkdir(sugar_cached("sprites/{$nameSpace}"), 0775, true); } // save sprite image // Unfortunately, in PHP before 5.4 imagepng can not save to streams, so we need to do a little trick here $temp = tempnam($outputDir, "sprites"); imagepng($this->spriteImg, $temp, $this->pngCompression, $this->pngFilter); copy($temp, "{$outputDir}/{$spriteFileName}"); unlink($temp); imagedestroy($this->spriteImg); /* generate css & metadata */ $head = ''; $body = ''; $metadata = ''; foreach ($sp->spriteSrc as $id => $info) { // sprite id $hash_id = md5($id); // header $head .= "span.spr_{$hash_id},\n"; // image size $w = $info['x']; $h = $info['y']; // image offset $offset_x = $sp->spriteMatrix[$id]['x']; $offset_y = $sp->spriteMatrix[$id]['y']; // sprite css $body .= "/* {$id} */\nspan.spr_{$hash_id} {\nwidth: {$w}px;\nheight: {$h}px;\nbackground-position: -{$offset_x}px -{$offset_y}px;\n}\n"; $metadata .= '$sprites["' . $id . '"] = array ("class"=>"' . $hash_id . '","width"=>"' . $w . '","height"=>"' . $h . '");' . "\n"; } // common css header require_once 'include/utils.php'; $bg_path = getVersionedPath('index.php') . '&entryPoint=getImage&imageName=' . $spriteFileName . '&spriteNamespace=' . $nameSpace; $head = rtrim($head, "\n,") . " {background: url('../../../{$bg_path}'); no-repeat;display:inline-block;}\n"; // append mode for repeatable sprites $fileMode = $isRepeat ? 'a' : 'w'; // save css $css_content = "\n/* autogenerated sprites - {$name} */\n" . $head . $body; if ($this->cssMinify) { $css_content = cssmin::minify($css_content); } $fh = fopen("{$outputDir}/{$cssFileName}", $fileMode); fwrite($fh, $css_content); fclose($fh); /* save metadata */ $add_php_tag = file_exists("{$outputDir}/{$metaFileName}") && $isRepeat ? false : true; $fh = fopen("{$outputDir}/{$metaFileName}", $fileMode); if ($add_php_tag) { fwrite($fh, '<?php'); } fwrite($fh, "\n/* sprites metadata - {$name} */\n"); fwrite($fh, $metadata . "\n"); fclose($fh); // if width & height } else { if (!$this->silentRun) { $msg = string_format($mod_strings['LBL_SPRITES_ADDED'], array($name)); $GLOBALS['log']->debug($msg); $this->logMessage($msg); } } } return true; }
foreach ($cssp->config['allowed_dirs'] as $allowed_dir) { if (strpos($file_path, realpath($allowed_dir)) === 0) { $allowed = true; break; } } } if (!$allowed) { $cssp->report_error('Path of ' . $file . ' is not in the base directory. File not processed for security reasons.'); continue; } } if ($fileinfo['extension'] == 'css') { // Simply include normal css files in the output. Minify if not debugging and configured to minify if ($cssp->config['debug_level'] == 0 && $cssp->config['minify_css'] == true) { $css .= cssmin::minify(file_get_contents($file)); } else { $css .= file_get_contents($file); } } else { $incache = false; // Server-side cache: Has file already been parsed? $cachedir = isset($cssp->config['cache_dir']) ? $cssp->config['cache_dir'] : $cssp->config['turbine_base_dir'] . 'cache'; // Cache directory // Server-side cache: Check if cache-directory has been created if (!is_dir($cachedir)) { if (!@mkdir($cachedir, 0777)) { $cssp->report_error("The cache directory doesn't exist! '{$cachedir}'"); } } elseif (!is_writable($cachedir)) { if (!@chmod($cachedir, 0777)) {
public function css($section, $revision) { $revision = explode('.', $revision); $revision = (int) $revision[0]; $file = sprintf("%s.css", $section); $cache = new Cache($file); if ($cache->isValid($revision)) { $content = $cache->load(); } else { $content = ''; foreach ($this->css[$section] as $style) { $content .= file_get_contents($style) . "\n"; } $content = cssmin::minify($content); $cache->cache($content); } $context = Context::getInstance(); $context->response->contentType = 'text/css'; $context->response->addHeader("Expires", gmdate('D, d M Y H:i:s', time() + 365 * 24 * 3600) . ' GMT'); return ETag::send($cache->cache_file); }
/** * Generate the merged css file. * * @throws Exception if a file can not be opened in write mode */ private static function generateMergedCssFile() { $mergedContent = ""; // absolute path to doc root $rootDirectory = realpath(PIWIK_DOCUMENT_ROOT); if ($rootDirectory != '/' && substr_compare($rootDirectory, '/', -1)) { $rootDirectory .= '/'; } $rootDirectoryLen = strlen($rootDirectory); // Loop through each css file $files = self::getCssFiles(); foreach ($files as $file) { self::validateCssFile($file); $fileLocation = self::getAbsoluteLocation($file); $content = file_get_contents($fileLocation); // Rewrite css url directives // - assumes these are all relative paths // - rewrite windows directory separator \\ to / $baseDirectory = dirname($file); $content = preg_replace_callback("/(url\\(['\"]?)([^'\")]*)/", create_function('$matches', "return \$matches[1] . str_replace('\\\\', '/', substr(realpath(PIWIK_DOCUMENT_ROOT . '/{$baseDirectory}/' . \$matches[2]), {$rootDirectoryLen}));"), $content); $mergedContent = $mergedContent . $content; } $mergedContent = cssmin::minify($mergedContent); $mergedContent = str_replace("\n", "\r\n", $mergedContent); // Remove the previous file self::removeMergedAsset(self::MERGED_CSS_FILE); // Tries to open the new file $newFilePath = self::getAbsoluteMergedFileLocation(self::MERGED_CSS_FILE); $newFile = @fopen($newFilePath, "w"); if (!$newFile) { throw new Exception("The file : " . $newFile . " can not be opened in write mode."); } // Write the content in the new file fwrite($newFile, $mergedContent); fclose($newFile); }
/** * Minify content * * @param string $content Content to be minified * * @return string Minified content */ protected function minify($content) { return cssmin::minify($content); }
/** * Returns the URL for the css file in the current theme. If not found in the current theme, will revert * to looking in the base theme. * * @param string $cssFileName css file name * @param bool $returnURL if true, returns URL with unique image mark, otherwise returns path to the file * @return string path of css file to include */ public function getCSSURL($cssFileName, $returnURL = true) { if (isset($this->_cssCache[$cssFileName]) && sugar_is_file(sugar_cached($this->_cssCache[$cssFileName]))) { if ($returnURL) { return getJSPath("cache/" . $this->_cssCache[$cssFileName]); } else { return sugar_cached($this->_cssCache[$cssFileName]); } } $cssFileContents = ''; $defaultFileName = $this->getDefaultCSSPath() . '/' . $cssFileName; $fullFileName = $this->getCSSPath() . '/' . $cssFileName; if (isset($this->parentTheme) && SugarThemeRegistry::get($this->parentTheme) instanceof SugarTheme && ($filename = SugarThemeRegistry::get($this->parentTheme)->getCSSURL($cssFileName, false)) != '') { $cssFileContents .= file_get_contents($filename); } else { if (sugar_is_file($defaultFileName)) { $cssFileContents .= file_get_contents($defaultFileName); } if (sugar_is_file('custom/' . $defaultFileName)) { $cssFileContents .= file_get_contents('custom/' . $defaultFileName); } } if (sugar_is_file($fullFileName)) { $cssFileContents .= file_get_contents($fullFileName); } if (sugar_is_file('custom/' . $fullFileName)) { $cssFileContents .= file_get_contents('custom/' . $fullFileName); } if (empty($cssFileContents)) { $GLOBALS['log']->warn("CSS File {$cssFileName} not found"); return false; } // fix any image references that may be defined in css files $cssFileContents = str_ireplace("entryPoint=getImage&", "entryPoint=getImage&themeName={$this->dirName}&", $cssFileContents); // create the cached file location $cssFilePath = create_cache_directory($fullFileName); // if this is the style.css file, prepend the base.css and calendar-win2k-cold-1.css // files before the theme styles if ($cssFileName == 'style.css' && !isset($this->parentTheme)) { if (inDeveloperMode()) { $cssFileContents = file_get_contents('include/javascript/yui/build/base/base.css') . $cssFileContents; } else { $cssFileContents = file_get_contents('include/javascript/yui/build/base/base-min.css') . $cssFileContents; } } // minify the css if (!inDeveloperMode() && !sugar_is_file($cssFilePath)) { $cssFileContents = cssmin::minify($cssFileContents); } // now write the css to cache sugar_file_put_contents($cssFilePath, $cssFileContents); $this->_cssCache[$cssFileName] = $fullFileName; if ($returnURL) { return getJSPath("cache/" . $fullFileName); } return sugar_cached($fullFileName); }
} else { //处理非文本 $files[] = array($in_str); } } else { //文件不存在 $in_sta = file($YOUR_CDN . $k); //文本的处理 if (preg_match('/js|css/', $type)) { $files[] = '/* ' . $k . ' */'; $inner_str = join('', $in_sta); if ($MINIFY == true && $type == 'js') { $files[] = JSMin::minify($inner_str); } else { if ($MINIFY == true && $type == 'css') { $files[] = cssmin::minify($inner_str); } else { $files[] = $inner_str; } } } else { //非文本的处理 $files[] = $in_sta; } } } header("Expires: " . date("D, j M Y H:i:s", strtotime("now + 10 years")) . " GMT"); //文本的处理 header($header[$type]); //文件类型 if (preg_match('/js|css/', $type)) {
function get_files_content_string($obj) { $minify = $obj['minify']; $host = $obj['host']; $dir = $obj['dir']; $type = $obj['type']; $files = $obj['files']; $sep = $obj['sep']; //separator $path = $obj['host'] . $obj['dir']; $files_array = explode($sep, $files); $file_count = count($files_array); $files_content = array(); //压缩js $minify_js = function ($str) { include_once 'jsmin.php'; return JSMin::minify($str); }; //压缩css $minify_css = function ($str) { include_once 'cssmin.php'; return cssmin::minify($str); }; //访问远程,获得数据 $func_httpGet = function ($url, $timeout = 30) { $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_URL, $url); $res = curl_exec($ch); curl_close($ch); return $res; }; //判断文件是否存在 $func_file_exist = function ($fileUrl) { if (preg_match('/^http:\\/\\//', $fileUrl)) { if (ini_get('allow_url_fopen')) { if (@fopen($fileUrl, 'r')) { return true; } } else { $parseurl = parse_url($fileUrl); $host = $parseurl['host']; $path = $parseurl['path']; $fp = fsockopen($host, 80, $errno, $errstr, 10); if (!$fp) { return false; } fputs($fp, "GET {$path} HTTP/1.1 \r\nhost:{$host}\r\n\r\n"); if (preg_match('/HTTP\\/1.1 200/', fgets($fp, 1024))) { return true; } } return false; } return file_exists($fileUrl); }; if (!$files || !$file_count) { return '/* 文件列表参数files不存在 */'; } for ($i = 0; $i < $file_count; $i++) { $file_name = $files_array[$i]; if ($func_file_exist($path . $file_name . '.' . $type) && preg_match('/js|css/', $type)) { //join('',file($path.$file_name.'.'.$type)); $file_content = $func_httpGet($path . $file_name . '.' . $type); if ($minify == true) { if ($type == 'js') { $files_content[] = preg_replace('/\\r|\\n/', "", trim($minify_js($file_content))); } elseif ($type == 'css') { $files_content[] = trim($minify_css($file_content)); } } else { $files_content[] = "\n"; $files_content[] = '/***** Follow is the content of "' . $path . $file_name . '.' . $type . '" *****/' . "\n\n"; $files_content[] = trim($file_content) . "\n\n\n"; } } else { if ($file_name) { $files_content[] = "\n" . '/***** The file of "' . $path . $file_name . '.' . $type . '" is not exist. *****/' . "\n"; } } } if (preg_match('/js|css/', $type)) { $res = join('', $files_content); return $res; } else { return '文件类型错误'; } }
/** * @see sfCombineMinifierInterface */ public static function minify($content, array $options = array()) { return cssmin::minify($content, $options); }
/** * Compresses using the very basic cssmin * * @return void * @author Jonathan Geiger **/ protected function compress_cssmin($file) { include_once Kohana::find_file('vendor', 'cssmin/cssmin-v1.0.1.b3'); // Pretty simple, actually file_put_contents($file, cssmin::minify(file_get_contents($file), $this->compressor_options)); }
/** * @internal Performs CSS minifying */ function minify_css($paths, $target_file, $nc_argument = false) { require_once __DIR__ . "/minify/cssmin.php"; global $current_url; $files = minify_collect_files($paths, 'css'); $files = array_merge($files, minify_collect_files($paths, 'less')); log_debug("CSS files to minify: ", $files); //die("stopped"); $code = ""; $res = array(); $map = array(); foreach ($files as $f) { if (!$f) { continue; } if (starts_with($f, "/") && !starts_with($f, "//")) { $f = (isSSL() ? "https" : "http") . "://{$_SERVER['SERVER_NAME']}" . $f; } $css = sendHTTPRequest($f, false, false, $response_header); if (stripos($response_header, "404 Not Found") !== false) { continue; } if (mb_detect_encoding($css) != "UTF-8") { $css = mb_convert_encoding($css, "UTF-8"); } $current_url = parse_url($f); $current_url['onlypath'] = dirname($current_url['path']) . "/"; if ($nc_argument) { $current_url['onlypath'] = preg_replace('|/nc(.*)/|U', "/nc{$nc_argument}/", $current_url['onlypath']); } $css = preg_replace_callback("/url\\s*\\((.*)\\)/siU", "minify_css_translate_url", $css); $css = preg_replace_callback("/AlphaImageLoader\\(src='([^']*)'/siU", "minify_css_translate_url", $css); $css = "/* FILE: {$f} */\n{$css}"; if (!isset($GLOBALS['nominify'])) { $code .= cssmin::minify($css) . "\n"; } else { $code .= "{$css}\n"; $test = str_replace("\r", "", str_replace("\n", "", $css)); $test = preg_replace('|/\\*.*\\*/|U', "", $test); preg_match_all("/([^}]+){([^:]+:[^}]+)}/U", $test, $items, PREG_SET_ORDER); foreach ($items as $item) { $keys = explode(",", $item[1]); foreach ($keys as $k) { $k = trim($k); if (isset($res[$k])) { if ($f != $map[$k]) { $mem = $res[$k]; } } else { $map[$k] = $f; $res[$k] = array(); } foreach (explode(";", $item[2]) as $e) { $e = trim($e); if ($e === "") { continue; } $res[$k][] = $e; } sort($res[$k]); $res[$k] = array_unique($res[$k]); if (isset($mem)) { if (implode(",", $res[$k]) != implode(",", $mem)) { if (count($res[$k]) == count($mem)) { log_debug("[{$k}] defninition overrides previously defined\nFILE: {$f}\nPREV: {$map[$k]}\nNEW : " . implode(";", $res[$k]) . "\nORIG: " . implode(";", $mem) . "\n"); } else { foreach ($mem as $m) { if (!in_array($m, $res[$k])) { log_debug("[{$k}] defninition extends/overrides previously defined\nFILE: {$f}\nPREV: {$map[$k]}\nNEW : " . implode(";", $res[$k]) . "\nORIG: " . implode(";", $mem) . "\n"); } } } } unset($mem); } } } } } foreach (array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f') as $c) { $code = str_ireplace("#{$c}{$c}{$c}{$c}{$c}{$c}", "#{$c}{$c}{$c}", $code); } file_put_contents($target_file, $code); }
} // load libraries css foreach (glob(TERRIFIC_DIR . '/css/plugins/*.css') as $entry) { if (is_file($entry)) { $output .= file_get_contents($entry); } } // load plugin css foreach (glob(TERRIFIC_DIR . '/css/plugins/*.css') as $entry) { if (is_file($entry)) { $output .= file_get_contents($entry); } } // load module css including skins foreach (glob(TERRIFIC_DIR . '/modules/*', GLOB_ONLYDIR) as $dir) { $module = basename($dir); $css = $dir . '/css/' . strtolower($module) . '.css'; if (is_file($css)) { $output .= file_get_contents($css); } foreach (glob($dir . '/css/skin/*') as $entry) { if (is_file($entry)) { $output .= file_get_contents($entry); } } } require_once '../min/cssmin-v1.0.1.b3.php'; $output = cssmin::minify($output); file_put_contents($cache_dir . 'terrific-' . $version . '.css', $output); header("Content-Type: text/css"); echo $output;
/** * Minify css with cssmin * * @param <type> $css */ private function minifyCss($css) { Yii::import($this->jsMinPath, true); Yii::import($this->cssMinPath); return cssmin::minify($css, $this->cssMinFilters, $this->cssMinPlugins); }
public static function minify($v) { return cssmin::minify($v); }
public function Pack() { return cssmin::minify($this->content); }
/** * Send a group of files to client (ie : JS or CSS files) * Provide coherent user caching infos (1 month) for files and allow gzip when possible * * @param array $files : array of files path to send to client (FS relative) * @param string $contentType : the content type to send to client (default : text/html) * @return void * @access public * @static */ static function sendFiles($files, $contentType = 'text/html') { //check for the closest last modification date $lastdate = ''; //check for included files in less files $includes = array(); if ($contentType == 'text/css') { foreach ($files as $key => $file) { if (pathinfo($file, PATHINFO_EXTENSION) == 'less') { $lessCache = new CMS_cache(md5($file), 'lessphp', 2592000, false); if ($lessCache->exist()) { $includes = array_merge($includes, $lessCache->load()); } } } } if ($includes) { foreach ($includes as $key => $file) { if (file_exists($file) && is_file($file)) { $lastdate = filemtime($file) > $lastdate ? filemtime($file) : $lastdate; } } } foreach ($files as $key => $file) { if (file_exists($file) && is_file($file)) { $lastdate = filemtime($file) > $lastdate ? filemtime($file) : $lastdate; } else { CMS_grandFather::raiseError('Can\'t find file : ' . $file . ', skip it.'); unset($files[$key]); } } if (file_exists($_SERVER['SCRIPT_FILENAME'])) { $lastdate = filemtime($_SERVER['SCRIPT_FILENAME']) > $lastdate ? filemtime($_SERVER['SCRIPT_FILENAME']) : $lastdate; } //check If-Modified-Since header if exists then return a 304 if needed if (isset($_SERVER['IF-MODIFIED-SINCE'])) { $ifModifiedSince = strtotime($_SERVER['IF-MODIFIED-SINCE']); } elseif (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $ifModifiedSince = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); } if (isset($ifModifiedSince) && $lastdate <= $ifModifiedSince) { header('HTTP/1.1 304 Not Modified'); header('Content-Type: ' . $contentType); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastdate) . ' GMT'); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT'); //30 days header("Cache-Control: must-revalidate"); header("Pragma: public"); exit; } $compress = 'ob_gzhandler' != ini_get('output_handler') && extension_loaded('zlib') && !ini_get('zlib.output_compression') && strpos(strtolower(@$_SERVER['HTTP_ACCEPT_ENCODING']), 'gzip') !== false; //create cache id from files, compression status and last time files access $id = md5(implode(',', $files) . '-' . $compress . '-' . $lastdate); //create cache object $cache = new CMS_cache($id, $contentType, 2592000, false); $datas = ''; if (!$cache->exist() || !($datas = $cache->load())) { // datas cache missing so create it foreach ($files as $file) { $fileData = file_get_contents($file); //strip BOM from file if exists if (substr($fileData, 0, 3) === '') { $fileData = substr($fileData, 3); } //append file origin comment if ($contentType == 'text/javascript') { $fileData = '//<<' . "\n" . '//JS file: ' . str_replace(PATH_REALROOT_FS, '', $file) . '' . "\n" . '//!>>' . "\n" . $fileData; } //append file origin comment if ($contentType == 'text/css') { //compile less files if needed if (pathinfo($file, PATHINFO_EXTENSION) == 'less') { $less = new lessc($file); $fileData = $less->parse(); $lessIncludes = $less->allParsedFiles(); if (sizeof($lessIncludes) > 1) { $lessCache = new CMS_cache(md5($file), 'lessphp', 2592000, false); $lessCache->save(array_keys($lessIncludes), array('type' => 'lessphp')); } } $fileData = '/*<<*/' . "\n" . '/* CSS file: ' . str_replace(PATH_REALROOT_FS, '', $file) . ' */' . "\n" . '/*!>>*/' . "\n" . $fileData; } $datas .= $fileData . "\n"; } //minimize JS files if needed if (!SYSTEM_DEBUG && $contentType == 'text/javascript') { $datas = JSMin::minify($datas); } //minimize CSS files if needed if (!SYSTEM_DEBUG && $contentType == 'text/css') { $datas = cssmin::minify($datas); } //compres data if needed if ($compress) { $datas = gzencode($datas, 3); } if ($cache) { $cache->save($datas, array('type' => $contentType)); } } //send headers header('Content-Type: ' . $contentType); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastdate) . ' GMT'); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT'); //30 days header("Cache-Control: must-revalidate"); header("Pragma: public"); //send gzip header if needed if ($compress) { header('Vary: Accept-Encoding'); // Handle proxies header("Content-Encoding: gzip"); } //send content echo $datas; exit; }