26 public $disableRegisterFiles =
false;
64 public $splitDomainName;
95 'ImportImports' =>
false,
96 'RemoveComments' =>
true,
97 'RemoveEmptyRulesets' =>
true,
98 'RemoveEmptyAtBlocks' =>
true,
99 'ConvertLevel3AtKeyframes' =>
false,
100 'ConvertLevel3Properties' =>
false,
102 'RemoveLastDelarationSemiColon' =>
true
110 'ConvertFontWeight' =>
true,
111 'ConvertHslColors' =>
true,
112 'ConvertRgbColors' =>
true,
113 'ConvertNamedColors' =>
true,
114 'CompressColorValues' =>
true,
115 'CompressUnitValues' =>
true,
116 'CompressExpressionValues' =>
true,
119 private $_timestamps = array();
120 private $_gccFile = array();
130 if ($this->disableRegisterFiles && !$force) {
136 public function registerCssFile($file, $media =
'', $timestamp = null, $combine =
true, $gccFile =
false, $force =
false)
138 if ($this->disableRegisterFiles && !$force) {
142 $this->_gccFile[$file] = $gccFile;
143 if ($combine ==
false) {
144 $this->excludeFiles[] = $file;
145 } elseif ($timestamp !== null)
146 $this->_timestamps['css'][$file] = $timestamp;
147 return parent::registerCssFile($file, $media);
150 public function registerScriptFile($file, $position = self::POS_HEAD, $timestamp = null, $combine = true, $gccFile = false, $force = false)
152 if ($this->disableRegisterFiles && !$force) {
156 $this->_gccFile[$file] = $gccFile;
157 if ($combine ==
false) {
158 $this->excludeFiles[] = $file;
159 } elseif ($timestamp !== null)
160 $this->_timestamps['js'][$file] = $timestamp;
161 return parent::registerScriptFile($file);
172 if ($this->combineFiles) {
173 $this->combineJs = $this->combineCss =
true;
176 $this->processJs(parent::POS_HEAD);
190 $this->processJs(parent::POS_BEGIN);
202 $this->processJs(parent::POS_END);
211 private function processJs($pos)
213 if ($this->combineJs) {
214 if (isset($this->scriptFiles[$pos]) && count($this->scriptFiles[$pos]) !== 0) {
216 foreach ($this->scriptFiles[$pos] as $key => $file) {
217 if (!in_array($file, $this->excludeFiles)) {
218 $jsFiles[$key] = $file;
221 unset($this->scriptFiles[$pos][$key]);
222 $this->scriptFiles[$pos][$this->addSplitDomain($file)] = $this->addSplitDomain($file);
225 $this->combineAndCompress(
'js', $jsFiles);
230 private function processCss()
232 if ($this->combineCss) {
233 if (count($this->cssFiles) !== 0) {
235 foreach ($this->cssFiles as $url => $media) {
236 if (!in_array($url, $this->excludeFiles)) {
237 $cssFiles[$media][$url] = $url;
240 unset($this->cssFiles[$url]);
241 $this->cssFiles[$this->addSplitDomain($url)] = $media;
244 foreach ($cssFiles as $media => $url) {
245 $this->combineAndCompress(
'css', $url);
258 private function combineAndCompress($type, $urls)
260 $this->fileUrl or $this->fileUrl = $this->getCoreScriptUrl();
261 $this->basePath or $this->basePath = realpath($_SERVER[
'DOCUMENT_ROOT']);
262 $this->filePath or $this->filePath = $this->basePath .
$this->fileUrl;
264 $optionsHash = ($type ==
'js') ?
265 md5($this->basePath . $this->compressCombinedJs . $this->ttlDays . $this->prefix) :
266 md5($this->basePath . $this->compressCombinedCss . $this->ttlDays . $this->prefix . serialize($this->cssMinFilters) . serialize($this->cssMinPlugins));
267 $combineHash = md5(implode(
'', $urls));
268 $fileName = $this->prefix . md5($combineHash . $optionsHash) .
".$type";
269 $timestampHash = !empty($this->_timestamps[$type]) ? md5(implode(
'', $this->_timestamps[$type])) :
'';
271 $timestampChanged = Yii::app()->cache->get($fileName) != $timestampHash;
272 $fileNotExists = (file_exists($this->filePath .
'/' . $fileName)) ?
false :
true;
273 if ($fileNotExists || $timestampChanged) {
274 $this->garbageCollect($type);
276 foreach ($urls as $file) {
277 $combinedFile .= $this->_getFileContent($file);
279 if ($type ==
'js' && $this->compressCombinedJs) {
280 $combinedFile = $this->minifyJs($combinedFile);
281 } elseif ($type ==
'css' && $this->compressCombinedCss) {
282 $combinedFile = $this->minifyCss($combinedFile);
284 file_put_contents($this->filePath .
'/' . $fileName, $combinedFile);
285 Yii::app()->cache->set($fileName, $timestampHash);
287 foreach ($urls as $url)
288 $this->scriptMap[basename($url)] = $this->addSplitDomain($this->fileUrl .
'/' . $fileName);
290 $this->remapScripts();
293 private function garbageCollect($type)
295 $files = CFileHelper::findFiles($this->filePath, array(
'fileTypes' => array($type),
'level' => 0));
296 foreach ($files as $file) {
297 if (strpos($file, $this->prefix) !==
false && $this->fileTTL($file)) {
308 private function addSplitDomain($url)
310 if ($this->splitDomainName && !$this->isRemoteFile($url)) {
311 return (Yii::app()->request->getIsSecureConnection() ?
'https' :
'http') .
'://' . $this->splitDomainName . $url;
327 private function _getFileContent($file)
329 if ($this->isRemoteFile($file)) {
330 return file_get_contents($file);
331 } elseif (isset($this->_gccFile[$file]) && $this->_gccFile[$file]) {
332 $content = Yii::app()->getModule(
'contentSource')->getContent($file);
333 if($content ===
false){
334 Yii::trace(
'CMS static file not exists '. $file,
'compressing');
337 return file_get_contents($content->getFile());
339 return file_get_contents($content->getFile());
341 return file_get_contents(Yii::getPathOfAlias(
'webroot') .
'/' . $file);
351 private function fileTTL($file)
353 if (!file_exists($file)) {
356 $ttl = $this->ttlDays * 60 * 60 * 24;
357 return ((fileatime($file) + $ttl) < time()) ?
true :
false;
365 private function minifyJs($js)
367 Yii::import($this->jsMinPath);
376 private function minifyCss($css)
378 Yii::import($this->jsMinPath);
379 Yii::import($this->cssMinPath);
380 return cssmin::minify($css, $this->cssMinFilters, $this->cssMinPlugins);
388 private function isRemoteFile($file)
390 return (strpos($file,
'http://') === 0 || strpos($file,
'https://') === 0) ?
true :
false;
395 public function getCoreScriptUrl()
397 if ($this->_baseUrl !== null) {
398 return $this->_baseUrl;
400 return $this->_baseUrl = Yii::app()->getAssetManager()->publish(YII_PATH .
'/web/js/source',
true);