43 <IfModule mod_expires.c> 45 ExpiresDefault "access plus 7 days" 55 if (!is_dir((PATH_site . $this->targetDirectory))) {
59 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'generateApacheHtaccess']) {
61 $htaccessPath = PATH_site . $this->targetDirectory .
'.htaccess';
62 if (!file_exists($htaccessPath)) {
69 if (extension_loaded(
'zlib') && $compressionLevel) {
70 $this->createGzipped = TRUE;
73 $this->gzipCompressionLevel = (int)$compressionLevel;
167 $filesToInclude = array();
168 foreach ($cssFiles as $key => $fileOptions) {
170 if (!empty($fileOptions[
'excludeFromConcatenation'])) {
176 if ((!isset($options[
'baseDirectories']) || $this->
checkBaseDirectory($filenameFromMainDir, array_merge($options[
'baseDirectories'], array($this->targetDirectory)))) && $fileOptions[
'media'] ===
'all') {
177 if ($fileOptions[
'forceOnTop']) {
178 array_unshift($filesToInclude, $filenameFromMainDir);
180 $filesToInclude[] = $filenameFromMainDir;
183 unset($cssFiles[$key]);
186 if (!empty($filesToInclude)) {
188 $targetFileRelative = $this->relativePath . $targetFile;
189 $concatenatedOptions = array(
190 'file' => $targetFileRelative,
191 'rel' =>
'stylesheet',
194 'excludeFromConcatenation' => TRUE,
195 'forceOnTop' => FALSE,
199 $cssFiles = array_merge(array($targetFileRelative => $concatenatedOptions), $cssFiles);
211 $filesToInclude = array();
212 foreach ($jsFiles as $key => $fileOptions) {
214 if (empty($fileOptions[
'section']) || !empty($fileOptions[
'excludeFromConcatenation'])) {
217 if (!isset($filesToInclude[$fileOptions[
'section']])) {
218 $filesToInclude[$fileOptions[
'section']] = array();
222 if ($fileOptions[
'forceOnTop']) {
223 array_unshift($filesToInclude[$fileOptions[
'section']], $filenameFromMainDir);
225 $filesToInclude[$fileOptions[
'section']][] = $filenameFromMainDir;
228 unset($jsFiles[$key]);
230 if (!empty($filesToInclude)) {
231 foreach ($filesToInclude as $section => $files) {
233 $targetFileRelative = $this->relativePath . $targetFile;
234 $concatenatedOptions = array(
235 'file' => $targetFileRelative,
236 'type' =>
'text/javascript',
237 'section' => $section,
239 'excludeFromConcatenation' => TRUE,
240 'forceOnTop' => FALSE,
244 $jsFiles = array_merge(array($targetFileRelative => $concatenatedOptions), $jsFiles);
281 $type = strtolower(trim($type,
'. '));
283 throw new \InvalidArgumentException(
'Error in TYPO3\\CMS\\Core\\Resource\\ResourceCompressor: No valid file type given for merged file', 1308957498);
288 foreach ($filesToInclude as $key => $filename) {
300 $filesToInclude[$key] = $localFilename;
307 $filename = $filesToInclude[$key];
310 if (@file_exists($filenameAbsolute)) {
311 $fileStatus = stat($filenameAbsolute);
312 $unique .= $filenameAbsolute . $fileStatus[
'mtime'] . $fileStatus[
'size'];
314 $unique .= $filenameAbsolute;
317 $targetFile = $this->targetDirectory .
'merged-' . md5($unique) .
'.' . $type;
319 if (!file_exists((PATH_site . $targetFile))) {
322 foreach ($filesToInclude as $filename) {
326 $contents = substr($contents, 3);
332 $concatenated .= LF . $contents;
335 if ($type ===
'css') {
350 $filesAfterCompression = array();
351 foreach ($cssFiles as $key => $fileOptions) {
353 if ($fileOptions[
'compress']) {
355 $fileOptions[
'compress'] = FALSE;
356 $fileOptions[
'file'] = $filename;
357 $filesAfterCompression[$filename] = $fileOptions;
359 $filesAfterCompression[$key] = $fileOptions;
362 return $filesAfterCompression;
380 if (@file_exists($filenameAbsolute)) {
381 $fileStatus = stat($filenameAbsolute);
382 $unique = $filenameAbsolute . $fileStatus[
'mtime'] . $fileStatus[
'size'];
384 $unique = $filenameAbsolute;
388 $targetFile = $this->targetDirectory . $pathinfo[
'filename'] .
'-' . md5($unique) .
'.css';
390 if (!file_exists((PATH_site . $targetFile)) || $this->createGzipped && !file_exists((PATH_site . $targetFile .
'.gzip'))) {
393 $contents = str_replace(CR,
'', $contents);
397 $contents = preg_replace_callback(
'% 398 # One-regex-to-rule-them-all! - version: 20100220_0100 399 # Group 1: Match a double quoted string. 400 ("[^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+") | # or... 401 # Group 2: Match a single quoted string. 402 (\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*+)*+\') | # or... 403 # Group 3: Match a regular non-MacIE5-hack comment. 404 (/\\*[^\\\\*]*+\\*++(?:[^\\\\*/][^\\\\*]*+\\*++)*+/) | # or... 405 # Group 4: Match a MacIE5-type1 comment. 406 (/\\*(?:[^*\\\\]*+\\**+(?!/))*+\\\\[^*]*+\\*++(?:[^*/][^*]*+\\*++)*+/(?<!\\\\\\*/)) | # or... 407 # Group 5: Match a MacIE5-type2 comment. 408 (/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/(?<=\\\\\\*/)) # folllowed by... 409 # Group 6: Match everything up to final closing regular comment 410 ([^/]*+(?:(?!\\*)/[^/]*+)*?) 411 # Group 7: Match final closing regular comment 412 (/\\*[^/]++(?:(?<!\\*)/(?!\\*)[^/]*+)*+/(?<=(?<!\\\\)\\*/)) | # or... 413 # Group 8: Match regular non-string, non-comment text. 414 ([^"\'/]*+(?:(?!/\\*)/[^"\'/]*+)*+) 415 %Ssx', array(
'self',
'compressCssPregCallback'), $contents);
417 $contents = preg_replace(
'/^\\s++/',
'', $contents);
419 $contents = preg_replace(
'/[ \\t]*+\\n\\s*+/S',
' 422 $contents = preg_replace(
'/(?<!\\s)\\s*+$/S',
' 426 if (strpos($filename, $this->targetDirectory) === FALSE) {
427 $filenameRelativeToMainDir = substr($filename, strlen($this->backPath));
446 } elseif ($matches[2]) {
449 } elseif ($matches[3]) {
453 } elseif ($matches[4]) {
458 } elseif ($matches[5]) {
460 $matches[6] = preg_replace(
'/\\s++([+>{};,)])/S',
'$1', $matches[6]);
462 $matches[6] = preg_replace(
'/([+>{}:;,(])\\s++/S',
'$1', $matches[6]);
464 $matches[6] = preg_replace(
'/;?\\}/S',
'} 468 /*T2\\*/' . $matches[6] .
' 471 } elseif (isset($matches[8])) {
473 $matches[8] = preg_replace(
'/^\\s++/',
'', $matches[8]);
475 $matches[8] = preg_replace(
'/\\s++$/',
'', $matches[8]);
477 $matches[8] = preg_replace(
'/\\s{2,}+/',
' ', $matches[8]);
479 $matches[8] = preg_replace(
'/\\s++([+>{};,)])/S',
'$1', $matches[8]);
481 $matches[8] = preg_replace(
'/([+>{}:;,(])\\s++/S',
'$1', $matches[8]);
483 $matches[8] = preg_replace(
'/;?\\}/S',
'} 488 return $matches[0] .
' 489 /* ERROR! Unexpected _proccess_css_minify() parameter */ 500 $filesAfterCompression = array();
501 foreach ($jsFiles as $fileName => $fileOptions) {
503 if ($fileOptions[
'compress']) {
504 $compressedFilename = $this->
compressJsFile($fileOptions[
'file']);
505 $fileOptions[
'compress'] = FALSE;
506 $fileOptions[
'file'] = $compressedFilename;
507 $filesAfterCompression[$compressedFilename] = $fileOptions;
509 $filesAfterCompression[$fileName] = $fileOptions;
512 return $filesAfterCompression;
524 if (@file_exists($filenameAbsolute)) {
525 $fileStatus = stat($filenameAbsolute);
526 $unique = $filenameAbsolute . $fileStatus[
'mtime'] . $fileStatus[
'size'];
528 $unique = $filenameAbsolute;
531 $targetFile = $this->targetDirectory . $pathinfo[
'filename'] .
'-' . md5($unique) .
'.js';
533 if (!file_exists((PATH_site . $targetFile)) || $this->createGzipped && !file_exists((PATH_site . $targetFile .
'.gzip'))) {
548 if (empty($this->backPath)) {
552 if (strpos($filename, $this->backPath) === 0) {
553 $file = str_replace($this->backPath,
'', $filename);
559 if (is_file(realpath(PATH_site . TYPO3_mainDir . $filename))) {
560 $filename = TYPO3_mainDir . $filename;
563 $backPath = str_replace(TYPO3_mainDir,
'', $this->backPath);
564 $file = str_replace(
$backPath,
'', $filename);
565 if (substr($file, 0, 3) ===
'../') {
568 $file = PATH_site . $file;
571 if (is_file($file)) {
572 $mainDirDepth = substr_count(TYPO3_mainDir,
'/');
573 return str_repeat(
'../', $mainDirDepth) . str_replace(PATH_site,
'', $file);
576 return substr($filename, strlen($this->backPath));
587 foreach ($baseDirectories as $baseDirectory) {
604 $mainDir =
TYPO3_MODE ===
'BE' ? TYPO3_mainDir :
'';
605 $newDir =
'../../' . $mainDir . $oldDir;
607 if (stripos($contents,
'url') !== FALSE) {
608 $regex =
'/url(\\(\\s*["\']?(?!\\/)([^"\']+)["\']?\\s*\\))/iU';
612 if (stripos($contents,
'@import') !== FALSE) {
613 $regex =
'/@import\\s*(["\']?(?!\\/)([^"\']+)["\']?)/i';
630 $replacements = array();
631 $wrap = explode(
'|', $wrap);
632 preg_match_all($regex, $contents, $matches);
633 foreach ($matches[2] as $matchCount => $match) {
635 $match = trim($match,
'\'" '); 636 // we must not rewrite paths containing ":
" or "url(
", e.g. data URIs (see RFC 2397) 637 if (strpos($match, ':') === FALSE && !preg_match('/url\\s*\\(/i', $match)) { 638 $newPath = GeneralUtility::resolveBackPath($newDir . $match); 639 $replacements[$matches[1][$matchCount]] = $wrap[0] . $newPath . $wrap[1]; 642 // replace URL paths in content 643 if (!empty($replacements)) { 644 $contents = str_replace(array_keys($replacements), array_values($replacements), $contents); 656 protected function cssFixStatements($contents) { 658 $comment = LF . '/* moved by compressor */' . LF; 659 // nothing to do, so just return contents 660 if (stripos($contents, '@charset') === FALSE && stripos($contents, '@import') === FALSE && stripos($contents, '@namespace') === FALSE) { 663 $regex = '/@(charset|import|namespace)\\s*(url)?\\s*\\(?\\s*["\
']?[^"\'\\)]+["\']?\\s*\\)?\\s*;/i';
664 preg_match_all($regex, $contents, $matches);
665 if (!empty($matches[0])) {
667 $contents = str_replace($matches[0],
'', $contents);
669 $contents = $comment . implode($comment, $matches[0]) . LF . trim($contents);
684 if ($this->createGzipped) {
700 return $filename .
'.gzip';
714 $filename = $this->targetDirectory .
'external-' . md5($url);
716 if (!file_exists(PATH_site . $filename) &&
compressJsFile($filename)
setRelativePath($relativePath)
static writeFile($file, $content, $changePermissions=FALSE)
createMergedJsFile(array $filesToInclude)
compressJsFiles(array $jsFiles)
static isFirstPartOfStr($str, $partStr)
static compressCssPregCallback($matches)
findAndReplaceUrlPathsByRegex($contents, $regex, $newDir, $wrap='|')
static canBeInterpretedAsInteger($var)
static getIndpEnv($getEnvName)
createMergedCssFile(array $filesToInclude)
static pathinfo($path, $options=NULL)
concatenateJsFiles(array $jsFiles)
static isOnCurrentHost($url)
retrieveExternalFile($url)
getFilenameFromMainDir($filename)
static getUrl($url, $includeHeader=0, $requestHeaders=FALSE, &$report=NULL)
returnFileReference($filename)
compressCssFile($filename)
checkBaseDirectory($filename, array $baseDirectories)
createMergedFile(array $filesToInclude, $type='css')
compressCssFiles(array $cssFiles)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
cssFixRelativeUrlPaths($contents, $oldDir)
writeFileAndCompressed($filename, $contents)
static resolveBackPath($pathStr)
concatenateCssFiles(array $cssFiles, array $options=array())
cssFixStatements($contents)