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