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