Index: t3lib/class.t3lib_iconworks.php =================================================================== --- t3lib/class.t3lib_iconworks.php (revision 6911) +++ t3lib/class.t3lib_iconworks.php (working copy) @@ -84,6 +84,61 @@ */ final class t3lib_iconWorks { + public static $fileIconClasses = array( + 'htm' => 'mimetype-text-htm', + 'html' => 'mimetype-text-htm', + 'css' => 'mimetype-text-css', + 'js' => 'mimetype-text-js', + 'csv' => 'mimetype-text-csv', + 'xml' => 'mimetype-text-xml', + 'php' => 'mimetype-text-php', + 'php6' => 'mimetype-text-php', + 'php5' => 'mimetype-text-php', + 'php4' => 'mimetype-text-php', + 'php3' => 'mimetype-text-php', + 'inc' => 'mimetype-text-php', + 'ts' => 'mimetype-text-ts', + 'txt' => 'mimetype-text-text', + 'class' => 'mimetype-text-text', + 'tmpl' => 'mimetype-text-text', + 'jpg' => 'mimetype-media-image-jpg', + 'jpeg' => 'mimetype-media-image-jpg', + 'gif' => 'mimetype-media-image-gif', + 'png' => 'mimetype-media-image-png', + 'bmp' => 'mimetype-media-image-bmp', + 'tif' => 'mimetype-media-image', + 'tga' => 'mimetype-media-image', + 'psd' => 'mimetype-media-image', + 'eps' => 'mimetype-media-image', + 'avi' => 'mimetype-media-video-avi', + 'mpg' => 'mimetype-media-video', + 'mpeg' => 'mimetype-media-video', + 'mov' => 'mimetype-media-video', + 'wav' => 'mimetype-media-audio', + 'mp3' => 'mimetype-media-audio', + 'mid' => 'mimetype-media-audio', + 'swf' => 'mimetype-media-flash', + 'swa' => 'mimetype-media-flash', + 'exe' => 'mimetype-executable-executable', + 'com' => 'mimetype-executable-executable', + 't3x' => 'mimetype-compressed-t3x', + 't3d' => 'mimetype-compressed-t3d', + 'zip' => 'mimetype-compressed-compressed', + 'tgz' => 'mimetype-compressed-compressed', + 'gz' => 'mimetype-compressed-compressed', + 'pdf' => 'mimetype-word-pdf', + 'doc' => 'mimetype-word-word', + 'sxw' => 'mimetype-word-word', + 'rtf' => 'mimetype-word-word', + 'xls' => 'mimetype-spreadsheet-spreadsheet', + 'sxc' => 'mimetype-spreadsheet-spreadsheet', + 'ttf' => 'mimetype-font-font', + 'ppt' => 'mimetype-presentation-presentation', + 'mount' => 'apps-filetree-mount', + 'folder' => 'apps-filetree-folder-default', + 'default' => 'mimetype-other-other' + ); + /** * Returns an icon image tag, 18x16 pixels, based on input information. * This function is recommended to use in your backend modules. @@ -539,5 +594,310 @@ @ImageGif($im, $path); } } + + /** + * Generates a span tag with proper css classes so it's an icon with possible overlay + * + * @param string iconname will be passed to getSpriteIconClasses (see it options); can be multilevel by separation with '+' + * @param various an single- or multilevel options array or a title string [options are: baseCssClass, title, class, row] + * @params integer what option pass should be used (as we can have a muldimentional array as config; and multiple overlays with different configs) + * @return string full tag with css classes + */ + public static function getSpriteIcon($name, $overrideOptions = array(), $pass = 0) { + // get proper options + $fullOptions = $GLOBALS['TYPO3_CONF_VARS']['BE']['iconDefaultOptions']; + $options = $fullOptions[$pass]; + if (is_string($overrideOptions)) { + // option is a string -> set the title + $options['title'] = $overrideOptions; + } else if (is_array($overrideOptions) && !is_array($overrideOptions[$pass])) { + // options is an array -> merge it + $options = array_merge($options, $overrideOptions); + } else { + // options is a multidimentional array -> merge with local options; merge with full options + $options = array_merge($options, $overrideOptions[$pass]); + $fullOptions = t3lib_div::array_merge_recursive_overrule($fullOptions, $overrideOptions); + } + // row get's passed on to as we don't want to define this every time + $fullOptions[$pass+1]['row'] = $options['row']; + + // if the $name contains a '+' it uses multilevel, so get recursive configuration and content + $parts = explode('+', $name); + $subpart = ''; + if (count($parts) >= 2) { + $name = $parts[0]; + $subpart = self::getSpriteIcon($parts[1], $fullOptions, $pass + 1); + } + if ($subpart !== '') { + $options['html'] = ($options['html'] === ' ') ? $subpart : $options['html'] . $subpart; + } + + // if we actually get css classes create the html element according to the options + if ($classes = self::getSpriteIconClasses($name, $options)) { + $options['class'] = (!$options['class']) ? $classes : ($classes . ' ' . $options['class']); + $elementOptions = ''; + // add every string option as a html attribute (with some exception) + foreach ($options as $key => $option) { + if (is_string($option) && $option !== '' && $key !== 'html' && $key !== 'element' && $key !== 'baseCssClass') { + $elementOptions .= $key . '="' . $option . '" '; + } + } + return '<' . $options['element'] . ' ' . $elementOptions . '>' . $options['html'] . ''; + } + + return ''; + } + + /** + * Generates the css classes as a string needed for an icon + * + * @param string iconname like 'actions-document-new' || filepath like 'file:' || database like 'row:' (give row in options) + * @param array options like baseCssClass, row + * @return string all css classes needed for the icon + */ + public static function getSpriteIconClasses($name, array $overrideOptions = array()) { + $options = array('baseCssClass' => 't3-icon'); + if (is_string($overrideOptions)) { + $options['baseCssClass'] = $overrideOptions; + } else { + $options = array_merge($options, $overrideOptions); + } + + if (substr($name, 0, 5) === 'file:') { + if (substr($name, 0, 6) === 'file::') { + return self::getFileIconClasses('', substr($name, 6)); + } + return self::getFileIconClasses(substr($name, 5)); + } + if (substr($name, 0, 4) === 'row:') { + if (substr($name, 0, 5) === 'row::') { + return self::getRowIconOverlayClasses(substr($name, 5), $options['row']); + } + return self::getRowIconClasses(substr($name, 4), $options['row']); + } + + $parts = explode('-', $name); + $class = substr($name, strlen($parts[0]) + 1); + + if (count($parts) > 1) { + return $options['baseCssClass'] . ' ' . $options['baseCssClass'] . '-' . $parts[0] . '-' . $parts[1] . ' ' . $options['baseCssClass'] . '-' . $class; + } + + return ''; + } + + /** + * Generates the css classes needed for an icon of a row + * + * @param string table name of the row + * @param array data row + * @return string css classnames + */ + public static function getRowIconClasses($table, array $row) { + return self::getSpriteIconClasses(self::getRowIconString($table, $row)); + } + + /** + * Generates the IconStringName for a given tablerow + * + * @param string table name of the row + * @param array data row + * @return string iconstring + * + */ + public static function getRowIconString($table, array $row) { + global $TCA; + $column = $TCA[$table]['ctrl']['typeicon_column']; + // workaround to give nav_hide pages a complete different icon although it's not a separate doctype + if ($table === 'pages' && $row['nav_hide']) { + $row[$column] .= '-not-in-menu'; + } + + $rowIconString = $TCA[$table]['ctrl']['typeicon_classes'][$row[$column]]; + return ($rowIconString) ? $rowIconString : 'status-status-icon-missing'; + } + + /** + * Generates the css classes needed for an iconoverlay of a row + * + * @param string table name of the row + * @param array data row + * @param array set the priorites to use + * @param integer how many items (ordered by priority) you want to return + * @return string css classnames + */ + public static function getRowIconStatus($table, array $row, array $priorities = NULL, $count = 1) { + $statuses = self::getRowIconStatusUnprioritized($table, $row); + $priorities = ($priorities) ? $priorities : $GLOBALS['TYPO3_CONF_VARS']['BE']['iconOverlayPriorities']; + + return self::getStatusWithHighestPriority($statuses, $priorities, $count); + } + + /** + * Calculate for a given record the actual visibility at the moment + * (this code is moved out of getIcon and refactored a bit) + * + * @param string table name of the row + * @param array table row record + * @return array full status of a row + */ + private static function getRowIconStatusUnprioritized($table, array $row) { + global $TCA, $PAGES_TYPES, $ICON_TYPES; + + $status = array( + 'hidden' => false, + 'starttime' => false, + 'endtime' => false, + 'futureendtime' => false, + 'fe_group' => false, + 'deleted' => false, + 'protectSection' => false, + 'nav_hide' => $row['nav_hide'] ? true : false, + 'noIconFound' => $row['_NO_ICON_FOUND'] ? true : false, + ); + + // Icon state based on "enableFields": + if (is_array($TCA[$table]['ctrl']['enablecolumns'])) { + $enCols = $TCA[$table]['ctrl']['enablecolumns']; + // If "hidden" is enabled: + if ($enCols['disabled'] && $row[$enCols['disabled']]) { + $status['hidden'] = TRUE; + } + // If a "starttime" is set and higher than current time: + if ($enCols['starttime'] && $GLOBALS['EXEC_TIME'] < intval($row[$enCols['starttime']])) { + $status['starttime'] = TRUE; + } + + // If an "endtime" is set: + if ($enCols['endtime']) { + if (intval($row[$enCols['endtime']]) > 0) { + if (intval($row[$enCols['endtime']]) < $GLOBALS['EXEC_TIME']) { + // End-timing applies at this point. + $status['endtime'] = TRUE; + } else { + // End-timing WILL apply in the future for this element. + $status['futureendtime'] = TRUE; + } + } + } + // If a user-group field is set: + if ($enCols['fe_group']) { + $status['fe_group'] = $row[$enCols['fe_group']]; + if ($status['fe_group'] && $status['doNotRenderUserGroupNumber']) { + // Limit for user number rendering! + $status['fe_group'] = 100; + } + } + } + + // If "deleted" flag is set (only when listing records which are also deleted!) + if ($row[$TCA[$table]['ctrl']['delete']]) { + $status['deleted'] = TRUE; + } + + // Detecting extendToSubpages (for pages only) + if ($table == 'pages' && $row['extendToSubpages'] && ($status['hidden'] || $status['starttime'] || $status['endtime'] || $status['futuretiming'] || $status['fe_group'])) { + $status['protectSection'] = TRUE; + } + + return $status; + } + + /** + * Will get the first status repespecting the configured prefered statuses + * (so if start and hidden is set, hidden will be returned) + * + * @param array list of statuses + * @param array user defined priorites + * @param integer how many items (ordered by priority) you want to return [should be 1 most of the time] + * @return array list of $count ordered statuses (ordered by priority) + */ + private static function getStatusWithHighestPriority($statuses, array $priorities = NULL, $count = 1) { + if (!is_array($statuses)) { + return array(); + } + + $returnStatuses = array(); + $priorities = $priorities ? $priorities : $GLOBALS['TYPO3_CONF_VARS']['BE']['iconOverlayPriorities']; + + foreach ($priorities as $priority) { + if ($statuses[$priority]) { + $returnStatuses[] = $priority; + $count--; + if ($count <= 0) { + return $returnStatuses; + } + } + } + + return array(); + } + + /** + * returns the needed classes for the row icon overlay + * + * @param string table name of the row + * @param array data row + * @return string css classnames + */ + public static function getRowIconOverlayClasses($table, array $row) { + return self::getSpriteIconClasses(self::getRowIconOverlayString($table, $row)); + } + + /** + * gets the most important statuses and maps it a spriteiconname + * + * @param string table name of the row + * @param array data row + * @return string iconstring + */ + public static function getRowIconOverlayString($table, array $row) { + $status = self::getRowIconStatus($table, $row); + return $GLOBALS['TYPO3_CONF_VARS']['BE']['iconOverlayMapping'][$status[0]]; + } + + /** + * Generates the css classes for a given path + * + * @param string $path - give the full path to the file + * @param string $fileExtension - manually define the extension, saves some checks; can also be 'mount' or 'folder' + * @return string all css classes needed for the icon + */ + public static function getFileIconClasses($path, $fileExtension = NULL) { + return self::getSpriteIconClasses(self::getFileIconString($path, $fileExtension)); + } + + /** + * Generates the spriteiconname for a given path + * + * @param string path to a file or filename (fileExtension will be extracted) + * @param string manually define the fileExtension, saves some checks; can also be 'mount' or 'folder' + * @return string iconstring + */ + public static function getFileIconString($path, $fileExtension = NULL) { + // if no fileExtension is set try to find it out + if (!$fileExtension) { + $filePath = dirname(t3lib_div::getIndpEnv('SCRIPT_FILENAME')) . '/' . $GLOBALS['BACK_PATH'] . $path; + $path = t3lib_div::resolveBackPath($filePath); + if (is_dir($path)) { + $fileExtension = 'folder'; + } else { + $pos = strrpos($path, '.'); + if ($pos !== false) { + $fileExtension = substr($path, $pos + 1); + } else { + if (substr($path, -1) === '/' || substr($path, -1) === '\\') { + $fileExtension = 'folder'; + } + $fileExtension = 'default'; + } + } + } + + if (!self::$fileIconClasses[$fileExtension]) { + $fileExtension = 'default'; + } + return self::$fileIconClasses[$fileExtension]; + } } ?> Index: t3lib/config_default.php =================================================================== --- t3lib/config_default.php (revision 6911) +++ t3lib/config_default.php (working copy) @@ -284,6 +284,24 @@ 'ExtDirect::route' => 't3lib/extjs/class.t3lib_extjs_extdirectrouter.php:t3lib_extjs_ExtDirectRouter->route', ), 'XCLASS' => array(), // See 'Inside TYPO3' document for more information. + 'iconDefaultOptions' => array( + array('element' => 'span', 'baseCssClass' => 't3-icon', 'html' => ' '), + array('element' => 'span', 'baseCssClass' => 't3-icon', 'html' => ' ', 'class' => 't3-icon-overlay') + ), + 'iconOverlayPriorities' => array('hidden', 'starttime', 'endtime', 'futureendtime', 'fe_group', 'protectSection'), + 'iconOverlayMapping' => array( + 'hidden' => 'status-overlay-hidden', + 'fe_group' => 'status-overlay-access-restricted', + 'starttime' => 'status-overlay-scheduled-start', + 'endtime' => 'status-overlay-scheduled-end', + 'futureendtime' => 'status-overlay-scheduled-future-end', + 'readonly' => 'status-overlay-locked', + 'deleted' => 'status-overlay-deleted', + 'missing' => 'status-overlay-missing', + 'translated' => 'status-overlay-translated', + 'protectedSection' => 'status-overlay-includes-subpages', + ), + ), 'FE' => array( // Configuration for the TypoScript frontend (FE). Nothing here relates to the administration backend! 'png_to_gif' => FALSE, // Boolean. Enables conversion back to gif of all png-files generated in the frontend libraries. Notice that this leaves an increased number of temporary files in typo3temp/ Index: t3lib/stddb/tables.php =================================================================== --- t3lib/stddb/tables.php (revision 6911) +++ t3lib/stddb/tables.php (working copy) @@ -147,7 +147,31 @@ 'prependAtCopy' => 'LLL:EXT:lang/locallang_general.php:LGL.prependAtCopy', 'cruser_id' => 'cruser_id', 'editlock' => 'editlock', - 'useColumnsForDefaultValues' => 'doktype' + 'useColumnsForDefaultValues' => 'doktype', + 'typeicon_column' => 'doktype', + 'typeicon_classes' => array( + '1' => 'apps-pagetree-page-default', + '1-not-in-menu' => 'apps-pagetree-page-default-not-in-menu', + '3' => 'apps-pagetree-page-shortcut-external', + '3-not-in-menu' => 'apps-pagetree-page-shortcut-external-not-in-menu', + '4' => 'apps-pagetree-page-shortcut', + '4-not-in-menu' => 'apps-pagetree-page-shortcut-not-in-menu', + '6' => 'apps-pagetree-page-backend-user', + '6-not-in-menu' => 'apps-pagetree-page-backend-user-not-in-menu', + '7' => 'apps-pagetree-page-mountpoint', + '7-not-in-menu' => 'apps-pagetree-page-mountpoint-not-in-menu', + '199' => 'apps-pagetree-spacer', + '199-not-in-menu' => 'apps-pagetree-spacer-not-in-menu', + '254' => 'apps-pagetree-folder-default', + '254-not-in-menu' => 'apps-pagetree-folder-default-not-in-menu', + '255' => 'apps-pagetree-dust-bin', + '255-not-in-menu' => 'apps-pagetree-dust-bin-not-in-menu', + ), + 'typeicons' => array( + '1' => 'pages.gif', + '254' => 'sysf.gif', + '255' => 'recycler.gif', + ) ), 'interface' => array( 'showRecordFieldList' => 'doktype,title', @@ -499,7 +523,4 @@ 'default' => 'default.gif' ); - - - ?> Index: typo3/sysext/cms/ext_tables.php =================================================================== --- typo3/sysext/cms/ext_tables.php (revision 6911) +++ typo3/sysext/cms/ext_tables.php (working copy) @@ -675,6 +675,27 @@ 'fe_group' => 'fe_group', ), 'typeicon_column' => 'CType', + 'typeicon_classes' => array( + 'header' => 'mimetypes-x-content-header', + 'textpic' => 'mimetypes-x-content-text-picture', + 'image' => 'mimetypes-x-content-image', + 'bullets' => 'mimetypes-x-content-list-bullets', + 'table' => 'mimetypes-x-content-table', + 'splash' => 'mimetypes-x-content-splash', + 'uploads' => 'mimetypes-x-content-uploads', + 'multimedia' => 'mimetypes-x-content-multimedia', + 'media' => 'mimetypes-x-content-multimedia', + 'menu' => 'mimetypes-x-content-menu', + 'list' => 'mimetypes-x-content-plugin', + 'mailform' => 'mimetypes-x-content-form', + 'search' => 'mimetypes-x-content-search', + 'login' => 'mimetypes-x-content-login', + 'shortcut' => 'mimetypes-x-content-link', + 'script' => 'mimetypes-x-content-script', + 'div' => 'mimetypes-x-content-divider', + 'html' => 'mimetypes-x-content-html', + 'text' => 'mimetypes-x-content-text', + ), 'typeicons' => array ( 'header' => 'tt_content_header.gif', 'textpic' => 'tt_content_textpic.gif', @@ -825,6 +846,10 @@ 'endtime' => 'endtime' ), 'typeicon_column' => 'root', + 'typeicon_classes' => array( + '0' => 'mimetypes-x-content-template-extension', + '1' => 'mimetypes-x-content-template', + ), 'typeicons' => array ( '0' => 'template_add.gif' ),