public function minify($inPath, $outPath) { global $wgResourceLoaderMinifierStatementsOnOwnLine, $wgResourceLoaderMinifierMaxLineLength; $extension = $this->getExtension($inPath); $this->output(basename($inPath) . ' -> ' . basename($outPath) . '...'); $inText = file_get_contents($inPath); if ($inText === false) { $this->error("Unable to open file {$inPath} for reading."); exit(1); } $outFile = fopen($outPath, 'w'); if (!$outFile) { $this->error("Unable to open file {$outPath} for writing."); exit(1); } switch ($extension) { case 'js': $outText = JavaScriptMinifier::minify($inText, $this->getOption('js-statements-on-own-line', $wgResourceLoaderMinifierStatementsOnOwnLine), $this->getOption('js-max-line-length', $wgResourceLoaderMinifierMaxLineLength)); break; case 'css': $outText = CSSMin::minify($inText); break; default: $this->error("No minifier defined for extension \"{$extension}\""); } fwrite($outFile, $outText); fclose($outFile); $this->output(" ok\n"); }
public function minimizeFiles($files) { $css_out = ''; $webroot = (string) OC::$WEBROOT; foreach ($files as $file_info) { $file = $file_info[0] . '/' . $file_info[2]; $css_out .= '/* ' . $file . ' */' . "\n"; $css = file_get_contents($file); $in_root = false; foreach (OC::$APPSROOTS as $app_root) { if (strpos($file, $app_root['path'] . '/') === 0) { $in_root = rtrim($webroot . $app_root['url'], '/'); break; } } if ($in_root !== false) { $css = str_replace('%appswebroot%', $in_root, $css); $css = str_replace('%webroot%', $webroot, $css); } $remote = $file_info[1]; $remote .= '/'; $remote .= dirname($file_info[2]); $css_out .= CSSMin::remap($css, dirname($file), $remote, true); } if (!defined('DEBUG') || !DEBUG) { $css_out = CSSMin::minify($css_out); } return $css_out; }
/** * Combine multiple text assets into a single file for better http performance this * method generates a new cache file with every symfony cc you can override the cache * by adding ?clearassetcache=1 to the page request. * * @param type string css or js * @param namespace string the combined file namespace (eg. module+action names) * @param response object the sfWebResponse instance * @return string the url for the combiner service */ public function combine($type, $namespace, sfWebResponse $response) { //configure the combiner $type = $type === 'css' ? 'css' : 'js'; $fullname = $type === 'css' ? 'Stylesheets' : 'Javascripts'; $response_getter = 'get' . $fullname; $namespace = StreemeUtil::slugify($namespace); //integrate into symfony's asset globals sfConfig::set(sprintf('symfony.asset.%s_included', strtolower($fullname)), true); //build the cache filename - this file will be regenerated on a symfony cc $path = sprintf('%s/combine/%s/', sfConfig::get('sf_cache_dir'), $type); $filename = sprintf('%s.%s', $namespace, $type); // you can force a cache clear by passing ?clearassetcache=1 to any template if (!is_readable($path . $filename) || @$_GET['clearassetcache'] == 1) { //build one file of all of the css or js files $file_content = ''; //load vendor libraries for minifying assets require_once sfConfig::get('sf_lib_dir') . '/vendor/jsmin/jsmin.php'; require_once sfConfig::get('sf_lib_dir') . '/vendor/cssmin/cssmin.php'; foreach ($response->{$response_getter}() as $file => $options) { if ($type === 'css') { $file_content .= CSSMin::minify(file_get_contents(sfConfig::get('sf_web_dir') . $file)); } else { $file_content .= JSMin::minify(file_get_contents(sfConfig::get('sf_web_dir') . $file)); } } //this file resides in the cache and requires wide permissions for both cli and apache users @umask(00); @mkdir($path, 0777, true); file_put_contents($path . $filename, $file_content); } return sprintf('/service/combine/%s/%s', $type, str_replace('-', '_', $namespace)); }
function show_css($files) { global $root; $hash = ''; foreach ($files as $file) { $path = $root . '/' . $file . '.css'; $hash .= $file . filemtime($path); } $md5 = md5($hash); $cpath = $root . '/resources/c/' . $md5 . '.css'; if (!file_exists($cpath)) { require_once 'CSSMin.php'; $text = ''; foreach ($files as $file) { $path = $root . '/' . $file . '.css'; $text .= file_get_contents($path) . "\n\n"; } if (TEST) { $css = $text; } else { $css = CSSMin::minify($text); } file_put_contents($cpath, $css); } echo '<link rel="stylesheet" href="/resources/c/' . $md5 . '.css" />' . "\n"; }
function minify() { $this->setTemplate(get_template_path("empty")); if (!logged_user()->isAdministrator()) { die("You must be an administrator to run this tool."); } // include libraries include_once LIBRARY_PATH . '/jsmin/JSMin.class.php'; include_once LIBRARY_PATH . '/cssmin/CSSMin.class.php'; // process arguments $minify = isset($_GET['minify']); // process javascripts echo "Concatenating javascripts ... \n"; $files = (include "application/layouts/javascripts.php"); $jsmin = ""; foreach ($files as $file) { $jsmin .= file_get_contents("public/assets/javascript/{$file}") . "\n"; } echo "Done!<br>\n"; if ($minify) { echo "Minifying javascript ... \n"; $jsmin = JSMin::minify($jsmin); echo "Done!<br>\n"; } echo "Writing to file 'ogmin.js' ... "; file_put_contents("public/assets/javascript/ogmin.js", $jsmin); echo "Done!<br>"; echo "<br>"; // process CSS function changeUrls($css, $base) { return preg_replace("/url\\s*\\(\\s*['\"]?([^\\)'\"]*)['\"]?\\s*\\)/i", "url(" . $base . "/\$1)", $css); } function parseCSS($filename, $filebase, $imgbase) { $css = file_get_contents($filebase . $filename); $imports = explode("@import", $css); $cssmin = changeUrls($imports[0], $imgbase); for ($i = 1; $i < count($imports); $i++) { $split = explode(";", $imports[$i], 2); $import = trim($split[0], " \t\n\r\v'\""); $cssmin .= parseCSS($import, $filebase, $imgbase . "/" . dirname($import)); $cssmin .= changeUrls($split[1], $imgbase); } return $cssmin; } echo "Concatenating CSS ... "; $cssmin = parseCSS("website.css", "public/assets/themes/default/stylesheets/", "."); echo "Done!<br>"; if ($minify) { echo "Minifying CSS ... "; $cssmin = CSSMin::minify($cssmin); echo "Done!<br>"; } echo "Writing to file 'ogmin.css' ... "; file_put_contents("public/assets/themes/default/stylesheets/ogmin.css", $cssmin); echo "Done!<br>"; die; }
protected function optimize($data, $package, $type) { switch ($type) { case 'javascripts': $data = JSMin::minify($data); break; case 'stylesheets': $data = CSSMin::minify($data); break; } return $data; }
function compress($string, $filetype = "php") { if ($filetype === "php") { $string = str_replace("<?php\r", "<?php ", $string); return str_replace(array("\r\n", "\r", "\n", "\t", " ", " ", " "), "", $string); } else { global $Load; if ($filetype === "css") { $Load->library("cssmin", null, null, "minify"); return CSSMin::minify($string); } elseif ($filetype === 'js') { $Load->library("jsmin", null, null, "minify"); return JSMin::minify($string); } } return null; }
public static function minify($d, $t = 'js') { if (!empty(Core::$core->nominify) || $t != 'css' && $t != 'js' && $t != 'php') { return $d; } $d = trim($d); if ($t == 'css' && class_exists('CSSMin')) { return \CSSMin::minify($d); } if ($t == 'js' && class_exists('JSMin')) { return \JSMin::minify($d); } $n = ''; $i = 0; $l = strlen($d); while ($i < $l) { $c = @substr($n, -1); if (($d[$i] == "'" || $d[$i] == '"') && $c != '\\') { $s = $d[$i]; $j = $i; ++$i; while ($i < $l && $d[$i] != $s) { if ($d[$i] == '\\') { $i++; } ++$i; } ++$i; $n .= substr($d, $j, $i - $j); continue; } if ($t != 'css' && ($d[$i] == '/' && $d[$i + 1] == '/')) { $s = $i; $i += 2; while ($i < $l && $d[$i] != "\n") { $i++; } continue; } if ($d[$i] == '/' && $d[$i + 1] == '*') { $s = $i; $i += 2; while ($i + 1 < $l && ($d[$i] != '*' || $d[$i + 1] != '/')) { $i++; } $i += 2; continue; } if ($d[$i] == "\t" || $d[$i] == "\r" || $d[$i] == "\n") { if (($c >= 'a' && $c <= 'z' || $c >= 'A' && $c <= 'Z' || $c >= '0' && $c <= '9') && ($d[$i + 1] == '\\' || $d[$i + 1] == '/' || $d[$i + 1] == '_' || $d[$i + 1] == '*' || $d[$i + 1] >= 'a' && $d[$i + 1] <= 'z' || $d[$i + 1] >= 'A' && $d[$i + 1] <= 'Z' || $d[$i + 1] >= '0' && $d[$i + 1] <= '9' || $d[$i + 1] == '#')) { $n .= ' '; } $i++; continue; } if ($d[$i] == ' ' && (!($c >= 'a' && $c <= 'z' || $c >= 'A' && $c <= 'Z' || $c >= '0' && $c <= '9') || !($d[$i + 1] == '\\' || $d[$i + 1] == '/' || $d[$i + 1] == '_' || $d[$i + 1] >= 'a' && $d[$i + 1] <= 'z' || $d[$i + 1] >= 'A' && $d[$i + 1] <= 'Z' || $d[$i + 1] >= '0' && $d[$i + 1] <= '9' || $d[$i + 1] == '#' || $d[$i + 1] == '*' || $t == 'js' && $d[$i + 1] == '$'))) { ++$i; continue; } $n .= $d[$i++]; } return $n; }
/** * {@inheritDoc} */ public function compress($content) { require_once $this->options['path']; return \CSSMin::minify($content, $this->options); }
private static function applyFilter($filter, $data) { $data = trim($data); if ($data) { try { $data = $filter === 'minify-css' ? CSSMin::minify($data) : JavaScriptMinifier::minify($data); } catch (Exception $e) { MWExceptionHandler::logException($e); return null; } } return $data; }
/** * @dataProvider provideMediaStylesheets */ public function testStyleMedia($moduleName, $media, $filename, $css) { $cssText = CSSMin::minify($css->cssText); $this->assertTrue(strpos($cssText, '@media') === false, 'Stylesheets should not both specify "media" and contain @media'); }
/** * Build combined file * * @param array $params */ function smarty_build_combine($params) { $filelist = array(); $lastest_mtime = 0; foreach ($params['input'] as $item) { if (file_exists($_SERVER['DOCUMENT_ROOT'] . $item)) { $mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $item); $lastest_mtime = max($lastest_mtime, $mtime); $filelist[] = array('name' => $item, 'time' => $mtime); } else { trigger_error('File ' . $_SERVER['DOCUMENT_ROOT'] . $item . ' does not exists!', E_USER_WARNING); } } if ($params['debug'] == true) { $output_filename = ''; foreach ($filelist as $file) { if ($params['type'] == 'js') { $output_filename .= '<script type="text/javascript" src="' . $_SERVER['DOCUMENT_ROOT'] . $file['name'] . '" charset="utf-8"></script>'; } elseif ($params['type'] == 'css') { $output_filename .= '<link type="text/css" rel="stylesheet" href="' . $_SERVER['DOCUMENT_ROOT'] . $file['name'] . '" />'; } } echo $output_filename; return; } $last_cmtime = 0; if (file_exists($_SERVER['DOCUMENT_ROOT'] . $params['cache_file_name'])) { $last_cmtime = file_get_contents($_SERVER['DOCUMENT_ROOT'] . $params['cache_file_name']); } if ($lastest_mtime > $last_cmtime) { $glob_mask = preg_replace("/\\.(js|css)\$/i", "_*.\$1", $params['output']); $files_to_cleanup = glob($_SERVER['DOCUMENT_ROOT'] . $glob_mask); foreach ($files_to_cleanup as $cfile) { if (is_file($_SERVER['DOCUMENT_ROOT'] . $cfile) && file_exists($_SERVER['DOCUMENT_ROOT'] . $cfile)) { @unlink($_SERVER['DOCUMENT_ROOT'] . $cfile); } } $output_filename = preg_replace("/\\.(js|css)\$/i", date("_YmdHis.", $lastest_mtime) . "\$1", $params['output']); $fh = fopen($_SERVER['DOCUMENT_ROOT'] . $output_filename, "a+"); if (flock($fh, LOCK_EX)) { foreach ($filelist as $file) { $min = ''; if ($params['type'] == 'js') { $min = JSMin::minify(file_get_contents($_SERVER['DOCUMENT_ROOT'] . $file['name'])); } elseif ($params['type'] == 'css') { $min = CSSMin::minify(file_get_contents($_SERVER['DOCUMENT_ROOT'] . $file['name'])); } else { fputs($fh, PHP_EOL . PHP_EOL . "/* " . $file['name'] . " @ " . date("c", $file['time']) . " */" . PHP_EOL . PHP_EOL); $min = file_get_contents($_SERVER['DOCUMENT_ROOT'] . $file['name']); } fputs($fh, $min); } flock($fh, LOCK_UN); file_put_contents($_SERVER['DOCUMENT_ROOT'] . $params['cache_file_name'], $lastest_mtime, LOCK_EX); } fclose($fh); clearstatcache(); } touch($_SERVER['DOCUMENT_ROOT'] . $params['cache_file_name']); smarty_print_out($params); }
/** * Initialize the assets library * * Loads the config file and inserts the base css and js into the arrays for * later use. This ensures that the base files will be processed in the * order the user expects. * * @return void */ public static function init() { // It is recommended to combine as many config files as sensible into a // single file for performance reasons. If the config entry is already // available, don't load the file. // @todo Update this to remove the check for 'assets.base_folder' once // it can be safely assumed that the item should no longer be present $baseFolder = self::$ci->config->item('assets.base_folder'); $assetsDirs = self::$ci->config->item('assets.directories'); if (($baseFolder === false || $baseFolder === null) && ($assetsDirs === false || $assetsDirs === null)) { self::$ci->config->load('application'); } unset($baseFolder, $assetsDirs); // Retrieve the config settings if (self::$ci->config->item('assets.directories')) { self::$directories = self::$ci->config->item('assets.directories'); foreach (self::$directories as $key => &$value) { $value = trim($value, '/'); } } else { // If 'assets.directories' is not set, check the previous locations. self::$directories = array(); self::$directories['base'] = trim(self::$ci->config->item('assets.base_folder') ?: 'assets', '/'); self::$directories['cache'] = trim(self::$ci->config->item('assets.cache_folder') ?: 'cache', '/'); // Set to default because this directory was not in the previous // config locations. self::$directories['module'] = 'module'; $assetFolders = self::$ci->config->item('assets.asset_folders') ?: array('js' => 'js', 'css' => 'css', 'image' => 'images'); foreach ($assetFolders as $key => $value) { self::$directories[$key] = trim($value, '/'); } unset($assetFolders); } // Make sure the is_https() function is available for use by external_js() // and find_files(). if (!function_exists('is_https')) { self::$ci->load->helper('application'); } // Set the closures to minify CSS/JS self::$cssMinify = function ($css) { return CSSMin::minify($css); }; self::$jsMinify = function ($js) { return JSMin::minify($js); }; log_message('debug', 'Assets library loaded.'); }
} /** * Scripts that will be minified and included at the STANDARD level and above. */ if (Classification::is_standard() && (isset($_GET['standard']) || isset($_GET['touch']))) { $loadarr = isset($_GET['standard']) ? explode(' ', $_GET['standard']) : array(); // Support for deprecated TOUCH parameter. if (isset($_GET['touch'])) { $loadarr = array_merge(explode(' ', $_GET['touch']), $loadarr); } foreach ($loadarr as $file) { if (Path_Validator::is_safe($file, 'css') && ($contents = Path::get_contents($file))) { echo CSSMin::minify($contents); } } } /** * Scripts that will be minified and included at the FULL level only. */ if (Classification::is_full() && (isset($_GET['full']) || isset($_GET['webkit']))) { $loadarr = isset($_GET['full']) ? explode(' ', $_GET['full']) : array(); // Support for deprecated WEBKIT parameter. if (isset($_GET['webkit'])) { $loadarr = array_merge(explode(' ', $_GET['webkit']), $loadarr); } foreach ($loadarr as $file) { if (Path_Validator::is_safe($file, 'css') && ($contents = Path::get_contents($file))) { echo CSSMin::minify($contents); } } }
/** * Process files * @param string $data contents of file * @param string $type css or js * @param string $do what to do (all, minify) * @param string $base_url URL to assets directory * @return string returns the processed file data */ private static function _process($data = null, $type = null, $do = 'all', $base_url = null) { if (!$base_url) { $base_url = self::$base_url; } if ($type == 'css') { if ((self::$minify or self::$minify_css) and ($do == 'all' or $do == 'minify')) { $data = CSSMin::minify($data, array('currentDir' => str_replace(site_url(), '', $base_url) . '/')); } } else { if ((self::$minify or self::$minify_js) and ($do == 'all' or $do == 'minify')) { $data = JSMin::minify($data); } } return $data; }
/** * Ads the specified css files to the head of the page (minifies & joins them if necessary) * * @param string|array $files - single file or array with file paths * @param string $cachePath - the path to the cache folder * @param bool $minify - should we minify it * * @return void */ public static function css($files, $cachePath, $minify = true) { // If we have a string, then we are dealing with a single file if (is_string($files)) { $files = array($files); } // Check if there are any files if (!count($files)) { return; } // Let's merge and minify if we need to if ($minify) { $css = array(); $times = array(); foreach ($files as $file) { if (file_exists(JPATH_ROOT . '/' . $file)) { $times[] = filemtime(JPATH_ROOT . '/' . $file); } } $md5 = md5(json_encode($files)); $url = $cachePath . '/' . $md5 . '.min.css'; $minFile = JPATH_ROOT . '/' . $url; // If the minFile doesn't exist or the minFile time is older than any of the times, let's do our job! if (!file_exists($minFile) || max($times) > filemtime($minFile)) { // TODO Move to autoload require_once JPATH_LIBRARIES . "/compojoom/cssmin/cssmin.php"; // Minify & Join CSS filfes foreach ($files as $file) { $css[] = "/* File: " . $file . " */"; $css[] = CSSMin::minify(file_get_contents(JPATH_ROOT . "/" . $file)); } $mincss = implode("\n", $css); JFile::write($minFile, $mincss); } // Load css file JHtml::stylesheet($url); } else { // Output each file from the array as is foreach ($files as $file) { JHtml::stylesheet($file); } } }
public function encode_file($path, $base) { $rpath = self::relativePath($path, $base); if (preg_match('/\\.(php|phtml)$/', $path)) { echo " [34mPHP[0m: {$rpath}..."; //移除脚本中的注释和回车 $content = file_get_contents($path); $total = strlen($content); // 预编译代码 if (class_exists('\\Gini\\Dev\\Macro')) { $content = Macro::compile($content); } // 混淆变量 if (class_exists('\\Gini\\Dev\\Obfuscator')) { $ob = new Obfuscator($content); $ob->set_reserved_keywords(['$config', '$lang']); $content = $ob->format(); } $converted = strlen($content); $percentage = round($converted * 100 / $total, 1); echo " {$percentage}%"; } elseif (fnmatch("*.js", $path)) { echo " [32mJS[0m: {$rpath}..."; $content = @file_get_contents($path); $total = strlen($content); $content = shell_exec('uglifyjs ' . escapeshellarg($path) . ' 2>&1'); $converted = strlen($content); $percentage = round($converted * 100 / $total, 1); echo " {$percentage}%"; } elseif (fnmatch('*.css', $path)) { echo " [35mCSS[0m: {$rpath}..."; $content = @file_get_contents($path); $total = strlen($content); $content = \CSSMin::minify($content); $converted = strlen($content); $percentage = round($converted * 100 / $total, 1); echo " {$percentage}%"; } else { echo " DUP: {$rpath}..."; //复制相关文件 $content = @file_get_contents($path); $total = strlen($content); echo "{$total} bytes"; } if ($content) { $this->phar[$rpath] = $content; } else { echo "... EMPTY"; } echo "\n"; }
private function minifyCSS($content) { wfProfileIn(__METHOD__); $out = CSSMin::minify($content); wfProfileOut(__METHOD__); return $out; }
/** * @dataProvider provideMinifyCases * @covers CSSMin::minify */ public function testMinify($code, $expectedOutput) { $minified = CSSMin::minify($code); $this->assertEquals($expectedOutput, $minified, 'Minified output should be in the form expected.'); }
private static function applyFilter($filter, $data, Config $config) { switch ($filter) { case 'minify-js': return JavaScriptMinifier::minify($data); case 'minify-css': return CSSMin::minify($data); } return $data; }
/** * Runs JavaScript or CSS data through a filter, caching the filtered result for future calls. * * Available filters are: * - minify-js \see JavaScriptMinifier::minify * - minify-css \see CSSMin::minify * * If $data is empty, only contains whitespace or the filter was unknown, * $data is returned unmodified. * * @param $filter String: Name of filter to run * @param $data String: Text to filter, such as JavaScript or CSS text * @return String: Filtered data, or a comment containing an error message */ protected function filter($filter, $data) { global $wgResourceLoaderMinifierStatementsOnOwnLine, $wgResourceLoaderMinifierMaxLineLength; wfProfileIn(__METHOD__); // For empty/whitespace-only data or for unknown filters, don't perform // any caching or processing if (trim($data) === '' || !in_array($filter, array('minify-js', 'minify-css'))) { wfProfileOut(__METHOD__); return $data; } // Try for cache hit // Use CACHE_ANYTHING since filtering is very slow compared to DB queries $key = wfMemcKey('resourceloader', 'filter', $filter, self::$filterCacheVersion, md5($data)); $cache = wfGetCache(CACHE_ANYTHING); $cacheEntry = $cache->get($key); if (is_string($cacheEntry)) { wfProfileOut(__METHOD__); return $cacheEntry; } $result = ''; // Run the filter - we've already verified one of these will work try { switch ($filter) { case 'minify-js': $result = JavaScriptMinifier::minify($data, $wgResourceLoaderMinifierStatementsOnOwnLine, $wgResourceLoaderMinifierMaxLineLength); $result .= "\n/* cache key: {$key} */"; break; case 'minify-css': $result = CSSMin::minify($data); $result .= "\n/* cache key: {$key} */"; break; } // Save filtered text to Memcached $cache->set($key, $result); } catch (Exception $exception) { // Return exception as a comment $result = $this->makeComment($exception->__toString()); } wfProfileOut(__METHOD__); return $result; }
/** * Minify, less * */ function _process($data = null, $type = null, $do = 'all', $base_url = null) { if (!$base_url) { $base_url = $this->base_url; } if ($type == 'css') { if ($this->less_css and ($do == 'all' or $do == 'less')) { $data = $this->less->parse($data); } if (($this->minify or $this->minify_css) and ($do == 'all' or $do == 'minify')) { $data = CSSMin::minify($data, array('currentDir' => str_replace(site_url(), '', $base_url) . '/')); } } else { if (($this->minify or $this->minify_js) and ($do == 'all' or $do == 'minify')) { $data = JSMin::minify($data); } } return $data; }
require_once dirname(__FILE__) . '/css/default/full.css'; foreach ($custom as $dir) { if (file_exists(dirname(__FILE__) . '/css/' . $dir . '/full.css')) { include_once dirname(__FILE__) . '/css/' . $dir . '/full.css'; } } } /** * Load custom CSS files (minified) based on user agent. */ if (isset($_GET['basic'])) { foreach (explode(' ', $_GET['basic']) as $file) { if (Path_Validator::is_safe($file, 'css') && ($contents = Path::get_contents($file))) { echo ' ' . CSSMin::minify($contents); } } } if (User_Agent::is_standard() && isset($_GET['standard'])) { foreach (explode(' ', $_GET['standard']) as $file) { if (Path_Validator::is_safe($file, 'css') && ($contents = Path::get_contents($file))) { echo ' ' . CSSMin::minify($contents); } } } if (User_Agent::is_full() && isset($_GET['full'])) { foreach (explode(' ', $_GET['full']) as $file) { if (Path_Validator::is_safe($file, 'css') && ($contents = Path::get_contents($file))) { echo ' ' . CSSMin::minify($contents); } } }
/** * Process assets in group * @param string $type * @param string $group */ private static function _process($type = null, $group = null) { if (!$group) { $group = self::$default_group[$type]; } // Start benchmark if (self::$_enable_benchmark) { self::$_ci->benchmark->mark("Assets::process(" . $type . ", " . $group . ")_start"); } // Last modified date if (!isset(self::$_cache_info->{$type}->{$group})) { $last_modified = 0; } else { $last_modified = self::last_modified($type, $group); } // Create a cache filename if ($group !== self::$default_group[$type]) { $file_prefix = $group . '.'; } else { $file_prefix = ''; } $file_name = self::$_assets[$type][$group]['cache_file_name'] = $file_prefix . $last_modified . "." . $type; // And check if we should process it $file_exists = file_exists(self::$cache_path . '/' . $file_name); if (!$file_exists or !$last_modified) { // Get list of assets $assets = self::$_assets[$type][$group]; // Loop through all original assets foreach ($assets['src'] as $key => $asset) { // Get file contents $contents = read_file($asset['path']); // Get file info $asset['info'] = pathinfo($asset['file']); // Process imports in CSS files if ($type === 'css') { $import_result = self::_process_imports($contents, null, $asset['file']); $contents = $import_result['contents']; // Update last modified time if ($import_result['last_modified'] > self::$_assets[$type][$group]['last_modified']) { self::$_assets[$type][$group]['last_modified'] = $import_result['last_modified']; self::$_assets[$type][$group]['last_modified_human'] = date('Y-m-d H:i:s', $import_result['last_modified']); } // Update imported files self::$_assets[$type][$group]['file_list'] = array_unique(array_merge(self::$_assets[$type][$group]['file_list'], $import_result['file_list'])); } elseif ($type === 'js') { // CoffeeScript parser if (self::$enable_coffeescript and $asset['info']['extension'] === 'coffee') { if (!self::$_coffeescript_loaded) { self::_init_coffeescript(); } CoffeeScript\Init::load(); $contents = CoffeeScript\Compiler::compile($contents); } elseif (!self::$enable_coffeescript and $asset['info']['extension'] === 'coffee') { $contents = ''; } // Minify JS if (self::$minify_js) { self::_init_jsmin(); $contents = trim(JSMin::minify($contents)); } } // Or add to combine var (if we're combining) self::$_assets[$type][$group]['combined'] .= "\n" . $contents; } // New file name $file_name = self::$_assets[$type][$group]['cache_file_name'] = $file_prefix . self::$_assets[$type][$group]['last_modified'] . "." . $type; // Now minify/less if we choose so if ($type === 'css') { $output = self::$_assets[$type][$group]['combined']; // Less if (self::$enable_less and !self::$freeze) { self::_init_less(); $output = self::$_less->parse($output); } // Minify CSS if (self::$minify_css and !self::$freeze) { self::_init_cssmin(); $output = trim(CSSMin::minify($output, self::$cssmin_filters, self::$cssmin_plugins)); } // Add to output self::$_assets[$type][$group]['output'] = $output; unset($output); } elseif ($type === 'js') { $output = self::$_assets[$type][$group]['combined']; // Minify JS if (self::$minify_js) { self::_init_jsmin(); self::$_assets[$type][$group]['output'] = trim(JSMin::minify($output)); } // Add to output self::$_assets[$type][$group]['output'] = $output; unset($output); } // Once it's processed remove vars we dont need unset(self::$_assets[$type][$group]['combined']); // And finnaly we create the actual cached files self::_cache_assets($type); } // Update cache info self::_update_cache_info(); // End benchmark if (self::$_enable_benchmark) { self::$_ci->benchmark->mark("Assets::process(" . $type . ", " . $group . ")_end"); } }
/** * Run JavaScript or CSS data through a filter, caching the filtered result for future calls. * * Available filters are: * * - minify-js \see JavaScriptMinifier::minify * - minify-css \see CSSMin::minify * * If $data is empty, only contains whitespace or the filter was unknown, * $data is returned unmodified. * * @param string $filter Name of filter to run * @param string $data Text to filter, such as JavaScript or CSS text * @param string $cacheReport Whether to include the cache key report * @return string Filtered data, or a comment containing an error message */ public function filter($filter, $data, $cacheReport = true) { // For empty/whitespace-only data or for unknown filters, don't perform // any caching or processing if (trim($data) === '' || !in_array($filter, array('minify-js', 'minify-css'))) { return $data; } // Try for cache hit // Use CACHE_ANYTHING since filtering is very slow compared to DB queries $key = wfMemcKey('resourceloader', 'filter', $filter, self::$filterCacheVersion, md5($data)); $cache = wfGetCache(CACHE_ANYTHING); $cacheEntry = $cache->get($key); if (is_string($cacheEntry)) { wfIncrStats("rl-{$filter}-cache-hits"); return $cacheEntry; } $result = ''; // Run the filter - we've already verified one of these will work try { wfIncrStats("rl-{$filter}-cache-misses"); switch ($filter) { case 'minify-js': $result = JavaScriptMinifier::minify($data, $this->config->get('ResourceLoaderMinifierStatementsOnOwnLine'), $this->config->get('ResourceLoaderMinifierMaxLineLength')); if ($cacheReport) { $result .= "\n/* cache key: {$key} */"; } break; case 'minify-css': $result = CSSMin::minify($data); if ($cacheReport) { $result .= "\n/* cache key: {$key} */"; } break; } // Save filtered text to Memcached $cache->set($key, $result); } catch (Exception $e) { MWExceptionHandler::logException($e); wfDebugLog('resourceloader', __METHOD__ . ": minification failed: {$e}"); $this->errors[] = self::formatExceptionNoComment($e); } return $result; }
public function minify($inPath, $outPath) { $extension = $this->getExtension($inPath); $this->output(basename($inPath) . ' -> ' . basename($outPath) . '...'); $inText = file_get_contents($inPath); if ($inText === false) { $this->error("Unable to open file {$inPath} for reading."); exit(1); } $outFile = fopen($outPath, 'w'); if (!$outFile) { $this->error("Unable to open file {$outPath} for writing."); exit(1); } switch ($extension) { case 'js': $outText = JavaScriptMinifier::minify($inText); break; case 'css': $outText = CSSMin::minify($inText); break; default: $this->error("No minifier defined for extension \"{$extension}\""); } fwrite($outFile, $outText); fclose($outFile); $this->output(" ok\n"); }
private function generate_file($files = array(), $file_name, $file_type = 'css', $type = '') { if (count($files) == 0) { // While the file wasn't actually created, // there weren't any errors, either. return true; } // Where to save the combined file to. $cache_path = $_SERVER['DOCUMENT_ROOT'] . '/' . self::$asset_base . '/' . self::$asset_cache_folder . '/'; // full file path - without the extension $file_path = $cache_path . $file_name; if (self::$ci->config->item("assets.{$type}_minify")) { $file_path .= ".min"; } $file_path .= "." . $file_type; $modified_time = 0; // Holds the last modified date of all included files. $actual_file_time = 0; // The modified time of the combined file. // If the combined file already exists, // we need to grab the last modified time. if (is_file($file_path)) { $actual_file_time = filemtime($file_path); } foreach ($files as $key => $file) { // Javascript if ($file_type == 'js') { if (is_array($file)) { $app_file = $file['server_path']; } else { $app_file = $_SERVER['DOCUMENT_ROOT'] . '/' . str_replace(base_url(), '', $file); } $app_file = strpos($app_file, '.js') ? $app_file : $app_file . '.js'; $files_array[$key] = $app_file; } else { $app_file = $file['server_path']; $files_array[$key] = $app_file; } if ($file == 'global') { $files_array[$key] = $app_file; } // By this point, we already know that the files exist, // so just grab the modified time. $modified_time = max(filemtime($app_file), $modified_time); } $asset_output = ''; if ($actual_file_time < $modified_time) { // write to the file foreach ($files_array as $key => $file) { $file_output = file_get_contents($file); if (!empty($file_output)) { $asset_output .= $file_output . "\n"; } } switch ($file_type) { case 'js': if (config_item('assets.js_minify')) { $asset_output = JSMin::minify($asset_output); } break; case 'css': if (config_item('assets.css_minify')) { $asset_output = CSSMin::minify($asset_output); } break; default: throw new LoaderException("Unknown file type - {$file_type}."); break; } self::$ci->load->helper('file'); if (!is_dir($cache_path)) { @mkdir($cache_path); } if (!write_file($file_path, $asset_output)) { return FALSE; } } elseif ($actual_file_time == 0) { return FALSE; } return TRUE; }
$mystep->pageStart(true); $type = $req->GetServer("QUERY_STRING"); $result = ""; $cache_file = ROOT_PATH . "/" . $setting['path']['cache'] . "script/" . $setting['info']['web']['idx'] . "_cache." . $type; $header = array('js' => 'Content-Type: application/x-javascript', 'css' => 'Content-Type: text/css', 'jpg' => 'Content-Type: image/jpg', 'gif' => 'Content-Type: image/gif', 'png' => 'Content-Type: image/png', 'jpeg' => 'Content-Type: image/jpeg', 'swf' => 'Content-Type: application/x-shockwave-flash'); if (isset($header[$type])) { header($header[$type]); } if (file_exists($cache_file) && filemtime($cache_file) + $etag_expires > $setting['info']['time_start'] / 1000) { $result = GetFile($cache_file); } else { switch ($type) { case "css": $css = $mystep->getCSS(); for ($i = 0, $m = count($css); $i < $m; $i++) { $result .= CSSMin::minify(GetFile($css[$i])); } break; case "js": $js = $mystep->getJS(); for ($i = 0, $m = count($js); $i < $m; $i++) { $result .= JSMin::minify(GetFile($js[$i])); } break; default: break; } if (!empty($result)) { WriteFile($cache_file, $result, "wb"); } }
private static function applyFilter($filter, $data, Config $config) { switch ($filter) { case 'minify-js': return JavaScriptMinifier::minify($data, $config->get('ResourceLoaderMinifierStatementsOnOwnLine'), $config->get('ResourceLoaderMinifierMaxLineLength')); case 'minify-css': return CSSMin::minify($data); } return $data; }
/** * Static access to the CSS minifier * @param string $source CSS source to minify * @param boolean $removeImports True to remove the import statements, false otherwise * @return string Minified CSS source */ public static function min($source, $removeImports = false) { $cssMinifier = new CSSMin(); return $cssMinifier->minify($source, $removeImports); }