class.t3lib_iconworks.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2010 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 /**
00028  * Contains class for icon generation in the backend
00029  *
00030  * $Id: class.t3lib_iconworks.php 8145 2010-07-09 07:34:38Z steffenk $
00031  * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
00032  * XHTML compliant
00033  *
00034  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00035  */
00036 /**
00037  * [CLASS/FUNCTION INDEX of SCRIPT]
00038  *
00039  *
00040  *
00041  *   85: class t3lib_iconWorks
00042  *  100:     function getIconImage($table,$row=array(),$backPath,$params='',$shaded=FALSE)
00043  *  118:     function getIcon($table,$row=array(),$shaded=FALSE)
00044  *  264:     function skinImg($backPath,$src,$wHattribs='',$outputMode=0)
00045  *
00046  *              SECTION: Other functions
00047  *  353:     function makeIcon($iconfile,$mode, $user, $protectSection,$absFile,$iconFileName_stateTagged)
00048  *  475:     function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h)
00049  *  505:     function imagecreatefrom($file)
00050  *  522:     function imagemake($im, $path)
00051  *
00052  * TOTAL FUNCTIONS: 7
00053  * (This index is automatically created/updated by the extension "extdeveval")
00054  *
00055  */
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 /**
00067  * Icon generation, backend
00068  * This library has functions that returns - and if necessary creates - the icon for an element in TYPO3
00069  *
00070  * Expects global vars:
00071  * - $BACK_PATH
00072  * - PATH_typo3
00073  * - $TCA, $PAGES_TYPES
00074  *
00075  *
00076  * Notes:
00077  * These functions are strongly related to the interface of TYPO3.
00078  * The class is included in eg. init.php
00079  * ALL functions called without making a class instance, eg. "t3lib_iconWorks::getIconImage()"
00080  *
00081  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00082  * @package TYPO3
00083  * @subpackage t3lib
00084  */
00085 final class t3lib_iconWorks {
00086 
00087     public static $fileSpriteIconNames = array(
00088         'htm'   => 'mimetypes-text-html',
00089         'html'  => 'mimetypes-text-html',
00090         'css'   => 'mimetypes-text-css',
00091         'js'    => 'mimetypes-text-js',
00092         'csv'   => 'mimetypes-text-csv',
00093         'php'   => 'mimetypes-text-php',
00094         'php6'  => 'mimetypes-text-php',
00095         'php5'  => 'mimetypes-text-php',
00096         'php4'  => 'mimetypes-text-php',
00097         'php3'  => 'mimetypes-text-php',
00098         'inc'   => 'mimetypes-text-php',
00099         'ts'    => 'mimetypes-text-ts',
00100         'txt'   => 'mimetypes-text-text',
00101         'class' => 'mimetypes-text-text',
00102         'tmpl'  => 'mimetypes-text-text',
00103         'jpg'   => 'mimetypes-media-image',
00104         'jpeg'  => 'mimetypes-media-image',
00105         'gif'   => 'mimetypes-media-image',
00106         'png'   => 'mimetypes-media-image',
00107         'bmp'   => 'mimetypes-media-image',
00108         'tif'   => 'mimetypes-media-image',
00109         'tga'   => 'mimetypes-media-image',
00110         'psd'   => 'mimetypes-media-image',
00111         'eps'   => 'mimetypes-media-image',
00112         'avi'   => 'mimetypes-media-video',
00113         'mpg'   => 'mimetypes-media-video',
00114         'mpeg'  => 'mimetypes-media-video',
00115         'mov'   => 'mimetypes-media-video',
00116         'wav'   => 'mimetypes-media-audio',
00117         'mp3'   => 'mimetypes-media-audio',
00118         'mid'   => 'mimetypes-media-audio',
00119         'swf'   => 'mimetypes-media-flash',
00120         'swa'   => 'mimetypes-media-flash',
00121         'exe'   => 'mimetypes-executable-executable',
00122         'com'   => 'mimetypes-executable-executable',
00123         't3x'   => 'mimetypes-compressed',
00124         't3d'   => 'mimetypes-compressed',
00125         'zip'   => 'mimetypes-compressed',
00126         'tgz'   => 'mimetypes-compressed',
00127         'gz'    => 'mimetypes-compressed',
00128         'pdf'   => 'mimetypes-pdf',
00129         'doc'   => 'mimetypes-word',
00130         'sxw'   => 'mimetypes-word',
00131         'rtf'   => 'mimetypes-word',
00132         'xls'   => 'mimetypes-excel',
00133         'sxc'   => 'mimetypes-excel',
00134         'ppt'   => 'mimetypes-powerpoint',
00135         'mount' => 'apps-filetree-mount',
00136         'folder'  => 'apps-filetree-folder-default',
00137         'default' => 'mimetypes-other-other'
00138     );
00139 
00140     /**
00141      * Returns an icon image tag, 18x16 pixels, based on input information.
00142      * This function is recommended to use in your backend modules.
00143      * Usage: 60
00144      *
00145      * @param   string      The table name
00146      * @param   array       The table row ("enablefields" are at least needed for correct icon display and for pages records some more fields in addition!)
00147      * @param   string      The backpath to the main TYPO3 directory (relative path back to PATH_typo3)
00148      * @param   string      Additional attributes for the image tag
00149      * @param   boolean     If set, the icon will be grayed/shaded
00150      * @return  string      <img>-tag
00151      * @see getIcon()
00152      */
00153     public static function getIconImage($table, $row = array(), $backPath, $params = '', $shaded = FALSE) {
00154         $str = '<img' .
00155                 self::skinImg($backPath, self::getIcon($table, $row, $shaded), 'width="18" height="16"') .
00156                 (trim($params) ? ' ' . trim($params) : '');
00157         if (!stristr($str, 'alt="')) {
00158             $str.=' alt=""';
00159         }
00160         $str.=' />';
00161         return $str;
00162     }
00163 
00164     /**
00165      * Creates the icon for input table/row
00166      * Returns filename for the image icon, relative to PATH_typo3
00167      * Usage: 24
00168      *
00169      * @param   string      The table name
00170      * @param   array       The table row ("enablefields" are at least needed for correct icon display and for pages records some more fields in addition!)
00171      * @param   boolean     If set, the icon will be grayed/shaded
00172      * @return  string      Icon filename
00173      * @see getIconImage()
00174      */
00175     public static function getIcon($table, $row = array(), $shaded = FALSE) {
00176         global $TCA, $PAGES_TYPES, $ICON_TYPES;
00177 
00178             // Flags:
00179         $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]
00180         $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...
00181 
00182             // Shadow:
00183         if ($TCA[$table]['ctrl']['versioningWS']) {
00184             switch((int)$row['t3ver_state']) {
00185                 case 1:
00186                     return 'gfx/i/shadow_hide.png';
00187                 break;
00188                 case 2:
00189                     return 'gfx/i/shadow_delete.png';
00190                 break;
00191                 case 3:
00192                     return 'gfx/i/shadow_moveto_plh.png';
00193                 break;
00194                 case 4:
00195                     return 'gfx/i/shadow_moveto_pointer.png';
00196                 break;
00197             }
00198         }
00199 
00200             // First, find the icon file name. This can depend on configuration in TCA, field values and more:
00201         if ($table=='pages') {
00202                 // @TODO: RFC #7370: doktype 2&5 are deprecated since TYPO3 4.2-beta1
00203             if ($row['nav_hide'] && ($row['doktype']==1||$row['doktype']==2))   $row['doktype'] = 5;    // Workaround to change the icon if "Hide in menu" was set
00204 
00205             if (!$iconfile = $PAGES_TYPES[$row['doktype']]['icon']) {
00206                 $iconfile = $PAGES_TYPES['default']['icon'];
00207             }
00208             if ($row['module'] && $ICON_TYPES[$row['module']]['icon']) {
00209                 $iconfile = $ICON_TYPES[$row['module']]['icon'];
00210             }
00211         } else {
00212             if (!$iconfile = $TCA[$table]['ctrl']['typeicons'][$row[$TCA[$table]['ctrl']['typeicon_column']]]) {
00213                 $iconfile = (($TCA[$table]['ctrl']['iconfile']) ? $TCA[$table]['ctrl']['iconfile'] : $table.'.gif');
00214             }
00215         }
00216 
00217             // Setting path of iconfile if not already set. Default is "gfx/i/"
00218         if (!strstr($iconfile, '/')) {
00219             $iconfile = 'gfx/i/'.$iconfile;
00220         }
00221 
00222             // Setting the absolute path where the icon should be found as a file:
00223         if (substr($iconfile, 0, 3)=='../') {
00224             $absfile = PATH_site.substr($iconfile, 3);
00225         } else {
00226             $absfile = PATH_typo3.$iconfile;
00227         }
00228 
00229             // Initializing variables, all booleans except otherwise stated:
00230         $hidden = FALSE;
00231         $timing = FALSE;
00232         $futuretiming = FALSE;
00233         $user = FALSE;              // In fact an integer value...
00234         $deleted = FALSE;
00235         $protectSection = FALSE;    // Set, if a page-record (only pages!) has the extend-to-subpages flag set.
00236         $noIconFound = $row['_NO_ICON_FOUND'] ? TRUE : FALSE;
00237         // + $shaded which is also boolean!
00238 
00239             // Icon state based on "enableFields":
00240         if (is_array($TCA[$table]['ctrl']['enablecolumns'])) {
00241             $enCols = $TCA[$table]['ctrl']['enablecolumns'];
00242                 // If "hidden" is enabled:
00243             if ($enCols['disabled'])    { if ($row[$enCols['disabled']]) { $hidden = TRUE; }}
00244                 // If a "starttime" is set and higher than current time:
00245             if ($enCols['starttime']) {
00246                 if ($GLOBALS['EXEC_TIME'] < intval($row[$enCols['starttime']])) {
00247                     $timing = TRUE;
00248                         // ...And if "endtime" is NOT set:
00249                     if (intval($row[$enCols['endtime']]) == 0) {
00250                         $futuretiming = TRUE;
00251                     }
00252                 }
00253             }
00254                 // If an "endtime" is set:
00255             if ($enCols['endtime']) {
00256                 if (intval($row[$enCols['endtime']]) > 0) {
00257                     if (intval($row[$enCols['endtime']]) < $GLOBALS['EXEC_TIME']) {
00258                         $timing = TRUE; // End-timing applies at this point.
00259                     } else {
00260                         $futuretiming = TRUE;       // End-timing WILL apply in the future for this element.
00261                     }
00262                 }
00263             }
00264                 // If a user-group field is set:
00265             if ($enCols['fe_group']) {
00266                 $user = $row[$enCols['fe_group']];
00267                 if ($user && $doNotRenderUserGroupNumber)   $user = 100;    // Limit for user number rendering!
00268             }
00269         }
00270 
00271             // If "deleted" flag is set (only when listing records which are also deleted!)
00272         if ($col = $row[$TCA[$table]['ctrl']['delete']]) {
00273             $deleted = TRUE;
00274         }
00275             // Detecting extendToSubpages (for pages only)
00276         if ($table=='pages' && $row['extendToSubpages'] && ($hidden || $timing || $futuretiming || $user)) {
00277             $protectSection = TRUE;
00278         }
00279 
00280             // If ANY of the booleans are set it means we have to alter the icon:
00281         if ($hidden || $timing || $futuretiming || $user || $deleted || $shaded || $noIconFound) {
00282             $flags = '';
00283             $string = '';
00284             if ($deleted) {
00285                 $string = 'deleted';
00286                 $flags = 'd';
00287             } elseif ($noIconFound) {   // This is ONLY for creating icons with "?" on easily...
00288                 $string = 'no_icon_found';
00289                 $flags = 'x';
00290             } else {
00291                 if ($hidden) $string.='hidden';
00292                 if ($timing) $string.='timing';
00293                 if (!$string && $futuretiming) {
00294                     $string = 'futuretiming';
00295                 }
00296 
00297                 $flags.=
00298                     ($hidden ? 'h' : '').
00299                     ($timing ? 't' : '').
00300                     ($futuretiming ? 'f' : '').
00301                     ($user ? 'u' : '').
00302                     ($protectSection ? 'p' : '').
00303                     ($shaded ? 's' : '');
00304             }
00305 
00306                 // Create tagged icon file name:
00307             $iconFileName_stateTagged = preg_replace('/.([[:alnum:]]+)$/', '__'.$flags.'.\1', basename($iconfile));
00308 
00309                 // 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)
00310             if (@is_file(dirname($absfile) . '/' . $iconFileName_stateTagged) || @is_file($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . '/' . dirname($iconfile) . '/' . $iconFileName_stateTagged)) {   // Look for [iconname]_xxxx.[ext]
00311                 return dirname($iconfile).'/'.$iconFileName_stateTagged;
00312             } elseif ($doNotGenerateIcon)   {       // If no icon generation can be done, try to look for the _X icon:
00313                 $iconFileName_X = preg_replace('/.([[:alnum:]]+)$/', '__x.\1', basename($iconfile));
00314                 if (@is_file(dirname($absfile).'/'.$iconFileName_X)) {
00315                     return dirname($iconfile).'/'.$iconFileName_X;
00316                 } else {
00317                     return 'gfx/i/no_icon_found.gif';
00318                 }
00319             } else {    // Otherwise, create the icon:
00320                 $theRes = self::makeIcon($GLOBALS['BACK_PATH'] . $iconfile, $string, $user, $protectSection, $absfile, $iconFileName_stateTagged);
00321                 return $theRes;
00322             }
00323         } else {
00324             return $iconfile;
00325         }
00326     }
00327 
00328     /**
00329      * Returns the src=... for the input $src value OR any alternative found in $TBE_STYLES['skinImg']
00330      * Used for skinning the TYPO3 backend with an alternative set of icons
00331      * Usage: 336
00332      *
00333      * @param   string      Current backpath to PATH_typo3 folder
00334      * @param   string      Icon file name relative to PATH_typo3 folder
00335      * @param   string      Default width/height, defined like 'width="12" height="14"'
00336      * @param   integer     Mode: 0 (zero) is default and returns src/width/height. 1 returns value of src+backpath, 2 returns value of w/h.
00337      * @return  string      Returns ' src="[backPath][src]" [wHattribs]'
00338      * @see skinImgFile()
00339      */
00340     public static function skinImg($backPath, $src, $wHattribs = '', $outputMode = 0)   {
00341 
00342         static $cachedSkinImages = array();
00343 
00344         $imageId = md5($backPath . $src . $wHattribs . $outputMode);
00345 
00346         if (isset($cachedSkinImages[$imageId])) {
00347             return $cachedSkinImages[$imageId];
00348         }
00349             // Setting source key. If the icon is refered to inside an extension, we homogenize the prefix to "ext/":
00350         $srcKey = preg_replace('/^(\.\.\/typo3conf\/ext|sysext|ext)\//', 'ext/', $src);
00351         #if ($src!=$srcKey)debug(array($src, $srcKey));
00352 
00353             // LOOKING for alternative icons:
00354         if ($GLOBALS['TBE_STYLES']['skinImg'][$srcKey]) {   // Slower or faster with is_array()? Could be used.
00355             list($src, $wHattribs) = $GLOBALS['TBE_STYLES']['skinImg'][$srcKey];
00356         } elseif ($GLOBALS['TBE_STYLES']['skinImgAutoCfg']) {   // Otherwise, test if auto-detection is enabled:
00357 
00358                 // Search for alternative icon automatically:
00359             $fExt = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['forceFileExtension'];
00360             $scaleFactor = ($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['scaleFactor'] ? $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['scaleFactor'] : 1); // Scaling factor
00361             $lookUpName = ($fExt ? preg_replace('/\.[[:alnum:]]+$/', '', $srcKey) . '.' . $fExt : $srcKey); // Set filename to look for
00362 
00363             if ($fExt && !@is_file($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . $lookUpName)) {
00364                 // fallback to original filename if icon with forced extension doesn't exists
00365                 $lookUpName = $srcKey;
00366             }
00367                 // If file is found:
00368             if (@is_file($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'].$lookUpName)) { // If there is a file...
00369                 $iInfo = @getimagesize($GLOBALS['TBE_STYLES']['skinImgAutoCfg']['absDir'] . $lookUpName);   // Get width/height:
00370 
00371                     // Set $src and $wHattribs:
00372                 $src = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['relDir'] . $lookUpName;
00373                 $wHattribs = 'width="' . round($iInfo[0] * $scaleFactor) . '" height="' . round($iInfo[1] * $scaleFactor) . '"';
00374             }
00375 
00376                 // In any case, set currect src / wHattrib - this way we make sure that an entry IS found next time we hit the function,
00377                 // regardless of whether it points to a alternative icon or just the current.
00378             $GLOBALS['TBE_STYLES']['skinImg'][$srcKey] = array($src, $wHattribs);       // Set default...
00379         }
00380 
00381             // DEBUG: This doubles the size of all icons - for testing/debugging:
00382         # if (preg_match('/^width="([0-9]+)" height="([0-9]+)"$/', $wHattribs, $reg))   $wHattribs='width="'.($reg[1]*2).'" height="'.($reg[2]*2).'"';
00383 
00384 
00385             // rendering disabled (greyed) icons using _i (inactive) as name suffix ("_d" is already used)
00386         $matches = array();
00387         $srcBasename = basename($src);
00388         if (preg_match('/(.*)_i(\....)$/', $srcBasename, $matches)) {
00389             $temp_path = dirname(PATH_thisScript) . '/';
00390             if (!@is_file($temp_path . $backPath . $src)) {
00391                 $srcOrg = preg_replace('/_i' . preg_quote($matches[2]) . '$/', $matches[2], $src);
00392                 $src = self::makeIcon($backPath . $srcOrg, 'disabled', 0, false, $temp_path . $backPath . $srcOrg, $srcBasename);
00393             }
00394         }
00395 
00396 
00397             // Return icon source/wHattributes:
00398         $output = '';
00399         switch($outputMode) {
00400             case 0:
00401                 $output = ' src="' . $backPath . $src . '" ' . $wHattribs;
00402             break;
00403             case 1:
00404                 $output = $backPath . $src;
00405             break;
00406             case 2:
00407                 $output = $wHattribs;
00408             break;
00409         }
00410 
00411         $cachedSkinImages[$imageId] = $output;
00412         return $output;
00413     }
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425     /***********************************
00426      *
00427      * Other functions
00428      *
00429      ***********************************/
00430 
00431     /**
00432      * Creates the icon file for the function getIcon()
00433      *
00434      * @param   string      Original unprocessed Icon file, relative path to PATH_typo3
00435      * @param   string      Mode string, eg. "deleted" or "futuretiming" determining how the icon will look
00436      * @param   integer     The number of the fe_group record uid if applicable
00437      * @param   boolean     Flag determines if the protected-section icon should be applied.
00438      * @param   string      Absolute path to file from which to create the icon.
00439      * @param   string      The filename that this icon should have had, basically [icon base name]_[flags].[extension] - used for part of temporary filename
00440      * @return  string      Filename relative to PATH_typo3
00441      * @access private
00442      */
00443     public static function makeIcon($iconfile, $mode, $user, $protectSection, $absFile, $iconFileName_stateTagged) {
00444         $iconFileName = 'icon_'.t3lib_div::shortMD5($iconfile.'|'.$mode.'|-'.$user.'|'.$protectSection).'_'.$iconFileName_stateTagged.'.'.($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']?'png':'gif');
00445         $mainpath = '../typo3temp/'.$iconFileName;
00446         $path = PATH_site.'typo3temp/'.$iconFileName;
00447 
00448 
00449         if (file_exists(PATH_typo3.'icons/'.$iconFileName)) {   // Returns if found in typo3/icons/
00450             return 'icons/'.$iconFileName;
00451         } elseif (file_exists($path))   {   // Returns if found in ../typo3temp/icons/
00452             return $mainpath;
00453         } else {    // Makes icon:
00454             if (file_exists($absFile)) {
00455                 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'])    {
00456 
00457                         // Create image pointer, if possible
00458                     $im = self::imagecreatefrom($absFile);
00459                     if ($im<0)  return $iconfile;
00460 
00461                         // Converting to gray scale, dimming the icon:
00462                     if (($mode=='disabled') OR ($mode!='futuretiming' && $mode!='no_icon_found' && !(!$mode && $user))) {
00463                         for ($c = 0; $c<ImageColorsTotal($im); $c++) {
00464                             $cols = ImageColorsForIndex($im, $c);
00465                             $newcol = round(($cols['red']+$cols['green']+$cols['blue'])/3);
00466                             $lighten = ($mode=='disabled') ? 2.5 : 2;
00467                             $newcol = round(255-((255-$newcol)/$lighten));
00468                             ImageColorSet($im, $c, $newcol, $newcol, $newcol);
00469                         }
00470                     }
00471                         // Applying user icon, if there are access control on the item:
00472                     if ($user) {
00473                         if ($user < 100)    {   // Apply user number only if lower than 100
00474                             $black = ImageColorAllocate($im, 0, 0, 0);
00475                             imagefilledrectangle($im, 0, 0, (($user>10)?9:5), 8, $black);
00476 
00477                             $white = ImageColorAllocate($im, 255, 255, 255);
00478                             imagestring($im, 1, 1, 1, $user, $white);
00479                         }
00480 
00481                         $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_group.gif');
00482                         if ($ol_im<0)   return $iconfile;
00483 
00484                         self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
00485                     }
00486                         // Applying overlay based on mode:
00487                     if ($mode) {
00488                         unset($ol_im);
00489                         switch($mode) {
00490                             case 'deleted':
00491                                 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_deleted.gif');
00492                             break;
00493                             case 'futuretiming':
00494                                 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_timing.gif');
00495                             break;
00496                             case 'timing':
00497                                 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_timing.gif');
00498                             break;
00499                             case 'hiddentiming':
00500                                 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_hidden_timing.gif');
00501                             break;
00502                             case 'no_icon_found':
00503                                 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_no_icon_found.gif');
00504                             break;
00505                             case 'disabled':
00506                                     // is already greyed - nothing more
00507                                 $ol_im = 0;
00508                             break;
00509                             case 'hidden':
00510                             default:
00511                                 $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_hidden.gif');
00512                             break;
00513                         }
00514                         if ($ol_im<0)   return $iconfile;
00515                         if ($ol_im) {
00516                             self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
00517                         }
00518                     }
00519                         // Protect-section icon:
00520                     if ($protectSection) {
00521                         $ol_im = self::imagecreatefrom($GLOBALS['BACK_PATH'] . 'gfx/overlay_sub5.gif');
00522                         if ($ol_im<0)   return $iconfile;
00523                         self::imagecopyresized($im, $ol_im, 0, 0, 0, 0, imagesx($ol_im), imagesy($ol_im), imagesx($ol_im), imagesy($ol_im));
00524                     }
00525 
00526                         // Create the image as file, destroy GD image and return:
00527                     @self::imagemake($im, $path);
00528                     t3lib_div::gif_compress($path, 'IM');
00529                     ImageDestroy($im);
00530                     return $mainpath;
00531                 } else {
00532                     return $iconfile;
00533                 }
00534             } else {
00535                 return $GLOBALS['BACK_PATH'].'gfx/fileicons/default.gif';
00536             }
00537         }
00538     }
00539 
00540     /**
00541      * The necessity of using this function for combining two images if GD is version 2 is that
00542      * GD2 cannot manage to combine two indexed-color images without totally spoiling everything.
00543      * In class.t3lib_stdgraphic this was solved by combining the images onto a first created true color image
00544      * However it has turned out that this method will not work if the indexed png-files contains transparency.
00545      * So I had to turn my attention to ImageMagick - my 'enemy of death'.
00546      * And so it happend - ImageMagick is now used to combine my two indexed-color images with transparency. And that works.
00547      * 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+)
00548      * 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.
00549      *
00550      * For parameters, see PHP function "imagecopyresized()"
00551      *
00552      * @param   pointer     see PHP function "imagecopyresized()"
00553      * @param   pointer     see PHP function "imagecopyresized()"
00554      * @param   integer     see PHP function "imagecopyresized()"
00555      * @param   integer     see PHP function "imagecopyresized()"
00556      * @param   integer     see PHP function "imagecopyresized()"
00557      * @param   integer     see PHP function "imagecopyresized()"
00558      * @param   integer     see PHP function "imagecopyresized()"
00559      * @param   integer     see PHP function "imagecopyresized()"
00560      * @param   integer     see PHP function "imagecopyresized()"
00561      * @param   integer     see PHP function "imagecopyresized()"
00562      * @return  void
00563      * @access private
00564      */
00565     public static function imagecopyresized(&$im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h) {
00566         imagecopyresized($im, $cpImg, $Xstart, $Ystart, $cpImgCutX, $cpImgCutY, $w, $h, $w, $h);
00567     }
00568 
00569     /**
00570      * Create new image pointer from input file (either gif/png, in case the wrong format it is converted by t3lib_div::read_png_gif())
00571      *
00572      * @param   string      Absolute filename of the image file from which to start the icon creation.
00573      * @return  mixed       If success, image pointer, otherwise "-1"
00574      * @access private
00575      * @see t3lib_div::read_png_gif
00576      */
00577     public static function imagecreatefrom($file) {
00578         $file = t3lib_div::read_png_gif($file, $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']);
00579         if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']) {
00580             return $file ? imagecreatefrompng($file) : -1;
00581         } else {
00582             return $file ? imagecreatefromgif($file) : -1;
00583         }
00584     }
00585 
00586     /**
00587      * Write the icon in $im pointer to $path
00588      *
00589      * @param   pointer     Pointer to GDlib image resource
00590      * @param   string      Absolute path to the filename in which to write the icon.
00591      * @return  void
00592      * @access private
00593      */
00594     public static function imagemake($im, $path) {
00595         if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']) {
00596             @ImagePng($im, $path);
00597         } else {
00598             @ImageGif($im, $path);
00599         }
00600     }
00601 
00602 
00603     /**********************************************
00604      *         SPRITE ICON API
00605      *
00606      * The Sprite Icon API helps you to quickly get the HTML for any icon you want
00607      * this is typically wrapped in a <span> tag with corresponding CSS classes that
00608      * will be responsible for the
00609      *
00610      * There are three ways to use this API:
00611      *
00612      * 1) for any given TCA record
00613      *    $spriteIconHtml = t3lib_iconWorks::getSpriteIconForRecord('pages', $row);
00614      *
00615      * 2) for any given file
00616      *    $spriteIconHtml = t3lib_iconWorks::getSpriteIconForFile('myimage.png');
00617      *
00618      * 3) for any other icon you know the name
00619      *    $spriteIconHtml = t3lib_iconWorks::getSpriteIcon('actions-document-open');
00620      *
00621      **********************************************/
00622 
00623     /**
00624      * This generic method is used throughout the TYPO3 Backend to show icons in any variation which are not
00625      * bound to any file type (see getSpriteIconForFile) or database record (see getSpriteIconForRecord)
00626      *
00627      * Generates a HTML tag with proper CSS classes. The TYPO3 skin has defined these CSS classes
00628      * already to have a pre-defined background image, and the correct background-position to show
00629      * the necessary icon.
00630      *
00631      * @param   string  $iconName   the name of the icon to fetch
00632      * @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)
00633      * @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)
00634      * @return  string  the full HTML tag (usually a <span>)
00635      * @access public
00636      */
00637     public static function getSpriteIcon($iconName, array $options = array(), array $overlays = array()) {
00638         $innerHtml = (isset($options['html'])    ? $options['html']    : '');
00639         $tagName   = (isset($options['tagName']) ? $options['tagName'] : 'span');
00640 
00641             // deal with the overlays
00642         if (count($overlays)) {
00643             foreach ($overlays as $overlayIconName => $overlayOptions) {
00644                 $overlayOptions['html']  = $innerHtml;
00645                 $overlayOptions['class'] = (isset($overlayOptions['class']) ? $overlayOptions['class'] . ' ': '') . 't3-icon-overlay';
00646                 $innerHtml = self::getSpriteIcon($overlayIconName, $overlayOptions);
00647             }
00648         }
00649 
00650             // check if whished icon is available
00651         $iconName = (in_array($iconName, $GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable']) || $iconName == 'empty-empty' ? $iconName : 'status-status-icon-missing');
00652 
00653             // create the CSS class
00654         $options['class'] = self::getSpriteIconClasses($iconName) . (isset($options['class']) ? ' ' . $options['class'] : '');
00655 
00656         unset($options['html']);
00657         unset($options['tagName']);
00658         return self::buildSpriteHtmlIconTag($options, $innerHtml, $tagName);
00659     }
00660 
00661 
00662     /**
00663      * This method is used throughout the TYPO3 Backend to show icons for a file type
00664      *
00665      * Generates a HTML tag with proper CSS classes. The TYPO3 skin has defined these CSS classes
00666      * already to have a pre-defined background image, and the correct background-position to show
00667      * the necessary icon.
00668      *
00669      * @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"
00670      * @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)
00671      * @return  string  the full HTML tag (usually a <span>)
00672      * @access public
00673      */
00674     public static function getSpriteIconForFile($fileExtension, array $options = array()) {
00675         $innerHtml = (isset($options['html'])    ? $options['html']    : '');
00676         $tagName   = (isset($options['tagName']) ? $options['tagName'] : 'span');
00677 
00678             // create the CSS class
00679         $options['class'] = self::mapFileExtensionToSpriteIconClass($fileExtension) . (isset($options['class']) ? ' ' . $options['class'] : '');
00680 
00681         unset($options['html']);
00682         unset($options['tagName']);
00683         return self::buildSpriteHtmlIconTag($options, $innerHtml, $tagName);
00684     }
00685 
00686 
00687     /**
00688      * Generates the spriteicon name for a given path or fileExtension
00689      * usually called from getSpriteIconForFile
00690      *
00691      * @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
00692      * @return  string      the string of the CSS class, see t3lib_iconworks::$fileSpriteIconNames
00693      */
00694     public static function mapFileExtensionToSpriteIconClass($fileExtension) {
00695 
00696             // if the file is a whole file with name etc (mainly, if it has a "." or a "/"),
00697             // then it is checked whether it is a valid directory
00698         if (strpos($fileExtension, '.') !== FALSE || strpos($fileExtension, '/') !== FALSE) {
00699 
00700                 // check if it is a directory
00701             $filePath = dirname(t3lib_div::getIndpEnv('SCRIPT_FILENAME')) . '/' . $GLOBALS['BACK_PATH'] . $fileExtension;
00702             $path = t3lib_div::resolveBackPath($filePath);
00703             if (is_dir($path) || substr($fileExtension, -1) === '/' || substr($fileExtension, -1) === '\\') {
00704                 $fileExtension = 'folder';
00705             } else if (($pos = strrpos($fileExtension, '.')) !== FALSE) {
00706                 $fileExtension = strtolower(substr($fileExtension, $pos + 1));
00707             } else {
00708                 $fileExtension = 'default';
00709             }
00710         }
00711 
00712             // if the file extension is not valid
00713             // then use the default one
00714         if (!isset(self::$fileSpriteIconNames[$fileExtension])) {
00715             $fileExtension = 'default';
00716         }
00717         $iconName = self::$fileSpriteIconNames[$fileExtension];
00718         return self::getSpriteIconClasses($iconName);
00719     }
00720 
00721 
00722     /**
00723      * This method is used throughout the TYPO3 Backend to show icons for a DB record
00724      *
00725      * Generates a HTML tag with proper CSS classes. The TYPO3 skin has defined these CSS classes
00726      * already to have a pre-defined background image, and the correct background-position to show
00727      * the necessary icon.
00728      *
00729      * @param   string  $table  the TCA table name
00730      * @param   array   $row    the DB record of the TCA table
00731      * @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)
00732      * @return  string  the full HTML tag (usually a <span>)
00733      * @access public
00734      */
00735     public static function getSpriteIconForRecord($table, array $row, array $options = array()) {
00736         $innerHtml = (isset($options['html'])    ? $options['html']    : '');
00737         $tagName   = (isset($options['tagName']) ? $options['tagName'] : 'span');
00738 
00739             // overlay this record icon with the status of the row
00740         $overlaySpriteIconName = self::mapRecordOverlayToSpriteIconName($table, $row);
00741         if ($overlaySpriteIconName) {
00742             $overlayOptions = array(
00743                 'html'  => $innerHtml,
00744                 'class' => 't3-icon-overlay'
00745             );
00746             $innerHtml = self::getSpriteIcon($overlaySpriteIconName, $overlayOptions);
00747         }
00748 
00749             // fetch the name for the CSS class, based on the $row
00750         $options['class'] = self::mapRecordTypeToSpriteIconClass($table, $row) . (isset($options['class']) ? ' ' . $options['class'] : '');
00751 
00752         unset($options['html']);
00753         unset($options['tagName']);
00754         return self::buildSpriteHtmlIconTag($options, $innerHtml, $tagName);
00755     }
00756 
00757 
00758     /**
00759      * this helper functions looks up the column that is used for the type of
00760      * the chosen TCA table. And then fetches the corresponding class
00761      * based on the chosen iconsprite class in this TCA
00762      * The TCA looks up
00763      *   - [ctrl][typeicon_column]
00764      *   -
00765      * This method solely takes care of the type of this record, not any
00766      * statuses, used for overlays.
00767      *
00768      * see t3lib/stddb/tables.php for an example with the TCA table "pages"
00769      *
00770      * @param   string  $table  the TCA table
00771      * @param   array   $row    the selected record
00772      * @return  string  the CSS class for the sprite icon of that DB record
00773      * @access  private
00774      **/
00775     protected static function mapRecordTypeToSpriteIconClass($table, array $row) {
00776         $iconName = '';
00777         $recordType = array();
00778         if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_column'])) {
00779             $column = $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
00780 
00781             if (isset($row[$column])) {
00782                 $recordType[1] = $row[$column];
00783             } else {
00784                 $recordType[1] = 'default';
00785             }
00786 
00787                 // workaround to give nav_hide pages a complete different icon
00788                 // although it's not a separate doctype
00789                 // and to give root-pages an own icon
00790             if ($table === 'pages') {
00791                 if ($row['nav_hide']) {
00792                     $recordType[2] = $recordType[1] . '-hideinmenu';
00793                 }
00794                 if ($row['is_siteroot']) {
00795                     $recordType[3] = $recordType[1] . '-root';
00796                 }
00797                 if ($row['module']) {
00798                     $recordType[4] = 'contains-' . $row['module'];
00799                 }
00800             }
00801 
00802             if (is_array($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'])) {
00803                 foreach ($recordType AS $key => $type) {
00804                     if (isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'][$type])) {
00805                         $recordType[$key] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'][$type];
00806                     } else {
00807                         unset($recordType[$key]);
00808                     }
00809                 }
00810                 $recordType[0] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['default'];
00811             } else {
00812                 foreach ($recordType AS $key => $type) {
00813                     $recordType[$key] = 'tcarecords-' . $table . '-' . $type;
00814                 }
00815                 $recordType[0] = 'tcarecords-' . $table . '-default';
00816             }
00817         } else {
00818             if (is_array($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'])) {
00819                 $recordType[0] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']['default'];
00820             } else {
00821                 $recordType[0] = 'tcarecords-' . $table . '-default';
00822             }
00823         }
00824         krsort($recordType);
00825         foreach ($recordType as $record) {
00826             if (in_array($record, $GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable'])) {
00827                 return self::getSpriteIconClasses($record);
00828             }
00829         }
00830         return self::getSpriteIconClasses('status-status-icon-missing');
00831     }
00832 
00833 
00834     /**
00835      * this helper functions checks if the DB record ($row) has any special status
00836      * based on the TCA settings like hidden, starttime etc, and then returns a specific
00837      * Sprite icon class for the overlay of this DB record
00838      * This method solely takes care of the overlay of this record, not any type
00839      *
00840      * Please note that this only returns one overlay, one status, that is prioritized
00841      * by $GLOBALS['TYPO3_CONF_VARS']['BE']['spriteIconRecordOverlayPriorities']
00842      * We wanted to not have these icons blown over by tons of overlays, so this is limited
00843      * to just one.
00844      *
00845      * see t3lib/config_default.php for the default options, you will find
00846      * $GLOBALS['TYPO3_CONF_VARS']['BE']['spriteIconRecordOverlayNames'] that shows
00847      * the list of CSS classes that will be used for the sprites, mapped to the statuses here
00848      *
00849      * @param   string  $table  the TCA table
00850      * @param   array   $row    the selected record
00851      * @return  string  the CSS class for the sprite icon of that DB record
00852      * @access  private
00853      */
00854     protected static function mapRecordOverlayToSpriteIconName($table, array $row) {
00855         $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
00856 
00857             // Calculate for a given record the actual visibility at the moment
00858         $status = array(
00859             'hidden'           => FALSE,
00860             'starttime'        => FALSE,
00861             'endtime'          => FALSE,
00862             'futureendtime'    => FALSE,
00863             'fe_group'         => FALSE,
00864             'deleted'          => FALSE,
00865             'protectedSection' => FALSE,
00866             'nav_hide'         => ($row['nav_hide'] ? TRUE : FALSE),
00867             'noIconFound'      => ($row['_NO_ICON_FOUND'] ? TRUE : FALSE),
00868         );
00869 
00870             // Icon state based on "enableFields":
00871         if (is_array($tcaCtrl['enablecolumns'])) {
00872             $enCols = $tcaCtrl['enablecolumns'];
00873                 // If "hidden" is enabled:
00874             if ($tcaCtrl['enablecolumns']['disabled'] && $row[$tcaCtrl['enablecolumns']['disabled']]) {
00875                 $status['hidden'] = TRUE;
00876             }
00877                 // If a "starttime" is set and higher than current time:
00878             if ($tcaCtrl['enablecolumns']['starttime'] && $GLOBALS['EXEC_TIME'] < intval($row[$tcaCtrl['enablecolumns']['starttime']])) {
00879                 $status['starttime'] = TRUE;
00880             }
00881 
00882                 // If an "endtime" is set
00883             if ($tcaCtrl['enablecolumns']['endtime']) {
00884                 if (intval($row[$tcaCtrl['enablecolumns']['endtime']]) > 0) {
00885                     if (intval($row[$tcaCtrl['enablecolumns']['endtime']]) < $GLOBALS['EXEC_TIME']) {
00886                             // End-timing applies at this point.
00887                         $status['endtime'] = TRUE;
00888                     } else {
00889                             // End-timing WILL apply in the future for this element.
00890                         $status['futureendtime'] = TRUE;
00891                     }
00892                 }
00893             }
00894                 // If a user-group field is set
00895             if ($tcaCtrl['enablecolumns']['fe_group'] && $row[$tcaCtrl['enablecolumns']['fe_group']]) {
00896                 $status['fe_group'] = TRUE;
00897             }
00898         }
00899 
00900             // If "deleted" flag is set (only when listing records which are also deleted!)
00901         if ($row[$tcaCtrl['delete']]) {
00902             $status['deleted'] = TRUE;
00903         }
00904 
00905             // Detecting extendToSubpages (for pages only)
00906         if ($table == 'pages' && $row['extendToSubpages']) {
00907             $status['protectedSection'] = TRUE;
00908         }
00909 
00910 
00911             // now only show the status with the highest priority
00912         $priorities = $GLOBALS['TBE_STYLES']['spriteIconApi']['spriteIconRecordOverlayPriorities'];
00913 
00914         $iconName = '';
00915         foreach ($priorities as $priority) {
00916             if ($status[$priority]) {
00917                 $iconName = $GLOBALS['TBE_STYLES']['spriteIconApi']['spriteIconRecordOverlayNames'][$priority];
00918                 break;
00919             }
00920         }
00921 
00922         return $iconName;
00923     }
00924 
00925 
00926 
00927     /**
00928      * generic method to create the final CSS classes based on the sprite icon name
00929      * with the base class and splits the name into parts
00930      * is usually called by the methods that are responsible for fetching the names
00931      * out of the file name, or the record type
00932      *
00933      * @param   string  $name   iconname like 'actions-document-new'
00934      * @return  string  a list of all CSS classes needed for the HTML tag
00935      * @access public
00936      */
00937     public static function getSpriteIconClasses($iconName) {
00938         $cssClasses = $baseCssClass = 't3-icon';
00939         $parts = explode('-', $iconName);
00940 
00941         if (count($parts) > 1) {
00942                 // will be something like "t3-icon-actions"
00943             $cssClasses .= ' ' . ($baseCssClass . '-' . $parts[0]);
00944                 // will be something like "t3-icon-actions-document"
00945             $cssClasses .= ' ' . ($baseCssClass . '-' . $parts[0] . '-' . $parts[1]);
00946                 // will be something like "t3-icon-document-new"
00947             $cssClasses .= ' ' . ($baseCssClass . '-' . substr($iconName, strlen($parts[0]) + 1));
00948         }
00949         return $cssClasses;
00950     }
00951 
00952 
00953     /**
00954      * low level function that generates the HTML tag for the sprite icon
00955      * is usually called by the three API classes (getSpriteIcon, getSpriteIconForFile, getSpriteIconForRecord)
00956      * it does not care about classes or anything else, but just plainly builds the HTML tag
00957      *
00958      * @param   array   $tagAttributes  an associative array of additional tagAttributes for the HTML tag
00959      * @param   string  $innerHtml (optional)   the content within the tag, a "&nbsp;" by default
00960      * @param   string  $tagName (optional) the name of the HTML element that should be used (span by default)
00961      */
00962     protected static function buildSpriteHtmlIconTag(array $tagAttributes, $innerHtml = '&nbsp;', $tagName = 'span') {
00963         $attributes = '';
00964         foreach ($tagAttributes as $attribute => $value) {
00965             $attributes .= ' ' . htmlspecialchars($attribute) . '="' . htmlspecialchars($value) . '"';
00966         }
00967         return '<' . $tagName . $attributes . '>' . $innerHtml . '</' . $tagName . '>';
00968     }
00969 
00970 }
00971 
00972 ?>

Generated on Sat Jul 24 04:17:17 2010 for TYPO3 API by  doxygen 1.4.7