Added $Id$ keywords, cleaned up comment tags
[Packages/TYPO3.CMS.git] / typo3 / template.php
index 0b95d63..7cf0116 100755 (executable)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *  
-*  (c) 1999-2003 Kasper Skårhøj (kasper@typo3.com)
+*  (c) 1999-2003 Kasper Skaarhoj (kasper@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is 
 /** 
  * Contains class with layout/output function for TYPO3 Backend Scripts
  *
- * Revised for TYPO3 3.6 2/2003 by Kasper Skårhøj
+ * $Id$
+ * Revised for TYPO3 3.6 2/2003 by Kasper Skaarhoj
  * XHTML-trans compliant
  *
- * @author     Kasper Skårhøj <kasper@typo3.com>
- * @package TYPO3
- * @subpackage core
+ * @author     Kasper Skaarhoj <kasper@typo3.com>
  */
 /**
  * [CLASS/FUNCTION INDEX of SCRIPT]
  *
- *  143: function fw($str)     
+ *  144: function fw($str)     
  *
  *
- *  165: class template 
- *  209:     function template()       
+ *  168: class template 
+ *  214:     function template()       
  *
  *              SECTION: EVALUATION FUNCTIONS
- *  263:     function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1)       
- *  279:     function viewPageIcon($id,$backPath,$addParams='hspace="3"')      
- *  304:     function issueCommand($params,$rUrl='')   
- *  319:     function isCMlayers()     
- *  329:     function thisBlur()       
- *  339:     function helpStyle()      
- *  356:     function getHeader($table,$row,$path,$noViewPageIcon=0,$tWrap=array('',''))       
- *  381:     function getFileheader($title,$path,$iconfile)    
- *  397:     function makeShortcutIcon($gvList,$setList,$modName,$motherModName="")    
- *  430:     function makeShortcutUrl($gvList,$setList)        
- *  451:     function formWidth($size=48,$textarea=0,$styleOverride='') 
- *  476:     function formWidthText($size=48,$styleOverride='',$wrap='') 
- *  493:     function redirectUrls($thisLocation='')   
- *  517:     function formatTime($tstamp,$type)        
- *  530:     function parseTime()      
+ *  268:     function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1)       
+ *  284:     function viewPageIcon($id,$backPath,$addParams='hspace="3"')      
+ *  309:     function issueCommand($params,$rUrl='')   
+ *  324:     function isCMlayers()     
+ *  334:     function thisBlur()       
+ *  344:     function helpStyle()      
+ *  361:     function getHeader($table,$row,$path,$noViewPageIcon=0,$tWrap=array('',''))       
+ *  386:     function getFileheader($title,$path,$iconfile)    
+ *  402:     function makeShortcutIcon($gvList,$setList,$modName,$motherModName="")    
+ *  435:     function makeShortcutUrl($gvList,$setList)        
+ *  456:     function formWidth($size=48,$textarea=0,$styleOverride='') 
+ *  481:     function formWidthText($size=48,$styleOverride='',$wrap='') 
+ *  498:     function redirectUrls($thisLocation='')   
+ *  522:     function formatTime($tstamp,$type)        
+ *  535:     function parseTime()      
  *
  *              SECTION: PAGE BUILDING FUNCTIONS.
- *  563:     function startPage($title)        
- *  623:     function endPage()        
- *  648:     function header($text)    
- *  668:     function section($label,$text,$nostrtoupper=0,$sH=0,$type=0)      
- *  689:     function divider($dist)   
- *  705:     function spacer($dist)    
- *  723:     function sectionHeader($label,$sH=0)      
- *  740:     function sectionBegin()   
- *  761:     function sectionEnd()     
- *  781:     function middle() 
- *  790:     function endPageJS()      
- *  811:     function docBodyTagBegin()        
- *  822:     function docStyle()       
- *  846:     function getBackgroundImage($CSS=0)       
- *  859:     function initCharset()    
- *  869:     function generator()      
+ *  568:     function startPage($title)        
+ *  636:     function endPage()        
+ *  661:     function header($text)    
+ *  681:     function section($label,$text,$nostrtoupper=0,$sH=0,$type=0)      
+ *  702:     function divider($dist)   
+ *  718:     function spacer($dist)    
+ *  736:     function sectionHeader($label,$sH=0)      
+ *  753:     function sectionBegin()   
+ *  774:     function sectionEnd()     
+ *  794:     function middle() 
+ *  803:     function endPageJS()      
+ *  824:     function docBodyTagBegin()        
+ *  835:     function docStyle()       
+ *  866:     function insertStylesAndJS($content)      
+ *  885:     function getBackgroundImage($CSS=0)       
+ *  898:     function initCharset()    
+ *  910:     function generator()      
  *
  *              SECTION: OTHER ELEMENTS
- *  901:     function icons($type)     
- *  930:     function t3Button($onClick,$label)        
- *  941:     function dfw($string)     
- *  951:     function rfw($string)     
- *  961:     function wrapInCData($string)     
- *  975:     function wrapScriptTags($string)  
- * 1003:     function table($arr)      
- * 1043:     function menuTable($arr1,$arr2=array(), $arr3=array())    
- * 1076:     function funcMenu($content,$menu) 
- * 1090:     function clearCacheMenu($id,$addSaveOptions=0)    
- * 1124:     function getContextMenuCode()     
- * 1141:     function GL_checkBrowser()
- * 1156:     function GL_getObj(obj)
- * 1168:     function GL_getObjCss(obj)
- * 1172:     function GL_getMouse(event) 
- * 1186:     function outsideLayer(level)      
- * 1193:     function setLayerObj(html,level)  
- * 1211:     function hideEmpty()      
- * 1217:     function hideSpecific(level)      
- * 1223:     function debugObj(obj,name)       
- * 1229:     function initLayer()
+ *  942:     function icons($type)     
+ *  971:     function t3Button($onClick,$label)        
+ *  982:     function dfw($string)     
+ *  992:     function rfw($string)     
+ * 1002:     function wrapInCData($string)     
+ * 1019:     function wrapScriptTags($string, $linebreak=TRUE) 
+ * 1056:     function table($arr)      
+ * 1096:     function menuTable($arr1,$arr2=array(), $arr3=array())    
+ * 1129:     function funcMenu($content,$menu) 
+ * 1143:     function clearCacheMenu($id,$addSaveOptions=0)    
+ * 1177:     function getContextMenuCode()     
+ * 1194:     function GL_checkBrowser()
+ * 1210:     function GL_getObj(obj)
+ * 1222:     function GL_getObjCss(obj)
+ * 1226:     function GL_getMouse(event) 
+ * 1240:     function outsideLayer(level)      
+ * 1247:     function setLayerObj(html,level)  
+ * 1268:     function hideEmpty()      
+ * 1274:     function hideSpecific(level)      
+ * 1280:     function debugObj(obj,name)       
+ * 1286:     function initLayer()
+ * 1322:     function getTabMenu($id,$elementName,$currentValue,$menuItems,$script='',$addparams='')   
  *
  *
- * 1262: class bigDoc extends template 
+ * 1431: class bigDoc extends template 
  *
  *
- * 1271: class noDoc extends template 
+ * 1440: class noDoc extends template 
  *
  *
- * 1280: class smallDoc extends template 
+ * 1449: class smallDoc extends template 
  *
  *
- * 1289: class mediumDoc extends template 
+ * 1458: class mediumDoc extends template 
  *
- * TOTAL FUNCTIONS: 54
+ * TOTAL FUNCTIONS: 56
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
@@ -160,7 +161,9 @@ function fw($str)   {
  * 
  * Please refer to Inside TYPO3 for a discussion of how to use this API.
  * 
- * @author     Kasper Skårhøj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @package TYPO3
+ * @subpackage core
  */
 class template {
 
@@ -168,12 +171,14 @@ class template {
        var $backPath = '';     // 'backPath' pointing back to the PATH_typo3
        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.
        var $JScode='';         // Additional header code (eg. a JavaScript section) could be accommulated in this var. It will be directly outputted in the header.
+       var $JScodeArray=array();               // Similar to $JScode but for use as array with assioziative keys to prevent double inclusion of JS code. a <script> tag is automatically wrapped around.
        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.
        var $docType='';        // Doc-type used in the header. Default is HTML 3.2. You can also set it to 'xhtml_strict', 'xhtml_trans', or 'xhtml_frames'.
 
                // Other vars you can change, but less frequently used:
        var $bodyTagAdditions='';       // You can add additional attributes to the body-tag through this variable.
        var $inDocStyles='';            // Additional CSS styles which will be added to the <style> section in the header
+       var $inDocStylesArray=array();          // Like $inDocStyles but for use as array with assioziative keys to prevent double inclusion of css code
        var $form_rowsToStylewidth = 9.58;      // Multiplication factor for formWidth() input size (default is 48* this value).
        var $form_largeComp = 1.33;             // Compensation for large documents (used in class.t3lib_tceforms.php)
        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. 
@@ -190,7 +195,7 @@ class template {
        var $styleSheetFile = 'stylesheet.css'; // Filename of stylesheet (relative to PATH_typo3)
        var $styleSheetFile2 = '';      // Filename of stylesheet #2 - linked to right after the $this->styleSheetFile script (relative to PATH_typo3)
        var $backGroundImage = '';              // Background image of page (relative to PATH_typo3)
-       
+
                // DEV: 
        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.
        
@@ -251,7 +256,7 @@ class template {
 
        /**
         * Makes click menu link (context sensitive menu)
-        * 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)
+        * 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)
         * 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)
         * 
         * @param       string          String to be wrapped in link, typ. image tag.
@@ -261,7 +266,7 @@ class template {
         * @return      string          The link-wrapped input string.
         */
        function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1)     {
-               $onClick = 'top.loadTopMenu(\''.$this->backPath.'alt_clickmenu.php?item='.rawurlencode($table.'|'.$uid.'|'.$listFr).'\');'.$this->thisBlur().'return false;';
+               $onClick = 'top.loadTopMenu(\''.$this->backPath.'alt_clickmenu.php?item='.rawurlencode($table.'|'.$uid.'|'.$listFr).($this->backPath?'&backPath='.rawurlencode($this->backPath.'|'.md5($this->backPath.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])):'').'\');'.$this->thisBlur().'return false;';
                return '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.$str.'</a>';
        }
 
@@ -561,9 +566,13 @@ class template {
         * @see endPage()
         */
        function startPage($title)      {
+                       // Get META tag containing the currently selected charset for backend output. The function sets $this->charSet.
                $charSet = $this->initCharset();
                $generator = $this->generator();
-               
+
+                       // Send HTTP header for selected charset. Added by Robert Lemke 23.10.2003
+               header ('Content-Type:text/html;charset='.$this->charset);
+
                switch($this->docType)  {
                        case 'xhtml_strict':
                                $headerStart= '<?xml version="1.0" encoding="'.$this->charset.'"?>
@@ -599,8 +608,12 @@ class template {
        <title>'.htmlspecialchars($title).'</title>
        '.$this->docStyle().'
        '.$this->JScode.'
+       '.$this->wrapScriptTags(implode("\n", $this->JScodeArray)).'
+       <!--###POSTJSMARKER###-->
 </head>
 ';
+               $this->JScode='';
+               $this->JScodeArray=array();
 
                if ($this->docType=='xhtml_frames')     {
                        return $str;
@@ -683,7 +696,7 @@ trim($this->form);
         * Inserts a divider image
         * Ends a section (if open) before inserting the image
         * 
-        * @param       integer         The padding-top/-bottom of the <hr> ruler.
+        * @param       integer         The margin-top/-bottom of the <hr> ruler.
         * @return      string          HTML content
         */
        function divider($dist) {
@@ -691,7 +704,7 @@ trim($this->form);
                $str='
 
        <!-- DIVIDER -->
-       <hr style="padding-top: '.$dist.'px; padding-bottom: '.$dist.'px;" />
+       <hr style="margin-top: '.$dist.'px; margin-bottom: '.$dist.'px;" />
 ';
                return $this->sectionEnd().$str;
        }
@@ -699,7 +712,7 @@ trim($this->form);
        /**
         * Returns a blank <div>-section with a height
         * 
-        * @param       integer         Padding-top for the div-section
+        * @param       integer         Padding-top for the div-section (should be margin-top but konquorer (3.1) don't like it :-(
         * @return      string          HTML content
         */
        function spacer($dist)  {
@@ -820,6 +833,9 @@ trim($this->form);
         * @return      string          HTML style section/link tags
         */
        function docStyle()     {
+               $this->inDocStylesArray[] = $this->inDocStyles;
+               $inDocStyles = "\n".implode("\n", $this->inDocStylesArray);
+
                        // The default color scheme should also in full be represented in the stylesheet.
                $style='
                '.($this->styleSheetFile?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile.'" />':'').'
@@ -830,14 +846,37 @@ trim($this->form);
                                H2 {background-color: '.$this->bgColor2.';}
                                H3 {background-color: '.$this->bgColor6.';}
                                BODY {background-color: '.$this->bgColor.';'.$this->getBackgroundImage(1).'}
-                               '.$this->inDocStyles.'
+                               '.$inDocStyles.'
+                               /*###POSTCSSMARKER###*/
                        /*]]>*/
                </style>
 ';
+               $this->inDocStyles='';
+               $this->inDocStylesArray=array();
+
                return $style;
        }
 
        /**
+        * Insert post rendering document style into already rendered content
+        * 
+        * @param       string          style-content to insert.
+        * @return      string          content with inserted styles
+        */
+       function insertStylesAndJS($content)    {
+                       // insert accumulated CSS
+               $this->inDocStylesArray[] = $this->inDocStyles;
+               $styles = "\n".implode("\n", $this->inDocStylesArray);
+               $content = str_replace('/*###POSTCSSMARKER###*/',$styles,$content);
+
+                       // insert accumulated JS
+               $jscode = $this->JScode."\n".$this->wrapScriptTags(implode("\n", $this->JScodeArray));
+               $content = str_replace('<!--###POSTJSMARKER###-->',$jscode,$content);
+
+               return $content;
+       }
+
+       /**
         * Returns the 'background' attribute for the bodytag if the TBE_STYLES[background] value is set (must be relative to PATH_typo3)
         * 
         * @param       boolean         If set, a background image is referred to with the CSS property "background-image" instead of the body-tag property "background"
@@ -953,7 +992,7 @@ trim($this->form);
        function rfw($string)   {
                return '<span class="typo3-red">'.$string.'</span>';
        }
-       
+
        /**
         * Returns string wrapped in CDATA "tags" for XML / XHTML (wrap content of <script> and <style> sections in those!)
         * 
@@ -970,18 +1009,30 @@ trim($this->form);
        
        /**
         * Wraps the input string in script tags.
+        * Automatic re-identing of the JS code is done by using the first line as ident reference.
+        * This is nice for identing JS code with PHP code on the same level.
         * 
         * @param       string          Input string
+        * @param       boolean         Wrap script element in linebreaks? Default is TRUE.
         * @return      string          Output string
         */
-       function wrapScriptTags($string)        {
-               $string = '
-<script type="text/javascript">
+       function wrapScriptTags($string, $linebreak=TRUE)       {
+               if(trim($string)) {
+                               // <script wrapped in nl?
+                       $cr = $linebreak? "\n" : '';
+
+                               // remove nl from the beginning
+                       $string = preg_replace ('/^\n+/', '', $string);
+                               // re-ident to one tab using the first line as reference
+                       if(preg_match('/^(\t+)/',$string,$match)) {
+                               $string = str_replace($match[1],"\t", $string);
+                       }
+                       $string = $cr.'<script type="text/javascript">
 /*<![CDATA[*/
-       '.$string.'
+'.$string.'
 /*]]>*/
-</script>
-       ';
+</script>'.$cr;
+               }
                return trim($string);
        }
 
@@ -1187,9 +1238,9 @@ trim($this->form);
                                }
                                        // outsideLayer(level)
                                function outsideLayer(level)    {
-                                       return GLV_x+GLV_gap-GLV_curLayerX[level] <0 || 
-                                                       GLV_y+GLV_gap-GLV_curLayerY[level] <0 || 
-                                                       GLV_curLayerX[level]+GLV_curLayerWidth[level]+GLV_gap-GLV_x <0 || 
+                                       return GLV_x+GLV_gap-GLV_curLayerX[level] <0 ||
+                                                       GLV_y+GLV_gap-GLV_curLayerY[level] <0 ||
+                                                       GLV_curLayerX[level]+GLV_curLayerWidth[level]+GLV_gap-GLV_x <0 ||
                                                        GLV_curLayerY[level]+GLV_curLayerHeight[level]+GLV_gap-GLV_y <0;
                                }
                                        // setLayerObj(html,level)
@@ -1202,8 +1253,10 @@ trim($this->form);
                                                tempLayerObj.height= (bw.ie4||bw.ie5||bw.ns6||bw.konq||bw.op7)?this.el.offsetHeight:bw.ns4?this.ref.height:bw.op?this.css.pixelHeight:0;
                                                tempLayerObj.width= (bw.ie4||bw.ie5||bw.ns6||bw.konq||bw.op7)?this.el.offsetWidth:bw.ns4?this.ref.width:bw.op?this.css.pixelWidth:0;
 
-                                               tempLayerObjCss.left = GLV_curLayerX[level] = GLV_x;
-                                               tempLayerObjCss.top = GLV_curLayerY[level] = GLV_y;
+                                               GLV_curLayerX[level] = GLV_x;
+                                               GLV_curLayerY[level] = GLV_y;
+                                               tempLayerObjCss.left = GLV_x+"px";
+                                               tempLayerObjCss.top = GLV_y+"px";
                                                tempLayerObjCss.visibility = "visible";
 
                                                GLV_isVisible[level]=1;
@@ -1247,6 +1300,118 @@ trim($this->form);
                        );
                } else return array('','','');
        }
+
+
+
+
+       /**
+        * creates a tab menu from an array definition
+        * 
+        * Returns a tab menu for a module
+        * Requires the JS function jumpToUrl() to be available
+        * 
+        * @param       string          $id is the "&id=" parameter value to be sent to the module
+        * @param       string          $elementName it the form elements name, probably something like "SET[...]"
+        * @param       string          $currentValue is the value to be selected currently.
+        * @param       array           $menuItems is an array with the menu items for the selector box
+        * @param       string          $script is the script to send the &id to, if empty it's automatically found
+        * @param       string          $addParams is additional parameters to pass to the script.
+        * @return      string          HTML code for tab menu
+        * @author      René Fritz <r.fritz@colorcube.de>
+        */
+       function getTabMenu($id,$elementName,$currentValue,$menuItems,$script='',$addparams='') {
+               $content='';
+
+               if (is_array($menuItems))       {
+                       if (!$script) {basename(PATH_thisScript);}
+                       $options='';
+
+                       $count = count($menuItems);
+                       $widthLeft = 1;
+                       $addToAct = 5;
+
+                       $widthRight = max (1,floor(30-pow($count,1.72)));
+                       $widthTabs = 100 - $widthRight - $widthLeft;
+                       $widthNo = floor(($widthTabs - $addToAct)/$count);
+                       $addToAct = max ($addToAct,$widthTabs-($widthNo*$count));
+                       $widthAct = $widthNo + $addToAct;
+                       $widthRight = 100 - ($widthLeft + ($count*$widthNo) + $addToAct);
+
+                       $first=true;
+                       foreach($menuItems as $value => $label) {
+                               $isActive = !strcmp($currentValue,$value);
+                               $class = $isActive ? "tabact" : "tab";
+                               $width = $isActive ? $widthAct : $widthNo;
+
+                               $label = t3lib_div::deHSCentities(htmlspecialchars($label));
+                               $link = htmlspecialchars($script.'?id='.rawurlencode($id).$addparams.'&'.$elementName.'='.$value);
+                               if($first) {
+                                       $options .= "\n\t".'<td width="'.$width.'%" class="'.$class.'" style="border-left: solid #000 1px;"><a href="'.$link.'" class="'.$class.'" style="padding-left:5px;padding-right:2px;">'.$label.'</a></td>';
+                               } else {
+                                       $options .= "\n\t".'<td width="'.$width.'%" class="'.$class.'"><a href="'.$link.'" class="'.$class.'">'.$label.'</a></td>';
+                               }
+                               $first=false;
+                       }
+
+                       if ($options)   {
+                               $content .= "\n\t".'<!-- Tab menu -->';
+                               $content .= "\n\t".'<table cellpadding="0" cellspacing="0" border="0" width="100%"><tr>';
+                               $content .= "\n\t".'<td width="'.$widthLeft.'%">&nbsp;</td>';
+
+                               $content .= $options;
+
+                               $content .= "\n\t".'<td width="'.$widthRight.'%">&nbsp;</td>';
+                               $content .= "\n\t".'</tr></table>';
+                               $content .= '<div class="hr" style="display:block;margin:0px;padding:0px;"></div>';
+                       }
+
+                               // include CSS
+                       $actBgColor = t3lib_div::modifyHTMLcolor($this->bgColor6,0,0,0);
+                       $lgBgColor = t3lib_div::modifyHTMLcolor($this->bgColor5,25,25,25);
+                       $hoverBgColor = t3lib_div::modifyHTMLcolor($this->bgColor6,15,15,15);
+
+                       $this->inDocStylesArray['getTabMenu'] = '
+                               td.tabact {
+                                       border: solid black 1px;
+                                       background: '.$actBgColor.';
+                                       color:#000;
+                               }
+                               td.tabact>a {
+                                       color:#000;
+                               }
+                               td.tab {
+                                       border: solid #555 1px;
+                                       border-left: solid #aaa 3px;
+                                       background: '.$lgBgColor.';
+                                       color:grey;
+                               }
+                               td.tab, td.tabact {
+                                       border-bottom: none;
+                                       border-radius: 3px;
+                                       -moz-border-radius: 3px;
+                               }
+                               a.tab, a.tabact {
+                                       color:grey;
+                                       text-decoration:none;
+                                       display: block;
+                                       width:auto;
+                                       padding:2px;
+                                       padding-left:3px;
+                                       padding-right:5px;
+                               }
+                               a.tabact {
+                                       padding-left:10px;
+                                       padding-right:10px;
+                               }
+                               a.tab:hover,a.tabact:hover {
+                                       color:black;
+                                       background: '.$hoverBgColor.';
+                                       text-decoration:none;
+                                       cursor: pointer;
+                               }';
+               }
+               return $content;
+       }
 }
 
 
@@ -1316,4 +1481,4 @@ $LANG->init($BE_USER->uc['lang']);
 // The template is loaded
 // ******************************
 $TBE_TEMPLATE = t3lib_div::makeInstance('template');
-?>
\ No newline at end of file
+?>