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