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