‪TYPO3CMS  10.4
ResourceCompressor.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
23 
29 {
33  protected ‪$targetDirectory = 'typo3temp/assets/compressed/';
34 
38  protected ‪$rootPath = '';
39 
45  protected ‪$createGzipped = false;
46 
50  protected ‪$gzipCompressionLevel = -1;
51 
55  protected ‪$htaccessTemplate = '<FilesMatch "\\.(js|css)(\\.gzip)?$">
56  <IfModule mod_expires.c>
57  ExpiresActive on
58  ExpiresDefault "access plus 7 days"
59  </IfModule>
60  FileETag MTime Size
61 </FilesMatch>';
62 
66  public function ‪__construct()
67  {
68  // we check for existence of our targetDirectory
69  if (!is_dir(‪Environment::getPublicPath() . '/' . $this->targetDirectory)) {
70  ‪GeneralUtility::mkdir_deep(‪Environment::getPublicPath() . '/' . $this->targetDirectory);
71  }
72  // if enabled, we check whether we should auto-create the .htaccess file
73  if (‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['generateApacheHtaccess']) {
74  // check whether .htaccess exists
75  $htaccessPath = ‪Environment::getPublicPath() . '/' . $this->targetDirectory . '.htaccess';
76  if (!file_exists($htaccessPath)) {
77  ‪GeneralUtility::writeFile($htaccessPath, $this->htaccessTemplate);
78  }
79  }
80  // decide whether we should create gzipped versions or not
81  $compressionLevel = ‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['compressionLevel'];
82  // we need zlib for gzencode()
83  if (extension_loaded('zlib') && $compressionLevel) {
84  $this->createGzipped = true;
85  // $compressionLevel can also be TRUE
86  if (‪MathUtility::canBeInterpretedAsInteger($compressionLevel)) {
87  $this->gzipCompressionLevel = (int)$compressionLevel;
88  }
89  }
90  $this->‪setRootPath(TYPO3_MODE === 'BE' ? ‪Environment::getBackendPath() . '/' : ‪Environment::getPublicPath() . '/');
91  }
92 
98  public function ‪setRootPath(‪$rootPath)
99  {
100  if (is_string(‪$rootPath)) {
101  $this->rootPath = ‪$rootPath;
102  }
103  }
104 
111  public function ‪concatenateCssFiles(array $cssFiles)
112  {
113  $filesToIncludeByType = ['all' => []];
114  foreach ($cssFiles as $key => $fileOptions) {
115  // no concatenation allowed for this file, so continue
116  if (!empty($fileOptions['excludeFromConcatenation'])) {
117  continue;
118  }
119  $filenameFromMainDir = $this->‪getFilenameFromMainDir($fileOptions['file']);
120  $type = isset($fileOptions['media']) ? strtolower($fileOptions['media']) : 'all';
121  if (!isset($filesToIncludeByType[$type])) {
122  $filesToIncludeByType[$type] = [];
123  }
124  if (!empty($fileOptions['forceOnTop'])) {
125  array_unshift($filesToIncludeByType[$type], $filenameFromMainDir);
126  } else {
127  $filesToIncludeByType[$type][] = $filenameFromMainDir;
128  }
129  // remove the file from the incoming file array
130  unset($cssFiles[$key]);
131  }
132  foreach ($filesToIncludeByType as $mediaOption => $filesToInclude) {
133  if (empty($filesToInclude)) {
134  continue;
135  }
136  $targetFile = $this->‪createMergedCssFile($filesToInclude);
137  $concatenatedOptions = [
138  'file' => $targetFile,
139  'rel' => 'stylesheet',
140  'media' => $mediaOption,
141  'compress' => true,
142  'excludeFromConcatenation' => true,
143  'forceOnTop' => false,
144  'allWrap' => ''
145  ];
146  // place the merged stylesheet on top of the stylesheets
147  $cssFiles = array_merge($cssFiles, [$targetFile => $concatenatedOptions]);
148  }
149  return $cssFiles;
150  }
151 
158  public function ‪concatenateJsFiles(array $jsFiles)
159  {
160  $concatenatedJsFileIsAsync = false;
161  $allFilesToConcatenateAreAsync = true;
162  $filesToInclude = [];
163  foreach ($jsFiles as $key => $fileOptions) {
164  // invalid section found or no concatenation allowed, so continue
165  if (empty($fileOptions['section']) || !empty($fileOptions['excludeFromConcatenation']) || !empty($fileOptions['nomodule']) || !empty($fileOptions['defer'])) {
166  continue;
167  }
168  if (!isset($filesToInclude[$fileOptions['section']])) {
169  $filesToInclude[$fileOptions['section']] = [];
170  }
171  $filenameFromMainDir = $this->‪getFilenameFromMainDir($fileOptions['file']);
172  if (!empty($fileOptions['forceOnTop'])) {
173  array_unshift($filesToInclude[$fileOptions['section']], $filenameFromMainDir);
174  } else {
175  $filesToInclude[$fileOptions['section']][] = $filenameFromMainDir;
176  }
177  if (!empty($fileOptions['async']) && (bool)$fileOptions['async']) {
178  $concatenatedJsFileIsAsync = true;
179  } else {
180  $allFilesToConcatenateAreAsync = false;
181  }
182  // remove the file from the incoming file array
183  unset($jsFiles[$key]);
184  }
185  if (!empty($filesToInclude)) {
186  $defaultTypeAttributeForJavaScript = $this->‪getJavaScriptFileType();
187  foreach ($filesToInclude as $section => $files) {
188  $targetFile = $this->‪createMergedJsFile($files);
189  $concatenatedOptions = [
190  'file' => $targetFile,
191  'type' => $defaultTypeAttributeForJavaScript,
192  'section' => $section,
193  'compress' => true,
194  'excludeFromConcatenation' => true,
195  'forceOnTop' => false,
196  'allWrap' => '',
197  'async' => $concatenatedJsFileIsAsync && $allFilesToConcatenateAreAsync,
198  ];
199  // place the merged javascript on top of the JS files
200  $jsFiles = array_merge([$targetFile => $concatenatedOptions], $jsFiles);
201  }
202  }
203  return $jsFiles;
204  }
205 
212  protected function ‪createMergedCssFile(array $filesToInclude)
213  {
214  return $this->‪createMergedFile($filesToInclude, 'css');
215  }
216 
223  protected function ‪createMergedJsFile(array $filesToInclude)
224  {
225  return $this->‪createMergedFile($filesToInclude, 'js');
226  }
227 
237  protected function ‪createMergedFile(array $filesToInclude, $type = 'css')
238  {
239  // Get file type
240  $type = strtolower(trim($type, '. '));
241  if (empty($type)) {
242  throw new \InvalidArgumentException('No valid file type given for files to be merged.', 1308957498);
243  }
244  // we add up the filenames, filemtimes and filesizes to later build a checksum over
245  // it and include it in the temporary file name
246  $unique = '';
247  foreach ($filesToInclude as $key => $filename) {
248  if (‪GeneralUtility::isValidUrl($filename)) {
249  // check if it is possibly a local file with fully qualified URL
250  if (GeneralUtility::isOnCurrentHost($filename) &&
251  GeneralUtility::isFirstPartOfStr(
252  $filename,
253  GeneralUtility::getIndpEnv('TYPO3_SITE_URL')
254  )
255  ) {
256  // attempt to turn it into a local file path
257  $localFilename = substr($filename, strlen(GeneralUtility::getIndpEnv('TYPO3_SITE_URL')));
258  if (@is_file(GeneralUtility::resolveBackPath($this->rootPath . $localFilename))) {
259  $filesToInclude[$key] = $localFilename;
260  } else {
261  $filesToInclude[$key] = $this->‪retrieveExternalFile($filename);
262  }
263  } else {
264  $filesToInclude[$key] = $this->‪retrieveExternalFile($filename);
265  }
266  $filename = $filesToInclude[$key];
267  }
268  $filenameAbsolute = GeneralUtility::resolveBackPath($this->rootPath . $filename);
269  if (@file_exists($filenameAbsolute)) {
270  $fileStatus = stat($filenameAbsolute);
271  $unique .= $filenameAbsolute . $fileStatus['mtime'] . $fileStatus['size'];
272  } else {
273  $unique .= $filenameAbsolute;
274  }
275  }
276  $targetFile = $this->targetDirectory . 'merged-' . md5($unique) . '.' . $type;
277  // if the file doesn't already exist, we create it
278  if (!file_exists(‪Environment::getPublicPath() . '/' . $targetFile)) {
279  $concatenated = '';
280  // concatenate all the files together
281  foreach ($filesToInclude as $filename) {
282  $filenameAbsolute = GeneralUtility::resolveBackPath($this->rootPath . $filename);
283  $filename = ‪PathUtility::stripPathSitePrefix($filenameAbsolute);
284  $contents = (string)file_get_contents($filenameAbsolute);
285  // remove any UTF-8 byte order mark (BOM) from files
286  if (strpos($contents, "\xEF\xBB\xBF") === 0) {
287  $contents = substr($contents, 3);
288  }
289  // only fix paths if files aren't already in typo3temp (already processed)
290  if ($type === 'css' && !GeneralUtility::isFirstPartOfStr($filename, $this->targetDirectory)) {
291  $contents = $this->‪cssFixRelativeUrlPaths($contents, $filename);
292  }
293  $concatenated .= LF . $contents;
294  }
295  // move @charset, @import and @namespace statements to top of new file
296  if ($type === 'css') {
297  $concatenated = $this->‪cssFixStatements($concatenated);
298  }
299  ‪GeneralUtility::writeFile(‪Environment::getPublicPath() . '/' . $targetFile, $concatenated);
300  }
301  return $targetFile;
302  }
303 
310  public function ‪compressCssFiles(array $cssFiles)
311  {
312  $filesAfterCompression = [];
313  foreach ($cssFiles as $key => $fileOptions) {
314  // if compression is enabled
315  if ($fileOptions['compress']) {
316  $filename = $this->‪compressCssFile($fileOptions['file']);
317  $fileOptions['compress'] = false;
318  $fileOptions['file'] = $filename;
319  $filesAfterCompression[$filename] = $fileOptions;
320  } else {
321  $filesAfterCompression[$key] = $fileOptions;
322  }
323  }
324  return $filesAfterCompression;
325  }
326 
339  public function ‪compressCssFile($filename)
340  {
341  // generate the unique name of the file
342  $filenameAbsolute = GeneralUtility::resolveBackPath($this->rootPath . $this->‪getFilenameFromMainDir($filename));
343  if (@file_exists($filenameAbsolute)) {
344  $fileStatus = stat($filenameAbsolute);
345  $unique = $filenameAbsolute . $fileStatus['mtime'] . $fileStatus['size'];
346  } else {
347  $unique = $filenameAbsolute;
348  }
349  // make sure it is again the full filename
350  $filename = ‪PathUtility::stripPathSitePrefix($filenameAbsolute);
351 
352  $pathinfo = ‪PathUtility::pathinfo($filenameAbsolute);
353  $targetFile = $this->targetDirectory . $pathinfo['filename'] . '-' . md5($unique) . '.css';
354  // only create it, if it doesn't exist, yet
355  if (!file_exists(‪Environment::getPublicPath() . '/' . $targetFile) || $this->createGzipped && !file_exists(‪Environment::getPublicPath() . '/' . $targetFile . '.gzip')) {
356  $contents = $this->‪compressCssString((string)file_get_contents($filenameAbsolute));
357  if (strpos($filename, $this->targetDirectory) === false) {
358  $contents = $this->‪cssFixRelativeUrlPaths($contents, $filename);
359  }
360  $this->‪writeFileAndCompressed($targetFile, $contents);
361  }
362  return $this->‪returnFileReference($targetFile);
363  }
364 
371  public function ‪compressJsFiles(array $jsFiles)
372  {
373  $filesAfterCompression = [];
374  foreach ($jsFiles as $fileName => $fileOptions) {
375  // If compression is enabled
376  if ($fileOptions['compress']) {
377  $compressedFilename = $this->‪compressJsFile($fileOptions['file']);
378  $fileOptions['compress'] = false;
379  $fileOptions['file'] = $compressedFilename;
380  $filesAfterCompression[$compressedFilename] = $fileOptions;
381  } else {
382  $filesAfterCompression[$fileName] = $fileOptions;
383  }
384  }
385  return $filesAfterCompression;
386  }
387 
394  public function ‪compressJsFile($filename)
395  {
396  // generate the unique name of the file
397  $filenameAbsolute = GeneralUtility::resolveBackPath($this->rootPath . $this->‪getFilenameFromMainDir($filename));
398  if (@file_exists($filenameAbsolute)) {
399  $fileStatus = stat($filenameAbsolute);
400  $unique = $filenameAbsolute . $fileStatus['mtime'] . $fileStatus['size'];
401  } else {
402  $unique = $filenameAbsolute;
403  }
404  $pathinfo = ‪PathUtility::pathinfo($filename);
405  $targetFile = $this->targetDirectory . $pathinfo['filename'] . '-' . md5($unique) . '.js';
406  // only create it, if it doesn't exist, yet
407  if (!file_exists(‪Environment::getPublicPath() . '/' . $targetFile) || $this->createGzipped && !file_exists(‪Environment::getPublicPath() . '/' . $targetFile . '.gzip')) {
408  $contents = (string)file_get_contents($filenameAbsolute);
409  $this->‪writeFileAndCompressed($targetFile, $contents);
410  }
411  return $this->‪returnFileReference($targetFile);
412  }
413 
420  protected function ‪getFilenameFromMainDir($filename)
421  {
422  /*
423  * The various paths may have those values (e.g. if TYPO3 is installed in a subdir)
424  * - docRoot = /var/www/html/
425  * - Environment::getPublicPath() = /var/www/html/sites/site1/
426  * - $this->rootPath = /var/www/html/sites/site1/typo3
427  *
428  * The file names passed into this function may be either:
429  * - relative to $this->rootPath
430  * - relative to Environment::getPublicPath()
431  * - relative to docRoot
432  */
433  $docRoot = GeneralUtility::getIndpEnv('TYPO3_DOCUMENT_ROOT');
434  $fileNameWithoutSlash = ltrim($filename, '/');
435 
436  // if the file is an absolute reference within the docRoot
437  $absolutePath = $docRoot . '/' . $fileNameWithoutSlash;
438  // If the $filename stems from a call to PathUtility::getAbsoluteWebPath() it has a leading slash,
439  // hence isAbsolutePath() results in true, which is obviously wrong. Check file existence to be sure.
440  // Calling is_file without @ for a path starting with '../' causes a PHP Warning when using open_basedir restriction
441  if (‪PathUtility::isAbsolutePath($filename) && @is_file($filename)) {
442  $absolutePath = $filename;
443  }
444  if (@is_file($absolutePath)) {
445  if (strpos($absolutePath, $this->rootPath) === 0) {
446  // the path is within the current root path, simply strip rootPath off
447  return substr($absolutePath, strlen($this->rootPath));
448  }
449  // the path is not within the root path, strip off the site path, the remaining logic below
450  // takes care about adjusting the path correctly.
451  $filename = substr($absolutePath, strlen(‪Environment::getPublicPath() . '/'));
452  }
453  // if the file exists in the root path, just return the $filename
454  if (is_file($this->rootPath . $fileNameWithoutSlash)) {
455  return $fileNameWithoutSlash;
456  }
457  // if the file is from a special TYPO3 internal directory, add the missing typo3/ prefix
458  if (is_file((string)realpath(‪Environment::getBackendPath() . '/' . $filename))) {
459  $filename = 'typo3/' . $filename;
460  }
461  // build the file path relative to the public web path
462  if (strpos($filename, 'EXT:') === 0) {
463  $file = GeneralUtility::getFileAbsFileName($filename);
464  } elseif (strpos($filename, '../') === 0) {
465  $file = GeneralUtility::resolveBackPath(‪Environment::getBackendPath() . '/' . $filename);
466  } else {
467  $file = ‪Environment::getPublicPath() . '/' . $filename;
468  }
469 
470  // check if the file exists, and if so, return the path relative to current PHP script
471  if (is_file($file)) {
472  return rtrim((string)‪PathUtility::getRelativePathTo($file), '/');
473  }
474  // none of above conditions were met, fallback to default behaviour
475  return $filename;
476  }
477 
485  protected function ‪checkBaseDirectory($filename, array $baseDirectories)
486  {
487  foreach ($baseDirectories as $baseDirectory) {
488  // check, if $filename starts with base directory
489  if (GeneralUtility::isFirstPartOfStr($filename, $baseDirectory)) {
490  return true;
491  }
492  }
493  return false;
494  }
495 
501  protected function ‪cssFixRelativeUrlPaths(string $contents, string $filename): string
502  {
503  $newDir = '../../../' . ‪PathUtility::dirname($filename) . '/';
504  return $this->‪getPathFixer()->fixRelativeUrlPaths($contents, $newDir);
505  }
506 
514  protected function ‪cssFixStatements($contents)
515  {
516  $matches = [];
517  $comment = LF . '/* moved by compressor */' . LF;
518  // nothing to do, so just return contents
519  if (stripos($contents, '@charset') === false && stripos($contents, '@import') === false && stripos($contents, '@namespace') === false) {
520  return $contents;
521  }
522  $regex = '/@(charset|import|namespace)\\s*(url)?\\s*\\(?\\s*["\']?[^"\'\\)]+["\']?\\s*\\)?\\s*;/i';
523  preg_match_all($regex, $contents, $matches);
524  if (!empty($matches[0])) {
525  // Ensure correct order of @charset, @namespace and @import
526  $charset = '';
527  $namespaces = [];
528  $imports = [];
529  foreach ($matches[1] as $index => $keyword) {
530  switch ($keyword) {
531  case 'charset':
532  if (empty($charset)) {
533  $charset = $matches[0][$index];
534  }
535  break;
536  case 'namespace':
537  $namespaces[] = $matches[0][$index];
538  break;
539  case 'import':
540  $imports[] = $matches[0][$index];
541  break;
542  }
543  }
544 
545  $namespaces = !empty($namespaces) ? implode('', $namespaces) . $comment : '';
546  $imports = !empty($imports) ? implode('', $imports) . $comment : '';
547  // remove existing statements
548  $contents = str_replace($matches[0], '', $contents);
549  // add statements to the top of contents in the order they occur in original file
550  $contents =
551  $charset
552  . $comment
553  . $namespaces
554  . $imports
555  . trim($contents);
556  }
557  return $contents;
558  }
559 
566  protected function ‪writeFileAndCompressed($filename, $contents)
567  {
568  // write uncompressed file
569  ‪GeneralUtility::writeFile(‪Environment::getPublicPath() . '/' . $filename, $contents);
570  if ($this->createGzipped) {
571  // create compressed version
572  ‪GeneralUtility::writeFile(‪Environment::getPublicPath() . '/' . $filename . '.gzip', (string)gzencode($contents, $this->gzipCompressionLevel));
573  }
574  }
575 
583  protected function ‪returnFileReference($filename)
584  {
585  // if the client accepts gzip and we can create gzipped files, we give him compressed versions
586  if ($this->createGzipped && strpos(GeneralUtility::getIndpEnv('HTTP_ACCEPT_ENCODING'), 'gzip') !== false) {
587  $filename .= '.gzip';
588  }
589  return ‪PathUtility::getRelativePath($this->rootPath, ‪Environment::getPublicPath() . '/') . $filename;
590  }
591 
598  protected function ‪retrieveExternalFile($url)
599  {
600  $externalContent = ‪GeneralUtility::getUrl($url);
601  $filename = $this->targetDirectory . 'external-' . md5($url);
602  // Write only if file does not exist OR md5 of the content is not the same as fetched one
603  if (!file_exists(‪Environment::getPublicPath() . '/' . $filename)
604  || !hash_equals(md5((string)file_get_contents(‪Environment::getPublicPath() . '/' . $filename)), md5($externalContent))
605  ) {
606  ‪GeneralUtility::writeFile(‪Environment::getPublicPath() . '/' . $filename, $externalContent);
607  }
608  return $filename;
609  }
610 
617  protected function ‪compressCssString($contents)
618  {
619  // Perform some safe CSS optimizations.
620  // Regexp to match comment blocks.
621  $comment = '/\*[^*]*\*+(?:[^/*][^*]*\*+)*/';
622  // Regexp to match double quoted strings.
623  $double_quot = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
624  // Regexp to match single quoted strings.
625  $single_quot = "'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'";
626  // Strip all comment blocks, but keep double/single quoted strings.
627  $contents = (string)preg_replace(
628  "<($double_quot|$single_quot)|$comment>Ss",
629  '$1',
630  $contents
631  );
632  // Remove certain whitespace.
633  // There are different conditions for removing leading and trailing
634  // whitespace.
635  // @see https://php.net/manual/regexp.reference.subpatterns.php
636  $contents = (string)preg_replace(
637  '<
638  # Strip leading and trailing whitespace.
639  \s*([@{};,])\s*
640  # Strip only leading whitespace from:
641  # - Closing parenthesis: Retain "@media (bar) and foo".
642  | \s+([\‍)])
643  # Strip only trailing whitespace from:
644  # - Opening parenthesis: Retain "@media (bar) and foo".
645  # - Colon: Retain :pseudo-selectors.
646  | ([\‍(:])\s+
647  >xS',
648  // Only one of the three capturing groups will match, so its reference
649  // will contain the wanted value and the references for the
650  // two non-matching groups will be replaced with empty strings.
651  '$1$2$3',
652  $contents
653  );
654  // End the file with a new line.
655  $contents = trim($contents);
656  // Ensure file ends in newline.
657  $contents .= LF;
658  return $contents;
659  }
660 
670  protected function ‪getJavaScriptFileType(): string
671  {
672  if (TYPO3_MODE === 'BE' || !isset(‪$GLOBALS['TSFE']) || !(‪$GLOBALS['TSFE'] instanceof TypoScriptFrontendController)) {
673  // Backend (or at least no TSFE), always HTML5
674  return '';
675  }
676  if ((‪$GLOBALS['TSFE']->config['config']['doctype'] ?? 'html5') === 'html5') {
677  return '';
678  }
679  return 'text/javascript';
680  }
681 
682  protected function ‪getPathFixer(): RelativeCssPathFixer
683  {
684  return GeneralUtility::makeInstance(RelativeCssPathFixer::class);
685  }
686 }
‪TYPO3\CMS\Core\Resource\ResourceCompressor\getFilenameFromMainDir
‪string getFilenameFromMainDir($filename)
Definition: ResourceCompressor.php:415
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:24
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:74
‪TYPO3\CMS\Core\Resource\ResourceCompressor\$targetDirectory
‪string $targetDirectory
Definition: ResourceCompressor.php:32
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:180
‪TYPO3\CMS\Core\Resource\ResourceCompressor\cssFixRelativeUrlPaths
‪string cssFixRelativeUrlPaths(string $contents, string $filename)
Definition: ResourceCompressor.php:496
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static string dirname($path)
Definition: PathUtility.php:186
‪TYPO3\CMS\Core\Resource\ResourceCompressor\getJavaScriptFileType
‪string getJavaScriptFileType()
Definition: ResourceCompressor.php:665
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static string stripPathSitePrefix($path)
Definition: PathUtility.php:372
‪TYPO3\CMS\Core\Resource\ResourceCompressor\$rootPath
‪string $rootPath
Definition: ResourceCompressor.php:36
‪TYPO3\CMS\Core\Utility\GeneralUtility\getUrl
‪static mixed getUrl($url, $includeHeader=0, $requestHeaders=null, &$report=null)
Definition: GeneralUtility.php:1748
‪TYPO3\CMS\Core\Utility\PathUtility\getRelativePath
‪static string null getRelativePath($sourcePath, $targetPath)
Definition: PathUtility.php:73
‪TYPO3\CMS\Core\Resource\ResourceCompressor
Definition: ResourceCompressor.php:29
‪TYPO3\CMS\Core\Resource\ResourceCompressor\retrieveExternalFile
‪string retrieveExternalFile($url)
Definition: ResourceCompressor.php:593
‪TYPO3\CMS\Core\Resource\ResourceCompressor\$htaccessTemplate
‪string $htaccessTemplate
Definition: ResourceCompressor.php:50
‪TYPO3\CMS\Core\Resource\ResourceCompressor\createMergedJsFile
‪mixed createMergedJsFile(array $filesToInclude)
Definition: ResourceCompressor.php:218
‪TYPO3\CMS\Core\Resource\ResourceCompressor\createMergedCssFile
‪mixed createMergedCssFile(array $filesToInclude)
Definition: ResourceCompressor.php:207
‪TYPO3\CMS\Core\Resource\ResourceCompressor\$createGzipped
‪bool $createGzipped
Definition: ResourceCompressor.php:42
‪TYPO3\CMS\Core\Resource\ResourceCompressor\cssFixStatements
‪string cssFixStatements($contents)
Definition: ResourceCompressor.php:509
‪TYPO3\CMS\Core\Utility\PathUtility\getRelativePathTo
‪static string null getRelativePathTo($targetPath)
Definition: PathUtility.php:32
‪TYPO3\CMS\Core\Resource\ResourceCompressor\compressCssFiles
‪array compressCssFiles(array $cssFiles)
Definition: ResourceCompressor.php:305
‪TYPO3\CMS\Core\Resource\ResourceCompressor\setRootPath
‪setRootPath($rootPath)
Definition: ResourceCompressor.php:93
‪TYPO3\CMS\Core\Resource\ResourceCompressor\returnFileReference
‪string returnFileReference($filename)
Definition: ResourceCompressor.php:578
‪TYPO3\CMS\Core\Resource\ResourceCompressor\compressJsFile
‪string compressJsFile($filename)
Definition: ResourceCompressor.php:389
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir_deep
‪static mkdir_deep($directory)
Definition: GeneralUtility.php:2022
‪TYPO3\CMS\Core\Resource\ResourceCompressor\getPathFixer
‪getPathFixer()
Definition: ResourceCompressor.php:677
‪TYPO3\CMS\Core\Resource\ResourceCompressor\__construct
‪__construct()
Definition: ResourceCompressor.php:61
‪TYPO3\CMS\Core\Core\Environment\getBackendPath
‪static string getBackendPath()
Definition: Environment.php:250
‪TYPO3\CMS\Core\Utility\PathUtility\pathinfo
‪static string string[] pathinfo($path, $options=null)
Definition: PathUtility.php:208
‪TYPO3\CMS\Core\Resource\ResourceCompressor\concatenateCssFiles
‪array concatenateCssFiles(array $cssFiles)
Definition: ResourceCompressor.php:106
‪TYPO3\CMS\Core\Utility\PathUtility\isAbsolutePath
‪static bool isAbsolutePath($path)
Definition: PathUtility.php:223
‪TYPO3\CMS\Core\Resource\ResourceCompressor\writeFileAndCompressed
‪writeFileAndCompressed($filename, $contents)
Definition: ResourceCompressor.php:561
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:52
‪TYPO3\CMS\Core\Utility\GeneralUtility\isValidUrl
‪static bool isValidUrl($url)
Definition: GeneralUtility.php:944
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
Definition: TypoScriptFrontendController.php:98
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:40
‪TYPO3\CMS\Core\Resource\ResourceCompressor\compressCssFile
‪string compressCssFile($filename)
Definition: ResourceCompressor.php:334
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22
‪TYPO3\CMS\Core\Resource\ResourceCompressor\compressCssString
‪string compressCssString($contents)
Definition: ResourceCompressor.php:612
‪TYPO3\CMS\Core\Resource\ResourceCompressor\createMergedFile
‪mixed createMergedFile(array $filesToInclude, $type='css')
Definition: ResourceCompressor.php:232
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Resource\ResourceCompressor\compressJsFiles
‪array compressJsFiles(array $jsFiles)
Definition: ResourceCompressor.php:366
‪TYPO3\CMS\Core\Resource\ResourceCompressor\checkBaseDirectory
‪bool checkBaseDirectory($filename, array $baseDirectories)
Definition: ResourceCompressor.php:480
‪TYPO3\CMS\Core\Resource\ResourceCompressor\$gzipCompressionLevel
‪int $gzipCompressionLevel
Definition: ResourceCompressor.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility\writeFile
‪static bool writeFile($file, $content, $changePermissions=false)
Definition: GeneralUtility.php:1836
‪TYPO3\CMS\Core\Resource\ResourceCompressor\concatenateJsFiles
‪array concatenateJsFiles(array $jsFiles)
Definition: ResourceCompressor.php:153
‪TYPO3\CMS\Core\Resource\RelativeCssPathFixer
Definition: RelativeCssPathFixer.php:29