[BUGFIX] Prevent IconUtility to throw PHP Warning
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Utility / IconUtility.php
1 <?php
2 namespace TYPO3\CMS\Backend\Utility;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 1999-2013 Kasper Skårhøj (kasperYYYY@typo3.com)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the text file GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 use TYPO3\CMS\Core\Utility\GeneralUtility;
31 use TYPO3\CMS\Core\Versioning\VersionState;
32
33 /**
34 * Contains class for icon generation in the backend
35 * This library has functions that returns - and if necessary creates - the icon for an element in TYPO3
36 *
37 * Expects global vars:
38 * - $BACK_PATH
39 * - PATH_typo3
40 * - $TCA, $PAGES_TYPES
41 *
42 *
43 * Notes:
44 * These functions are strongly related to the interface of TYPO3.
45 * The class is included in eg. init.php
46 * Static class, functions called without making a class instance.
47 *
48 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
49 */
50 class IconUtility {
51
52 static public $fileSpriteIconNames = array(
53 'htm' => 'mimetypes-text-html',
54 'html' => 'mimetypes-text-html',
55 'css' => 'mimetypes-text-css',
56 'js' => 'mimetypes-text-js',
57 'csv' => 'mimetypes-text-csv',
58 'php' => 'mimetypes-text-php',
59 'php6' => 'mimetypes-text-php',
60 'php5' => 'mimetypes-text-php',
61 'php4' => 'mimetypes-text-php',
62 'php3' => 'mimetypes-text-php',
63 'inc' => 'mimetypes-text-php',
64 'ts' => 'mimetypes-text-ts',
65 'txt' => 'mimetypes-text-text',
66 'class' => 'mimetypes-text-text',
67 'tmpl' => 'mimetypes-text-text',
68 'jpg' => 'mimetypes-media-image',
69 'jpeg' => 'mimetypes-media-image',
70 'gif' => 'mimetypes-media-image',
71 'png' => 'mimetypes-media-image',
72 'bmp' => 'mimetypes-media-image',
73 'tif' => 'mimetypes-media-image',
74 'tga' => 'mimetypes-media-image',
75 'psd' => 'mimetypes-media-image',
76 'eps' => 'mimetypes-media-image',
77 'avi' => 'mimetypes-media-video',
78 'mpg' => 'mimetypes-media-video',
79 'mpeg' => 'mimetypes-media-video',
80 'mov' => 'mimetypes-media-video',
81 'wav' => 'mimetypes-media-audio',
82 'mp3' => 'mimetypes-media-audio',
83 'mid' => 'mimetypes-media-audio',
84 'swf' => 'mimetypes-media-flash',
85 'swa' => 'mimetypes-media-flash',
86 'exe' => 'mimetypes-executable-executable',
87 'com' => 'mimetypes-executable-executable',
88 't3x' => 'mimetypes-compressed',
89 't3d' => 'mimetypes-compressed',
90 'zip' => 'mimetypes-compressed',
91 'tgz' => 'mimetypes-compressed',
92 'gz' => 'mimetypes-compressed',
93 'pdf' => 'mimetypes-pdf',
94 'doc' => 'mimetypes-word',
95 'dot' => 'mimetypes-word',
96 'docm' => 'mimetypes-word',
97 'docx' => 'mimetypes-word',
98 'dotm' => 'mimetypes-word',
99 'dotx' => 'mimetypes-word',
100 'sxw' => 'mimetypes-word',
101 'rtf' => 'mimetypes-word',
102 'xls' => 'mimetypes-excel',
103 'xlsm' => 'mimetypes-excel',
104 'xlsx' => 'mimetypes-excel',
105 'xltm' => 'mimetypes-excel',
106 'xltx' => 'mimetypes-excel',
107 'sxc' => 'mimetypes-excel',
108 'pps' => 'mimetypes-powerpoint',
109 'ppsx' => 'mimetypes-powerpoint',
110 'ppt' => 'mimetypes-powerpoint',
111 'pptm' => 'mimetypes-powerpoint',
112 'pptx' => 'mimetypes-powerpoint',
113 'potm' => 'mimetypes-powerpoint',
114 'potx' => 'mimetypes-powerpoint',
115 'mount' => 'apps-filetree-mount',
116 'folder' => 'apps-filetree-folder-default',
117 'default' => 'mimetypes-other-other'
118 );
119
120 /**
121 * Array of icons rendered by getSpriteIcon(). This contains only icons
122 * without overlays or options. These are the most common form.
123 *
124 * @var array
125 */
126 static protected $spriteIconCache = array();
127
128 /**
129 * Returns an icon image tag, 18x16 pixels, based on input information.
130 * This function is recommended to use in your backend modules.
131 *
132 * @param string $table The table name
133 * @param array $row The table row ("enablefields" are at least needed for correct icon display and for pages records some more fields in addition!)
134 * @param string $backPath The backpath to the main TYPO3 directory (relative path back to PATH_typo3)
135 * @param string $params Additional attributes for the image tag
136 * @param boolean $shaded If set, the icon will be grayed/shaded
137 * @return string <img>-tag
138 * @see getIcon()
139 * @deprecated since TYPO3 6.1 will be removed in 7.0, should not be used anymore as only sprite icons are used since TYPO3 4.4
140 */
141 static public function getIconImage($table, $row = array(), $backPath, $params = '', $shaded = FALSE) {
142 GeneralUtility::logDeprecatedFunction();
143
144 $str = '<img' . self::skinImg($backPath, self::getIcon($table, $row, $shaded), 'width="18" height="16"') . (trim($params) ? ' ' . trim($params) : '');
145 if (!stristr($str, 'alt="')) {
146 $str .= ' alt=""';
147 }
148 $str .= ' />';
149 return $str;
150 }
151
152 /**
153 * Creates the icon for input table/row
154 * Returns filename for the image icon, relative to PATH_typo3
155 *
156 * @param string $table The table name
157 * @param array $row The table row ("enablefields" are at least needed for correct icon display and for pages records some more fields in addition!)
158 * @param boolean $shaded If set, the icon will be grayed/shaded
159 * @return string Icon filename
160 * @see getIconImage()
161 */
162 static public function getIcon($table, $row = array(), $shaded = FALSE) {
163 // Flags
164 // If set, then the usergroup number will NOT be printed unto the icon. NOTICE.
165 // The icon is generated only if a default icon for groups is not found... So effectively this is ineffective.
166 $doNotRenderUserGroupNumber = TRUE;
167 // Shadow
168 if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
169 switch (VersionState::cast($row['t3ver_state'])) {
170 case new VersionState(VersionState::NEW_PLACEHOLDER):
171 return 'gfx/i/shadow_hide.png';
172 break;
173 case new VersionState(VersionState::DELETE_PLACEHOLDER):
174 return 'gfx/i/shadow_delete.png';
175 break;
176 case new VersionState(VersionState::MOVE_PLACEHOLDER):
177 return 'gfx/i/shadow_moveto_plh.png';
178 break;
179 case new VersionState(VersionState::MOVE_POINTER):
180 return 'gfx/i/shadow_moveto_pointer.png';
181 break;
182 }
183 }
184 // First, find the icon file name. This can depend on configuration in TCA, field values and more:
185 if ($table == 'pages') {
186 $iconfile = $GLOBALS['PAGES_TYPES'][$row['doktype']]['icon'];
187 if (!$iconfile) {
188 $iconfile = $GLOBALS['PAGES_TYPES']['default']['icon'];
189 }
190 } else {
191 if (!($iconfile = $GLOBALS['TCA'][$table]['ctrl']['typeicons'][$row[$GLOBALS['TCA'][$table]['ctrl']['typeicon_column']]])) {
192 $iconfile = $GLOBALS['TCA'][$table]['ctrl']['iconfile'] ?: $table . '.gif';
193 }
194 }
195 // Setting path of iconfile if not already set. Default is "gfx/i/"
196 if (!strstr($iconfile, '/')) {
197 $iconfile = 'gfx/i/' . $iconfile;
198 }
199 // Setting the absolute path where the icon should be found as a file:
200 if (substr($iconfile, 0, 3) == '../') {
201 $absfile = PATH_site . substr($iconfile, 3);
202 } else {
203 $absfile = PATH_typo3 . $iconfile;
204 }
205 // Initializing variables, all booleans except otherwise stated:
206 $hidden = FALSE;
207 $timing = FALSE;
208 $futuretiming = FALSE;
209 // In fact an integer value
210 $user = FALSE;
211 $deleted = FALSE;
212 // Set, if a page-record (only pages!) has the extend-to-subpages flag set.
213 $protectSection = FALSE;
214 $noIconFound = $row['_NO_ICON_FOUND'] ? TRUE : FALSE;
215 // + $shaded which is also boolean!
216 // Icon state based on "enableFields":
217 if (is_array($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
218 $enCols = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'];
219 // If "hidden" is enabled:
220 if ($enCols['disabled']) {
221 if ($row[$enCols['disabled']]) {
222 $hidden = TRUE;
223 }
224 }
225 // If a "starttime" is set and higher than current time:
226 if ($enCols['starttime']) {
227 if ($GLOBALS['EXEC_TIME'] < (int)$row[$enCols['starttime']]) {
228 $timing = TRUE;
229 // And if "endtime" is NOT set:
230 if ((int)$row[$enCols['endtime']] === 0) {
231 $futuretiming = TRUE;
232 }
233 }
234 }
235 // If an "endtime" is set:
236 if ($enCols['endtime']) {
237 if ((int)$row[$enCols['endtime']] > 0) {
238 if ((int)$row[$enCols['endtime']] < $GLOBALS['EXEC_TIME']) {
239 // End-timing applies at this point.
240 $timing = TRUE;
241 } else {
242 // End-timing WILL apply in the future for this element.
243 $futuretiming = TRUE;
244 }
245 }
246 }
247 // If a user-group field is set:
248 if ($enCols['fe_group']) {
249 $user = $row[$enCols['fe_group']];
250 if ($user && $doNotRenderUserGroupNumber) {
251 $user = 100;
252 }
253 }
254 }
255 // If "deleted" flag is set (only when listing records which are also deleted!)
256 if ($col = $row[$GLOBALS['TCA'][$table]['ctrl']['delete']]) {
257 $deleted = TRUE;
258 }
259 // Detecting extendToSubpages (for pages only)
260 if ($table == 'pages' && $row['extendToSubpages'] && ($hidden || $timing || $futuretiming || $user)) {
261 $protectSection = TRUE;
262 }
263 // If ANY of the booleans are set it means we have to alter the icon:
264 if ($hidden || $timing || $futuretiming || $user || $deleted || $shaded || $noIconFound) {
265 $flags = '';
266 $string = '';
267 if ($deleted) {
268 $string = 'deleted';
269 $flags = 'd';
270 } elseif ($noIconFound) {
271 // This is ONLY for creating icons with "?" on easily...
272 $string = 'no_icon_found';
273 $flags = 'x';
274 } else {
275 if ($hidden) {
276 $string .= 'hidden';
277 }
278 if ($timing) {
279 $string .= 'timing';
280 }
281 if (!$string && $futuretiming) {
282 $string = 'futuretiming';
283 }
284 $flags .= ($hidden ? 'h' : '') . ($timing ? 't' : '') . ($futuretiming ? 'f' : '') . ($user ? 'u' : '') . ($protectSection ? 'p' : '') . ($shaded ? 's' : '');
285 }
286 // Create tagged icon file name:
287 $iconFileName_stateTagged = preg_replace('/.([[:alnum:]]+)$/', '__' . $flags . '.\\1', basename($iconfile));
288 // 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)
289 if (@is_file((dirname($absfile) . '/' . $iconFileName_stateTagged)) || @is_file(($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . '/' . dirname($iconfile) . '/' . $iconFileName_stateTagged))) {
290 // Look for [iconname]_xxxx.[ext]
291 return dirname($iconfile) . '/' . $iconFileName_stateTagged;
292 } else {
293 // Otherwise, create the icon:
294 $theRes = self::makeIcon($GLOBALS['BACK_PATH'] . $iconfile, $string, $user, $protectSection, $absfile, $iconFileName_stateTagged);
295 return $theRes;
296 }
297 } else {
298 return $iconfile;
299 }
300 }
301
302 /**
303 * Returns the src=... for the input $src value OR any alternative found in $TBE_STYLES['skinImg']
304 * Used for skinning the TYPO3 backend with an alternative set of icons
305 *
306 * @param string $backPath Current backpath to PATH_typo3 folder
307 * @param string $src Icon file name relative to PATH_typo3 folder
308 * @param string $wHattribs Default width/height, defined like 'width="12" height="14"'
309 * @param integer $outputMode Mode: 0 (zero) is default and returns src/width/height. 1 returns value of src+backpath, 2 returns value of w/h.
310 * @return string Returns ' src="[backPath][src]" [wHattribs]'
311 * @see skinImgFile()
312 */
313 static public function skinImg($backPath, $src, $wHattribs = '', $outputMode = 0) {
314 static $cachedSkinImages = array();
315 $imageId = md5($backPath . $src . $wHattribs . $outputMode);
316 if (isset($cachedSkinImages[$imageId])) {
317 return $cachedSkinImages[$imageId];
318 }
319 // Setting source key. If the icon is refered to inside an extension, we homogenize the prefix to "ext/":
320 $srcKey = preg_replace('/^(\\.\\.\\/typo3conf\\/ext|sysext|ext)\\//', 'ext/', $src);
321 // LOOKING for alternative icons:
322 if ($GLOBALS['TBE_STYLES']['skinImg'][$srcKey]) {
323 // Slower or faster with is_array()? Could be used.
324 list($src, $wHattribs) = $GLOBALS['TBE_STYLES']['skinImg'][$srcKey];
325 } elseif ($GLOBALS['TBE_STYLES']['skinImgAutoCfg']) {
326 // Otherwise, test if auto-detection is enabled:
327 // Search for alternative icon automatically:
328 $fExt = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['forceFileExtension'];
329 $scaleFactor = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['scaleFactor'] ?: 1;
330 // Scaling factor
331 $lookUpName = $fExt ? preg_replace('/\\.[[:alnum:]]+$/', '', $srcKey) . '.' . $fExt : $srcKey;
332 // Set filename to look for
333 if ($fExt && !@is_file(($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . $lookUpName))) {
334 // Fallback to original filename if icon with forced extension doesn't exists
335 $lookUpName = $srcKey;
336 }
337 // If file is found:
338 if (@is_file(($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . $lookUpName))) {
339 // If there is a file...
340 $iInfo = @getimagesize(($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . $lookUpName));
341 // Get width/height:
342 // Set $src and $wHattribs:
343 $src = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['relDir'] . $lookUpName;
344 $wHattribs = 'width="' . round($iInfo[0] * $scaleFactor) . '" height="' . round($iInfo[1] * $scaleFactor) . '"';
345 }
346 // In any case, set currect src / wHattrib - this way we make sure that an entry IS found next time we hit the function,
347 // regardless of whether it points to a alternative icon or just the current.
348 $GLOBALS['TBE_STYLES']['skinImg'][$srcKey] = array($src, $wHattribs);
349 }
350 // Rendering disabled (greyed) icons using _i (inactive) as name suffix ("_d" is already used)
351 $matches = array();
352 $srcBasename = basename($src);
353 if (preg_match('/(.*)_i(\\....)$/', $srcBasename, $matches)) {
354 $temp_path = dirname(PATH_thisScript) . '/';
355 if (!@is_file(($temp_path . $backPath . $src))) {
356 $srcOrg = preg_replace('/_i' . preg_quote($matches[2], '/') . '$/', $matches[2], $src);
357 $src = self::makeIcon($backPath . $srcOrg, 'disabled', 0, FALSE, $temp_path . $backPath . $srcOrg, $srcBasename);
358 }
359 }
360 // Return icon source/wHattributes:
361 $output = '';
362 switch ($outputMode) {
363 case 0:
364 $output = ' src="' . $backPath . $src . '" ' . $wHattribs;
365 break;
366 case 1:
367 $output = $backPath . $src;
368 break;
369 case 2:
370 $output = $wHattribs;
371 break;
372 }
373 $cachedSkinImages[$imageId] = $output;
374 return $output;
375 }
376
377 /***********************************
378 *
379 * Other functions
380 *
381 ***********************************/
382 /**
383 * Creates the icon file for the function getIcon()
384 *
385 * @param string $iconfile Original unprocessed Icon file, relative path to PATH_typo3
386 * @param string $mode Mode string, eg. "deleted" or "futuretiming" determining how the icon will look
387 * @param integer $user The number of the fe_group record uid if applicable
388 * @param boolean $protectSection Flag determines if the protected-section icon should be applied.
389 * @param string $absFile Absolute path to file from which to create the icon.
390 * @param string $iconFileName_stateTagged The filename that this icon should have had, basically [icon base name]_[flags].[extension] - used for part of temporary filename
391 * @return string Filename relative to PATH_typo3
392 * @access private
393 */
394 static public function makeIcon($iconfile, $mode, $user, $protectSection, $absFile, $iconFileName_stateTagged) {
395 $iconFileName = 'icon_' . GeneralUtility::shortMD5(($iconfile . '|' . $mode . '|-' . $user . '|' . $protectSection)) . '_' . $iconFileName_stateTagged . '.' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] ? 'png' : 'gif');
396 $mainpath = '../typo3temp/' . $iconFileName;
397 $path = PATH_site . 'typo3temp/' . $iconFileName;
398 if (file_exists(PATH_typo3 . 'icons/' . $iconFileName)) {
399 // Returns if found in typo3/icons/
400 return 'icons/' . $iconFileName;
401 } elseif (file_exists($path)) {
402 // Returns if found in ../typo3temp/icons/
403 return $mainpath;
404 } else {
405 // Makes icon:
406 if (file_exists($absFile)) {
407 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) {
408 // Create image pointer, if possible
409 $im = self::imagecreatefrom($absFile);
410 if ($im < 0) {
411 return $iconfile;
412 }
413 // Converting to gray scale, dimming the icon:
414 if ($mode == 'disabled' or $mode != 'futuretiming' && $mode != 'no_icon_found' && !(!$mode && $user)) {
415 $totalImageColors = ImageColorsTotal($im);
416 for ($c = 0; $c < $totalImageColors; $c++) {
417 $cols = ImageColorsForIndex($im, $c);
418 $newcol = round(($cols['red'] + $cols['green'] + $cols['blue']) / 3);
419 $lighten = $mode == 'disabled' ? 2.5 : 2;
420 $newcol = round(255 - (255 - $newcol) / $lighten);
421 ImageColorSet($im, $c, $newcol, $newcol, $newcol);
422 }
423 }
424 // Applying user icon, if there are access control on the item:
425 if ($user) {
426 if ($user < 100) {
427 // Apply user number only if lower than 100
428 $black = ImageColorAllocate($im, 0, 0, 0);
429 imagefilledrectangle($im, 0, 0, $user > 10 ? 9 : 5, 8, $black);
430 $white = ImageColorAllocate($im, 255, 255, 255);
431 imagestring($im, 1, 1, 1, $user, $white);
432 }
433 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_group.gif');
434 if ($ol_im < 0) {
435 return $iconfile;
436 }
437 self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
438 }
439 // Applying overlay based on mode:
440 if ($mode) {
441 unset($ol_im);
442 switch ($mode) {
443 case 'deleted':
444 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_deleted.gif');
445 break;
446 case 'futuretiming':
447 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_timing.gif');
448 break;
449 case 'timing':
450 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_timing.gif');
451 break;
452 case 'hiddentiming':
453 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_hidden_timing.gif');
454 break;
455 case 'no_icon_found':
456 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_no_icon_found.gif');
457 break;
458 case 'disabled':
459 // is already greyed - nothing more
460 $ol_im = 0;
461 break;
462 case 'hidden':
463
464 default:
465 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_hidden.gif');
466 }
467 if ($ol_im < 0) {
468 return $iconfile;
469 }
470 if ($ol_im) {
471 self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
472 }
473 }
474 // Protect-section icon:
475 if ($protectSection) {
476 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_sub5.gif');
477 if ($ol_im < 0) {
478 return $iconfile;
479 }
480 self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
481 }
482 // Create the image as file, destroy GD image and return:
483 @self::imagemake($im, $path);
484 GeneralUtility::gif_compress($path, 'IM');
485 ImageDestroy($im);
486 return $mainpath;
487 } else {
488 return $iconfile;
489 }
490 } else {
491 return $GLOBALS['BACK_PATH'] . 'gfx/fileicons/default.gif';
492 }
493 }
494 }
495
496 /**
497 * The necessity of using this function for combining two images if GD is version 2 is that
498 * GD2 cannot manage to combine two indexed-color images without totally spoiling everything.
499 * In class \TYPO3\CMS\Core\Imaging\GraphicalFunctions this was solved by combining the images
500 * onto a first created true color image.
501 * However it has turned out that this method will not work if the indexed png-files contains transparency.
502 * So I had to turn my attention to ImageMagick - my 'enemy of death'.
503 * And so it happend - ImageMagick is now used to combine my two indexed-color images with transparency. And that works.
504 * Of course it works only if ImageMagick is able to create valid png-images - which you cannot be sure of with older versions (still 5+)
505 * The only drawback is (apparently) that IM creates true-color png's. The transparency of these will not be shown by MSIE on windows at this time (although it's straight 0%/100% transparency!) and the file size may be larger.
506 *
507 * @param resource $destinationImage Destination image
508 * @param resource $sourceImage Source image
509 * @param integer $destinationX Destination x-coordinate
510 * @param integer $destinationY Destination y-coordinate
511 * @param integer $sourceX Source x-coordinate
512 * @param integer $sourceY Source y-coordinate
513 * @param integer $destinationWidth Destination width
514 * @param integer $destinationHeight Destination height
515 * @param integer $sourceWidth Source width
516 * @param integer $sourceHeight Source height
517 * @return void
518 * @access private
519 * @see \TYPO3\CMS\Core\Imaging\GraphicalFunctions::imagecopyresized()
520 */
521 static public function imagecopyresized(&$destinationImage, $sourceImage, $destinationX, $destinationY, $sourceX, $sourceY, $destinationWidth, $destinationHeight, $sourceWidth, $sourceHeight) {
522 imagecopyresized($destinationImage, $sourceImage, $destinationX, $destinationY, $sourceX, $sourceY, $destinationWidth, $destinationHeight, $sourceWidth, $sourceHeight);
523 }
524
525 /**
526 * Create new image pointer from input file (either gif/png, in case the wrong format it is converted by \TYPO3\CMS\Core\Utility\GeneralUtility::read_png_gif())
527 *
528 * @param string $file Absolute filename of the image file from which to start the icon creation.
529 * @return mixed If success, image pointer, otherwise "-1
530 * @access private
531 * @see \TYPO3\CMS\Core\Utility\GeneralUtility::read_png_gif
532 */
533 static public function imagecreatefrom($file) {
534 $file = GeneralUtility::read_png_gif($file, $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']);
535 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']) {
536 return $file ? imagecreatefrompng($file) : -1;
537 } else {
538 return $file ? imagecreatefromgif($file) : -1;
539 }
540 }
541
542 /**
543 * Write the icon in $im pointer to $path
544 *
545 * @param pointer $im Pointer to GDlib image resource
546 * @param string $path Absolute path to the filename in which to write the icon.
547 * @return void
548 * @access private
549 */
550 static public function imagemake($im, $path) {
551 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']) {
552 @ImagePng($im, $path);
553 } else {
554 @ImageGif($im, $path);
555 }
556 if (@is_file($path)) {
557 GeneralUtility::fixPermissions($path);
558 }
559 }
560
561 /**********************************************
562 * SPRITE ICON API
563 *
564 * The Sprite Icon API helps you to quickly get the HTML for any icon you want
565 * this is typically wrapped in a <span> tag with corresponding CSS classes that
566 * will be responsible for the
567 *
568 * There are four ways to use this API:
569 *
570 * 1) for any given TCA record
571 * $spriteIconHtml = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord('pages', $row);
572 *
573 * 2) for any given File of Folder object
574 * $spriteIconHtml = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForResource($fileOrFolderObject);
575 *
576 * 3) for any given file
577 * $spriteIconHtml = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForFile('myimage.png');
578 *
579 * 4) for any other icon you know the name
580 * $spriteIconHtml = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-open');
581 *
582 **********************************************/
583 /**
584 * This generic method is used throughout the TYPO3 Backend to show icons
585 * in any variation which are not bound to any resource object (see getSpriteIconForResource)
586 * or database record (see getSpriteIconForRecord)
587 *
588 * Generates a HTML tag with proper CSS classes. The TYPO3 skin has
589 * defined these CSS classes already to have a pre-defined background image,
590 * and the correct background-position to show the necessary icon.
591 *
592 * If no options or overlays are given, the icon will be cached in
593 * $priteIconCache.
594 *
595 * @param string $iconName The name of the icon to fetch
596 * @param array $options An associative array with additional options and attributes for the tag. by default, the key is the name of the attribute, and the value is the parameter string that is set. However, there are some additional special reserved keywords that can be used as keys: "html" (which is the HTML that will be inside the icon HTML tag), "tagName" (which is an alternative tagName than "span"), and "class" (additional class names that will be merged with the sprite icon CSS classes)
597 * @param array $overlays An associative array with the icon-name as key, and the options for this overlay as an array again (see the parameter $options again)
598 *
599 * @return string The full HTML tag (usually a <span>)
600 * @access public
601 */
602 static public function getSpriteIcon($iconName, array $options = array(), array $overlays = array()) {
603 // Check if icon can be cached and return cached version if present
604 if (empty($options) && empty($overlays)) {
605 if (isset(static::$spriteIconCache[$iconName])) {
606 return static::$spriteIconCache[$iconName];
607 }
608 $iconIsCacheable = TRUE;
609 } else {
610 $iconIsCacheable = FALSE;
611 }
612
613 $innerHtml = isset($options['html']) ? $options['html'] : NULL;
614 $tagName = isset($options['tagName']) ? $options['tagName'] : NULL;
615
616 // Deal with the overlays
617 foreach ($overlays as $overlayIconName => $overlayOptions) {
618 $overlayOptions['html'] = $innerHtml;
619 $overlayOptions['class'] = (isset($overlayOptions['class']) ? $overlayOptions['class'] . ' ' : '') . 't3-icon-overlay';
620 $innerHtml = self::getSpriteIcon($overlayIconName, $overlayOptions);
621 }
622
623 $availableIcons = isset($GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable'])
624 ? (array) $GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable']
625 : array();
626 if ($iconName !== 'empty-empty' && !in_array($iconName, $availableIcons, TRUE)) {
627 $iconName = 'status-status-icon-missing';
628 }
629
630 // Create the CSS class
631 $options['class'] = self::getSpriteIconClasses($iconName) . (isset($options['class']) ? ' ' . $options['class'] : '');
632 unset($options['html'], $options['tagName']);
633 $spriteHtml = self::buildSpriteHtmlIconTag($options, $innerHtml, $tagName);
634
635 // Store result in cache if possible
636 if ($iconIsCacheable) {
637 static::$spriteIconCache[$iconName] = $spriteHtml;
638 }
639 return $spriteHtml;
640 }
641
642 /**
643 * This method is used throughout the TYPO3 Backend to show icons for a file type
644 *
645 * Generates a HTML tag with proper CSS classes. The TYPO3 skin has defined these CSS classes
646 * already to have a pre-defined background image, and the correct background-position to show
647 * the necessary icon.
648 *
649 * @param string $fileExtension The name of the icon to fetch, can be a file extension, full file path or one of the special keywords "folder" or "mount
650 * @param array $options An associative array with additional options and attributes for the tag. by default, the key is the name of the attribute, and the value is the parameter string that is set. However, there are some additional special reserved keywords that can be used as keys: "html" (which is the HTML that will be inside the icon HTML tag), "tagName" (which is an alternative tagName than "span"), and "class" (additional class names that will be merged with the sprite icon CSS classes)
651 * @return string The full HTML tag (usually a <span>)
652 * @access public
653 */
654 static public function getSpriteIconForFile($fileExtension, array $options = array()) {
655 $innerHtml = isset($options['html']) ? $options['html'] : NULL;
656 $tagName = isset($options['tagName']) ? $options['tagName'] : NULL;
657 // Create the CSS class
658 $options['class'] = self::mapFileExtensionToSpriteIconClass($fileExtension) . (isset($options['class']) ? ' ' . $options['class'] : '');
659 unset($options['html']);
660 unset($options['tagName']);
661 return self::buildSpriteHtmlIconTag($options, $innerHtml, $tagName);
662 }
663
664 /**
665 * Generates the spriteicon css classes name for a given path or fileExtension
666 * usually called from getSpriteIconForFile or ExtJs Provider
667 *
668 * @param string $fileExtension FileExtension can be jpg, gif etc, but also be 'mount' or 'folder', but can also be a full path which will be resolved then
669 * @return string The string of the CSS class, see \TYPO3\CMS\Backend\Utility\IconUtility::$fileSpriteIconNames
670 * @access private
671 */
672 static public function mapFileExtensionToSpriteIconClass($fileExtension) {
673 return self::getSpriteIconClasses(self::mapFileExtensionToSpriteIconName($fileExtension));
674 }
675
676 /**
677 * Generates the spriteicon name for a given path or fileExtension
678 * usually called from mapFileExtensionToSpriteIconClass and tceforms
679 *
680 * @param string $fileExtension FileExtension can be jpg, gif etc, but also be 'mount' or 'folder', but can also be a full path which will be resolved then
681 * @return string The string of the CSS class, see \TYPO3\CMS\Backend\Utility\IconUtility::$fileSpriteIconNames
682 * @access private
683 */
684 static public function mapFileExtensionToSpriteIconName($fileExtension) {
685 // If the file is a whole file with name etc (mainly, if it has a "." or a "/"),
686 // then it is checked whether it is a valid directory
687 if (strpos($fileExtension, '.') !== FALSE || strpos($fileExtension, '/') !== FALSE) {
688 // Check if it is a directory
689 $filePath = dirname(GeneralUtility::getIndpEnv('SCRIPT_FILENAME')) . '/' . $GLOBALS['BACK_PATH'] . $fileExtension;
690 $path = GeneralUtility::resolveBackPath($filePath);
691 if (is_dir($path) || substr($fileExtension, -1) === '/' || substr($fileExtension, -1) === '\\') {
692 $fileExtension = 'folder';
693 } else {
694 if (($pos = strrpos($fileExtension, '.')) !== FALSE) {
695 $fileExtension = strtolower(substr($fileExtension, $pos + 1));
696 } else {
697 $fileExtension = 'default';
698 }
699 }
700 }
701 // If the file extension is not valid
702 // then use the default one
703 if (!isset(self::$fileSpriteIconNames[$fileExtension])) {
704 $fileExtension = 'default';
705 }
706 $iconName = self::$fileSpriteIconNames[$fileExtension];
707 return $iconName;
708 }
709
710 /**
711 * This method is used throughout the TYPO3 Backend to show icons for a DB record
712 *
713 * Generates a HTML tag with proper CSS classes. The TYPO3 skin has defined these CSS classes
714 * already to have a pre-defined background image, and the correct background-position to show
715 * the necessary icon.
716 *
717 * @param string $table The TCA table name
718 * @param array $row The DB record of the TCA table
719 * @param array $options An associative array with additional options and attributes for the tag. by default, the key is the name of the attribute, and the value is the parameter string that is set. However, there are some additional special reserved keywords that can be used as keys: "html" (which is the HTML that will be inside the icon HTML tag), "tagName" (which is an alternative tagName than "span"), and "class" (additional class names that will be merged with the sprite icon CSS classes)
720 * @return string The full HTML tag (usually a <span>)
721 * @access public
722 */
723 static public function getSpriteIconForRecord($table, array $row, array $options = array()) {
724 $innerHtml = isset($options['html']) ? $options['html'] : NULL;
725 $tagName = isset($options['tagName']) ? $options['tagName'] : NULL;
726 // Overlay this record icon with the status of the row
727 $overlaySpriteIconName = self::mapRecordOverlayToSpriteIconName($table, $row);
728 if ($overlaySpriteIconName) {
729 $overlayOptions = array(
730 'html' => $innerHtml,
731 'class' => 't3-icon-overlay'
732 );
733 $innerHtml = self::getSpriteIcon($overlaySpriteIconName, $overlayOptions);
734 }
735 // Fetch the name for the CSS class, based on the $row
736 $options['class'] = self::mapRecordTypeToSpriteIconClass($table, $row) . (isset($options['class']) ? ' ' . $options['class'] : '');
737 unset($options['html']);
738 unset($options['tagName']);
739 return self::buildSpriteHtmlIconTag($options, $innerHtml, $tagName);
740 }
741
742 /**
743 * This method is used throughout the TYPO3 Backend to show icons for files and folders
744 *
745 * The method takes care of the translation of file extension to proper icon and for folders
746 * it will return the icon depending on the role of the folder.
747 *
748 * If the given resource is a folder there are some additional options that can be used:
749 * - mount-root => TRUE (to indicate this is the root of a mount)
750 * - folder-open => TRUE (to indicate that the folder is opened in the file tree)
751 *
752 * There is a hook in place to manipulate the icon name and overlays.
753 *
754 * @param \TYPO3\CMS\Core\Resource\ResourceInterface $resource
755 * @param array $options An associative array with additional options and attributes for the tag. See self::getSpriteIcon()
756 * @param array $overlays An associative array with the icon-name as key, and the options for this overlay as an array again (see the parameter $options again)
757 * @return string
758 * @throws \UnexpectedValueException
759 */
760 static public function getSpriteIconForResource(\TYPO3\CMS\Core\Resource\ResourceInterface $resource, array $options = array(), array $overlays = array()) {
761 // Folder
762 if ($resource instanceof \TYPO3\CMS\Core\Resource\FolderInterface) {
763 // non browsable storage
764 if ($resource->getStorage()->isBrowsable() === FALSE && !empty($options['mount-root'])) {
765 $iconName = 'apps-filetree-folder-locked';
766 // storage root
767 } elseif ($resource->getStorage()->getRootLevelFolder()->getIdentifier() === $resource->getIdentifier()) {
768 $iconName = 'apps-filetree-root';
769 // user/group mount root
770 } elseif (!empty($options['mount-root'])) {
771 $iconName = 'apps-filetree-mount';
772 } else {
773
774 // in folder tree view $options['folder-open'] can define a open folder icon
775 if (!empty($options['folder-open'])) {
776 $iconName = 'apps-filetree-folder-opened';
777 } else {
778 $iconName = 'apps-filetree-folder-default';
779 }
780
781 $role = $resource->getRole();
782 if ($role === \TYPO3\CMS\Core\Resource\FolderInterface::ROLE_TEMPORARY) {
783 $iconName = 'apps-filetree-folder-temp';
784 } elseif ($role === \TYPO3\CMS\Core\Resource\FolderInterface::ROLE_RECYCLER) {
785 $iconName = 'apps-filetree-folder-recycler';
786 }
787
788 // if locked add overlay
789 if ($resource instanceof \TYPO3\CMS\Core\Resource\InaccessibleFolder) {
790 $overlays['status-overlay-locked'] = array();
791 }
792 }
793 // File
794 } else {
795 $iconName = self::mapFileExtensionToSpriteIconName($resource->getExtension());
796
797 if ($resource instanceof \TYPO3\CMS\Core\Resource\File && $resource->isMissing()) {
798 $overlays['status-overlay-missing'] = array();
799 }
800 }
801
802 // Hook: allow some other process to influence the choice of icon and overlays
803 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_iconworks.php']['overrideResourceIcon'])) {
804 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_iconworks.php']['overrideResourceIcon'] as $classRef) {
805 $hookObject = GeneralUtility::getUserObj($classRef);
806 if (!$hookObject instanceof IconUtilityOverrideResourceIconHookInterface) {
807 throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Backend\\Utility\\IconUtilityOverrideResourceIconHookInterface', 1393574895);
808 }
809 $hookObject->overrideResourceIcon($resource, $iconName, $options, $overlays);
810 }
811 }
812
813 unset($options['mount-root']);
814 unset($options['folder-open']);
815 return self::getSpriteIcon($iconName, $options, $overlays);
816 }
817
818 /**
819 * this helper functions looks up the column that is used for the type of
820 * the chosen TCA table. And then fetches the corresponding class
821 * based on the chosen iconsprite class in this TCA
822 * The TCA looks up
823 * - [ctrl][typeicon_column]
824 * -
825 * This method solely takes care of the type of this record, not any
826 * statuses, used for overlays.
827 * You should not use this directly besides if you need classes for ExtJS iconCls.
828 *
829 * see ext:core/Configuration/TCA/pages.php for an example with the TCA table "pages"
830 *
831 * @param string $table The TCA table
832 * @param array $row The selected record
833 * @return string The CSS class for the sprite icon of that DB record
834 * @access private
835 */
836 static public function mapRecordTypeToSpriteIconClass($table, array $row) {
837 return self::getSpriteIconClasses(self::mapRecordTypeToSpriteIconName($table, $row));
838 }
839
840 /**
841 * this helper functions looks up the column that is used for the type of
842 * the chosen TCA table. And then fetches the corresponding iconname
843 * based on the chosen iconsprite class in this TCA
844 * The TCA looks up
845 * - [ctrl][typeicon_column]
846 * -
847 * This method solely takes care of the type of this record, not any
848 * statuses, used for overlays.
849 * You should not use this directly besides if you need it in tceforms/core classes
850 *
851 * see ext:core/Configuration/TCA/pages.php for an example with the TCA table "pages"
852 *
853 * @param string $tableThe TCA table
854 * @param array $row The selected record
855 * @return string The CSS class for the sprite icon of that DB record
856 * @access private
857 */
858 static public function mapRecordTypeToSpriteIconName($table, array $row) {
859 $recordType = array();
860 $ref = NULL;
861 if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_column'])) {
862 $column = $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
863 if (isset($row[$column])) {
864 $recordType[1] = $row[$column];
865 } else {
866 $recordType[1] = 'default';
867 }
868 // Workaround to give nav_hide pages a complete different icon
869 // Although it's not a separate doctype
870 // and to give root-pages an own icon
871 if ($table === 'pages') {
872 if ($row['nav_hide']) {
873 $recordType[2] = $recordType[1] . '-hideinmenu';
874 }
875 if ($row['is_siteroot']) {
876 $recordType[3] = $recordType[1] . '-root';
877 }
878 if ($row['module']) {
879 $recordType[4] = 'contains-' . $row['module'];
880 }
881 }
882 if (is_array($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'])) {
883 foreach ($recordType as $key => $type) {
884 if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'][$type])) {
885 $recordType[$key] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'][$type];
886 } else {
887 unset($recordType[$key]);
888 }
889 }
890 $recordType[0] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['default'];
891 if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['mask'])) {
892 $recordType[5] = str_replace('###TYPE###', $row[$column], $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['mask']);
893 }
894 if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['userFunc'])) {
895 $parameters = array('row' => $row);
896 $recordType[6] = GeneralUtility::callUserFunction($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['userFunc'], $parameters, $ref);
897 }
898 } else {
899 foreach ($recordType as &$type) {
900 $type = 'tcarecords-' . $table . '-' . $type;
901 }
902 unset($type);
903 $recordType[0] = 'tcarecords-' . $table . '-default';
904 }
905 } else {
906 if (is_array($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'])) {
907 $recordType[0] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['default'];
908 } else {
909 $recordType[0] = 'tcarecords-' . $table . '-default';
910 }
911 }
912 krsort($recordType);
913 if (is_array($GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable'])) {
914 foreach ($recordType as $iconName) {
915 if (in_array($iconName, $GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable'])) {
916 return $iconName;
917 }
918 }
919 }
920 return 'status-status-icon-missing';
921 }
922
923 /**
924 * this helper functions checks if the DB record ($row) has any special status
925 * based on the TCA settings like hidden, starttime etc, and then returns a specific
926 * Sprite icon class for the overlay of this DB record
927 * This method solely takes care of the overlay of this record, not any type
928 *
929 * Please note that this only returns one overlay, one status, that is prioritized
930 * by $GLOBALS['TYPO3_CONF_VARS']['BE']['spriteIconRecordOverlayPriorities']
931 * We wanted to not have these icons blown over by tons of overlays, so this is limited
932 * to just one.
933 *
934 * see ext:core/Configuration/DefaultConfiguration.php for the default options, you will find
935 * $GLOBALS['TYPO3_CONF_VARS']['BE']['spriteIconRecordOverlayNames'] that shows
936 * the list of CSS classes that will be used for the sprites, mapped to the statuses here
937 *
938 * @param string $table The TCA table
939 * @param array $row The selected record
940 * @return string The CSS class for the sprite icon of that DB record
941 * @access private
942 */
943 static public function mapRecordOverlayToSpriteIconName($table, array $row) {
944 $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
945 // Calculate for a given record the actual visibility at the moment
946 $status = array(
947 'hidden' => FALSE,
948 'starttime' => FALSE,
949 'endtime' => FALSE,
950 'futureendtime' => FALSE,
951 'fe_group' => FALSE,
952 'deleted' => FALSE,
953 'protectedSection' => FALSE,
954 'nav_hide' => $row['nav_hide'] ? TRUE : FALSE,
955 'noIconFound' => $row['_NO_ICON_FOUND'] ? TRUE : FALSE
956 );
957 // Icon state based on "enableFields":
958 if (is_array($tcaCtrl['enablecolumns'])) {
959 $enCols = $tcaCtrl['enablecolumns'];
960 // If "hidden" is enabled:
961 if ($tcaCtrl['enablecolumns']['disabled'] && $row[$tcaCtrl['enablecolumns']['disabled']]) {
962 $status['hidden'] = TRUE;
963 }
964 // If a "starttime" is set and higher than current time:
965 if ($tcaCtrl['enablecolumns']['starttime'] && $GLOBALS['EXEC_TIME'] < (int)$row[$tcaCtrl['enablecolumns']['starttime']]) {
966 $status['starttime'] = TRUE;
967 }
968 // If an "endtime" is set
969 if ($tcaCtrl['enablecolumns']['endtime']) {
970 if ((int)$row[$tcaCtrl['enablecolumns']['endtime']] > 0) {
971 if ((int)$row[$tcaCtrl['enablecolumns']['endtime']] < $GLOBALS['EXEC_TIME']) {
972 // End-timing applies at this point.
973 $status['endtime'] = TRUE;
974 } else {
975 // End-timing WILL apply in the future for this element.
976 $status['futureendtime'] = TRUE;
977 }
978 }
979 }
980 // If a user-group field is set
981 if ($tcaCtrl['enablecolumns']['fe_group'] && $row[$tcaCtrl['enablecolumns']['fe_group']]) {
982 $status['fe_group'] = TRUE;
983 }
984 }
985 // If "deleted" flag is set (only when listing records which are also deleted!)
986 if ($row[$tcaCtrl['delete']]) {
987 $status['deleted'] = TRUE;
988 }
989 // Detecting extendToSubpages (for pages only)
990 if ($table == 'pages' && $row['extendToSubpages']) {
991 $status['protectedSection'] = TRUE;
992 }
993 // Hook: allow some other process to influence the choice of icon overlay
994 // The method called receives the table name, the current row and the current status array as parameters
995 // The status array should be passed as a reference and in order to be modified within the hook
996 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_iconworks.php']['overrideIconOverlay'])) {
997 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_iconworks.php']['overrideIconOverlay'] as $classRef) {
998 $hookObject = GeneralUtility::getUserObj($classRef);
999 if (method_exists($hookObject, 'overrideIconOverlay')) {
1000 $hookObject->overrideIconOverlay($table, $row, $status);
1001 }
1002 }
1003 }
1004 // Now only show the status with the highest priority
1005 $priorities = $GLOBALS['TBE_STYLES']['spriteIconApi']['spriteIconRecordOverlayPriorities'];
1006 $iconName = '';
1007 if (is_array($priorities)) {
1008 foreach ($priorities as $priority) {
1009 if ($status[$priority]) {
1010 $iconName = $GLOBALS['TBE_STYLES']['spriteIconApi']['spriteIconRecordOverlayNames'][$priority];
1011 break;
1012 }
1013 }
1014 }
1015 return $iconName;
1016 }
1017
1018 /**
1019 * generic method to create the final CSS classes based on the sprite icon name
1020 * with the base class and splits the name into parts
1021 * is usually called by the methods that are responsible for fetching the names
1022 * out of the file name, or the record type
1023 *
1024 * @param string $name Iconname like 'actions-document-new'
1025 * @return string A list of all CSS classes needed for the HTML tag
1026 */
1027 static public function getSpriteIconClasses($iconName) {
1028 $cssClasses = ($baseCssClass = 't3-icon');
1029 $parts = explode('-', $iconName);
1030 if (count($parts) > 1) {
1031 // Will be something like "t3-icon-actions"
1032 $cssClasses .= ' ' . ($baseCssClass . '-' . $parts[0]);
1033 // Will be something like "t3-icon-actions-document"
1034 $cssClasses .= ' ' . ($baseCssClass . '-' . $parts[0] . '-' . $parts[1]);
1035 // Will be something like "t3-icon-document-new"
1036 $cssClasses .= ' ' . ($baseCssClass . '-' . substr($iconName, (strlen($parts[0]) + 1)));
1037 }
1038 return $cssClasses;
1039 }
1040
1041 /**
1042 * low level function that generates the HTML tag for the sprite icon
1043 * is usually called by the three API classes (getSpriteIcon, getSpriteIconForFile, getSpriteIconForRecord)
1044 * it does not care about classes or anything else, but just plainly builds the HTML tag
1045 *
1046 * @param array $tagAttributes An associative array of additional tagAttributes for the HTML tag
1047 * @param string $innerHtml The content within the tag, a "&nbsp;" by default
1048 * @param string $tagName The name of the HTML element that should be used (span by default)
1049 * @return string The sprite html icon tag
1050 */
1051 static protected function buildSpriteHtmlIconTag(array $tagAttributes, $innerHtml = NULL, $tagName = NULL) {
1052 $innerHtml = $innerHtml === NULL ? '&nbsp;' : $innerHtml;
1053 $tagName = $tagName === NULL ? 'span' : $tagName;
1054 $attributes = '';
1055 foreach ($tagAttributes as $attribute => $value) {
1056 $attributes .= ' ' . htmlspecialchars($attribute) . '="' . htmlspecialchars($value) . '"';
1057 }
1058 return '<' . $tagName . $attributes . '>' . $innerHtml . '</' . $tagName . '>';
1059 }
1060
1061 }