TYPO3 CMS  TYPO3_7-6
IconUtility.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
23 
40 {
44  public static $fileSpriteIconNames = [
45  'htm' => 'mimetypes-text-html',
46  'html' => 'mimetypes-text-html',
47  'css' => 'mimetypes-text-css',
48  'js' => 'mimetypes-text-js',
49  'csv' => 'mimetypes-text-csv',
50  'php' => 'mimetypes-text-php',
51  'php7' => 'mimetypes-text-php',
52  'php6' => 'mimetypes-text-php',
53  'php5' => 'mimetypes-text-php',
54  'php4' => 'mimetypes-text-php',
55  'php3' => 'mimetypes-text-php',
56  'inc' => 'mimetypes-text-php',
57  'ts' => 'mimetypes-text-ts',
58  'txt' => 'mimetypes-text-text',
59  'class' => 'mimetypes-text-text',
60  'tmpl' => 'mimetypes-text-text',
61  'jpg' => 'mimetypes-media-image',
62  'jpeg' => 'mimetypes-media-image',
63  'gif' => 'mimetypes-media-image',
64  'png' => 'mimetypes-media-image',
65  'bmp' => 'mimetypes-media-image',
66  'tif' => 'mimetypes-media-image',
67  'tiff' => 'mimetypes-media-image',
68  'tga' => 'mimetypes-media-image',
69  'psd' => 'mimetypes-media-image',
70  'eps' => 'mimetypes-media-image',
71  'ai' => 'mimetypes-media-image',
72  'svg' => 'mimetypes-media-image',
73  'pcx' => 'mimetypes-media-image',
74  'avi' => 'mimetypes-media-video',
75  'mpg' => 'mimetypes-media-video',
76  'mpeg' => 'mimetypes-media-video',
77  'mov' => 'mimetypes-media-video',
78  'wav' => 'mimetypes-media-audio',
79  'mp3' => 'mimetypes-media-audio',
80  'mid' => 'mimetypes-media-audio',
81  'swf' => 'mimetypes-media-flash',
82  'swa' => 'mimetypes-media-flash',
83  'exe' => 'mimetypes-application',
84  'com' => 'mimetypes-application',
85  't3x' => 'mimetypes-compressed',
86  't3d' => 'mimetypes-compressed',
87  'zip' => 'mimetypes-compressed',
88  'tgz' => 'mimetypes-compressed',
89  'gz' => 'mimetypes-compressed',
90  'pdf' => 'mimetypes-pdf',
91  'doc' => 'mimetypes-word',
92  'dot' => 'mimetypes-word',
93  'docm' => 'mimetypes-word',
94  'docx' => 'mimetypes-word',
95  'dotm' => 'mimetypes-word',
96  'dotx' => 'mimetypes-word',
97  'rtf' => 'mimetypes-word',
98  'xls' => 'mimetypes-excel',
99  'xlsm' => 'mimetypes-excel',
100  'xlsx' => 'mimetypes-excel',
101  'xltm' => 'mimetypes-excel',
102  'xltx' => 'mimetypes-excel',
103  'pps' => 'mimetypes-powerpoint',
104  'ppsx' => 'mimetypes-powerpoint',
105  'ppt' => 'mimetypes-powerpoint',
106  'pptm' => 'mimetypes-powerpoint',
107  'pptx' => 'mimetypes-powerpoint',
108  'potm' => 'mimetypes-powerpoint',
109  'potx' => 'mimetypes-powerpoint',
110  'odb' => 'mimetypes-open-document-database',
111  'odg' => 'mimetypes-open-document-drawing',
112  'sxd' => 'mimetypes-open-document-drawing',
113  'odf' => 'mimetypes-open-document-formula',
114  'sxm' => 'mimetypes-open-document-formula',
115  'odp' => 'mimetypes-open-document-presentation',
116  'sxi' => 'mimetypes-open-document-presentation',
117  'ods' => 'mimetypes-open-document-spreadsheet',
118  'sxc' => 'mimetypes-open-document-spreadsheet',
119  'odt' => 'mimetypes-open-document-text',
120  'sxw' => 'mimetypes-open-document-text',
121  'mount' => 'apps-filetree-mount',
122  'folder' => 'apps-filetree-folder-default',
123  'default' => 'mimetypes-other-other'
124  ];
125 
132  protected static $spriteIconCache = [];
133 
144  public static function getIcon($table, $row = [], $shaded = false)
145  {
147  // Flags
148  // If set, then the usergroup number will NOT be printed unto the icon. NOTICE.
149  // The icon is generated only if a default icon for groups is not found... So effectively this is ineffective.
150  $doNotRenderUserGroupNumber = true;
151  // Shadow
152  if (!empty($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) && !empty($row['t3ver_state'])) {
153  switch (VersionState::cast($row['t3ver_state'])) {
155  return 'gfx/i/shadow_hide.png';
156  break;
158  return 'gfx/i/shadow_delete.png';
159  break;
161  return 'gfx/i/shadow_moveto_plh.png';
162  break;
164  return 'gfx/i/shadow_moveto_pointer.png';
165  break;
166  }
167  }
168  // First, find the icon file name. This can depend on configuration in TCA, field values and more:
169  if ($table === 'pages') {
170  $iconfile = $GLOBALS['PAGES_TYPES'][$row['doktype']]['icon'];
171  if (empty($iconfile)) {
172  $iconfile = $GLOBALS['PAGES_TYPES']['default']['icon'];
173  }
174  }
175 
176  if (empty($iconfile)) {
177  $iconfile = $GLOBALS['TCA'][$table]['ctrl']['iconfile'] ?: $table . '.gif';
178  }
179 
180  // Setting path of iconfile if not already set. Default is "gfx/i/"
181  if (!strstr($iconfile, '/')) {
182  $iconfile = 'gfx/i/' . $iconfile;
183  }
184  // Setting the absolute path where the icon should be found as a file:
185  if (substr($iconfile, 0, 3) == '../') {
186  $absfile = PATH_site . substr($iconfile, 3);
187  } else {
188  $absfile = PATH_typo3 . $iconfile;
189  }
190  // Initializing variables, all booleans except otherwise stated:
191  $hidden = false;
192  $timing = false;
193  $futuretiming = false;
194  // In fact an integer value
195  $user = false;
196  $deleted = false;
197  // Set, if a page-record (only pages!) has the extend-to-subpages flag set.
198  $protectSection = false;
199  $noIconFound = (bool)$row['_NO_ICON_FOUND'];
200  // + $shaded which is also boolean!
201  // Icon state based on "enableFields":
202  if (is_array($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
203  $enCols = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'];
204  // If "hidden" is enabled:
205  if ($enCols['disabled']) {
206  if ($row[$enCols['disabled']]) {
207  $hidden = true;
208  }
209  }
210  // If a "starttime" is set and higher than current time:
211  if ($enCols['starttime']) {
212  if ($GLOBALS['EXEC_TIME'] < (int)$row[$enCols['starttime']]) {
213  $timing = true;
214  // And if "endtime" is NOT set:
215  if ((int)$row[$enCols['endtime']] === 0) {
216  $futuretiming = true;
217  }
218  }
219  }
220  // If an "endtime" is set:
221  if ($enCols['endtime']) {
222  if ((int)$row[$enCols['endtime']] > 0) {
223  if ((int)$row[$enCols['endtime']] < $GLOBALS['EXEC_TIME']) {
224  // End-timing applies at this point.
225  $timing = true;
226  } else {
227  // End-timing WILL apply in the future for this element.
228  $futuretiming = true;
229  }
230  }
231  }
232  // If a user-group field is set:
233  if ($enCols['fe_group']) {
234  $user = $row[$enCols['fe_group']];
235  if ($user && $doNotRenderUserGroupNumber) {
236  $user = 100;
237  }
238  }
239  }
240  // If "deleted" flag is set (only when listing records which are also deleted!)
241  if ($col = $row[$GLOBALS['TCA'][$table]['ctrl']['delete']]) {
242  $deleted = true;
243  }
244  // Detecting extendToSubpages (for pages only)
245  if ($table == 'pages' && $row['extendToSubpages'] && ($hidden || $timing || $futuretiming || $user)) {
246  $protectSection = true;
247  }
248  // If ANY of the booleans are set it means we have to alter the icon:
249  if ($hidden || $timing || $futuretiming || $user || $deleted || $shaded || $noIconFound) {
250  $flags = '';
251  $string = '';
252  if ($deleted) {
253  $string = 'deleted';
254  $flags = 'd';
255  } elseif ($noIconFound) {
256  // This is ONLY for creating icons with "?" on easily...
257  $string = 'no_icon_found';
258  $flags = 'x';
259  } else {
260  if ($hidden) {
261  $string .= 'hidden';
262  }
263  if ($timing) {
264  $string .= 'timing';
265  }
266  if (!$string && $futuretiming) {
267  $string = 'futuretiming';
268  }
269  $flags .= ($hidden ? 'h' : '') . ($timing ? 't' : '') . ($futuretiming ? 'f' : '') . ($user ? 'u' : '') . ($protectSection ? 'p' : '') . ($shaded ? 's' : '');
270  }
271  // Create tagged icon file name:
272  $iconFileName_stateTagged = preg_replace('/.([[:alnum:]]+)$/', '__' . $flags . '.\\1', basename($iconfile));
273  // Check if tagged icon file name exists (a tagged icon means the icon base name with the flags added between body and extension of the filename, prefixed with underscore)
274  if (@is_file((dirname($absfile) . '/' . $iconFileName_stateTagged)) || @is_file(($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . '/' . dirname($iconfile) . '/' . $iconFileName_stateTagged))) {
275  // Look for [iconname]_xxxx.[ext]
276  return dirname($iconfile) . '/' . $iconFileName_stateTagged;
277  } else {
278  // Otherwise, create the icon:
279  $theRes = self::makeIcon($GLOBALS['BACK_PATH'] . $iconfile, $string, $user, $protectSection, $absfile, $iconFileName_stateTagged);
280  return $theRes;
281  }
282  } else {
283  return $iconfile;
284  }
285  }
286 
299  public static function skinImg($backPath, $src, $wHattribs = '', $outputMode = 0)
300  {
302  static $cachedSkinImages = [];
303  $imageId = md5($backPath . $src . $wHattribs . $outputMode);
304  if (isset($cachedSkinImages[$imageId])) {
305  return $cachedSkinImages[$imageId];
306  }
307  // Setting source key. If the icon is referred to inside an extension, we homogenize the prefix to "ext/":
308  $srcKey = preg_replace('/^(\\.\\.\\/typo3conf\\/ext|sysext|ext)\\//', 'ext/', $src);
309  // LOOKING for alternative icons:
310  if ($GLOBALS['TBE_STYLES']['skinImg'][$srcKey]) {
311  // Slower or faster with is_array()? Could be used.
312  list($src, $wHattribs) = $GLOBALS['TBE_STYLES']['skinImg'][$srcKey];
313  } elseif ($GLOBALS['TBE_STYLES']['skinImgAutoCfg']) {
314  // Otherwise, test if auto-detection is enabled:
315  // Search for alternative icon automatically:
316  $fExt = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['forceFileExtension'];
317  $scaleFactor = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['scaleFactor'] ?: 1;
318  // Scaling factor
319  $lookUpName = $fExt ? preg_replace('/\\.[[:alnum:]]+$/', '', $srcKey) . '.' . $fExt : $srcKey;
320  // Set filename to look for
321  if ($fExt && !@is_file(($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . $lookUpName))) {
322  // Fallback to original filename if icon with forced extension doesn't exists
323  $lookUpName = $srcKey;
324  }
325  // If file is found:
326  if (@is_file(($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . $lookUpName))) {
327  // If there is a file...
328  $iInfo = @getimagesize(($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . $lookUpName));
329  // Get width/height:
330  // Set $src and $wHattribs:
331  $src = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['relDir'] . $lookUpName;
332  $wHattribs = 'width="' . round($iInfo[0] * $scaleFactor) . '" height="' . round($iInfo[1] * $scaleFactor) . '"';
333  }
334  // In any case, set currect src / wHattrib - this way we make sure that an entry IS found next time we hit the function,
335  // regardless of whether it points to an alternative icon or just the current.
336  $GLOBALS['TBE_STYLES']['skinImg'][$srcKey] = [$src, $wHattribs];
337  }
338  // Rendering disabled (greyed) icons using _i (inactive) as name suffix ("_d" is already used)
339  $matches = [];
340  $srcBasename = basename($src);
341  if (preg_match('/(.*)_i(\\....)$/', $srcBasename, $matches)) {
342  $temp_path = dirname(PATH_thisScript) . '/';
343  if (!@is_file(($temp_path . $backPath . $src))) {
344  $srcOrg = preg_replace('/_i' . preg_quote($matches[2], '/') . '$/', $matches[2], $src);
345  $src = self::makeIcon($backPath . $srcOrg, 'disabled', 0, false, $temp_path . $backPath . $srcOrg, $srcBasename);
346  }
347  }
348  // Return icon source/wHattributes:
349  $output = '';
350  switch ($outputMode) {
351  case 0:
352  $output = ' src="' . $backPath . $src . '" ' . $wHattribs;
353  break;
354  case 1:
355  $output = $backPath . $src;
356  break;
357  case 2:
358  $output = $wHattribs;
359  break;
360  }
361  $cachedSkinImages[$imageId] = $output;
362 
363  return $output;
364  }
365 
366  /***********************************
367  *
368  * Other functions
369  *
370  ***********************************/
383  public static function makeIcon($iconfile, $mode, $user, $protectSection, $absFile, $iconFileName_stateTagged)
384  {
385  $iconFileName = GeneralUtility::shortMD5(($iconfile . '|' . $mode . '|-' . $user . '|' . $protectSection)) . '_' . $iconFileName_stateTagged . '.' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] ? 'png' : 'gif');
386  $mainpath = '../typo3temp/Icons/' . $iconFileName;
387  $path = PATH_site . 'typo3temp/Icons/' . $iconFileName;
388  if (file_exists($path)) {
389  // Returns if found in ../typo3temp/Icons/
390  return $mainpath;
391  } else {
392  // Makes icon:
393  if (file_exists($absFile)) {
394  if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) {
395  // Create image pointer, if possible
396  $im = self::imagecreatefrom($absFile);
397  if ($im < 0) {
398  return $iconfile;
399  }
400  // Converting to gray scale, dimming the icon:
401  if ($mode == 'disabled' or $mode != 'futuretiming' && $mode != 'no_icon_found' && !(!$mode && $user)) {
402  $totalImageColors = imagecolorstotal($im);
403  for ($c = 0; $c < $totalImageColors; $c++) {
404  $cols = imagecolorsforindex($im, $c);
405  $newcol = round(($cols['red'] + $cols['green'] + $cols['blue']) / 3);
406  $lighten = $mode == 'disabled' ? 2.5 : 2;
407  $newcol = round(255 - (255 - $newcol) / $lighten);
408  imagecolorset($im, $c, $newcol, $newcol, $newcol);
409  }
410  }
411  // Applying user icon, if there are access control on the item:
412  if ($user) {
413  if ($user < 100) {
414  // Apply user number only if lower than 100
415  $black = imagecolorallocate($im, 0, 0, 0);
416  imagefilledrectangle($im, 0, 0, $user > 10 ? 9 : 5, 8, $black);
417  $white = imagecolorallocate($im, 255, 255, 255);
418  imagestring($im, 1, 1, 1, $user, $white);
419  }
420  $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/overlay_group.gif');
421  if ($ol_im < 0) {
422  return $iconfile;
423  }
424  self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
425  }
426  // Applying overlay based on mode:
427  if ($mode) {
428  unset($ol_im);
429  switch ($mode) {
430  case 'deleted':
431  $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/overlay_deleted.gif');
432  break;
433  case 'futuretiming':
434  $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/overlay_timing.gif');
435  break;
436  case 'timing':
437  $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/overlay_timing.gif');
438  break;
439  case 'hiddentiming':
440  $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/overlay_hidden_timing.gif');
441  break;
442  case 'no_icon_found':
443  $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/overlay_no_icon_found.gif');
444  break;
445  case 'disabled':
446  // is already greyed - nothing more
447  $ol_im = 0;
448  break;
449  case 'hidden':
450 
451  default:
452  $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/overlay_hidden.gif');
453  }
454  if ($ol_im < 0) {
455  return $iconfile;
456  }
457  if ($ol_im) {
458  self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
459  }
460  }
461  // Protect-section icon:
462  if ($protectSection) {
463  $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/overlay_sub5.gif');
464  if ($ol_im < 0) {
465  return $iconfile;
466  }
467  self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
468  }
469  // Create the image as file, destroy GD image and return:
470  $targetDirectory = dirname($path);
471  if (!@is_dir($targetDirectory)) {
472  GeneralUtility::mkdir($targetDirectory);
473  }
474  @self::imagemake($im, $path);
475  GraphicalFunctions::gifCompress($path, 'IM');
476  imagedestroy($im);
477 
478  return $mainpath;
479  } else {
480  return $iconfile;
481  }
482  } else {
483  return $GLOBALS['BACK_PATH'] . 'typo3/sysext/backend/Resources/Public/Images/Overlay/default.gif';
484  }
485  }
486  }
487 
513  public static function imagecopyresized(&$destinationImage, $sourceImage, $destinationX, $destinationY, $sourceX, $sourceY, $destinationWidth, $destinationHeight, $sourceWidth, $sourceHeight)
514  {
515  imagecopyresized($destinationImage, $sourceImage, $destinationX, $destinationY, $sourceX, $sourceY, $destinationWidth, $destinationHeight, $sourceWidth, $sourceHeight);
516  }
517 
526  public static function imagecreatefrom($file)
527  {
528  $file = GraphicalFunctions::readPngGif($file, $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']);
529  if (!$file) {
530  return -1;
531  }
532 
533  return $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] ? imagecreatefrompng($file) : imagecreatefromgif($file);
534  }
535 
544  public static function imagemake($im, $path)
545  {
546  if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']) {
547  @imagepng($im, $path);
548  } else {
549  @imagegif($im, $path);
550  }
551  if (@is_file($path)) {
553  }
554  }
555 
556  /**********************************************
557  * SPRITE ICON API
558  *
559  * The Sprite Icon API helps you to quickly get the HTML for any icon you want
560  * this is typically wrapped in a <span> tag with corresponding CSS classes that
561  * will be responsible for the
562  *
563  * There are four ways to use this API:
564  *
565  * 1) for any given TCA record
566  * $spriteIconHtml = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord('pages', $row);
567  *
568  * 2) for any given File of Folder object
569  * $spriteIconHtml = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForResource($fileOrFolderObject);
570  *
571  * 3) for any given file
572  * $spriteIconHtml = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForFile('myimage.png');
573  *
574  * 4) for any other icon you know the name
575  * $spriteIconHtml = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-open');
576  *
577  **********************************************/
597  public static function getSpriteIcon($iconName, array $options = [], array $overlays = [])
598  {
600 
601  // First check if an icon is registered in IconRegistry and
602  // return if icon is available.
603  $iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
604  if ($iconRegistry->isRegistered($iconName)) {
605  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
606  return $iconFactory->getIcon($iconName, Icon::SIZE_SMALL)->render();
607  }
608 
609  // Check if icon can be cached and return cached version if present
610  if (empty($options) && empty($overlays)) {
611  if (isset(static::$spriteIconCache[$iconName])) {
612  return static::$spriteIconCache[$iconName];
613  }
614  $iconIsCacheable = true;
615  } else {
616  $iconIsCacheable = false;
617  }
618 
619  $innerHtml = isset($options['html']) ? $options['html'] : null;
620  $tagName = isset($options['tagName']) ? $options['tagName'] : null;
621 
622  // Deal with the overlays
623  foreach ($overlays as $overlayIconName => $overlayOptions) {
624  $overlayOptions['html'] = $innerHtml;
625  $overlayOptions['class'] = (isset($overlayOptions['class']) ? $overlayOptions['class'] . ' ' : '') . 't3-icon-overlay';
626  $innerHtml = self::getSpriteIcon($overlayIconName, $overlayOptions);
627  }
628 
629  $availableIcons = isset($GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable'])
630  ? (array)$GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable']
631  : [];
632  if ($iconName !== 'empty-empty' && !in_array($iconName, $availableIcons, true)) {
633  $iconName = 'status-status-icon-missing';
634  }
635 
636  // Create the CSS class
637  $options['class'] = self::getSpriteIconClasses($iconName) . (isset($options['class']) ? ' ' . $options['class'] : '');
638  unset($options['html'], $options['tagName']);
639  $spriteHtml = self::buildSpriteHtmlIconTag($options, $innerHtml, $tagName);
640 
641  // Store result in cache if possible
642  if ($iconIsCacheable) {
643  static::$spriteIconCache[$iconName] = $spriteHtml;
644  }
645 
646  return $spriteHtml;
647  }
648 
662  public static function getSpriteIconForFile($fileExtension, array $options = null)
663  {
665  if ($options !== null) {
666  GeneralUtility::deprecationLog('The parameter $options of IconUtility::getSpriteIconForFile is not used anymore');
667  }
668  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
669 
670  return $iconFactory->getIconForFileExtension($fileExtension)->render();
671  }
672 
681  public static function mapFileExtensionToSpriteIconClass($fileExtension)
682  {
683  return self::getSpriteIconClasses(self::mapFileExtensionToSpriteIconName($fileExtension));
684  }
685 
694  public static function mapFileExtensionToSpriteIconName($fileExtension)
695  {
696  // If the file is a whole file with name etc (mainly, if it has a "." or a "/"),
697  // then it is checked whether it is a valid directory
698  if (strpos($fileExtension, '.') !== false || strpos($fileExtension, '/') !== false) {
699  // Check if it is a directory
700  $filePath = dirname(GeneralUtility::getIndpEnv('SCRIPT_FILENAME')) . '/' . $GLOBALS['BACK_PATH'] . $fileExtension;
701  $path = GeneralUtility::resolveBackPath($filePath);
702  if (is_dir($path) || substr($fileExtension, -1) === '/' || substr($fileExtension, -1) === '\\') {
703  $fileExtension = 'folder';
704  } else {
705  if (($pos = strrpos($fileExtension, '.')) !== false) {
706  $fileExtension = strtolower(substr($fileExtension, $pos + 1));
707  } else {
708  $fileExtension = 'default';
709  }
710  }
711  }
712  // If the file extension is not valid
713  // then use the default one
714  if (!isset(self::$fileSpriteIconNames[$fileExtension])) {
715  $fileExtension = 'default';
716  }
717  $iconName = self::$fileSpriteIconNames[$fileExtension];
718 
719  return $iconName;
720  }
721 
736  public static function getSpriteIconForRecord($table, array $row, array $options = null)
737  {
739  if ($options !== null) {
740  GeneralUtility::deprecationLog('The parameter $options of IconUtility::getSpriteIconForRecord is not used anymore');
741  }
742  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
743 
744  return $iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render();
745  }
746 
766  public static function getSpriteIconForResource(\TYPO3\CMS\Core\Resource\ResourceInterface $resource, array $options = [], array $overlays = null)
767  {
769  if ($overlays !== null) {
770  GeneralUtility::deprecationLog('The parameter $overlays of IconUtility::getSpriteIconForResource is not used anymore');
771  }
772  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
773 
774  return $iconFactory->getIconForResource($resource, Icon::SIZE_SMALL, null, $options)->render();
775  }
776 
796  public static function mapRecordTypeToSpriteIconClass($table, array $row)
797  {
799  return self::getSpriteIconClasses(self::mapRecordTypeToSpriteIconName($table, $row));
800  }
801 
820  public static function mapRecordTypeToSpriteIconName($table, array $row)
821  {
822  $recordType = [];
823  $ref = null;
824  if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_column'])) {
825  $column = $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
826  if (isset($row[$column])) {
827  $recordType[1] = $row[$column];
828  } else {
829  $recordType[1] = 'default';
830  }
831  // Workaround to give nav_hide pages a complete different icon
832  // Although it's not a separate doctype
833  // and to give root-pages an own icon
834  if ($table === 'pages') {
835  if ($row['nav_hide']) {
836  $recordType[2] = $recordType[1] . '-hideinmenu';
837  }
838  if ($row['is_siteroot']) {
839  $recordType[3] = $recordType[1] . '-root';
840  }
841  if ($row['module']) {
842  $recordType[4] = 'contains-' . $row['module'];
843  }
844  if ((int)$row['content_from_pid'] > 0) {
845  $recordType[4] = (int)$row['nav_hide'] === 0 ? 'page-contentFromPid' : 'page-contentFromPid-hideinmenu';
846  }
847  }
848  if (is_array($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'])) {
849  foreach ($recordType as $key => $type) {
850  if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'][$type])) {
851  $recordType[$key] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'][$type];
852  } else {
853  unset($recordType[$key]);
854  }
855  }
856  $recordType[0] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['default'];
857  if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['mask'])) {
858  $recordType[5] = str_replace('###TYPE###', $row[$column], $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['mask']);
859  }
860  if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['userFunc'])) {
861  $parameters = ['row' => $row];
862  $recordType[6] = GeneralUtility::callUserFunction($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['userFunc'], $parameters, $ref);
863  }
864  } else {
865  foreach ($recordType as &$type) {
866  $type = 'tcarecords-' . $table . '-' . $type;
867  }
868  unset($type);
869  $recordType[0] = 'tcarecords-' . $table . '-default';
870  }
871  } else {
872  if (is_array($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'])) {
873  $recordType[0] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['default'];
874  } else {
875  $recordType[0] = 'tcarecords-' . $table . '-default';
876  }
877  }
878  krsort($recordType);
879  if (is_array($GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable'])) {
880  foreach ($recordType as $iconName) {
881  if (in_array($iconName, $GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable'])) {
882  return $iconName;
883  }
884  }
885  }
886 
887  return 'status-status-icon-missing';
888  }
889 
900  public static function getSpriteIconClasses($iconName)
901  {
903  $cssClasses = ($baseCssClass = 't3-icon');
904  $parts = explode('-', $iconName);
905  if (count($parts) > 1) {
906  // Will be something like "t3-icon-actions"
907  $cssClasses .= ' ' . ($baseCssClass . '-' . $parts[0]);
908  // Will be something like "t3-icon-actions-document"
909  $cssClasses .= ' ' . ($baseCssClass . '-' . $parts[0] . '-' . $parts[1]);
910  // Will be something like "t3-icon-document-new"
911  $cssClasses .= ' ' . ($baseCssClass . '-' . substr($iconName, (strlen($parts[0]) + 1)));
912  }
913 
914  return $cssClasses;
915  }
916 
928  protected static function buildSpriteHtmlIconTag(array $tagAttributes, $innerHtml = null, $tagName = null)
929  {
931 
932  $innerHtml = $innerHtml === null ? ' ' : $innerHtml;
933  $tagName = $tagName === null ? 'span' : $tagName;
934  $attributes = '';
935  foreach ($tagAttributes as $attribute => $value) {
936  $attributes .= ' ' . htmlspecialchars($attribute) . '="' . htmlspecialchars($value) . '"';
937  }
938 
939  return '<' . $tagName . $attributes . '>' . $innerHtml . '</' . $tagName . '>';
940  }
941 }
static skinImg($backPath, $src, $wHattribs='', $outputMode=0)
static getIcon($table, $row=[], $shaded=false)
static mapRecordTypeToSpriteIconName($table, array $row)
static getSpriteIconForResource(\TYPO3\CMS\Core\Resource\ResourceInterface $resource, array $options=[], array $overlays=null)
static mapFileExtensionToSpriteIconName($fileExtension)
static buildSpriteHtmlIconTag(array $tagAttributes, $innerHtml=null, $tagName=null)
static getSpriteIcon($iconName, array $options=[], array $overlays=[])
static mapRecordTypeToSpriteIconClass($table, array $row)
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
static getSpriteIconForFile($fileExtension, array $options=null)
static mapFileExtensionToSpriteIconClass($fileExtension)
static imagecopyresized(&$destinationImage, $sourceImage, $destinationX, $destinationY, $sourceX, $sourceY, $destinationWidth, $destinationHeight, $sourceWidth, $sourceHeight)
static fixPermissions($path, $recursive=false)
static makeIcon($iconfile, $mode, $user, $protectSection, $absFile, $iconFileName_stateTagged)
static readPngGif($theFile, $output_png=false)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static getSpriteIconForRecord($table, array $row, array $options=null)