TYPO3 API  SVNRelease
template.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2011 Kasper Skårhøj (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 with layout/output function for TYPO3 Backend Scripts
00029  *
00030  * $Id: template.php 10661 2011-02-28 19:18:36Z lolli $
00031  * Revised for TYPO3 3.6 2/2003 by Kasper Skårhøj
00032  * XHTML-trans compliant
00033  *
00034  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00035  */
00036 /**
00037  * [CLASS/FUNCTION INDEX of SCRIPT]
00038  *
00039  *  145: function fw($str)
00040  *
00041  *
00042  *  169: class template
00043  *  224:     function template()
00044  *
00045  *              SECTION: EVALUATION FUNCTIONS
00046  *  298:     function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1,$addParams='',$enDisItems='', $returnOnClick=FALSE)
00047  *  315:     function viewPageIcon($id,$backPath,$addParams='hspace="3"')
00048  *  341:     function issueCommand($params,$rUrl='')
00049  *  356:     function isCMlayers()
00050  *  366:     function thisBlur()
00051  *  376:     function helpStyle()
00052  *  393:     function getHeader($table,$row,$path,$noViewPageIcon=0,$tWrap=array('',''))
00053  *  419:     function getFileheader($title,$path,$iconfile)
00054  *  434:     function makeShortcutIcon($gvList,$setList,$modName,$motherModName="")
00055  *  467:     function makeShortcutUrl($gvList,$setList)
00056  *  488:     function formWidth($size=48,$textarea=0,$styleOverride='')
00057  *  513:     function formWidthText($size=48,$styleOverride='',$wrap='')
00058  *  530:     function redirectUrls($thisLocation='')
00059  *  554:     function formatTime($tstamp,$type)
00060  *  571:     function parseTime()
00061  *
00062  *              SECTION: PAGE BUILDING FUNCTIONS.
00063  *  604:     function startPage($title)
00064  *  686:     function endPage()
00065  *  720:     function header($text)
00066  *  741:     function section($label,$text,$nostrtoupper=FALSE,$sH=FALSE,$type=0,$allowHTMLinHeader=FALSE)
00067  *  765:     function divider($dist)
00068  *  781:     function spacer($dist)
00069  *  800:     function sectionHeader($label,$sH=FALSE,$addAttrib='')
00070  *  817:     function sectionBegin()
00071  *  838:     function sectionEnd()
00072  *  858:     function middle()
00073  *  867:     function endPageJS()
00074  *  884:     function docBodyTagBegin()
00075  *  894:     function docStyle()
00076  *  936:     function insertStylesAndJS($content)
00077  *  956:     function initCharset()
00078  *  968:     function generator()
00079  *
00080  *              SECTION: OTHER ELEMENTS
00081  * 1001:     function icons($type, $styleAttribValue='')
00082  * 1030:     function t3Button($onClick,$label)
00083  * 1041:     function dfw($string)
00084  * 1051:     function rfw($string)
00085  * 1061:     function wrapInCData($string)
00086  * 1078:     function wrapScriptTags($string, $linebreak=TRUE)
00087  * 1117:     function table($arr, $layout='')
00088  * 1159:     function menuTable($arr1,$arr2=array(), $arr3=array())
00089  * 1192:     function funcMenu($content,$menu)
00090  * 1210:     function clearCacheMenu($id,$addSaveOptions=0)
00091  * 1246:     function getContextMenuCode()
00092  * 1251:     function showClickmenu(table, uid, listFr, enDisItems, backPath, addParams)
00093  * 1280:     function showClickmenu_noajax(url)
00094  * 1287:     function showClickmenu_ajax(t3ajax)
00095  * 1472:     function getDragDropCode($table)
00096  * 1483:     function cancelDragEvent(event)
00097  * 1496:     function mouseMoveEvent (event)
00098  * 1509:     function dragElement(id,elementID)
00099  * 1528:     function dropElement(id)
00100  * 1577:     function getTabMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='')
00101  * 1607:     function getTabMenuRaw($menuItems)
00102  * 1676:     function getDynTabMenu($menuItems,$identString,$toggle=0,$foldout=FALSE,$newRowCharLimit=50,$noWrap=1,$fullWidth=FALSE,$defaultTabIndex=1)
00103  * 1801:     function getDynTabMenuJScode()
00104  * 1892:     function getVersionSelector($id,$noAction=FALSE)
00105  *
00106  *
00107  * 2060: class bigDoc extends template
00108  *
00109  *
00110  * 2069: class noDoc extends template
00111  *
00112  *
00113  * 2078: class smallDoc extends template
00114  *
00115  *
00116  * 2087: class mediumDoc extends template
00117  *
00118  * TOTAL FUNCTIONS: 57
00119  * (This index is automatically created/updated by the extension "extdeveval")
00120  *
00121  */
00122 
00123 
00124 
00125 if (!defined('TYPO3_MODE')) die("Can't include this file directly.");
00126 
00127 
00128 /**
00129  * TYPO3 Backend Template Class
00130  *
00131  * This class contains functions for starting and ending the HTML of backend modules
00132  * It also contains methods for outputting sections of content.
00133  * Further there are functions for making icons, links, setting form-field widths etc.
00134  * Color scheme and stylesheet definitions are also available here.
00135  * Finally this file includes the language class for TYPO3's backend.
00136  *
00137  * After this file $LANG and $TBE_TEMPLATE are global variables / instances of their respective classes.
00138  * This file is typically included right after the init.php file,
00139  * if language and layout is needed.
00140  *
00141  * Please refer to Inside TYPO3 for a discussion of how to use this API.
00142  *
00143  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00144  * @package TYPO3
00145  * @subpackage core
00146  */
00147 class template {
00148 
00149         // Vars you typically might want to/should set from outside after making instance of this class:
00150     var $backPath = '';             // 'backPath' pointing back to the PATH_typo3
00151     var $form='';                   // This can be set to the HTML-code for a formtag. Useful when you need a form to span the whole page; Inserted exactly after the body-tag.
00152     var $JScodeLibArray = array();      // Similar to $JScode (see below) but used as an associative array to prevent double inclusion of JS code. This is used to include certain external Javascript libraries before the inline JS code. <script>-Tags are not wrapped around automatically
00153     var $JScode='';                 // Additional header code (eg. a JavaScript section) could be accommulated in this var. It will be directly outputted in the header.
00154     var $extJScode = '';                // Additional header code for ExtJS. It will be included in document header and inserted in a Ext.onReady(function()
00155     var $JScodeArray = array();     // Similar to $JScode but for use as array with associative keys to prevent double inclusion of JS code. a <script> tag is automatically wrapped around.
00156     var $postCode='';               // Additional 'page-end' code could be accommulated in this var. It will be outputted at the end of page before </body> and some other internal page-end code.
00157     var $docType = '';              // Doc-type used in the header. Default is xhtml_trans. You can also set it to 'html_3', 'xhtml_strict' or 'xhtml_frames'.
00158     var $moduleTemplate = '';       // HTML template with markers for module
00159     protected $moduleTemplateFilename = ''; // the base file (not overlaid by TBE_STYLES) for the current module, useful for hooks when finding out which modules is rendered currently
00160 
00161         // Other vars you can change, but less frequently used:
00162     var $scriptID='';               // Script ID.
00163     var $bodyTagId='';              // Id which can be set for the body tag. Default value is based on script ID
00164     var $bodyTagAdditions='';       // You can add additional attributes to the body-tag through this variable.
00165     var $inDocStyles='';            // Additional CSS styles which will be added to the <style> section in the header
00166     var $inDocStylesArray=array();      // Like $inDocStyles but for use as array with associative keys to prevent double inclusion of css code
00167     var $form_rowsToStylewidth = 9.58;  // Multiplication factor for formWidth() input size (default is 48* this value).
00168     var $form_largeComp = 1.33;     // Compensation for large documents (used in class.t3lib_tceforms.php)
00169     var $endJS=1;                   // If set, then a JavaScript section will be outputted in the bottom of page which will try and update the top.busy session expiry object.
00170 
00171         // TYPO3 Colorscheme.
00172         // If you want to change this, please do so through a skin using the global var $TBE_STYLES
00173     var $bgColor = '#F7F3EF';       // Light background color
00174     var $bgColor2 = '#9BA1A8';      // Steel-blue
00175     var $bgColor3 = '#F6F2E6';      // dok.color
00176     var $bgColor4 = '#D9D5C9';      // light tablerow background, brownish
00177     var $bgColor5 = '#ABBBB4';      // light tablerow background, greenish
00178     var $bgColor6 = '#E7DBA8';      // light tablerow background, yellowish, for section headers. Light.
00179     var $hoverColor = '#254D7B';
00180     var $styleSheetFile = '';   // Filename of stylesheet (relative to PATH_typo3)
00181     var $styleSheetFile2 = '';      // Filename of stylesheet #2 - linked to right after the $this->styleSheetFile script (relative to PATH_typo3)
00182     var $styleSheetFile_post = '';  // Filename of a post-stylesheet - included right after all inline styles.
00183     var $backGroundImage = '';      // Background image of page (relative to PATH_typo3)
00184     var $inDocStyles_TBEstyle = ''; // Inline css styling set from TBE_STYLES array
00185 
00186     /**
00187      * Whether to use the X-UA-Compatible meta tag
00188      * @var boolean
00189      */
00190     protected $useCompatibilityTag = TRUE;
00191 
00192         // Skinning
00193         // stylesheets from core
00194     protected $stylesheetsCore = array(
00195         'structure' => 'stylesheets/structure/',
00196         'visual' => 'stylesheets/visual/',
00197         'generatedSprites' => '../typo3temp/sprites/',
00198     );
00199 
00200         // include these CSS directories from skins by default
00201     protected $stylesheetsSkins = array(
00202         'structure' => 'stylesheets/structure/',
00203         'visual' => 'stylesheets/visual/',
00204     );
00205 
00206     /**
00207      * JavaScript files loaded for every page in the Backend
00208      * @var array
00209      */
00210     protected $jsFiles = array(
00211         'modernizr' => 'contrib/modernizr/modernizr.min.js',
00212     );
00213 
00214         // DEV:
00215     var $parseTimeFlag = 0;         // Will output the parsetime of the scripts in milliseconds (for admin-users). Set this to false when releasing TYPO3. Only for dev.
00216 
00217         // INTERNAL
00218     var $charset = 'iso-8859-1';    // Default charset. see function initCharset()
00219 
00220     var $sectionFlag=0;             // Internal: Indicates if a <div>-output section is open
00221     var $divClass = '';             // (Default) Class for wrapping <DIV>-tag of page. Is set in class extensions.
00222 
00223     var $pageHeaderBlock = '';
00224     var $endOfPageJsBlock = '';
00225 
00226     var $hasDocheader = true;
00227 
00228     /**
00229      * @var t3lib_PageRenderer
00230      */
00231     protected $pageRenderer;
00232     protected $pageHeaderFooterTemplateFile = '';   // alternative template file
00233 
00234     protected $extDirectStateProvider = FALSE;
00235 
00236     /**
00237      * Whether flashmessages should be rendered or not
00238      *
00239      * @var $showFlashMessages
00240      */
00241     public $showFlashMessages = TRUE;
00242 
00243     /**
00244      * Constructor
00245      * Imports relevant parts from global $TBE_STYLES (colorscheme)
00246      *
00247      * @return  void
00248      */
00249     function template() {
00250         global $TBE_STYLES;
00251 
00252             // Initializes the page rendering object:
00253         $this->getPageRenderer();
00254 
00255             // Setting default scriptID:
00256         if (($temp_M = (string) t3lib_div::_GET('M')) && $GLOBALS['TBE_MODULES']['_PATHS'][$temp_M]) {
00257             $this->scriptID = preg_replace('/^.*\/(sysext|ext)\//', 'ext/', $GLOBALS['TBE_MODULES']['_PATHS'][$temp_M] . 'index.php');
00258         } else {
00259             $this->scriptID = preg_replace('/^.*\/(sysext|ext)\//', 'ext/', substr(PATH_thisScript, strlen(PATH_site)));
00260         }
00261         if (TYPO3_mainDir!='typo3/' && substr($this->scriptID,0,strlen(TYPO3_mainDir)) == TYPO3_mainDir)    {
00262             $this->scriptID = 'typo3/'.substr($this->scriptID,strlen(TYPO3_mainDir));   // This fixes if TYPO3_mainDir has been changed so the script ids are STILL "typo3/..."
00263         }
00264 
00265         $this->bodyTagId = preg_replace('/[^A-Za-z0-9-]/','-',$this->scriptID);
00266 
00267             // Individual configuration per script? If so, make a recursive merge of the arrays:
00268         if (is_array($TBE_STYLES['scriptIDindex'][$this->scriptID]))    {
00269             $ovr = $TBE_STYLES['scriptIDindex'][$this->scriptID];       // Make copy
00270             $TBE_STYLES = t3lib_div::array_merge_recursive_overrule($TBE_STYLES,$ovr);      // merge styles.
00271             unset($TBE_STYLES['scriptIDindex'][$this->scriptID]);   // Have to unset - otherwise the second instantiation will do it again!
00272         }
00273 
00274             // Color scheme:
00275         if ($TBE_STYLES['mainColors']['bgColor'])   $this->bgColor=$TBE_STYLES['mainColors']['bgColor'];
00276         if ($TBE_STYLES['mainColors']['bgColor1'])  $this->bgColor1=$TBE_STYLES['mainColors']['bgColor1'];
00277         if ($TBE_STYLES['mainColors']['bgColor2'])  $this->bgColor2=$TBE_STYLES['mainColors']['bgColor2'];
00278         if ($TBE_STYLES['mainColors']['bgColor3'])  $this->bgColor3=$TBE_STYLES['mainColors']['bgColor3'];
00279         if ($TBE_STYLES['mainColors']['bgColor4'])  $this->bgColor4=$TBE_STYLES['mainColors']['bgColor4'];
00280         if ($TBE_STYLES['mainColors']['bgColor5'])  $this->bgColor5=$TBE_STYLES['mainColors']['bgColor5'];
00281         if ($TBE_STYLES['mainColors']['bgColor6'])  $this->bgColor6=$TBE_STYLES['mainColors']['bgColor6'];
00282         if ($TBE_STYLES['mainColors']['hoverColor'])    $this->hoverColor=$TBE_STYLES['mainColors']['hoverColor'];
00283 
00284             // Main Stylesheets:
00285         if ($TBE_STYLES['stylesheet'])  $this->styleSheetFile = $TBE_STYLES['stylesheet'];
00286         if ($TBE_STYLES['stylesheet2']) $this->styleSheetFile2 = $TBE_STYLES['stylesheet2'];
00287         if ($TBE_STYLES['styleSheetFile_post']) $this->styleSheetFile_post = $TBE_STYLES['styleSheetFile_post'];
00288         if ($TBE_STYLES['inDocStyles_TBEstyle'])    $this->inDocStyles_TBEstyle = $TBE_STYLES['inDocStyles_TBEstyle'];
00289 
00290             // include all stylesheets
00291         foreach ($this->getSkinStylesheetDirectories() as $stylesheetDirectory) {
00292             $this->addStylesheetDirectory($stylesheetDirectory);
00293         }
00294 
00295             // Background image
00296         if ($TBE_STYLES['background'])  $this->backGroundImage = $TBE_STYLES['background'];
00297     }
00298 
00299 
00300     /**
00301      * Gets instance of PageRenderer
00302      *
00303      * @return  t3lib_PageRenderer
00304      */
00305     public function getPageRenderer() {
00306         if (!isset($this->pageRenderer)) {
00307             $this->pageRenderer = t3lib_div::makeInstance('t3lib_PageRenderer');
00308             $this->pageRenderer->setTemplateFile(
00309                 TYPO3_mainDir . 'templates/template_page_backend.html'
00310             );
00311             $this->pageRenderer->setLanguage($GLOBALS['LANG']->lang);
00312             $this->pageRenderer->enableConcatenateFiles();
00313             $this->pageRenderer->enableCompressCss();
00314             $this->pageRenderer->enableCompressJavascript();
00315 
00316                 // add all JavaScript files defined in $this->jsFiles to the PageRenderer
00317             foreach ($this->jsFiles as $file) {
00318                 $this->pageRenderer->addJsFile($GLOBALS['BACK_PATH'] . $file);
00319             }
00320         }
00321         if (intval($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) === 1) {
00322             $this->pageRenderer->enableDebugMode();
00323         }
00324         return $this->pageRenderer;
00325     }
00326 
00327 
00328 
00329    /**
00330      * Sets inclusion of StateProvider
00331      *
00332      * @return void
00333      */
00334     public function setExtDirectStateProvider() {
00335         $this->extDirectStateProvider = TRUE;
00336     }
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346     /*****************************************
00347      *
00348      * EVALUATION FUNCTIONS
00349      * Various centralized processing
00350      *
00351      *****************************************/
00352 
00353     /**
00354      * Makes click menu link (context sensitive menu)
00355      * Returns $str (possibly an <|img> tag/icon) wrapped in a link which will activate the context sensitive menu for the record ($table/$uid) or file ($table = file)
00356      * The link will load the top frame with the parameter "&item" which is the table,uid and listFr arguments imploded by "|": rawurlencode($table.'|'.$uid.'|'.$listFr)
00357      *
00358      * @param   string      String to be wrapped in link, typ. image tag.
00359      * @param   string      Table name/File path. If the icon is for a database record, enter the tablename from $TCA. If a file then enter the absolute filepath
00360      * @param   integer     If icon is for database record this is the UID for the record from $table
00361      * @param   boolean     Tells the top frame script that the link is coming from a "list" frame which means a frame from within the backend content frame.
00362      * @param   string      Additional GET parameters for the link to alt_clickmenu.php
00363      * @param   string      Enable / Disable click menu items. Example: "+new,view" will display ONLY these two items (and any spacers in between), "new,view" will display all BUT these two items.
00364      * @param   boolean     If set, will return only the onclick JavaScript, not the whole link.
00365      * @return  string      The link-wrapped input string.
00366      */
00367     function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1,$addParams='',$enDisItems='', $returnOnClick=FALSE)  {
00368         $backPath = rawurlencode($this->backPath).'|'.t3lib_div::shortMD5($this->backPath.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
00369         $onClick = 'showClickmenu("'.$table.'","'.$uid.'","'.$listFr.'","'.str_replace('+','%2B',$enDisItems).'","'.str_replace('&','&amp;',addcslashes($backPath,'"')).'","'.str_replace('&','&amp;',addcslashes($addParams,'"')).'");return false;';
00370         return $returnOnClick ? $onClick : '<a href="#" onclick="'.htmlspecialchars($onClick).'"'.($GLOBALS['TYPO3_CONF_VARS']['BE']['useOnContextMenuHandler'] ? ' oncontextmenu="'.htmlspecialchars($onClick).'"' : '').'>'.$str.'</a>';
00371     }
00372 
00373     /**
00374      * Makes link to page $id in frontend (view page)
00375      * Returns an magnifier-glass icon which links to the frontend index.php document for viewing the page with id $id
00376      * $id must be a page-uid
00377      * If the BE_USER has access to Web>List then a link to that module is shown as well (with return-url)
00378      *
00379      * @param   integer     The page id
00380      * @param   string      The current "BACK_PATH" (the back relative to the typo3/ directory)
00381      * @param   string      Additional parameters for the image tag(s)
00382      * @return  string      HTML string with linked icon(s)
00383      */
00384     function viewPageIcon($id,$backPath,$addParams='hspace="3"')    {
00385         global $BE_USER;
00386             // If access to Web>List for user, then link to that module.
00387         $str = t3lib_BEfunc::getListViewLink(
00388             array(
00389                 'id' => $id,
00390                 'returnUrl' => t3lib_div::getIndpEnv('REQUEST_URI'),
00391             ),
00392             $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showList')
00393         );
00394 
00395             // Make link to view page
00396         $str.= '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($id,$backPath,t3lib_BEfunc::BEgetRootLine($id))).'">'.
00397                 '<img'.t3lib_iconWorks::skinImg($backPath,'gfx/zoom.gif','width="12" height="12"').' title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showPage',1).'"'.($addParams?' '.trim($addParams):"").' hspace="3" alt="" />'.
00398                 '</a>';
00399         return $str;
00400     }
00401 
00402     /**
00403      * Returns a URL with a command to TYPO3 Core Engine (tce_db.php)
00404      * See description of the API elsewhere.
00405      *
00406      * @param   string      $params is a set of GET params to send to tce_db.php. Example: "&cmd[tt_content][123][move]=456" or "&data[tt_content][123][hidden]=1&data[tt_content][123][title]=Hello%20World"
00407      * @param   string      Redirect URL if any other that t3lib_div::getIndpEnv('REQUEST_URI') is wished
00408      * @return  string      URL to tce_db.php + parameters (backpath is taken from $this->backPath)
00409      * @see t3lib_BEfunc::editOnClick()
00410      */
00411     function issueCommand($params,$rUrl='') {
00412         $rUrl = $rUrl ? $rUrl : t3lib_div::getIndpEnv('REQUEST_URI');
00413         $commandUrl = $this->backPath.'tce_db.php?' .
00414                 $params .
00415                 '&redirect=' . ($rUrl==-1 ? "'+T3_THIS_LOCATION+'" : rawurlencode($rUrl)) .
00416                 '&vC='.rawurlencode($GLOBALS['BE_USER']->veriCode()) .
00417                 t3lib_BEfunc::getUrlToken('tceAction') .
00418                 '&prErr=1&uPT=1';
00419 
00420         return $commandUrl;
00421     }
00422 
00423     /**
00424      * Returns true if click-menu layers can be displayed for the current user/browser
00425      * Use this to test if click-menus (context sensitive menus) can and should be displayed in the backend.
00426      *
00427      * @return  boolean
00428      */
00429     function isCMlayers()   {
00430         return !$GLOBALS['BE_USER']->uc['disableCMlayers'] && $GLOBALS['CLIENT']['FORMSTYLE'] && !($GLOBALS['CLIENT']['SYSTEM']=='mac' && $GLOBALS['CLIENT']['BROWSER']=='Opera');
00431     }
00432 
00433     /**
00434      * Returns 'this.blur();' if the client supports CSS styles
00435      * Use this in links to remove the underlining after being clicked
00436      *
00437      * @return  string
00438      * @deprecated since TYPO3 4.5, will be removed in TYPO3 4.7
00439      */
00440     function thisBlur() {
00441         t3lib_div::logDeprecatedFunction();
00442         return ($GLOBALS['CLIENT']['FORMSTYLE']?'this.blur();':'');
00443     }
00444 
00445     /**
00446      * Returns ' style='cursor:help;'' if the client supports CSS styles
00447      * Use for <a>-links to help texts
00448      *
00449      * @return  string
00450      * @deprecated since TYPO3 4.5, will be removed in TYPO3 4.7
00451      */
00452     function helpStyle()    {
00453         t3lib_div::logDeprecatedFunction();
00454         return $GLOBALS['CLIENT']['FORMSTYLE'] ? ' style="cursor:help;"':'';
00455     }
00456 
00457     /**
00458      * Makes the header (icon+title) for a page (or other record). Used in most modules under Web>*
00459      * $table and $row must be a tablename/record from that table
00460      * $path will be shown as alt-text for the icon.
00461      * The title will be truncated to 45 chars.
00462      *
00463      * @param   string      Table name
00464      * @param   array       Record row
00465      * @param   string      Alt text
00466      * @param   boolean     Set $noViewPageIcon true if you don't want a magnifier-icon for viewing the page in the frontend
00467      * @param   array       $tWrap is an array with indexes 0 and 1 each representing HTML-tags (start/end) which will wrap the title
00468      * @return  string      HTML content
00469      */
00470     function getHeader($table,$row,$path,$noViewPageIcon=0,$tWrap=array('','')) {
00471         global $TCA;
00472         if (is_array($row) && $row['uid'])  {
00473             $iconImgTag=t3lib_iconWorks::getSpriteIconForRecord($table, $row , array('title' => htmlspecialchars($path)));
00474             $title= strip_tags($row[$TCA[$table]['ctrl']['label']]);
00475             $viewPage = $noViewPageIcon ? '' : $this->viewPageIcon($row['uid'],$this->backPath,'');
00476             if ($table=='pages')    $path.=' - '.t3lib_BEfunc::titleAttribForPages($row,'',0);
00477         } else {
00478             $iconImgTag = t3lib_iconWorks::getSpriteIcon('apps-pagetree-page-domain', array('title' => htmlspecialchars($path)));
00479             $title=$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
00480         }
00481 
00482         return '<span class="typo3-moduleHeader">'.$this->wrapClickMenuOnIcon($iconImgTag,$table,$row['uid']).
00483                 $viewPage.
00484                 $tWrap[0].htmlspecialchars(t3lib_div::fixed_lgd_cs($title,45)).$tWrap[1].'</span>';
00485     }
00486 
00487     /**
00488      * Like ->getHeader() but for files in the File>* main module/submodules
00489      * Returns the file-icon with the path of the file set in the alt/title attribute. Shows the file-name after the icon.
00490      *
00491      * @param   string      Title string, expected to be the filepath
00492      * @param   string      Alt text
00493      * @param   string      The icon file (relative to TYPO3 dir)
00494      * @return  string      HTML content
00495      */
00496     function getFileheader($title,$path,$iconfile)  {
00497         $fileInfo = t3lib_div::split_fileref($title);
00498         $title = htmlspecialchars(t3lib_div::fixed_lgd_cs($fileInfo['path'],-35)).'<strong>'.htmlspecialchars($fileInfo['file']).'</strong>';
00499         return '<span class="typo3-moduleHeader"><img'.t3lib_iconWorks::skinImg($this->backPath,$iconfile,'width="18" height="16"').' title="'.htmlspecialchars($path).'" alt="" />'.$title.'</span>';
00500     }
00501 
00502     /**
00503      * Returns a linked shortcut-icon which will call the shortcut frame and set a shortcut there back to the calling page/module
00504      *
00505      * @param   string      Is the list of GET variables to store (if any)
00506      * @param   string      Is the list of SET[] variables to store (if any) - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS for backend modules
00507      * @param   string      Module name string
00508      * @param   string      Is used to enter the "parent module name" if the module is a submodule under eg. Web>* or File>*. You can also set this value to "1" in which case the currentLoadedModule is sent to the shortcut script (so - not a fixed value!) - that is used in file_edit.php and wizard_rte.php scripts where those scripts are really running as a part of another module.
00509      * @return  string      HTML content
00510      */
00511     function makeShortcutIcon($gvList,$setList,$modName,$motherModName="")  {
00512         $backPath=$this->backPath;
00513         $storeUrl=$this->makeShortcutUrl($gvList,$setList);
00514         $pathInfo = parse_url(t3lib_div::getIndpEnv('REQUEST_URI'));
00515 
00516             // Add the module identifier automatically if typo3/mod.php is used:
00517         if (preg_match('/typo3\/mod\.php$/', $pathInfo['path']) && isset($GLOBALS['TBE_MODULES']['_PATHS'][$modName])) {
00518             $storeUrl = '&M='.$modName.$storeUrl;
00519         }
00520 
00521         if (!strcmp($motherModName,'1'))    {
00522             $mMN="&motherModName='+top.currentModuleLoaded+'";
00523         } elseif ($motherModName)   {
00524             $mMN='&motherModName='.rawurlencode($motherModName);
00525         } else $mMN='';
00526 
00527         $onClick = 'top.ShortcutManager.createShortcut('
00528             .$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeBookmark')).', '
00529             .'\''.$backPath.'\', '
00530             .'\''.rawurlencode($modName).'\', '
00531             .'\''.rawurlencode($pathInfo['path']."?".$storeUrl).$mMN.'\''
00532         .');return false;';
00533 
00534         $sIcon = '<a href="#" onclick="' . htmlspecialchars($onClick).'" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeBookmark', TRUE) . '">'
00535             . t3lib_iconworks::getSpriteIcon('actions-system-shortcut-new') . '</a>';
00536         return $sIcon;
00537     }
00538 
00539     /**
00540      * MAKE url for storing
00541      * Internal func
00542      *
00543      * @param   string      Is the list of GET variables to store (if any)
00544      * @param   string      Is the list of SET[] variables to store (if any) - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS for backend modules
00545      * @return  string
00546      * @access private
00547      * @see makeShortcutIcon()
00548      */
00549     function makeShortcutUrl($gvList,$setList)  {
00550         $GET = t3lib_div::_GET();
00551         $storeArray = array_merge(
00552             t3lib_div::compileSelectedGetVarsFromArray($gvList,$GET),
00553             array('SET'=>t3lib_div::compileSelectedGetVarsFromArray($setList, (array)$GLOBALS['SOBE']->MOD_SETTINGS))
00554         );
00555         $storeUrl = t3lib_div::implodeArrayForUrl('',$storeArray);
00556         return $storeUrl;
00557     }
00558 
00559     /**
00560      * Returns <input> attributes to set the width of an text-type input field.
00561      * For client browsers with no CSS support the cols/size attribute is returned.
00562      * For CSS compliant browsers (recommended) a ' style="width: ...px;"' is returned.
00563      *
00564      * @param   integer     A relative number which multiplied with approx. 10 will lead to the width in pixels
00565      * @param   boolean     A flag you can set for textareas - DEPRECATED, use ->formWidthText() for textareas!!!
00566      * @param   string      A string which will be returned as attribute-value for style="" instead of the calculated width (if CSS is enabled)
00567      * @return  string      Tag attributes for an <input> tag (regarding width)
00568      * @see formWidthText()
00569      */
00570     function formWidth($size=48,$textarea=0,$styleOverride='') {
00571         $wAttrib = $textarea?'cols':'size';
00572         if (!$GLOBALS['CLIENT']['FORMSTYLE'])   {   // If not setting the width by style-attribute
00573             $size = $size;
00574             $retVal = ' '.$wAttrib.'="'.$size.'"';
00575         } else {    // Setting width by style-attribute. 'cols' MUST be avoided with NN6+
00576             $pixels = ceil($size*$this->form_rowsToStylewidth);
00577             $retVal = $styleOverride ? ' style="'.$styleOverride.'"' : ' style="width:'.$pixels.'px;"';
00578         }
00579         return $retVal;
00580     }
00581 
00582     /**
00583      * This function is dedicated to textareas, which has the wrapping on/off option to observe.
00584      * EXAMPLE:
00585      *      <textarea rows="10" wrap="off" '.$GLOBALS["TBE_TEMPLATE"]->formWidthText(48,"","off").'>
00586      *   or
00587      *      <textarea rows="10" wrap="virtual" '.$GLOBALS["TBE_TEMPLATE"]->formWidthText(48,"","virtual").'>
00588      *
00589      * @param   integer     A relative number which multiplied with approx. 10 will lead to the width in pixels
00590      * @param   string      A string which will be returned as attribute-value for style="" instead of the calculated width (if CSS is enabled)
00591      * @param   string      Pass on the wrap-attribute value you use in your <textarea>! This will be used to make sure that some browsers will detect wrapping alright.
00592      * @return  string      Tag attributes for an <input> tag (regarding width)
00593      * @see formWidth()
00594      */
00595     function formWidthText($size=48,$styleOverride='',$wrap='') {
00596         $wTags = $this->formWidth($size,1,$styleOverride);
00597             // Netscape 6+/Mozilla seems to have this ODD problem where there WILL ALWAYS be wrapping with the cols-attribute set and NEVER without the col-attribute...
00598         if (strtolower(trim($wrap))!='off' && $GLOBALS['CLIENT']['BROWSER']=='net' && $GLOBALS['CLIENT']['VERSION']>=5) {
00599             $wTags.=' cols="'.$size.'"';
00600         }
00601         return $wTags;
00602     }
00603 
00604     /**
00605      * Returns JavaScript variables setting the returnUrl and thisScript location for use by JavaScript on the page.
00606      * Used in fx. db_list.php (Web>List)
00607      *
00608      * @param   string      URL to "this location" / current script
00609      * @return  string
00610      * @see typo3/db_list.php
00611      */
00612     function redirectUrls($thisLocation='') {
00613         $thisLocation = $thisLocation?$thisLocation:t3lib_div::linkThisScript(
00614         array(
00615             'CB'=>'',
00616             'SET'=>'',
00617             'cmd' => '',
00618             'popViewId'=>''
00619         ));
00620 
00621         $out ="
00622     var T3_RETURN_URL = '".str_replace('%20','',rawurlencode(t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('returnUrl'))))."';
00623     var T3_THIS_LOCATION = '".str_replace('%20','',rawurlencode($thisLocation))."';
00624         ";
00625         return $out;
00626     }
00627 
00628     /**
00629      * Returns a formatted string of $tstamp
00630      * Uses $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] and $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] to format date and time
00631      *
00632      * @param   integer     UNIX timestamp, seconds since 1970
00633      * @param   integer     How much data to show: $type = 1: hhmm, $type = 10: ddmmmyy
00634      * @return  string      Formatted timestamp
00635      */
00636     function formatTime($tstamp,$type)  {
00637         $dateStr = '';
00638         switch($type)   {
00639             case 1: $dateStr = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],$tstamp);
00640             break;
00641             case 10: $dateStr = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],$tstamp);
00642             break;
00643         }
00644         return $dateStr;
00645     }
00646 
00647     /**
00648      * Returns script parsetime IF ->parseTimeFlag is set and user is "admin"
00649      * Automatically outputted in page end
00650      *
00651      * @return  string
00652      */
00653     function parseTime()    {
00654         if ($this->parseTimeFlag && $GLOBALS['BE_USER']->isAdmin()) {
00655             return '<p>(ParseTime: '.(t3lib_div::milliseconds()-$GLOBALS['PARSETIME_START']).' ms</p>
00656                     <p>REQUEST_URI-length: '.strlen(t3lib_div::getIndpEnv('REQUEST_URI')).')</p>';
00657         }
00658     }
00659 
00660     /**
00661      * Defines whether to use the X-UA-Compatible meta tag.
00662      *
00663      * @param boolean $useCompatibilityTag Whether to use the tag
00664      * @return void
00665      */
00666     public function useCompatibilityTag($useCompatibilityTag = TRUE) {
00667         $this->useCompatibilityTag = (bool) $useCompatibilityTag;
00668     }
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 
00679 
00680 
00681     /*****************************************
00682      *
00683      *  PAGE BUILDING FUNCTIONS.
00684      *  Use this to build the HTML of your backend modules
00685      *
00686      *****************************************/
00687 
00688     /**
00689      * Returns page start
00690      * This includes the proper header with charset, title, meta tag and beginning body-tag.
00691      *
00692      * @param   string      HTML Page title for the header
00693      * @param   boolean     flag for including CSH
00694      * @return  string      Returns the whole header section of a HTML-document based on settings in internal variables (like styles, javascript code, charset, generator and docType)
00695      * @see endPage()
00696      */
00697     function startPage($title, $includeCsh = TRUE) {
00698             // hook pre start page
00699         if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preStartPageHook'])) {
00700             $preStartPageHook =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preStartPageHook'];
00701             if (is_array($preStartPageHook)) {
00702                 $hookParameters = array(
00703                     'title' => &$title,
00704                 );
00705                 foreach ($preStartPageHook as $hookFunction)    {
00706                     t3lib_div::callUserFunction($hookFunction, $hookParameters, $this);
00707                 }
00708             }
00709         }
00710 
00711         $this->pageRenderer->backPath = $this->backPath;
00712 
00713             // alternative template for Header and Footer
00714         if ($this->pageHeaderFooterTemplateFile) {
00715             $file =  t3lib_div::getFileAbsFileName($this->pageHeaderFooterTemplateFile, TRUE);
00716             if ($file) {
00717                 $this->pageRenderer->setTemplateFile($file);
00718             }
00719         }
00720             // For debugging: If this outputs "QuirksMode"/"BackCompat" (IE) the browser runs in quirks-mode. Otherwise the value is "CSS1Compat"
00721 #       $this->JScodeArray[]='alert(document.compatMode);';
00722 
00723             // Send HTTP header for selected charset. Added by Robert Lemke 23.10.2003
00724         $this->initCharset();
00725         header ('Content-Type:text/html;charset='.$this->charset);
00726 
00727             // Standard HTML tag
00728         $htmlTag = '<html xmlns="http://www.w3.org/1999/xhtml">';
00729 
00730         switch($this->docType)  {
00731             case 'html_3':
00732                 $headerStart = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">';
00733                 $htmlTag = '<html>';
00734                 // disable rendering of XHTML tags
00735                 $this->getPageRenderer()->setRenderXhtml(FALSE);
00736                 break;
00737             case 'xhtml_strict':
00738                 $headerStart = '<!DOCTYPE html
00739     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
00740     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
00741                 break;
00742             case 'xhtml_frames':
00743                 $headerStart = '<!DOCTYPE html
00744     PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
00745     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
00746                 break;
00747             case 'xhtml_trans':
00748                 $headerStart = '<!DOCTYPE html
00749      PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
00750      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
00751                 // The fallthrough is intended as HTML5, as this is the default for the BE since TYPO3 4.5
00752             case 'html5':
00753             default:
00754                 $headerStart = '<!DOCTYPE html>' . LF;
00755                 $htmlTag = '<html>';
00756                 // disable rendering of XHTML tags
00757                 $this->getPageRenderer()->setRenderXhtml(FALSE);
00758                 break;
00759         }
00760 
00761         $this->pageRenderer->setHtmlTag($htmlTag);
00762 
00763         // This loads the tabulator-in-textarea feature. It automatically modifies
00764         // every textarea which is found.
00765         if (!$GLOBALS['BE_USER']->uc['disableTabInTextarea']) {
00766             $this->loadJavascriptLib('tab.js');
00767         }
00768 
00769             // include the JS for the Context Sensitive Help
00770         if ($includeCsh) {
00771             $this->loadCshJavascript();
00772         }
00773 
00774             // Get the browser info
00775         $browserInfo = t3lib_utility_Client::getBrowserInfo(t3lib_div::getIndpEnv('HTTP_USER_AGENT'));
00776 
00777             // Set the XML prologue
00778         $xmlPrologue = '<?xml version="1.0" encoding="' . $this->charset . '"?>';
00779 
00780             // Set the XML stylesheet
00781         $xmlStylesheet = '<?xml-stylesheet href="#internalStyle" type="text/css"?>';
00782 
00783             // Add the XML prologue for XHTML doctypes
00784         if (strpos($this->doctype, 'xhtml') !== FALSE) {
00785                 // Put the XML prologue before or after the doctype declaration according to browser
00786             if ($browserInfo['browser'] === 'msie' && $browserInfo['version'] < 7) {
00787                 $headerStart = $headerStart . LF . $xmlPrologue;
00788             } else {
00789                 $headerStart = $xmlPrologue . LF . $headerStart;
00790             }
00791 
00792                 // Add the xml stylesheet according to doctype
00793             if ($this->docType !== 'xhtml_frames') {
00794                 $headerStart = $headerStart . LF . $xmlStylesheet;
00795             }
00796         }
00797 
00798         $this->pageRenderer->setXmlPrologAndDocType($headerStart);
00799         $this->pageRenderer->setHeadTag('<head>' . LF. '<!-- TYPO3 Script ID: '.htmlspecialchars($this->scriptID).' -->');
00800         $this->pageRenderer->setCharSet($this->charset);
00801         $this->pageRenderer->addMetaTag($this->generator());
00802         if ($this->useCompatibilityTag) {
00803             $this->pageRenderer->addMetaTag($this->xUaCompatible());
00804         }
00805         $this->pageRenderer->setTitle($title);
00806 
00807         // add docstyles
00808         $this->docStyle();
00809 
00810        if ($this->extDirectStateProvider) {
00811             $this->pageRenderer->addJsFile($this->backPath . '../t3lib/js/extjs/ExtDirect.StateProvider.js');
00812         }
00813 
00814             // add jsCode for overriding the console with a debug panel connection
00815         $this->pageRenderer->addJsInlineCode(
00816             'consoleOverrideWithDebugPanel',
00817             'if (typeof top.Ext === "object") {
00818                 top.Ext.onReady(function() {
00819                     if (typeof console === "undefined") {
00820                         if (top && top.TYPO3 && top.TYPO3.Backend && top.TYPO3.Backend.DebugConsole) {
00821                             console = top.TYPO3.Backend.DebugConsole;
00822                         } else {
00823                             console = {
00824                                 log: Ext.log,
00825                                 info: Ext.log,
00826                                 warn: Ext.log,
00827                                 error: Ext.log
00828                             };
00829                         }
00830                     }
00831                 });
00832             }
00833         ');
00834 
00835         $this->pageRenderer->addHeaderData($this->JScode);
00836 
00837         foreach ($this->JScodeArray as $name => $code) {
00838             $this->pageRenderer->addJsInlineCode($name, $code);
00839         }
00840 
00841         if (count($this->JScodeLibArray)) {
00842             foreach($this->JScodeLibArray as $library) {
00843                 $this->pageRenderer->addHeaderData($library);
00844             }
00845         }
00846 
00847         if ($this->extJScode) {
00848             $this->pageRenderer->addExtOnReadyCode($this->extJScode);
00849         }
00850 
00851             // hook for additional headerData
00852         if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preHeaderRenderHook'])) {
00853             $preHeaderRenderHook =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preHeaderRenderHook'];
00854             if (is_array($preHeaderRenderHook)) {
00855                 $hookParameters = array(
00856                     'pageRenderer' => &$this->pageRenderer,
00857                 );
00858                 foreach ($preHeaderRenderHook as $hookFunction) {
00859                     t3lib_div::callUserFunction($hookFunction, $hookParameters, $this);
00860                 }
00861             }
00862         }
00863 
00864             // Construct page header.
00865         $str = $this->pageRenderer->render(t3lib_PageRenderer::PART_HEADER);
00866 
00867         $this->JScodeLibArray = array();
00868         $this->JScode = $this->extJScode = '';
00869         $this->JScodeArray = array();
00870 
00871         $this->endOfPageJsBlock = $this->pageRenderer->render(t3lib_PageRenderer::PART_FOOTER);
00872 
00873         if ($this->docType=='xhtml_frames') {
00874             return $str;
00875         } else
00876 $str.=$this->docBodyTagBegin().
00877 ($this->divClass?'
00878 
00879 <!-- Wrapping DIV-section for whole page BEGIN -->
00880 <div class="' . $this->divClass . '">
00881 ' : '' ) . trim($this->form);
00882         return $str;
00883     }
00884 
00885     /**
00886      * Returns page end; This includes finishing form, div, body and html tags.
00887      *
00888      * @return  string      The HTML end of a page
00889      * @see startPage()
00890      */
00891     function endPage()  {
00892         $str = $this->sectionEnd().
00893                 $this->postCode.
00894                 $this->endPageJS().
00895                 $this->wrapScriptTags(t3lib_BEfunc::getUpdateSignalCode()).
00896                 $this->parseTime().
00897                 ($this->form?'
00898 </form>':'');
00899             // if something is in buffer like debug, put it to end of page
00900         if (ob_get_contents()) {
00901             $str .= ob_get_clean();
00902             header('Content-Encoding: None');
00903         }
00904 
00905         if ($this->docType !== 'xhtml_frames') {
00906 
00907             $str .= ($this->divClass?'
00908 
00909 <!-- Wrapping DIV-section for whole page END -->
00910 </div>':'') . $this->endOfPageJsBlock ;
00911             t3lib_formprotection_Factory::get()->persistTokens();
00912         }
00913 
00914 
00915             // Logging: Can't find better place to put it:
00916         if (TYPO3_DLOG) t3lib_div::devLog('END of BACKEND session', 'template', 0, array('_FLUSH' => true));
00917 
00918         return $str;
00919     }
00920 
00921     /**
00922      * Shortcut for render the complete page of a module
00923      *
00924      * @param  $title  page title
00925      * @param  $content  page content
00926      * @param bool $includeCsh  flag for including csh code
00927      * @return string complete page
00928      */
00929     public function render($title, $content, $includeCsh = TRUE)  {
00930         $pageContent = $this->startPage($title, $includeCsh);
00931         $pageContent .= $content;
00932         $pageContent .= $this->endPage();
00933 
00934         return $this->insertStylesAndJS($pageContent);
00935     }
00936 
00937     /**
00938      * Returns the header-bar in the top of most backend modules
00939      * Closes section if open.
00940      *
00941      * @param   string      The text string for the header
00942      * @return  string      HTML content
00943      */
00944     function header($text)  {
00945         $str='
00946 
00947     <!-- MAIN Header in page top -->
00948     <h2>'.htmlspecialchars($text).'</h2>
00949 ';
00950         return $this->sectionEnd().$str;
00951     }
00952 
00953     /**
00954      * Begins an output section and sets header and content
00955      *
00956      * @param   string      The header
00957      * @param   string      The HTML-content
00958      * @param   boolean     A flag that will prevent the header from being converted to uppercase
00959      * @param   boolean     Defines the type of header (if set, "<h3>" rather than the default "h4")
00960      * @param   integer     The number of an icon to show with the header (see the icon-function). -1,1,2,3
00961      * @param   boolean     If set, HTML tags are allowed in $label (otherwise this value is by default htmlspecialchars()'ed)
00962      * @return  string      HTML content
00963      * @see icons(), sectionHeader()
00964      */
00965     function section($label,$text,$nostrtoupper=FALSE,$sH=FALSE,$type=0,$allowHTMLinHeader=FALSE)   {
00966         $str='';
00967 
00968             // Setting header
00969         if ($label) {
00970             if (!$allowHTMLinHeader)    $label = htmlspecialchars($label);
00971             $str.=$this->sectionHeader($this->icons($type).$label, $sH, $nostrtoupper ? '' : ' class="uppercase"');
00972         }
00973             // Setting content
00974         $str.='
00975 
00976     <!-- Section content -->
00977 '.$text;
00978 
00979         return $this->sectionBegin().$str;
00980     }
00981 
00982     /**
00983      * Inserts a divider image
00984      * Ends a section (if open) before inserting the image
00985      *
00986      * @param   integer     The margin-top/-bottom of the <hr> ruler.
00987      * @return  string      HTML content
00988      */
00989     function divider($dist) {
00990         $dist = intval($dist);
00991         $str='
00992 
00993     <!-- DIVIDER -->
00994     <hr style="margin-top: '.$dist.'px; margin-bottom: '.$dist.'px;" />
00995 ';
00996         return $this->sectionEnd().$str;
00997     }
00998 
00999     /**
01000      * Returns a blank <div>-section with a height
01001      *
01002      * @param   integer     Padding-top for the div-section (should be margin-top but konqueror (3.1) doesn't like it :-(
01003      * @return  string      HTML content
01004      */
01005     function spacer($dist)  {
01006         if ($dist>0)    {
01007             return '
01008 
01009     <!-- Spacer element -->
01010     <div style="padding-top: '.intval($dist).'px;"></div>
01011 ';
01012         }
01013     }
01014 
01015     /**
01016      * Make a section header.
01017      * Begins a section if not already open.
01018      *
01019      * @param   string      The label between the <h3> or <h4> tags. (Allows HTML)
01020      * @param   boolean     If set, <h3> is used, otherwise <h4>
01021      * @param   string      Additional attributes to h-tag, eg. ' class=""'
01022      * @return  string      HTML content
01023      */
01024     function sectionHeader($label, $sH=FALSE, $addAttrib='') {
01025         $tag = ($sH ? 'h3' : 'h4');
01026         if ($addAttrib && substr($addAttrib, 0, 1) !== ' ') {
01027             $addAttrib = ' ' . $addAttrib;
01028         }
01029         $str='
01030 
01031     <!-- Section header -->
01032     <' . $tag . $addAttrib . '>' . $label . '</' . $tag . '>
01033 ';
01034         return $this->sectionBegin() . $str;
01035     }
01036 
01037     /**
01038      * Begins an output section.
01039      * Returns the <div>-begin tag AND sets the ->sectionFlag true (if the ->sectionFlag is not already set!)
01040      * You can call this function even if a section is already begun since the function will only return something if the sectionFlag is not already set!
01041      *
01042      * @return  string      HTML content
01043      */
01044     function sectionBegin() {
01045         if (!$this->sectionFlag)    {
01046             $this->sectionFlag=1;
01047             $str='
01048 
01049     <!-- ***********************
01050           Begin output section.
01051          *********************** -->
01052     <div>
01053 ';
01054             return $str;
01055         } else return '';
01056     }
01057 
01058     /**
01059      * Ends and output section
01060      * Returns the </div>-end tag AND clears the ->sectionFlag (but does so only IF the sectionFlag is set - that is a section is 'open')
01061      * See sectionBegin() also.
01062      *
01063      * @return  string      HTML content
01064      */
01065     function sectionEnd()   {
01066         if ($this->sectionFlag) {
01067             $this->sectionFlag=0;
01068             return '
01069     </div>
01070     <!-- *********************
01071           End output section.
01072          ********************* -->
01073 ';
01074         } else return '';
01075     }
01076 
01077     /**
01078      * If a form-tag is defined in ->form then and end-tag for that <form> element is outputted
01079      * Further a JavaScript section is outputted which will update the top.busy session-expiry object (unless $this->endJS is set to false)
01080      *
01081      * @return  string      HTML content (<script> tag section)
01082      */
01083     function endPageJS()    {
01084         return ($this->endJS?'
01085     <script type="text/javascript">
01086           /*<![CDATA[*/
01087         if (top.busy && top.busy.loginRefreshed) {
01088             top.busy.loginRefreshed();
01089         }
01090          /*]]>*/
01091     </script>':'');
01092     }
01093 
01094     /**
01095      * Creates the bodyTag.
01096      * You can add to the bodyTag by $this->bodyTagAdditions
01097      *
01098      * @return  string      HTML body tag
01099      */
01100     function docBodyTagBegin()  {
01101         $bodyContent = 'body onclick="if (top.menuReset) top.menuReset();" '.trim($this->bodyTagAdditions.($this->bodyTagId ? ' id="'.$this->bodyTagId.'"' : ''));
01102         return '<'.trim($bodyContent).'>';
01103     }
01104 
01105     /**
01106      * Outputting document style
01107      *
01108      * @return  string      HTML style section/link tags
01109      */
01110     function docStyle() {
01111 
01112             // Request background image:
01113         if ($this->backGroundImage) {
01114             $this->inDocStylesArray[]=' BODY { background-image: url('.$this->backPath.$this->backGroundImage.'); }';
01115         }
01116 
01117             // Add inDoc styles variables as well:
01118         $this->inDocStylesArray[] = $this->inDocStyles;
01119         $this->inDocStylesArray[] = $this->inDocStyles_TBEstyle;
01120 
01121             // Implode it all:
01122         $inDocStyles = implode(LF, $this->inDocStylesArray);
01123 
01124         if ($this->styleSheetFile) {
01125             $this->pageRenderer->addCssFile($this->backPath . $this->styleSheetFile);
01126         }
01127         if ($this->styleSheetFile2) {
01128             $this->pageRenderer->addCssFile($this->backPath . $this->styleSheetFile2);
01129         }
01130 
01131         $this->pageRenderer->addCssInlineBlock('inDocStyles', $inDocStyles . LF . '/*###POSTCSSMARKER###*/');
01132         if ($this->styleSheetFile_post) {
01133             $this->pageRenderer->addCssFile($this->backPath . $this->styleSheetFile_post);
01134         }
01135 
01136     }
01137 
01138     /**
01139      * Insert additional style sheet link
01140      *
01141      * @param   string      $key: some key identifying the style sheet
01142      * @param   string      $href: uri to the style sheet file
01143      * @param   string      $title: value for the title attribute of the link element
01144      * @return  string      $relation: value for the rel attribute of the link element
01145      * @return  void
01146      */
01147     function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
01148         if (strpos($href, '://') !== FALSE || substr($href, 0, 1) === '/') {
01149             $file = $href;
01150         } else {
01151             $file = $this->backPath . $href;
01152         }
01153         $this->pageRenderer->addCssFile($file, $relation, 'screen', $title);
01154     }
01155 
01156     /**
01157      * Add all *.css files of the directory $path to the stylesheets
01158      *
01159      * @param   string      directory to add
01160      * @return  void
01161      */
01162     function addStyleSheetDirectory($path) {
01163             // calculation needed, when TYPO3 source is used via a symlink
01164             // absolute path to the stylesheets
01165         $filePath = dirname(t3lib_div::getIndpEnv('SCRIPT_FILENAME')) . '/' . $GLOBALS['BACK_PATH'] . $path;
01166             // clean the path
01167         $resolvedPath = t3lib_div::resolveBackPath($filePath);
01168             // read all files in directory and sort them alphabetically
01169         $files = t3lib_div::getFilesInDir($resolvedPath, 'css', FALSE, 1);
01170         foreach ($files as $file) {
01171             $this->pageRenderer->addCssFile($GLOBALS['BACK_PATH'] . $path . $file, 'stylesheet', 'all');
01172         }
01173     }
01174 
01175     /**
01176      * Insert post rendering document style into already rendered content
01177      * This is needed for extobjbase
01178      *
01179      * @param   string      style-content to insert.
01180      * @return  string      content with inserted styles
01181      */
01182     function insertStylesAndJS($content)    {
01183             // insert accumulated CSS
01184         $this->inDocStylesArray[] = $this->inDocStyles;
01185         $styles = LF.implode(LF, $this->inDocStylesArray);
01186         $content = str_replace('/*###POSTCSSMARKER###*/',$styles,$content);
01187 
01188             // insert accumulated JS
01189         $jscode = $this->JScode.LF.$this->wrapScriptTags(implode(LF, $this->JScodeArray));
01190         $content = str_replace('<!--###POSTJSMARKER###-->',$jscode,$content);
01191 
01192         return $content;
01193     }
01194 
01195     /**
01196      * Returns an array of all stylesheet directories belonging to core and skins
01197      *
01198      * @return  array   Stylesheet directories
01199      */
01200     public function getSkinStylesheetDirectories() {
01201         $stylesheetDirectories = array();
01202 
01203             // add default core stylesheets
01204         foreach ($this->stylesheetsCore as $stylesheetDir) {
01205             $stylesheetDirectories[] = $stylesheetDir;
01206         }
01207 
01208             // Stylesheets from skins
01209             // merge default css directories ($this->stylesheetsSkin) with additional ones and include them
01210         if (is_array($GLOBALS['TBE_STYLES']['skins'])) {
01211                 // loop over all registered skins
01212             foreach ($GLOBALS['TBE_STYLES']['skins'] as $skinExtKey => $skin) {
01213                 $skinStylesheetDirs = $this->stylesheetsSkins;
01214 
01215                     // skins can add custom stylesheetDirectories using
01216                     // $TBE_STYLES['skins'][$_EXTKEY]['stylesheetDirectories']
01217                 if (is_array($skin['stylesheetDirectories'])) {
01218                     $skinStylesheetDirs = array_merge($skinStylesheetDirs, $skin['stylesheetDirectories']);
01219                 }
01220 
01221                     // add all registered directories
01222                 foreach ($skinStylesheetDirs as $stylesheetDir) {
01223                         // for EXT:myskin/stylesheets/ syntax
01224                     if (substr($stylesheetDir, 0, 4) === 'EXT:') {
01225                         list($extKey, $path) = explode('/', substr($stylesheetDir, 4), 2);
01226                         if (strcmp($extKey, '') && t3lib_extMgm::isLoaded($extKey) && strcmp($path, '')) {
01227                             $stylesheetDirectories[] = t3lib_extMgm::extRelPath($extKey) . $path;
01228                         }
01229                     } else {
01230                         // for relative paths
01231                         $stylesheetDirectories[] = t3lib_extMgm::extRelPath($skinExtKey) . $stylesheetDir;
01232                     }
01233                 }
01234             }
01235         }
01236         return $stylesheetDirectories;
01237     }
01238 
01239     /**
01240      * Initialize the charset.
01241      * Sets the internal $this->charset variable to the charset defined in $GLOBALS["LANG"] (or the default as set in this class)
01242      * Returns the meta-tag for the document header
01243      *
01244      * @return  string      <meta> tag with charset from $this->charset or $GLOBALS['LANG']->charSet
01245      */
01246     function initCharset()  {
01247             // Set charset to the charset provided by the current backend users language selection:
01248         $this->charset = $GLOBALS['LANG']->charSet ? $GLOBALS['LANG']->charSet : $this->charset;
01249             // Return meta tag:
01250         return '<meta http-equiv="Content-Type" content="text/html; charset='.$this->charset.'" />';
01251     }
01252 
01253     /**
01254      * Returns generator meta tag
01255      *
01256      * @return  string      <meta> tag with name "generator"
01257      */
01258     function generator()    {
01259         $str = 'TYPO3 '.TYPO3_branch.', ' . TYPO3_URL_GENERAL . ', &#169; Kasper Sk&#229;rh&#248;j 1998-2009, extensions are copyright of their respective owners.';
01260         return '<meta name="generator" content="'.$str .'" />';
01261     }
01262 
01263     /**
01264      * Returns X-UA-Compatible meta tag
01265      *
01266      * @param   string      $content Content of the compatible tag (default: IE-8)
01267      * @return  string      <meta http-equiv="X-UA-Compatible" content="???" />
01268      */
01269     public function xUaCompatible($content = 'IE=8') {
01270         return '<meta http-equiv="X-UA-Compatible" content="' . $content . '" />';
01271     }
01272 
01273 
01274 
01275 
01276 
01277 
01278 
01279     /*****************************************
01280      *
01281      * OTHER ELEMENTS
01282      * Tables, buttons, formatting dimmed/red strings
01283      *
01284      ******************************************/
01285 
01286 
01287     /**
01288      * Returns an image-tag with an 18x16 icon of the following types:
01289      *
01290      * $type:
01291      * -1:  OK icon (Check-mark)
01292      * 1:   Notice (Speach-bubble)
01293      * 2:   Warning (Yellow triangle)
01294      * 3:   Fatal error (Red stop sign)
01295      *
01296      * @param   integer     See description
01297      * @param   string      Value for style attribute
01298      * @return  string      HTML image tag (if applicable)
01299      */
01300     function icons($type, $styleAttribValue='') {
01301         switch($type)   {
01302             case '3':
01303                 $icon = 'status-dialog-error';
01304             break;
01305             case '2':
01306                 $icon = 'status-dialog-warning';
01307             break;
01308             case '1':
01309                 $icon = 'status-dialog-notification';
01310             break;
01311             case '-1':
01312                 $icon = 'status-dialog-ok';
01313             break;
01314             default:
01315             break;
01316         }
01317         if ($icon)  {
01318             return t3lib_iconWorks::getSpriteIcon($icon);
01319         }
01320     }
01321 
01322     /**
01323      * Returns an <input> button with the $onClick action and $label
01324      *
01325      * @param   string      The value of the onclick attribute of the input tag (submit type)
01326      * @param   string      The label for the button (which will be htmlspecialchar'ed)
01327      * @return  string      A <input> tag of the type "submit"
01328      */
01329     function t3Button($onClick,$label)  {
01330         $button = '<input type="submit" onclick="'.htmlspecialchars($onClick).'; return false;" value="'.htmlspecialchars($label).'" />';
01331         return $button;
01332     }
01333 
01334     /**
01335      * dimmed-fontwrap. Returns the string wrapped in a <span>-tag defining the color to be gray/dimmed
01336      *
01337      * @param   string      Input string
01338      * @return  string      Output string
01339      */
01340     function dfw($string)   {
01341         return '<span class="typo3-dimmed">'.$string.'</span>';
01342     }
01343 
01344     /**
01345      * red-fontwrap. Returns the string wrapped in a <span>-tag defining the color to be red
01346      *
01347      * @param   string      Input string
01348      * @return  string      Output string
01349      */
01350     function rfw($string)   {
01351         return '<span class="typo3-red">'.$string.'</span>';
01352     }
01353 
01354     /**
01355      * Returns string wrapped in CDATA "tags" for XML / XHTML (wrap content of <script> and <style> sections in those!)
01356      *
01357      * @param   string      Input string
01358      * @return  string      Output string
01359      */
01360     function wrapInCData($string)   {
01361         $string = '/*<![CDATA[*/'.
01362             $string.
01363             '/*]]>*/';
01364 
01365         return $string;
01366     }
01367 
01368     /**
01369      * Wraps the input string in script tags.
01370      * Automatic re-identing of the JS code is done by using the first line as ident reference.
01371      * This is nice for identing JS code with PHP code on the same level.
01372      *
01373      * @param   string      Input string
01374      * @param   boolean     Wrap script element in linebreaks? Default is TRUE.
01375      * @return  string      Output string
01376      */
01377     function wrapScriptTags($string, $linebreak=TRUE)   {
01378         if(trim($string)) {
01379                 // <script wrapped in nl?
01380             $cr = $linebreak? LF : '';
01381 
01382                 // remove nl from the beginning
01383             $string = preg_replace ('/^\n+/', '', $string);
01384                 // re-ident to one tab using the first line as reference
01385             $match = array();
01386             if(preg_match('/^(\t+)/',$string,$match)) {
01387                 $string = str_replace($match[1],TAB, $string);
01388             }
01389             $string = $cr.'<script type="text/javascript">
01390 /*<![CDATA[*/
01391 '.$string.'
01392 /*]]>*/
01393 </script>'.$cr;
01394         }
01395         return trim($string);
01396     }
01397 
01398         // These vars defines the layout for the table produced by the table() function.
01399         // You can override these values from outside if you like.
01400     var $tableLayout = array(
01401         'defRow' => array(
01402             'defCol' => array('<td valign="top">','</td>')
01403         )
01404     );
01405     var $table_TR = '<tr>';
01406     var $table_TABLE = '<table border="0" cellspacing="0" cellpadding="0" class="typo3-dblist" id="typo3-tmpltable">';
01407 
01408     /**
01409      * Returns a table based on the input $data
01410      *
01411      * @param   array       Multidim array with first levels = rows, second levels = cells
01412      * @param   array       If set, then this provides an alternative layout array instead of $this->tableLayout
01413      * @return  string      The HTML table.
01414      * @internal
01415      */
01416     function table($data, $layout = '') {
01417         $result = '';
01418         if (is_array($data)) {
01419             $tableLayout = (is_array($layout) ? $layout : $this->tableLayout);
01420 
01421             $rowCount = 0;
01422             foreach ($data as $tableRow) {
01423                 if ($rowCount % 2) {
01424                     $layout = is_array($tableLayout['defRowOdd']) ? $tableLayout['defRowOdd'] : $tableLayout['defRow'];
01425                 } else {
01426                     $layout = is_array($tableLayout['defRowEven']) ? $tableLayout['defRowEven'] : $tableLayout['defRow'];
01427                 }
01428                 $rowLayout = is_array($tableLayout[$rowCount]) ? $tableLayout[$rowCount] : $layout;
01429                 $rowResult = '';
01430                 if (is_array($tableRow)) {
01431                     $cellCount = 0;
01432                     foreach ($tableRow as $tableCell) {
01433                         $cellWrap = (is_array($layout[$cellCount])    ? $layout[$cellCount]    : $layout['defCol']);
01434                         $cellWrap = (is_array($rowLayout['defCol'])   ? $rowLayout['defCol']   : $cellWrap);
01435                         $cellWrap = (is_array($rowLayout[$cellCount]) ? $rowLayout[$cellCount] : $cellWrap);
01436                         $rowResult .= $cellWrap[0] . $tableCell . $cellWrap[1];
01437                         $cellCount++;
01438                     }
01439                 }
01440                 $rowWrap = (is_array($layout['tr'])    ? $layout['tr']    : array($this->table_TR, '</tr>'));
01441                 $rowWrap = (is_array($rowLayout['tr']) ? $rowLayout['tr'] : $rowWrap);
01442                 $result .= $rowWrap[0] . $rowResult . $rowWrap[1];
01443                 $rowCount++;
01444             }
01445             $tableWrap = is_array($tableLayout['table']) ? $tableLayout['table'] : array($this->table_TABLE, '</table>');
01446             $result = $tableWrap[0] . $result . $tableWrap[1];
01447         }
01448         return $result;
01449     }
01450 
01451     /**
01452      * Constructs a table with content from the $arr1, $arr2 and $arr3.
01453      * Used in eg. ext/belog/mod/index.php - refer to that for examples
01454      *
01455      * @param   array       Menu elements on first level
01456      * @param   array       Secondary items
01457      * @param   array       Third-level items
01458      * @return  string      HTML content, <table>...</table>
01459      */
01460     function menuTable($arr1,$arr2=array(), $arr3=array())  {
01461         $rows = max(array(count($arr1),count($arr2),count($arr3)));
01462 
01463         $menu='
01464         <table border="0" cellpadding="0" cellspacing="0" id="typo3-tablemenu">';
01465         for($a=0;$a<$rows;$a++) {
01466             $menu.='<tr>';
01467             $cls=array();
01468             $valign='middle';
01469             $cls[]='<td valign="'.$valign.'">'.$arr1[$a][0].'</td><td>'.$arr1[$a][1].'</td>';
01470             if (count($arr2))   {
01471                 $cls[]='<td valign="'.$valign.'">'.$arr2[$a][0].'</td><td>'.$arr2[$a][1].'</td>';
01472                 if (count($arr3))   {
01473                     $cls[]='<td valign="'.$valign.'">'.$arr3[$a][0].'</td><td>'.$arr3[$a][1].'</td>';
01474                 }
01475             }
01476             $menu.=implode($cls,'<td>&nbsp;&nbsp;</td>');
01477             $menu.='</tr>';
01478         }
01479         $menu.='
01480         </table>
01481         ';
01482         return $menu;
01483     }
01484 
01485     /**
01486      * Returns a one-row/two-celled table with $content and $menu side by side.
01487      * The table is a 100% width table and each cell is aligned left / right
01488      *
01489      * @param   string      Content cell content (left)
01490      * @param   string      Menu cell content (right)
01491      * @return  string      HTML output
01492      */
01493     function funcMenu($content,$menu)   {
01494         return '
01495             <table border="0" cellpadding="0" cellspacing="0" width="100%" id="typo3-funcmenu">
01496                 <tr>
01497                     <td valign="top" nowrap="nowrap">'.$content.'</td>
01498                     <td valign="top" align="right" nowrap="nowrap">'.$menu.'</td>
01499                 </tr>
01500             </table>';
01501     }
01502 
01503     /**
01504      * Creates a selector box with clear-cache items.
01505      * Rather specialized functions - at least don't use it with $addSaveOptions unless you know what you do...
01506      *
01507      * @param   integer     The page uid of the "current page" - the one that will be cleared as "clear cache for this page".
01508      * @param   boolean     If $addSaveOptions is set, then also the array of save-options for TCE_FORMS will appear.
01509      * @return  string      <select> tag with content - a selector box for clearing the cache
01510      */
01511     function clearCacheMenu($id,$addSaveOptions=0)  {
01512         global $BE_USER;
01513         $opt=array();
01514         if ($addSaveOptions)    {
01515             $opt[]='<option value="">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.menu',1).'</option>';
01516             $opt[]='<option value="TBE_EDITOR.checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc',1).'</option>';
01517             $opt[]='<option value="document.editform.closeDoc.value=-2; TBE_EDITOR.checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc',1).'</option>';
01518             if ($BE_USER->uc['allSaveFunctions'])   $opt[]='<option value="document.editform.closeDoc.value=-3; TBE_EDITOR.checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseAllDocs',1).'</option>';
01519             $opt[]='<option value="document.editform.closeDoc.value=2; document.editform.submit();">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc',1).'</option>';
01520             $opt[]='<option value="document.editform.closeDoc.value=3; document.editform.submit();">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeAllDocs',1).'</option>';
01521             $opt[]='<option value=""></option>';
01522         }
01523         $opt[]='<option value="">[ '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.clearCache_clearCache',1).' ]</option>';
01524         if ($id) $opt[]='<option value="'.$id.'">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.clearCache_thisPage',1).'</option>';
01525         if ($BE_USER->isAdmin() || $BE_USER->getTSConfigVal('options.clearCache.pages')) $opt[]='<option value="pages">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.clearCache_pages',1).'</option>';
01526         if ($BE_USER->isAdmin() || $BE_USER->getTSConfigVal('options.clearCache.all')) $opt[]='<option value="all">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.clearCache_all',1).'</option>';
01527 
01528         $onChange = 'if (!this.options[this.selectedIndex].value) {
01529                 this.selectedIndex=0;
01530             } else if (this.options[this.selectedIndex].value.indexOf(\';\')!=-1) {
01531                 eval(this.options[this.selectedIndex].value);
01532             } else {
01533                 window.location.href=\'' . $this->backPath .
01534                         'tce_db.php?vC=' . $BE_USER->veriCode() .
01535                         t3lib_BEfunc::getUrlToken('tceAction') .
01536                         '&redirect=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) .
01537                         '&cacheCmd=\'+this.options[this.selectedIndex].value;
01538             }';
01539         $af_content = '<select name="cacheCmd" onchange="'.htmlspecialchars($onChange).'">'.implode('',$opt).'</select>';
01540 
01541         if (count($opt)>1)  {
01542             return $af_content;
01543         }
01544     }
01545 
01546 
01547     /**
01548      * Includes a javascript library that exists in the core /typo3/ directory. The
01549      * backpath is automatically applied
01550      *
01551      * @param   string      $lib: Library name. Call it with the full path
01552      *              like "contrib/prototype/prototype.js" to load it
01553      * @return  void
01554      */
01555     function loadJavascriptLib($lib)    {
01556         $this->pageRenderer->addJsFile($this->backPath . $lib);
01557     }
01558 
01559 
01560 
01561     /**
01562      * Includes the necessary Javascript function for the clickmenu (context sensitive menus) in the document
01563      *
01564      * @return  array   Deprecated: Includes the code already in the doc, so the return array is always empty.
01565      *          Please just call this function without expecting a return value for future calls
01566      */
01567     function getContextMenuCode()   {
01568            $this->pageRenderer->loadPrototype();
01569            $this->loadJavascriptLib('js/clickmenu.js');
01570 
01571            $this->JScodeArray['clickmenu'] = '
01572                    Clickmenu.clickURL = "'.$this->backPath.'alt_clickmenu.php";
01573                    Clickmenu.ajax     = '.($this->isCMLayers() ? 'true' : 'false' ).';';
01574 
01575                // return array deprecated since 4.2
01576            return array('','','');
01577     }
01578 
01579     /**
01580      * Includes the necessary javascript file (tree.js) for use on pages which have the
01581      * drag and drop functionality (usually pages and folder display trees)
01582      *
01583      * @param   string      indicator of which table the drag and drop function should work on (pages or folders)
01584      * @return  array       If values are present: [0] = A <script> section for the HTML page header, [1] = onmousemove/onload handler for HTML tag or alike, [2] = One empty <div> layer for the follow-mouse drag element
01585      */
01586     function getDragDropCode($table)    {
01587         $this->pageRenderer->loadPrototype();
01588         $this->loadJavascriptLib('js/common.js');
01589         $this->loadJavascriptLib('js/tree.js');
01590 
01591             // setting prefs for drag & drop
01592         $this->JScodeArray['dragdrop'] = '
01593             DragDrop.changeURL = "'.$this->backPath.'alt_clickmenu.php";
01594             DragDrop.backPath  = "'.t3lib_div::shortMD5(''.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']).'";
01595             DragDrop.table     = "'.$table.'";
01596         ';
01597 
01598                // return array deprecated since 4.2
01599            return array('','','');
01600     }
01601 
01602      /**
01603      * This loads everything needed for the Context Sensitive Help (CSH)
01604      *
01605      * @return void
01606      */
01607     protected function loadCshJavascript() {
01608         $this->pageRenderer->loadExtJS();
01609         $this->pageRenderer->addJsFile($this->backPath .'../t3lib/js/extjs/contexthelp.js');
01610         $this->pageRenderer->addExtDirectCode();
01611     }
01612 
01613     /**
01614      * Creates a tab menu from an array definition
01615      *
01616      * Returns a tab menu for a module
01617      * Requires the JS function jumpToUrl() to be available
01618      *
01619      * @param   mixed       $id is the "&id=" parameter value to be sent to the module, but it can be also a parameter array which will be passed instead of the &id=...
01620      * @param   string      $elementName it the form elements name, probably something like "SET[...]"
01621      * @param   string      $currentValue is the value to be selected currently.
01622      * @param   array       $menuItems is an array with the menu items for the selector box
01623      * @param   string      $script is the script to send the &id to, if empty it's automatically found
01624      * @param   string      $addParams is additional parameters to pass to the script.
01625      * @return  string      HTML code for tab menu
01626      * @author  René Fritz <r.fritz@colorcube.de>
01627      */
01628     function getTabMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='') {
01629         $content='';
01630 
01631         if (is_array($menuItems))   {
01632             if (!is_array($mainParams)) {
01633                 $mainParams = array('id' => $mainParams);
01634             }
01635             $mainParams = t3lib_div::implodeArrayForUrl('',$mainParams);
01636 
01637             if (!$script) {$script=basename(PATH_thisScript);}
01638 
01639             $menuDef = array();
01640             foreach($menuItems as $value => $label) {
01641                 $menuDef[$value]['isActive'] = !strcmp($currentValue,$value);
01642                 $menuDef[$value]['label'] = t3lib_div::deHSCentities(htmlspecialchars($label));
01643                 $menuDef[$value]['url'] = $script . '?' . $mainParams . $addparams . '&' . $elementName . '=' . $value;
01644             }
01645             $content = $this->getTabMenuRaw($menuDef);
01646 
01647         }
01648         return $content;
01649     }
01650 
01651     /**
01652      * Creates the HTML content for the tab menu
01653      *
01654      * @param   array       Menu items for tabs
01655      * @return  string      Table HTML
01656      * @access private
01657      */
01658     function getTabMenuRaw($menuItems)  {
01659         $content='';
01660 
01661         if (is_array($menuItems))   {
01662             $options='';
01663 
01664             $count = count($menuItems);
01665             $widthLeft = 1;
01666             $addToAct = 5;
01667 
01668             $widthRight = max (1,floor(30-pow($count,1.72)));
01669             $widthTabs = 100 - $widthRight - $widthLeft;
01670             $widthNo = floor(($widthTabs - $addToAct)/$count);
01671             $addToAct = max ($addToAct,$widthTabs-($widthNo*$count));
01672             $widthAct = $widthNo + $addToAct;
01673             $widthRight = 100 - ($widthLeft + ($count*$widthNo) + $addToAct);
01674 
01675             foreach($menuItems as $id => $def) {
01676                 $isActive = $def['isActive'];
01677                 $class = $isActive ? 'tabact' : 'tab';
01678                 $width = $isActive ? $widthAct : $widthNo;
01679 
01680                     // @rene: Here you should probably wrap $label and $url in htmlspecialchars() in order to make sure its XHTML compatible! I did it for $url already since that is VERY likely to break.
01681                 $label = $def['label'];
01682                 $url = htmlspecialchars($def['url']);
01683                 $params = $def['addParams'];
01684 
01685                 $options .= '<td width="' . $width . '%" class="' . $class . '"><a href="' . $url . '" ' . $params . '>' . $label . '</a></td>';
01686             }
01687 
01688             if ($options)   {
01689                 $content .= '
01690                 <!-- Tab menu -->
01691                 <table cellpadding="0" cellspacing="0" border="0" width="100%" id="typo3-tabmenu">
01692                     <tr>
01693                             <td width="'.$widthLeft.'%">&nbsp;</td>
01694                             '.$options.'
01695                         <td width="'.$widthRight.'%">&nbsp;</td>
01696                     </tr>
01697                 </table>
01698                 <div class="hr" style="margin:0px"></div>';
01699             }
01700 
01701         }
01702         return $content;
01703     }
01704 
01705     /**
01706      * Creates a DYNAMIC tab-menu where the tabs are switched between with DHTML.
01707      * Should work in MSIE, Mozilla, Opera and Konqueror. On Konqueror I did find a serious problem: <textarea> fields loose their content when you switch tabs!
01708      *
01709      * @param   array       Numeric array where each entry is an array in itself with associative keys: "label" contains the label for the TAB, "content" contains the HTML content that goes into the div-layer of the tabs content. "description" contains description text to be shown in the layer. "linkTitle" is short text for the title attribute of the tab-menu link (mouse-over text of tab). "stateIcon" indicates a standard status icon (see ->icon(), values: -1, 1, 2, 3). "icon" is an image tag placed before the text.
01710      * @param   string      Identification string. This should be unique for every instance of a dynamic menu!
01711      * @param   integer     If "1", then enabling one tab does not hide the others - they simply toggles each sheet on/off. This makes most sense together with the $foldout option. If "-1" then it acts normally where only one tab can be active at a time BUT you can click a tab and it will close so you have no active tabs.
01712      * @param   boolean     If set, the tabs are rendered as headers instead over each sheet. Effectively this means there is no tab menu, but rather a foldout/foldin menu. Make sure to set $toggle as well for this option.
01713      * @param   integer     Character limit for a new row, 0 by default, because this parameter is deprecated since TYPO3 4.5
01714      * @param   boolean     If set, tab table cells are not allowed to wrap their content
01715      * @param   boolean     If set, the tabs will span the full width of their position
01716      * @param   integer     Default tab to open (for toggle <=0). Value corresponds to integer-array index + 1 (index zero is "1", index "1" is 2 etc.). A value of zero (or something non-existing) will result in no default tab open.
01717      * @param   integer     If set to '1' empty tabs will be remove, If set to '2' empty tabs will be disabled
01718      * @return  string      JavaScript section for the HTML header.
01719      */
01720     public function getDynTabMenu($menuItems, $identString, $toggle = 0, $foldout = FALSE, $newRowCharLimit = 0, $noWrap = 1, $fullWidth = FALSE, $defaultTabIndex = 1, $dividers2tabs = 2) {
01721             // load the static code, if not already done with the function below
01722         $this->loadJavascriptLib('js/tabmenu.js');
01723 
01724         $content = '';
01725 
01726         if (is_array($menuItems))   {
01727 
01728                 // Init:
01729             $options = array(array());
01730             $divs = array();
01731             $JSinit = array();
01732             $id = $this->getDynTabMenuId($identString);
01733             $noWrap = $noWrap ? ' nowrap="nowrap"' : '';
01734 
01735                 // Traverse menu items
01736             $c=0;
01737             $tabRows=0;
01738             $titleLenCount = 0;
01739             foreach($menuItems as $index => $def) {
01740                     // Need to add one so checking for first index in JavaScript
01741                     // is different than if it is not set at all.
01742                 $index += 1;
01743 
01744                     // Switch to next tab row if needed
01745                 if (!$foldout && (($newRowCharLimit > 0 && $titleLenCount > $newRowCharLimit) | ($def['newline'] === TRUE && $titleLenCount > 0))) {
01746                     $titleLenCount=0;
01747                     $tabRows++;
01748                     $options[$tabRows] = array();
01749                 }
01750 
01751                 if ($toggle==1) {
01752                     $onclick = 'this.blur(); DTM_toggle("'.$id.'","'.$index.'"); return false;';
01753                 } else {
01754                     $onclick = 'this.blur(); DTM_activate("'.$id.'","'.$index.'", '.($toggle<0?1:0).'); return false;';
01755                 }
01756 
01757                 $isEmpty = !(strcmp(trim($def['content']),'') || strcmp(trim($def['icon']),''));
01758 
01759                     // "Removes" empty tabs
01760                 if ($isEmpty && $dividers2tabs == 1) {
01761                     continue;
01762                 }
01763 
01764                 $mouseOverOut = ' onmouseover="DTM_mouseOver(this);" onmouseout="DTM_mouseOut(this);"';
01765                 $requiredIcon = '<img name="' . $id . '-' . $index . '-REQ" src="' . $GLOBALS['BACK_PATH'] . 'gfx/clear.gif" class="t3-TCEforms-reqTabImg" alt="" />';
01766 
01767                 if (!$foldout)  {
01768                         // Create TAB cell:
01769                     $options[$tabRows][] = '
01770                             <td class="'.($isEmpty ? 'disabled' : 'tab').'" id="'.$id.'-'.$index.'-MENU"'.$noWrap.$mouseOverOut.'>'.
01771                             ($isEmpty ? '' : '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>').
01772                             $def['icon'].
01773                             ($def['label'] ? htmlspecialchars($def['label']) : '&nbsp;').
01774                             $requiredIcon.
01775                             $this->icons($def['stateIcon'],'margin-left: 10px;').
01776                             ($isEmpty ? '' : '</a>').
01777                             '</td>';
01778                     $titleLenCount+= strlen($def['label']);
01779                 } else {
01780                         // Create DIV layer for content:
01781                     $divs[] = '
01782                         <div class="'.($isEmpty ? 'disabled' : 'tab').'" id="'.$id.'-'.$index.'-MENU"'.$mouseOverOut.'>'.
01783                             ($isEmpty ? '' : '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>').
01784                             $def['icon'].
01785                             ($def['label'] ? htmlspecialchars($def['label']) : '&nbsp;').
01786                             $requiredIcon.
01787                             ($isEmpty ? '' : '</a>').
01788                             '</div>';
01789                 }
01790 
01791                     // Create DIV layer for content:
01792                 $divs[] = '
01793                         <div style="display: none;" id="'.$id.'-'.$index.'-DIV" class="c-tablayer">'.
01794                             ($def['description'] ? '<p class="c-descr">'.nl2br(htmlspecialchars($def['description'])).'</p>' : '').
01795                             $def['content'].
01796                             '</div>';
01797                     // Create initialization string:
01798                 $JSinit[] = '
01799                         DTM_array["'.$id.'"]['.$c.'] = "'.$id.'-'.$index.'";
01800                 ';
01801                     // If not empty and we have the toggle option on, check if the tab needs to be expanded
01802                 if ($toggle == 1 && !$isEmpty) {
01803                     $JSinit[] = '
01804                         if (top.DTM_currentTabs["'.$id.'-'.$index.'"]) { DTM_toggle("'.$id.'","'.$index.'",1); }
01805                     ';
01806                 }
01807 
01808                 $c++;
01809             }
01810 
01811                 // Render menu:
01812             if (count($options))    {
01813 
01814                     // Tab menu is compiled:
01815                 if (!$foldout)  {
01816                     $tabContent = '';
01817                     for($a=0;$a<=$tabRows;$a++) {
01818                         $tabContent.= '
01819 
01820                     <!-- Tab menu -->
01821                     <table cellpadding="0" cellspacing="0" border="0"'.($fullWidth ? ' width="100%"' : '').' class="typo3-dyntabmenu">
01822                         <tr>
01823                                 '.implode('',$options[$a]).'
01824                         </tr>
01825                     </table>';
01826                     }
01827                     $content.= '<div class="typo3-dyntabmenu-tabs">'.$tabContent.'</div>';
01828                 }
01829 
01830                     // Div layers are added:
01831                 $content.= '
01832                 <!-- Div layers for tab menu: -->
01833                 <div class="typo3-dyntabmenu-divs'.($foldout?'-foldout':'').'">
01834                 '.implode('',$divs).'</div>';
01835 
01836                     // Java Script section added:
01837                 $content.= '
01838                 <!-- Initialization JavaScript for the menu -->
01839                 <script type="text/javascript">
01840                     DTM_array["'.$id.'"] = new Array();
01841                     '.implode('',$JSinit).'
01842                     '.($toggle<=0 ? 'DTM_activate("'.$id.'", top.DTM_currentTabs["'.$id.'"]?top.DTM_currentTabs["'.$id.'"]:'.intval($defaultTabIndex).', 0);' : '').'
01843                 </script>
01844 
01845                 ';
01846             }
01847 
01848         }
01849         return $content;
01850     }
01851 
01852     /**
01853      * Creates the id for dynTabMenus.
01854      *
01855      * @param   string      $identString: Identification string. This should be unique for every instance of a dynamic menu!
01856      * @return  string      The id with a short MD5 of $identString and prefixed "DTM-", like "DTM-2e8791854a"
01857      */
01858     function getDynTabMenuId($identString) {
01859         $id = 'DTM-'.t3lib_div::shortMD5($identString);
01860         return $id;
01861     }
01862 
01863     /**
01864      * Returns dynamic tab menu header JS code.
01865      * This is now incorporated automatically when the function template::getDynTabMenu is called
01866      * (as long as it is called before $this->startPage())
01867      * The return value is not needed anymore
01868      *
01869      * @deprecated since TYPO3 4.5, as the getDynTabMenu() function includes the function automatically since TYPO3 4.3
01870      * @return  void
01871      */
01872     function getDynTabMenuJScode() {
01873         t3lib_div::logDeprecatedFunction();
01874         $this->loadJavascriptLib('js/tabmenu.js');
01875     }
01876 
01877     /**
01878      * Creates the version selector for the page id inputted.
01879      * Requires the core version management extension, "version" to be loaded.
01880      *
01881      * @param   integer     Page id to create selector for.
01882      * @param   boolean     If set, there will be no button for swapping page.
01883      * @return  void
01884      */
01885     public function getVersionSelector($id, $noAction = FALSE) {
01886         if (t3lib_extMgm::isLoaded('version')) {
01887             $versionGuiObj = t3lib_div::makeInstance('tx_version_gui');
01888             return $versionGuiObj->getVersionSelector($id, $noAction);
01889         }
01890     }
01891 
01892     /**
01893      * Function to load a HTML template file with markers.
01894      * When calling from own extension, use  syntax getHtmlTemplate('EXT:extkey/template.html')
01895      *
01896      * @param   string      tmpl name, usually in the typo3/template/ directory
01897      * @return  string      HTML of template
01898      */
01899     function getHtmlTemplate($filename) {
01900             // setting the name of the original HTML template
01901         $this->moduleTemplateFilename = $filename;
01902 
01903         if ($GLOBALS['TBE_STYLES']['htmlTemplates'][$filename]) {
01904             $filename = $GLOBALS['TBE_STYLES']['htmlTemplates'][$filename];
01905         }
01906         if (t3lib_div::isFirstPartOfStr($filename, 'EXT:')) {
01907             $filename = t3lib_div::getFileAbsFileName($filename, TRUE, TRUE);
01908         } else if (!t3lib_div::isAbsPath($filename)) {
01909             $filename = t3lib_div::resolveBackPath($this->backPath . $filename);
01910         } else if (!t3lib_div::isAllowedAbsPath($filename)) {
01911             $filename = '';
01912         }
01913         $htmlTemplate = '';
01914         if ($filename !== '') {
01915             $htmlTemplate = t3lib_div::getURL($filename);
01916         }
01917         return $htmlTemplate;
01918     }
01919 
01920     /**
01921      * Define the template for the module
01922      *
01923      * @param   string      filename
01924      */
01925     public function setModuleTemplate($filename) {
01926             // Load Prototype lib for IE event
01927         $this->pageRenderer->loadPrototype();
01928         $this->loadJavascriptLib('js/iecompatibility.js');
01929         $this->moduleTemplate = $this->getHtmlTemplate($filename);
01930     }
01931 
01932     /**
01933      * Put together the various elements for the module <body> using a static HTML
01934      * template
01935      *
01936      * @param   array       Record of the current page, used for page path and info
01937      * @param   array       HTML for all buttons
01938      * @param   array       HTML for all other markers
01939      * @return  string      Composite HTML
01940      */
01941     public function moduleBody($pageRecord = array(), $buttons = array(), $markerArray = array(), $subpartArray = array()) {
01942             // Get the HTML template for the module
01943         $moduleBody = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###FULLDOC###');
01944             // Add CSS
01945         $this->inDocStylesArray[] = 'html { overflow: hidden; }';
01946             // Add JS code to the <head> for IE
01947         $this->JScode.= $this->wrapScriptTags('
01948                 // workaround since IE6 cannot deal with relative height for scrolling elements
01949             function resizeDocBody()    {
01950                 $("typo3-docbody").style.height = (document.body.offsetHeight - parseInt($("typo3-docheader").getStyle("height")));
01951             }
01952             if (Prototype.Browser.IE) {
01953                 var version = parseFloat(navigator.appVersion.split(\';\')[1].strip().split(\' \')[1]);
01954                 if (version == 6) {
01955                     Event.observe(window, "resize", resizeDocBody, false);
01956                     Event.observe(window, "load", resizeDocBody, false);
01957                 }
01958             }
01959         ');
01960 
01961             // Get the page path for the docheader
01962         $markerArray['PAGEPATH'] = $this->getPagePath($pageRecord);
01963             // Get the page info for the docheader
01964         $markerArray['PAGEINFO'] = $this->getPageInfo($pageRecord);
01965             // Get all the buttons for the docheader
01966         $docHeaderButtons = $this->getDocHeaderButtons($buttons);
01967             // Merge docheader buttons with the marker array
01968         $markerArray = array_merge($markerArray, $docHeaderButtons);
01969             // replacing subparts
01970         foreach ($subpartArray as $marker => $content) {
01971             $moduleBody = t3lib_parsehtml::substituteSubpart($moduleBody, $marker, $content);
01972         }
01973 
01974             // adding flash messages
01975         if ($this->showFlashMessages) {
01976             $flashMessages = t3lib_FlashMessageQueue::renderFlashMessages();
01977             if (!empty($flashMessages)) {
01978                 $markerArray['FLASHMESSAGES'] = '<div id="typo3-messages">' . $flashMessages . '</div>';
01979 
01980                     // if there is no dedicated marker for the messages present
01981                     // then force them to appear before the content
01982                 if (strpos($moduleBody, '###FLASHMESSAGES###') === FALSE) {
01983                     $moduleBody = str_replace(
01984                         '###CONTENT###',
01985                         '###FLASHMESSAGES######CONTENT###',
01986                         $moduleBody
01987                     );
01988                 }
01989             }
01990         }
01991 
01992             // Hook for adding more markers/content to the page, like the version selector
01993         if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['moduleBodyPostProcess'])) {
01994             $params = array(
01995                 'moduleTemplateFilename' => &$this->moduleTemplateFilename,
01996                 'moduleTemplate' => &$this->moduleTemplate,
01997                 'moduleBody' => &$moduleBody,
01998                 'markers' => &$markerArray,
01999                 'parentObject' => &$this
02000             );
02001             foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['moduleBodyPostProcess'] as $funcRef) {
02002                 t3lib_div::callUserFunction($funcRef, $params, $this);
02003             }
02004         }
02005 
02006             // replacing all markers with the finished markers and return the HTML content
02007         return t3lib_parsehtml::substituteMarkerArray($moduleBody, $markerArray, '###|###');
02008 
02009     }
02010 
02011     /**
02012      * Fill the button lists with the defined HTML
02013      *
02014      * @param   array       HTML for all buttons
02015      * @return  array       Containing HTML for both buttonlists
02016      */
02017     protected function getDocHeaderButtons($buttons) {
02018         $markers = array();
02019             // Fill buttons for left and right float
02020         $floats = array('left', 'right');
02021         foreach($floats as $key) {
02022                 // Get the template for each float
02023             $buttonTemplate = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###BUTTON_GROUPS_' . strtoupper($key) . '###');
02024                 // Fill the button markers in this float
02025             $buttonTemplate = t3lib_parsehtml::substituteMarkerArray($buttonTemplate, $buttons, '###|###', true);
02026                 // getting the wrap for each group
02027             $buttonWrap = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###BUTTON_GROUP_WRAP###');
02028                 // looping through the groups (max 6) and remove the empty groups
02029             for ($groupNumber = 1; $groupNumber < 6; $groupNumber++) {
02030                 $buttonMarker = '###BUTTON_GROUP' . $groupNumber . '###';
02031                 $buttonGroup = t3lib_parsehtml::getSubpart($buttonTemplate, $buttonMarker);
02032                 if (trim($buttonGroup)) {
02033                     if ($buttonWrap) {
02034                         $buttonGroup = t3lib_parsehtml::substituteMarker($buttonWrap, '###BUTTONS###', $buttonGroup);
02035                     }
02036                     $buttonTemplate = t3lib_parsehtml::substituteSubpart($buttonTemplate, $buttonMarker, trim($buttonGroup));
02037                 }
02038             }
02039                 // replace the marker with the template and remove all line breaks (for IE compat)
02040             $markers['BUTTONLIST_' . strtoupper($key)] = str_replace(LF, '', $buttonTemplate);
02041         }
02042 
02043             // Hook for manipulating docHeaderButtons
02044         if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['docHeaderButtonsHook'])) {
02045             $params = array(
02046                 'buttons'   => $buttons,
02047                 'markers'   => &$markers,
02048                 'pObj'      => &$this
02049             );
02050             foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['docHeaderButtonsHook'] as $funcRef)    {
02051                 t3lib_div::callUserFunction($funcRef, $params, $this);
02052             }
02053         }
02054 
02055         return $markers;
02056     }
02057 
02058     /**
02059      * Generate the page path for docheader
02060      *
02061      * @param   array   Current page
02062      * @return  string  Page path
02063      */
02064     protected function getPagePath($pageRecord) {
02065             // Is this a real page
02066         if ($pageRecord['uid']) {
02067             $title = substr($pageRecord['_thePathFull'], 0, -1);
02068                 // remove current page title
02069             $pos = strrpos($title, '/');
02070             if ($pos !== FALSE) {
02071                 $title = substr($title, 0, $pos) . '/';
02072             }
02073         } else {
02074             $title = '';
02075         }
02076 
02077             // Setting the path of the page
02078         $pagePath = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.path', 1) . ': <span class="typo3-docheader-pagePath">';
02079 
02080             // crop the title to title limit (or 50, if not defined)
02081         $cropLength = (empty($GLOBALS['BE_USER']->uc['titleLen'])) ? 50 : $GLOBALS['BE_USER']->uc['titleLen'];
02082         $croppedTitle = t3lib_div::fixed_lgd_cs($title, -$cropLength);
02083         if ($croppedTitle !== $title) {
02084             $pagePath .= '<abbr title="' . htmlspecialchars($title) . '">' . htmlspecialchars($croppedTitle) . '</abbr>';
02085         } else {
02086             $pagePath .= htmlspecialchars($title);
02087         }
02088         $pagePath .= '</span>';
02089         return $pagePath;
02090     }
02091 
02092     /**
02093      * Setting page icon with clickmenu + uid for docheader
02094      *
02095      * @param   array   Current page
02096      * @return  string  Page info
02097      */
02098     protected function getPageInfo($pageRecord) {
02099         global $BE_USER;
02100                 // Add icon with clickmenu, etc:
02101         if ($pageRecord['uid']) {   // If there IS a real page
02102             $alttext = t3lib_BEfunc::getRecordIconAltText($pageRecord, 'pages');
02103             $iconImg = t3lib_iconWorks::getSpriteIconForRecord('pages', $pageRecord, array('title'=>$alttext));
02104                 // Make Icon:
02105             $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, 'pages', $pageRecord['uid']);
02106             $uid = $pageRecord['uid'];
02107             $title = t3lib_BEfunc::getRecordTitle('pages', $pageRecord);
02108         } else {    // On root-level of page tree
02109                 // Make Icon
02110             $iconImg = t3lib_iconWorks::getSpriteIcon('apps-pagetree-root', array('title' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'])));
02111             if($BE_USER->user['admin']) {
02112                 $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, 'pages', 0);
02113             } else {
02114                 $theIcon = $iconImg;
02115             }
02116             $uid = '0';
02117             $title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
02118         }
02119 
02120             // Setting icon with clickmenu + uid
02121         $pageInfo = $theIcon . '<strong>' . htmlspecialchars($title) . '&nbsp;[' . $uid . ']</strong>';
02122         return $pageInfo;
02123     }
02124 
02125     /**
02126      * Makes a collapseable section. See reports module for an example
02127      *
02128      * @param  string  $title
02129      * @param  string  $html
02130      * @param  string  $id
02131      * @param  string $saveStatePointer
02132      * @return string
02133      */
02134     public function collapseableSection($title, $html, $id, $saveStatePointer = '') {
02135         $hasSave = $saveStatePointer ? TRUE : FALSE;
02136         $collapsedStyle =  $collapsedClass = '';
02137 
02138         if ($hasSave) {
02139             /** @var $settings extDirect_DataProvider_BackendUserSettings */
02140             $settings = t3lib_div::makeInstance('extDirect_DataProvider_BackendUserSettings');
02141             $value = $settings->get($saveStatePointer . '.' . $id);
02142             if ($value) {
02143                 $collapsedStyle = ' style="display: none"';
02144                 $collapsedClass = ' collapsed';
02145             } else {
02146                 $collapsedStyle = '';
02147                 $collapsedClass = ' expanded';
02148             }
02149         }
02150 
02151         $this->pageRenderer->loadExtJS();
02152         $this->pageRenderer->addExtOnReadyCode('
02153             Ext.select("h2.section-header").each(function(element){
02154                 element.on("click", function(event, tag) {
02155                     var state = 0,
02156                         el = Ext.fly(tag),
02157                         div = el.next("div"),
02158                         saveKey = el.getAttribute("rel");
02159                     if (el.hasClass("collapsed")) {
02160                         el.removeClass("collapsed").addClass("expanded");
02161                         div.slideIn("t", {
02162                             easing: "easeIn",
02163                             duration: .5
02164                         });
02165                     } else {
02166                         el.removeClass("expanded").addClass("collapsed");
02167                         div.slideOut("t", {
02168                             easing: "easeOut",
02169                             duration: .5,
02170                             remove: false,
02171                             useDisplay: true
02172                         });
02173                         state = 1;
02174                     }
02175                     if (saveKey) {
02176                         try {
02177                             top.TYPO3.BackendUserSettings.ExtDirect.set(saveKey + "." + tag.id, state, function(response) {});
02178                         } catch(e) {}
02179                     }
02180                 });
02181             });
02182         ');
02183         return '
02184           <h2 id="' . $id . '" class="section-header' . $collapsedClass . '" rel="' . $saveStatePointer . '"> ' . $title . '</h2>
02185           <div' . $collapsedStyle  . '>' . $html . '</div>
02186         ';
02187 
02188     }
02189 
02190 
02191 }
02192 
02193 
02194 // ******************************
02195 // Extension classes of the template class.
02196 // These are meant to provide backend screens with different widths.
02197 // They still do because of the different class-prefixes used for the <div>-sections
02198 // but obviously the final width is determined by the stylesheet used.
02199 // ******************************
02200 
02201 /**
02202  * Extension class for "template" - used for backend pages which are wide. Typically modules taking up all the space in the "content" frame of the backend
02203  * The class were more significant in the past than today.
02204  *
02205  */
02206 class bigDoc extends template {
02207     var $divClass = 'typo3-bigDoc';
02208 }
02209 
02210 /**
02211  * Extension class for "template" - used for backend pages without the "document" background image
02212  * The class were more significant in the past than today.
02213  *
02214  */
02215 class noDoc extends template {
02216     var $divClass = 'typo3-noDoc';
02217 }
02218 
02219 /**
02220  * Extension class for "template" - used for backend pages which were narrow (like the Web>List modules list frame. Or the "Show details" pop up box)
02221  * The class were more significant in the past than today.
02222  *
02223  */
02224 class smallDoc extends template {
02225     var $divClass = 'typo3-smallDoc';
02226 }
02227 
02228 /**
02229  * Extension class for "template" - used for backend pages which were medium wide. Typically submodules to Web or File which were presented in the list-frame when the content frame were divided into a navigation and list frame.
02230  * The class were more significant in the past than today. But probably you should use this one for most modules you make.
02231  *
02232  */
02233 class mediumDoc extends template {
02234     var $divClass = 'typo3-mediumDoc';
02235 }
02236 
02237 
02238 /**
02239  * Extension class for "template" - used in the context of frontend editing.
02240  */
02241 class frontendDoc extends template {
02242 
02243     /**
02244      * Gets instance of PageRenderer
02245      *
02246      * @return  t3lib_PageRenderer
02247      */
02248     public function getPageRenderer() {
02249         if (!isset($this->pageRenderer)) {
02250             $this->pageRenderer = $GLOBALS['TSFE']->getPageRenderer();
02251         }
02252         return $this->pageRenderer;
02253     }
02254 
02255     /**
02256      * Used in the frontend context to insert header data via TSFE->additionalHeaderData.
02257      * Mimics header inclusion from template->startPage().
02258      *
02259      * @return  void
02260      */
02261     public function insertHeaderData() {
02262 
02263         $this->backPath = $GLOBALS['TSFE']->backPath = TYPO3_mainDir;
02264         $this->pageRenderer->setBackPath($this->backPath);
02265         $this->docStyle();
02266 
02267             // add applied JS/CSS to $GLOBALS['TSFE']
02268         if ($this->JScode) {
02269             $this->pageRenderer->addHeaderData($this->JScode);
02270         }
02271         if (count($this->JScodeArray)) {
02272             foreach ($this->JScodeArray as $name => $code) {
02273                 $this->pageRenderer->addJsInlineCode($name, $code);
02274             }
02275         }
02276     }
02277 }
02278 
02279 
02280 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/template.php'])) {
02281     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/template.php']);
02282 }
02283 
02284 
02285 
02286 // ******************************
02287 // The template is loaded
02288 // ******************************
02289 $GLOBALS['TBE_TEMPLATE'] = t3lib_div::makeInstance('template');
02290 
02291 
02292 ?>