[ Index ]
 

Code source de Typo3 4.1.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/t3lib/ -> class.t3lib_befunc.php (source)

   1  <?php
   2  /***************************************************************
   3  *  Copyright notice
   4  *
   5  *  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
   6  *  All rights reserved
   7  *
   8  *  This script is part of the TYPO3 project. The TYPO3 project is
   9  *  free software; you can redistribute it and/or modify
  10  *  it under the terms of the GNU General Public License as published by
  11  *  the Free Software Foundation; either version 2 of the License, or
  12  *  (at your option) any later version.
  13  *
  14  *  The GNU General Public License can be found at
  15  *  http://www.gnu.org/copyleft/gpl.html.
  16  *  A copy is found in the textfile GPL.txt and important notices to the license
  17  *  from the author is found in LICENSE.txt distributed with these scripts.
  18  *
  19  *
  20  *  This script is distributed in the hope that it will be useful,
  21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23  *  GNU General Public License for more details.
  24  *
  25  *  This copyright notice MUST APPEAR in all copies of the script!
  26  ***************************************************************/
  27  /**
  28   * Standard functions available for the TYPO3 backend.
  29   * You are encouraged to use this class in your own applications (Backend Modules)
  30   *
  31   * Call ALL methods without making an object!
  32   * Eg. to get a page-record 51 do this: 't3lib_BEfunc::getRecord('pages',51)'
  33   *
  34   * $Id: class.t3lib_befunc.php 2459 2007-08-23 13:11:42Z liels_bugs $
  35   * Usage counts are based on search 22/2 2003 through whole backend source of typo3/
  36   * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
  37   * XHTML compliant
  38   *
  39   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
  40   */
  41  /**
  42   * [CLASS/FUNCTION INDEX of SCRIPT]
  43   *
  44   *
  45   *
  46   *  185: class t3lib_BEfunc
  47   *
  48   *              SECTION: SQL-related, selecting records, searching
  49   *  206:     function deleteClause($table,$tableAlias='')
  50   *  230:     function getRecord($table,$uid,$fields='*',$where='',$useDeleteClause=true)
  51   *  253:     function getRecordWSOL($table,$uid,$fields='*',$where='',$useDeleteClause=true)
  52   *  286:     function getRecordRaw($table,$where='',$fields='*')
  53   *  309:     function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='',$useDeleteClause=true)
  54   *  342:     function searchQuery($searchWords,$fields,$table='')
  55   *  357:     function listQuery($field,$value)
  56   *  369:     function splitTable_Uid($str)
  57   *  384:     function getSQLselectableList($in_list,$tablename,$default_tablename)
  58   *  412:     function BEenableFields($table,$inv=0)
  59   *
  60   *              SECTION: SQL-related, DEPRECATED functions
  61   *  476:     function mm_query($select,$local_table,$mm_table,$foreign_table,$whereClause='',$groupBy='',$orderBy='',$limit='')
  62   *  498:     function DBcompileInsert($table,$fields_values)
  63   *  512:     function DBcompileUpdate($table,$where,$fields_values)
  64   *
  65   *              SECTION: Page tree, TCA related
  66   *  542:     function BEgetRootLine($uid,$clause='',$workspaceOL=FALSE)
  67   *  598:     function openPageTree($pid,$clearExpansion)
  68   *  643:     function getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
  69   *  686:     function getExcludeFields()
  70   *  716:     function getExplicitAuthFieldValues()
  71   *  787:     function getSystemLanguages()
  72   *  812:     function readPageAccess($id,$perms_clause)
  73   *  843:     function getTCAtypes($table,$rec,$useFieldNameAsKey=0)
  74   *  896:     function getTCAtypeValue($table,$rec)
  75   *  919:     function getSpecConfParts($str, $defaultExtras)
  76   *  950:     function getSpecConfParametersFromArray($pArr)
  77   *  978:     function getFlexFormDS($conf,$row,$table,$fieldName='',$WSOL=TRUE)
  78   *
  79   *              SECTION: Caching related
  80   * 1105:     function storeHash($hash,$data,$ident)
  81   * 1125:     function getHash($hash,$expTime=0)
  82   *
  83   *              SECTION: TypoScript related
  84   * 1161:     function getPagesTSconfig($id,$rootLine='',$returnPartArray=0)
  85   * 1217:     function updatePagesTSconfig($id,$pageTS,$TSconfPrefix,$impParams='')
  86   * 1272:     function implodeTSParams($p,$k='')
  87   *
  88   *              SECTION: Users / Groups related
  89   * 1309:     function getUserNames($fields='username,usergroup,usergroup_cached_list,uid',$where='')
  90   * 1327:     function getGroupNames($fields='title,uid', $where='')
  91   * 1344:     function getListGroupNames($fields='title,uid')
  92   * 1363:     function blindUserNames($usernames,$groupArray,$excludeBlindedFlag=0)
  93   * 1396:     function blindGroupNames($groups,$groupArray,$excludeBlindedFlag=0)
  94   *
  95   *              SECTION: Output related
  96   * 1437:     function daysUntil($tstamp)
  97   * 1449:     function date($tstamp)
  98   * 1460:     function datetime($value)
  99   * 1472:     function time($value)
 100   * 1488:     function calcAge($seconds,$labels = 'min|hrs|days|yrs')
 101   * 1514:     function dateTimeAge($tstamp,$prefix=1,$date='')
 102   * 1532:     function titleAttrib($content='',$hsc=0)
 103   * 1545:     function titleAltAttrib($content)
 104   * 1569:     function thumbCode($row,$table,$field,$backPath,$thumbScript='',$uploaddir=NULL,$abs=0,$tparams='',$size='')
 105   * 1637:     function getThumbNail($thumbScript,$theFile,$tparams='',$size='')
 106   * 1654:     function titleAttribForPages($row,$perms_clause='',$includeAttrib=1)
 107   * 1716:     function getRecordIconAltText($row,$table='pages')
 108   * 1758:     function getLabelFromItemlist($table,$col,$key)
 109   * 1784:     function getItemLabel($table,$col,$printAllWrap='')
 110   * 1809:     function getRecordTitle($table,$row,$prep=0)
 111   * 1847:     function getProcessedValue($table,$col,$value,$fixed_lgd_chars=0,$defaultPassthrough=0,$noRecordLookup=FALSE,$uid=0)
 112   * 2009:     function getProcessedValueExtra($table,$fN,$fV,$fixed_lgd_chars=0,$uid=0)
 113   * 2033:     function getFileIcon($ext)
 114   * 2047:     function getCommonSelectFields($table,$prefix='')
 115   * 2090:     function makeConfigForm($configArray,$defaults,$dataPrefix)
 116   *
 117   *              SECTION: Backend Modules API functions
 118   * 2165:     function helpTextIcon($table,$field,$BACK_PATH,$force=0)
 119   * 2187:     function helpText($table,$field,$BACK_PATH,$styleAttrib='')
 120   * 2239:     function cshItem($table,$field,$BACK_PATH,$wrap='',$onlyIconMode=FALSE, $styleAttrib='')
 121   * 2277:     function editOnClick($params,$backPath='',$requestUri='')
 122   * 2296:     function viewOnClick($id,$backPath='',$rootLine='',$anchor='',$altUrl='',$addGetVars='',$switchFocus=TRUE)
 123   * 2328:     function getModTSconfig($id,$TSref)
 124   * 2349:     function getFuncMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='')
 125   * 2392:     function getFuncCheck($mainParams,$elementName,$currentValue,$script='',$addparams='',$tagParams='')
 126   * 2417:     function getFuncInput($mainParams,$elementName,$currentValue,$size=10,$script="",$addparams="")
 127   * 2438:     function unsetMenuItems($modTSconfig,$itemArray,$TSref)
 128   * 2461:     function getSetUpdateSignal($set='')
 129   * 2512:     function getModuleData($MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='')
 130   *
 131   *              SECTION: Core
 132   * 2585:     function compilePreviewKeyword($getVarsStr, $beUserUid, $ttl=172800)
 133   * 2613:     function lockRecords($table='',$uid=0,$pid=0)
 134   * 2642:     function isRecordLocked($table,$uid)
 135   * 2682:     function exec_foreign_table_where_query($fieldValue,$field='',$TSconfig=array(),$prefix='')
 136   * 2763:     function getTCEFORM_TSconfig($table,$row)
 137   * 2814:     function getTSconfig_pidValue($table,$uid,$pid)
 138   * 2844:     function getPidForModTSconfig($table,$uid,$pid)
 139   * 2860:     function getTSCpid($table,$uid,$pid)
 140   * 2876:     function firstDomainRecord($rootLine)
 141   * 2898:     function getDomainStartPage($domain, $path='')
 142   * 2928:     function RTEsetup($RTEprop,$table,$field,$type='')
 143   * 2947:     function &RTEgetObj()
 144   * 2986:     function &softRefParserObj($spKey)
 145   * 3018:     function explodeSoftRefParserList($parserList)
 146   * 3050:     function isModuleSetInTBE_MODULES($modName)
 147   * 3073:     function referenceCount($table,$ref,$msg='')
 148   *
 149   *              SECTION: Workspaces / Versioning
 150   * 3132:     function selectVersionsOfRecord($table, $uid, $fields='*', $workspace=0)
 151   * 3180:     function fixVersioningPid($table,&$rr,$ignoreWorkspaceMatch=FALSE)
 152   * 3220:     function workspaceOL($table,&$row,$wsid=-99)
 153   * 3268:     function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields='*')
 154   * 3297:     function getLiveVersionOfRecord($table,$uid,$fields='*')
 155   * 3319:     function isPidInVersionizedBranch($pid, $table='',$returnStage=FALSE)
 156   * 3342:     function versioningPlaceholderClause($table)
 157   * 3356:     function countVersionsOfRecordsOnPage($workspace,$pageId, $allTables=FALSE)
 158   * 3391:     function wsMapId($table,$uid)
 159   *
 160   *              SECTION: Miscellaneous
 161   * 3421:     function typo3PrintError($header,$text,$js='',$head=1)
 162   * 3465:     function TYPO3_copyRightNotice()
 163   * 3489:     function displayWarningMessages()
 164   * 3546:     function getPathType_web_nonweb($path)
 165   * 3558:     function ADMCMD_previewCmds($pageinfo)
 166   * 3580:     function processParams($params)
 167   * 3606:     function getListOfBackendModules($name,$perms_clause,$backPath='',$script='index.php')
 168   *
 169   * TOTAL FUNCTIONS: 99
 170   * (This index is automatically created/updated by the extension "extdeveval")
 171   *
 172   */
 173  
 174  require_once (PATH_t3lib.'class.t3lib_loaddbgroup.php');
 175  
 176  
 177  /**
 178   * Standard functions available for the TYPO3 backend.
 179   * Don't instantiate - call functions with "t3lib_BEfunc::" prefixed the function name.
 180   *
 181   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
 182   * @package TYPO3
 183   * @subpackage t3lib
 184   */
 185  class t3lib_BEfunc    {
 186  
 187  
 188  
 189      /*******************************************
 190       *
 191       * SQL-related, selecting records, searching
 192       *
 193       *******************************************/
 194  
 195  
 196      /**
 197       * Returns the WHERE clause " AND NOT [tablename].[deleted-field]" if a deleted-field is configured in $TCA for the tablename, $table
 198       * This function should ALWAYS be called in the backend for selection on tables which are configured in TCA since it will ensure consistent selection of records, even if they are marked deleted (in which case the system must always treat them as non-existent!)
 199       * In the frontend a function, ->enableFields(), is known to filter hidden-field, start- and endtime and fe_groups as well. But that is a job of the frontend, not the backend. If you need filtering on those fields as well in the backend you can use ->BEenableFields() though.
 200       * Usage: 71
 201       *
 202       * @param    string        Table name present in $TCA
 203       * @param    string        Table alias if any
 204       * @return    string        WHERE clause for filtering out deleted records, eg " AND tablename.deleted=0"
 205       */
 206  	function deleteClause($table,$tableAlias='')    {
 207          global $TCA;
 208          if ($TCA[$table]['ctrl']['delete'])    {
 209              return ' AND '.($tableAlias ? $tableAlias : $table).'.'.$TCA[$table]['ctrl']['delete'].'=0';
 210          } else {
 211              return '';
 212          }
 213      }
 214  
 215      /**
 216       * Gets record with uid=$uid from $table
 217       * You can set $field to a list of fields (default is '*')
 218       * Additional WHERE clauses can be added by $where (fx. ' AND blabla=1')
 219       * Will automatically check if records has been deleted and if so, not return anything.
 220       * $table must be found in $TCA
 221       * Usage: 99
 222       *
 223       * @param    string        Table name present in $TCA
 224       * @param    integer        UID of record
 225       * @param    string        List of fields to select
 226       * @param    string        Additional WHERE clause, eg. " AND blablabla=0"
 227       * @param    boolean        Use the deleteClause to check if a record is deleted (default true)
 228       * @return    array        Returns the row if found, otherwise nothing
 229       */
 230  	function getRecord($table,$uid,$fields='*',$where='',$useDeleteClause=true)    {
 231          if ($GLOBALS['TCA'][$table])    {
 232              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
 233                  $fields,
 234                  $table,
 235                  'uid='.intval($uid).($useDeleteClause ? t3lib_BEfunc::deleteClause($table) : '').$where
 236              );
 237              $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
 238              $GLOBALS['TYPO3_DB']->sql_free_result($res);
 239              if ($row) {
 240                  return $row;
 241              }
 242          }
 243      }
 244  
 245      /**
 246       * Like getRecord(), but overlays workspace version if any.
 247       *
 248       * @param    string        Table name present in $TCA
 249       * @param    integer        UID of record
 250       * @param    string        List of fields to select
 251       * @param    string        Additional WHERE clause, eg. " AND blablabla=0"
 252       * @param    boolean        Use the deleteClause to check if a record is deleted (default true)
 253       * @return    array        Returns the row if found, otherwise nothing
 254       */
 255  	function getRecordWSOL($table,$uid,$fields='*',$where='',$useDeleteClause=true) {
 256          if ($fields !== '*') {
 257              $internalFields = t3lib_div::uniqueList($fields.',uid,pid'.($table == 'pages' ? ',t3ver_swapmode' : ''));
 258              $row = t3lib_BEfunc::getRecord($table,$uid,$internalFields,$where,$useDeleteClause);
 259              t3lib_BEfunc::workspaceOL($table,$row);
 260  
 261              if (is_array ($row)) {
 262                  foreach (array_keys($row) as $key) {
 263                      if (!t3lib_div::inList($fields, $key) && $key{0} !== '_') {
 264                          unset ($row[$key]);
 265                      }
 266                  }
 267              }
 268          } else {
 269              $row = t3lib_BEfunc::getRecord($table,$uid,$fields,$where);
 270              t3lib_BEfunc::workspaceOL($table,$row);
 271          }
 272          return $row;
 273      }
 274  
 275      /**
 276       * Returns the first record found from $table with $where as WHERE clause
 277       * This function does NOT check if a record has the deleted flag set.
 278       * $table does NOT need to be configured in $TCA
 279       * The query used is simply this:
 280       * $query='SELECT '.$fields.' FROM '.$table.' WHERE '.$where;
 281       * Usage: 5 (ext: sys_todos)
 282       *
 283       * @param    string        Table name (not necessarily in TCA)
 284       * @param    string        WHERE clause
 285       * @param    string        $fields is a list of fields to select, default is '*'
 286       * @return    array        First row found, if any, FALSE otherwise
 287       */
 288  	function getRecordRaw($table,$where='',$fields='*')    {
 289          $row = FALSE;
 290          if (FALSE !== ($res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, $where, '', '', '1')))    {
 291              $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
 292              $GLOBALS['TYPO3_DB']->sql_free_result($res);
 293          }
 294          return $row;
 295      }
 296  
 297      /**
 298       * Returns records from table, $theTable, where a field ($theField) equals the value, $theValue
 299       * The records are returned in an array
 300       * If no records were selected, the function returns nothing
 301       * Usage: 8
 302       *
 303       * @param    string        Table name present in $TCA
 304       * @param    string        Field to select on
 305       * @param    string        Value that $theField must match
 306       * @param    string        Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
 307       * @param    string        Optional GROUP BY field(s), if none, supply blank string.
 308       * @param    string        Optional ORDER BY field(s), if none, supply blank string.
 309       * @param    string        Optional LIMIT value ([begin,]max), if none, supply blank string.
 310       * @param    boolean        Use the deleteClause to check if a record is deleted (default true)
 311       * @return    mixed        Multidimensional array with selected records (if any is selected)
 312       */
 313  	function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='',$useDeleteClause=true)    {
 314          global $TCA;
 315          if (is_array($TCA[$theTable])) {
 316              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
 317                          '*',
 318                          $theTable,
 319                          $theField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($theValue, $theTable).
 320                              ($useDeleteClause ? t3lib_BEfunc::deleteClause($theTable).' ' : '').
 321                              t3lib_BEfunc::versioningPlaceholderClause($theTable).' '.
 322                              $whereClause,    // whereClauseMightContainGroupOrderBy
 323                          $groupBy,
 324                          $orderBy,
 325                          $limit
 326                      );
 327              $rows = array();
 328              while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 329                  $rows[] = $row;
 330              }
 331              $GLOBALS['TYPO3_DB']->sql_free_result($res);
 332              if (count($rows))    return $rows;
 333          }
 334      }
 335  
 336      /**
 337       * Returns a WHERE clause which will make an AND search for the words in the $searchWords array in any of the fields in array $fields.
 338       * Usage: 0
 339       *
 340       * @param    array        Array of search words
 341       * @param    array        Array of fields
 342       * @param    string        Table in which we are searching (for DBAL detection of quoteStr() method)
 343       * @return    string        WHERE clause for search
 344       * @deprecated        Use $GLOBALS['TYPO3_DB']->searchQuery() directly!
 345       */
 346  	function searchQuery($searchWords,$fields,$table='')    {
 347          return $GLOBALS['TYPO3_DB']->searchQuery($searchWords,$fields,$table);
 348      }
 349  
 350      /**
 351       * Returns a WHERE clause that can find a value ($value) in a list field ($field)
 352       * For instance a record in the database might contain a list of numbers, "34,234,5" (with no spaces between). This query would be able to select that record based on the value "34", "234" or "5" regardless of their positioni in the list (left, middle or right).
 353       * Is nice to look up list-relations to records or files in TYPO3 database tables.
 354       * Usage: 0
 355       *
 356       * @param    string        Table field name
 357       * @param    string        Value to find in list
 358       * @return    string        WHERE clause for a query
 359       * @deprecated        Use $GLOBALS['TYPO3_DB']->listQuery() directly!
 360       */
 361  	function listQuery($field,$value)    {
 362          return $GLOBALS['TYPO3_DB']->listQuery($field,$value,'');
 363      }
 364  
 365      /**
 366       * Makes an backwards explode on the $str and returns an array with ($table,$uid).
 367       * Example: tt_content_45    =>    array('tt_content',45)
 368       * Usage: 1
 369       *
 370       * @param    string        [tablename]_[uid] string to explode
 371       * @return    array
 372       */
 373  	function splitTable_Uid($str)    {
 374          list($uid,$table) = explode('_',strrev($str),2);
 375          return array(strrev($table),strrev($uid));
 376      }
 377  
 378      /**
 379       * Returns a list of pure integers based on $in_list being a list of records with table-names prepended.
 380       * Ex: $in_list = "pages_4,tt_content_12,45" would result in a return value of "4,45" if $tablename is "pages" and $default_tablename is 'pages' as well.
 381       * Usage: 1 (t3lib_userauthgroup)
 382       *
 383       * @param    string        Input list
 384       * @param    string        Table name from which ids is returned
 385       * @param    string        $default_tablename denotes what table the number '45' is from (if nothing is prepended on the value)
 386       * @return    string        List of ids
 387       */
 388  	function getSQLselectableList($in_list,$tablename,$default_tablename)    {
 389          $list = Array();
 390          if ((string)trim($in_list)!='')    {
 391              $tempItemArray = explode(',',trim($in_list));
 392              while(list($key,$val)=each($tempItemArray))    {
 393                  $val = strrev($val);
 394                  $parts = explode('_',$val,2);
 395                  if ((string)trim($parts[0])!='')    {
 396                      $theID = intval(strrev($parts[0]));
 397                      $theTable = trim($parts[1]) ? strrev(trim($parts[1])) : $default_tablename;
 398                      if ($theTable==$tablename)    {$list[]=$theID;}
 399                  }
 400              }
 401          }
 402          return implode(',',$list);
 403      }
 404  
 405      /**
 406       * Backend implementation of enableFields()
 407       * Notice that "fe_groups" is not selected for - only disabled, starttime and endtime.
 408       * Notice that deleted-fields are NOT filtered - you must ALSO call deleteClause in addition.
 409       * $GLOBALS["SIM_EXEC_TIME"] is used for date.
 410       * Usage: 5
 411       *
 412       * @param    string        $table is the table from which to return enableFields WHERE clause. Table name must have a 'ctrl' section in $TCA.
 413       * @param    boolean        $inv means that the query will select all records NOT VISIBLE records (inverted selection)
 414       * @return    string        WHERE clause part
 415       */
 416  	function BEenableFields($table,$inv=0)    {
 417          $ctrl = $GLOBALS['TCA'][$table]['ctrl'];
 418          $query=array();
 419          $invQuery=array();
 420          if (is_array($ctrl))    {
 421              if (is_array($ctrl['enablecolumns']))    {
 422                  if ($ctrl['enablecolumns']['disabled'])    {
 423                      $field = $table.'.'.$ctrl['enablecolumns']['disabled'];
 424                      $query[]=$field.'=0';
 425                      $invQuery[]=$field.'!=0';
 426                  }
 427                  if ($ctrl['enablecolumns']['starttime'])    {
 428                      $field = $table.'.'.$ctrl['enablecolumns']['starttime'];
 429                      $query[]='('.$field.'<='.$GLOBALS['SIM_EXEC_TIME'].')';
 430                      $invQuery[]='('.$field.'!=0 AND '.$field.'>'.$GLOBALS['SIM_EXEC_TIME'].')';
 431                  }
 432                  if ($ctrl['enablecolumns']['endtime'])    {
 433                      $field = $table.'.'.$ctrl['enablecolumns']['endtime'];
 434                      $query[]='('.$field.'=0 OR '.$field.'>'.$GLOBALS['SIM_EXEC_TIME'].')';
 435                      $invQuery[]='('.$field.'!=0 AND '.$field.'<='.$GLOBALS['SIM_EXEC_TIME'].')';
 436                  }
 437              }
 438          }
 439          $outQ = ' AND '.($inv ? '('.implode(' OR ',$invQuery).')' : implode(' AND ',$query));
 440  
 441          return $outQ;
 442      }
 443  
 444  
 445  
 446  
 447  
 448  
 449  
 450  
 451  
 452  
 453      /*******************************************
 454       *
 455       * SQL-related, DEPRECATED functions
 456       * (use t3lib_DB functions instead)
 457       *
 458       *******************************************/
 459  
 460  
 461      /**
 462       * Returns a SELECT query, selecting fields ($select) from two/three tables joined
 463       * $local_table and $mm_table is mandatory. $foreign_table is optional.
 464       * The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local  / [$mm_table].uid_foreign <--> [$foreign_table].uid
 465       * The function is very useful for selecting MM-relations between tables adhering to the MM-format used by TCE (TYPO3 Core Engine). See the section on $TCA in Inside TYPO3 for more details.
 466       * DEPRECATED - Use $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query() instead since that will return the result pointer while this returns the query. Using this function may make your application less fitted for DBAL later.
 467       *
 468       * @param    string        Field list for SELECT
 469       * @param    string        Tablename, local table
 470       * @param    string        Tablename, relation table
 471       * @param    string        Tablename, foreign table
 472       * @param    string        Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
 473       * @param    string        Optional GROUP BY field(s), if none, supply blank string.
 474       * @param    string        Optional ORDER BY field(s), if none, supply blank string.
 475       * @param    string        Optional LIMIT value ([begin,]max), if none, supply blank string.
 476       * @return    string        Full SQL query
 477       * @deprecated
 478       * @see t3lib_DB::exec_SELECT_mm_query()
 479       */
 480  	function mm_query($select,$local_table,$mm_table,$foreign_table,$whereClause='',$groupBy='',$orderBy='',$limit='')    {
 481          $query = $GLOBALS['TYPO3_DB']->SELECTquery(
 482                      $select,
 483                      $local_table.','.$mm_table.($foreign_table?','.$foreign_table:''),
 484                      $local_table.'.uid='.$mm_table.'.uid_local'.($foreign_table?' AND '.$foreign_table.'.uid='.$mm_table.'.uid_foreign':'').' '.
 485                          $whereClause,    // whereClauseMightContainGroupOrderBy
 486                      $groupBy,
 487                      $orderBy,
 488                      $limit
 489                  );
 490          return $query;
 491      }
 492  
 493      /**
 494       * Creates an INSERT SQL-statement for $table from the array with field/value pairs $fields_values.
 495       * DEPRECATED - $GLOBALS['TYPO3_DB']->INSERTquery() directly instead! But better yet, use $GLOBALS['TYPO3_DB']->exec_INSERTquery()
 496       *
 497       * @param    string        Table name
 498       * @param    array        Field values as key=>value pairs.
 499       * @return    string        Full SQL query for INSERT
 500       * @deprecated
 501       */
 502  	function DBcompileInsert($table,$fields_values)    {
 503          return $GLOBALS['TYPO3_DB']->INSERTquery($table, $fields_values);
 504      }
 505  
 506      /**
 507       * Creates an UPDATE SQL-statement for $table where $where-clause (typ. 'uid=...') from the array with field/value pairs $fields_values.
 508       * DEPRECATED - $GLOBALS['TYPO3_DB']->UPDATEquery() directly instead! But better yet, use $GLOBALS['TYPO3_DB']->exec_UPDATEquery()
 509       *
 510       * @param    string        Database tablename
 511       * @param    string        WHERE clause, eg. "uid=1"
 512       * @param    array        Field values as key=>value pairs.
 513       * @return    string        Full SQL query for UPDATE
 514       * @deprecated
 515       */
 516  	function DBcompileUpdate($table,$where,$fields_values)    {
 517          return $GLOBALS['TYPO3_DB']->UPDATEquery($table, $where, $fields_values);
 518      }
 519  
 520  
 521  
 522  
 523  
 524  
 525  
 526  
 527  
 528  
 529      /*******************************************
 530       *
 531       * Page tree, TCA related
 532       *
 533       *******************************************/
 534  
 535      /**
 536       * Returns what is called the 'RootLine'. That is an array with information about the page records from a page id ($uid) and back to the root.
 537       * By default deleted pages are filtered.
 538       * This RootLine will follow the tree all the way to the root. This is opposite to another kind of root line known from the frontend where the rootline stops when a root-template is found.
 539       * Usage: 1
 540       *
 541       * @param    integer        Page id for which to create the root line.
 542       * @param    string        $clause can be used to select other criteria. It would typically be where-clauses that stops the process if we meet a page, the user has no reading access to.
 543       * @param    boolean        If true, version overlay is applied. This must be requested specifically because it is usually only wanted when the rootline is used for visual output while for permission checking you want the raw thing!
 544       * @return    array        Root line array, all the way to the page tree root (or as far as $clause allows!)
 545       */
 546  	function BEgetRootLine($uid,$clause='',$workspaceOL=FALSE)    {
 547          if (is_array($GLOBALS['T3_VAR']['BEgetRootLine_cache'][$uid][$clause][$workspaceOL?1:0]))    {
 548              return $GLOBALS['T3_VAR']['BEgetRootLine_cache'][$uid][$clause][$workspaceOL?1:0];
 549          }
 550          $pid = $uid;
 551          $loopCheck = 100;
 552          $theRowArray = Array();
 553          $output = Array();
 554          while ($uid!=0 && $loopCheck>0)    {
 555              $loopCheck--;
 556              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
 557                  'pid,uid,title,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_swapmode,t3ver_stage',
 558                  'pages',
 559                  'uid='.intval($uid).' '.
 560                      t3lib_BEfunc::deleteClause('pages').' '.
 561                      $clause        // whereClauseMightContainGroupOrderBy
 562              );
 563              if ($GLOBALS['TYPO3_DB']->sql_error())    {
 564                  debug($GLOBALS['TYPO3_DB']->sql_error(),1);
 565              }
 566              if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 567                  if($workspaceOL)    t3lib_BEfunc::workspaceOL('pages',$row);
 568                  t3lib_BEfunc::fixVersioningPid('pages',$row);
 569                  $uid = $row['pid'];
 570                  $theRowArray[] = $row;
 571              } else {
 572                  break;
 573              }
 574          }
 575          if ($uid==0) {$theRowArray[] = Array('uid'=>0,'title'=>'');}
 576          if (is_array($theRowArray))    {
 577              reset($theRowArray);
 578              $c=count($theRowArray);
 579              while(list($key,$val)=each($theRowArray))    {
 580                  $c--;
 581                  $output[$c]['uid'] = $val['uid'];
 582                  $output[$c]['pid'] = $val['pid'];
 583                  if (isset($val['_ORIG_pid'])) $output[$c]['_ORIG_pid'] = $val['_ORIG_pid'];
 584                  $output[$c]['title'] = $val['title'];
 585                  $output[$c]['TSconfig'] = $val['TSconfig'];
 586                  $output[$c]['is_siteroot'] = $val['is_siteroot'];
 587                  $output[$c]['storage_pid'] = $val['storage_pid'];
 588                  $output[$c]['t3ver_oid'] = $val['t3ver_oid'];
 589                  $output[$c]['t3ver_wsid'] = $val['t3ver_wsid'];
 590                  $output[$c]['t3ver_state'] = $val['t3ver_state'];
 591                  $output[$c]['t3ver_swapmode'] = $val['t3ver_swapmode'];
 592                  $output[$c]['t3ver_stage'] = $val['t3ver_stage'];
 593              }
 594          }
 595          $GLOBALS['T3_VAR']['BEgetRootLine_cache'][$pid][$clause][$workspaceOL?1:0] = $output;
 596  
 597          return $output;
 598      }
 599  
 600      /**
 601       * Opens the page tree to the specified page id
 602       *
 603       * @param    integer        Page id.
 604       * @param    boolean        If set, then other open branches are closed.
 605       * @return    void
 606       */
 607  	function openPageTree($pid,$clearExpansion)    {
 608          global $BE_USER;
 609  
 610              // Get current expansion data:
 611          if ($clearExpansion)    {
 612              $expandedPages = array();
 613          } else {
 614              $expandedPages = unserialize($BE_USER->uc['browseTrees']['browsePages']);
 615          }
 616  
 617              // Get rootline:
 618          $rL = t3lib_BEfunc::BEgetRootLine($pid);
 619  
 620              // First, find out what mount index to use (if more than one DB mount exists):
 621          $mountIndex = 0;
 622          $mountKeys = array_flip($BE_USER->returnWebmounts());
 623          foreach($rL as $rLDat)    {
 624              if (isset($mountKeys[$rLDat['uid']]))    {
 625                  $mountIndex = $mountKeys[$rLDat['uid']];
 626                  break;
 627              }
 628          }
 629  
 630              // Traverse rootline and open paths:
 631          foreach($rL as $rLDat)    {
 632              $expandedPages[$mountIndex][$rLDat['uid']] = 1;
 633          }
 634  
 635              // Write back:
 636          $BE_USER->uc['browseTrees']['browsePages'] = serialize($expandedPages);
 637          $BE_USER->writeUC();
 638      }
 639  
 640      /**
 641       * Returns the path (visually) of a page $uid, fx. "/First page/Second page/Another subpage"
 642       * Each part of the path will be limited to $titleLimit characters
 643       * Deleted pages are filtered out.
 644       * Usage: 15
 645       *
 646       * @param    integer        Page uid for which to create record path
 647       * @param    string        $clause is additional where clauses, eg. "
 648       * @param    integer        Title limit
 649       * @param    integer        Title limit of Full title (typ. set to 1000 or so)
 650       * @return    mixed        Path of record (string) OR array with short/long title if $fullTitleLimit is set.
 651       */
 652  	function getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)    {
 653          if (!$titleLimit) { $titleLimit=1000; }
 654  
 655          $loopCheck = 100;
 656          $output = $fullOutput = '/';
 657          while ($uid!=0 && $loopCheck>0)    {
 658              $loopCheck--;
 659              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
 660                          'uid,pid,title,t3ver_oid,t3ver_wsid,t3ver_swapmode',
 661                          'pages',
 662                          'uid='.intval($uid).
 663                              t3lib_BEfunc::deleteClause('pages').
 664                              (strlen(trim($clause)) ? ' AND '.$clause : '')
 665                      );
 666              if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 667                  t3lib_BEfunc::workspaceOL('pages',$row);
 668                  t3lib_BEfunc::fixVersioningPid('pages',$row);
 669  
 670                  if ($row['_ORIG_pid'] && $row['t3ver_swapmode']>0)    {    // Branch points
 671                      $output = ' [#VEP#]'.$output;        // Adding visual token - Versioning Entry Point - that tells that THIS position was where the versionized branch got connected to the main tree. I will have to find a better name or something...
 672                  }
 673                  $uid = $row['pid'];
 674                  $output = '/'.t3lib_div::fixed_lgd_cs(strip_tags($row['title']),$titleLimit).$output;
 675                  if ($fullTitleLimit)    $fullOutput = '/'.t3lib_div::fixed_lgd_cs(strip_tags($row['title']),$fullTitleLimit).$fullOutput;
 676              } else {
 677                  break;
 678              }
 679          }
 680  
 681          if ($fullTitleLimit)    {
 682              return array($output, $fullOutput);
 683          } else {
 684              return $output;
 685          }
 686      }
 687  
 688      /**
 689       * Returns an array with the exclude-fields as defined in TCA
 690       * Used for listing the exclude-fields in be_groups forms
 691       * Usage: 2 (t3lib_tceforms + t3lib_transferdata)
 692       *
 693       * @return    array        Array of arrays with excludeFields (fieldname, table:fieldname) from all TCA entries
 694       */
 695  	function getExcludeFields()    {
 696          global $TCA;
 697              // All TCA keys:
 698          $theExcludeArray = Array();
 699          $tc_keys = array_keys($TCA);
 700          foreach($tc_keys as $table)    {
 701                  // Load table
 702              t3lib_div::loadTCA($table);
 703                  // All field names configured:
 704              if (is_array($TCA[$table]['columns']))    {
 705                  $f_keys = array_keys($TCA[$table]['columns']);
 706                  foreach($f_keys as $field)    {
 707                      if ($TCA[$table]['columns'][$field]['exclude'])    {
 708                              // Get Human Readable names of fields and table:
 709                          $Fname=$GLOBALS['LANG']->sl($TCA[$table]['ctrl']['title']).': '.$GLOBALS['LANG']->sl($TCA[$table]['columns'][$field]['label']);
 710                              // add entry:
 711                          $theExcludeArray[] = Array($Fname , $table.':'.$field);
 712                      }
 713                  }
 714              }
 715          }
 716          return $theExcludeArray;
 717      }
 718  
 719      /**
 720       * Returns an array with explicit Allow/Deny fields.
 721       * Used for listing these field/value pairs in be_groups forms
 722       *
 723       * @return    array        Array with information from all of $TCA
 724       */
 725  	function getExplicitAuthFieldValues()    {
 726          global $TCA;
 727  
 728              // Initialize:
 729          $adLabel = array(
 730              'ALLOW' => $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xml:labels.allow'),
 731              'DENY' => $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xml:labels.deny'),
 732          );
 733  
 734              // All TCA keys:
 735          $allowDenyOptions = Array();
 736          $tc_keys = array_keys($TCA);
 737          foreach($tc_keys as $table)    {
 738  
 739                  // Load table
 740              t3lib_div::loadTCA($table);
 741  
 742                  // All field names configured:
 743              if (is_array($TCA[$table]['columns']))    {
 744                  $f_keys = array_keys($TCA[$table]['columns']);
 745                  foreach($f_keys as $field)    {
 746                      $fCfg = $TCA[$table]['columns'][$field]['config'];
 747                      if ($fCfg['type']=='select' && $fCfg['authMode'])    {
 748  
 749                              // Check for items:
 750                          if (is_array($fCfg['items']))    {
 751                                  // Get Human Readable names of fields and table:
 752                              $allowDenyOptions[$table.':'.$field]['tableFieldLabel'] = $GLOBALS['LANG']->sl($TCA[$table]['ctrl']['title']).': '.$GLOBALS['LANG']->sl($TCA[$table]['columns'][$field]['label']);
 753  
 754                                  // Check for items:
 755                              foreach($fCfg['items'] as $iVal)    {
 756                                  if (strcmp($iVal[1],''))    {    // Values '' is not controlled by this setting.
 757  
 758                                          // Find iMode:
 759                                      $iMode = '';
 760                                      switch((string)$fCfg['authMode'])    {
 761                                          case 'explicitAllow':
 762                                              $iMode = 'ALLOW';
 763                                          break;
 764                                          case 'explicitDeny':
 765                                              $iMode = 'DENY';
 766                                          break;
 767                                          case 'individual':
 768                                              if (!strcmp($iVal[4],'EXPL_ALLOW'))    {
 769                                                  $iMode = 'ALLOW';
 770                                              } elseif (!strcmp($iVal[4],'EXPL_DENY'))    {
 771                                                  $iMode = 'DENY';
 772                                              }
 773                                          break;
 774                                      }
 775  
 776                                          // Set iMode:
 777                                      if ($iMode)    {
 778                                          $allowDenyOptions[$table.':'.$field]['items'][$iVal[1]] = array($iMode, $GLOBALS['LANG']->sl($iVal[0]), $adLabel[$iMode]);
 779                                      }
 780                                  }
 781                              }
 782                          }
 783                      }
 784                  }
 785              }
 786          }
 787  
 788          return $allowDenyOptions;
 789      }
 790  
 791      /**
 792       * Returns an array with system languages:
 793       *
 794       * @return    array        Array with languages
 795       */
 796  	function getSystemLanguages()    {
 797  
 798              // Initialize, add default language:
 799          $sysLanguages = array();
 800          $sysLanguages[] = array('Default language', 0);
 801  
 802              // Traverse languages
 803          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,title,flag','sys_language','pid=0'.t3lib_BEfunc::deleteClause('sys_language'));
 804          while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 805              $sysLanguages[] = array($row['title'].' ['.$row['uid'].']', $row['uid'], ($row['flag'] ? 'flags/'.$row['flag'] : ''));
 806          }
 807  
 808          return $sysLanguages;
 809      }
 810  
 811      /**
 812       * Returns a page record (of page with $id) with an extra field "_thePath" set to the record path IF the WHERE clause, $perms_clause, selects the record. Thus is works as an access check that returns a page record if access was granted, otherwise not.
 813       * If $id is zero a pseudo root-page with "_thePath" set is returned IF the current BE_USER is admin.
 814       * In any case ->isInWebMount must return true for the user (regardless of $perms_clause)
 815       * Usage: 21
 816       *
 817       * @param    integer        Page uid for which to check read-access
 818       * @param    string        $perms_clause is typically a value generated with $BE_USER->getPagePermsClause(1);
 819       * @return    array        Returns page record if OK, otherwise false.
 820       */
 821  	function readPageAccess($id,$perms_clause)    {
 822          if ((string)$id!='')    {
 823              $id = intval($id);
 824              if (!$id)    {
 825                  if ($GLOBALS['BE_USER']->isAdmin())    {
 826                      $path = '/';
 827                      $pageinfo['_thePath'] = $path;
 828                      return $pageinfo;
 829                  }
 830              } else {
 831                  $pageinfo = t3lib_BEfunc::getRecord('pages',$id,'*',($perms_clause ? ' AND '.$perms_clause : ''));
 832                  if ($pageinfo['uid'] && $GLOBALS['BE_USER']->isInWebMount($id,$perms_clause))    {
 833                      t3lib_BEfunc::workspaceOL('pages', $pageinfo);
 834                      t3lib_BEfunc::fixVersioningPid('pages', $pageinfo);
 835                      list($pageinfo['_thePath'],$pageinfo['_thePathFull']) = t3lib_BEfunc::getRecordPath(intval($pageinfo['uid']), $perms_clause, 15, 1000);
 836                      return $pageinfo;
 837                  }
 838              }
 839          }
 840          return false;
 841      }
 842  
 843      /**
 844       * Returns the "types" configuration parsed into an array for the record, $rec, from table, $table
 845       * Usage: 6
 846       *
 847       * @param    string        Table name (present in TCA)
 848       * @param    array        Record from $table
 849       * @param    boolean        If $useFieldNameAsKey is set, then the fieldname is associative keys in the return array, otherwise just numeric keys.
 850       * @return    array
 851       */
 852  	function getTCAtypes($table,$rec,$useFieldNameAsKey=0)    {
 853          global $TCA;
 854  
 855          t3lib_div::loadTCA($table);
 856          if ($TCA[$table])    {
 857  
 858                  // Get type value:
 859              $fieldValue = t3lib_BEfunc::getTCAtypeValue($table,$rec);
 860  
 861                  // Get typesConf
 862              $typesConf = $TCA[$table]['types'][$fieldValue];
 863  
 864                  // Get fields list and traverse it
 865              $fieldList = explode(',', $typesConf['showitem']);
 866              $altFieldList = array();
 867  
 868                  // Traverse fields in types config and parse the configuration into a nice array:
 869              foreach($fieldList as $k => $v)    {
 870                  list($pFieldName, $pAltTitle, $pPalette, $pSpec) = t3lib_div::trimExplode(';', $v);
 871                  $defaultExtras = is_array($TCA[$table]['columns'][$pFieldName]) ? $TCA[$table]['columns'][$pFieldName]['defaultExtras'] : '';
 872                  $specConfParts = t3lib_BEfunc::getSpecConfParts($pSpec, $defaultExtras);
 873  
 874                  $fieldList[$k]=array(
 875                      'field' => $pFieldName,
 876                      'title' => $pAltTitle,
 877                      'palette' => $pPalette,
 878                      'spec' => $specConfParts,
 879                      'origString' => $v
 880                  );
 881                  if ($useFieldNameAsKey)    {
 882                      $altFieldList[$fieldList[$k]['field']] = $fieldList[$k];
 883                  }
 884              }
 885              if ($useFieldNameAsKey)    {
 886                  $fieldList = $altFieldList;
 887              }
 888  
 889                  // Return array:
 890              return $fieldList;
 891          }
 892      }
 893  
 894      /**
 895       * Returns the "type" value of $rec from $table which can be used to look up the correct "types" rendering section in $TCA
 896       * If no "type" field is configured in the "ctrl"-section of the $TCA for the table, zero is used.
 897       * If zero is not an index in the "types" section of $TCA for the table, then the $fieldValue returned will default to 1 (no matter if that is an index or not)
 898       * Usage: 7
 899       *
 900       * @param    string        Table name present in TCA
 901       * @param    array        Record from $table
 902       * @return    string        Field value
 903       * @see getTCAtypes()
 904       */
 905  	function getTCAtypeValue($table,$rec)    {
 906          global $TCA;
 907  
 908              // If no field-value, set it to zero. If there is no type matching the field-value (which now may be zero...) test field-value '1' as default.
 909          t3lib_div::loadTCA($table);
 910          if ($TCA[$table])    {
 911              $field = $TCA[$table]['ctrl']['type'];
 912              $fieldValue = $field ? ($rec[$field] ? $rec[$field] : 0) : 0;
 913              if (!is_array($TCA[$table]['types'][$fieldValue]))    $fieldValue = 1;
 914              return $fieldValue;
 915          }
 916      }
 917  
 918      /**
 919       * Parses a part of the field lists in the "types"-section of $TCA arrays, namely the "special configuration" at index 3 (position 4)
 920       * Elements are splitted by ":" and within those parts, parameters are splitted by "|".
 921       * Everything is returned in an array and you should rather see it visually than listen to me anymore now...  Check out example in Inside TYPO3
 922       * Usage: 5
 923       *
 924       * @param    string        Content from the "types" configuration of TCA (the special configuration) - see description of function
 925       * @param    string        The ['defaultExtras'] value from field configuration
 926       * @return    array
 927       */
 928  	function getSpecConfParts($str, $defaultExtras)    {
 929  
 930              // Add defaultExtras:
 931          $specConfParts = t3lib_div::trimExplode(':', $defaultExtras.':'.$str, 1);
 932  
 933          $reg = array();
 934          if (count($specConfParts))    {
 935              foreach($specConfParts as $k2 => $v2)    {
 936                  unset($specConfParts[$k2]);
 937                  if (ereg('(.*)\[(.*)\]',$v2,$reg))    {
 938                      $specConfParts[trim($reg[1])] = array(
 939                          'parameters' => t3lib_div::trimExplode('|', $reg[2], 1)
 940                      );
 941                  } else {
 942                      $specConfParts[trim($v2)] = 1;
 943                  }
 944              }
 945          } else {
 946              $specConfParts = array();
 947          }
 948          return $specConfParts;
 949      }
 950  
 951      /**
 952       * Takes an array of "[key]=[value]" strings and returns an array with the keys set as keys pointing to the value.
 953       * Better see it in action! Find example in Inside TYPO3
 954       * Usage: 6
 955       *
 956       * @param    array        Array of "[key]=[value]" strings to convert.
 957       * @return    array
 958       */
 959  	function getSpecConfParametersFromArray($pArr)    {
 960          $out=array();
 961          if (is_array($pArr))    {
 962              reset($pArr);
 963              while(list($k,$v)=each($pArr))    {
 964                  $parts=explode('=',$v,2);
 965                  if (count($parts)==2)    {
 966                      $out[trim($parts[0])]=trim($parts[1]);
 967                  } else {
 968                      $out[$k]=$v;
 969                  }
 970              }
 971          }
 972          return $out;
 973      }
 974  
 975      /**
 976       * Finds the Data Structure for a FlexForm field
 977       * NOTE ON data structures for deleted records: This function may fail to deliver the data structure for a record for a few reasons: a) The data structure could be deleted (either with deleted-flagged or hard-deleted), b) the data structure is fetched using the ds_pointerField_searchParent in which case any deleted record on the route to the final location of the DS will make it fail. In theory, we can solve the problem in the case where records that are deleted-flagged keeps us from finding the DS - this is done at the markers ###NOTE_A### where we make sure to also select deleted records. However, we generally want the DS lookup to fail for deleted records since for the working website we expect a deleted-flagged record to be as inaccessible as one that is completely deleted from the DB. Any way we look at it, this may lead to integrity problems of the reference index and even lost files if attached. However, that is not really important considering that a single change to a data structure can instantly invalidate large amounts of the reference index which we do accept as a cost for the flexform features. Other than requiring a reference index update, deletion of/changes in data structure or the failure to look them up when completely deleting records may lead to lost files in the uploads/ folders since those are now without a proper reference.
 978       * Usage: 5
 979       *
 980       * @param    array        Field config array
 981       * @param    array        Record data
 982       * @param    string        The table name
 983       * @param    string        Optional fieldname passed to hook object
 984       * @param    boolean        Boolean; If set, workspace overlay is applied to records. This is correct behaviour for all presentation and export, but NOT if you want a true reflection of how things are in the live workspace.
 985       * @param    integer        SPECIAL CASES: Use this, if the DataStructure may come from a parent record and the INPUT row doesn't have a uid yet (hence, the pid cannot be looked up). Then it is necessary to supply a PID value to search recursively in for the DS (used from TCEmain)
 986       * @return    mixed        If array, the data structure was found and returned as an array. Otherwise (string) it is an error message.
 987       * @see t3lib_TCEforms::getSingleField_typeFlex()
 988       */
 989  	function getFlexFormDS($conf,$row,$table,$fieldName='',$WSOL=TRUE,$newRecordPidValue=0)    {
 990          global $TYPO3_CONF_VARS;
 991  
 992              // Get pointer field etc from TCA-config:
 993          $ds_pointerField =     $conf['ds_pointerField'];
 994          $ds_array =         $conf['ds'];
 995          $ds_tableField =     $conf['ds_tableField'];
 996          $ds_searchParentField =     $conf['ds_pointerField_searchParent'];
 997  
 998              // Find source value:
 999          $dataStructArray='';
1000          if (is_array($ds_array))    {    // If there is a data source array, that takes precedence
1001                  // If a pointer field is set, take the value from that field in the $row array and use as key.
1002              if ($ds_pointerField)    {
1003                  $srcPointer = $row[$ds_pointerField];
1004                  $srcPointer = isset($ds_array[$srcPointer]) ? $srcPointer : 'default';
1005              } else $srcPointer='default';
1006  
1007                  // Get Data Source: Detect if it's a file reference and in that case read the file and parse as XML. Otherwise the value is expected to be XML.
1008              if (substr($ds_array[$srcPointer],0,5)=='FILE:')    {
1009                  $file = t3lib_div::getFileAbsFileName(substr($ds_array[$srcPointer],5));
1010                  if ($file && @is_file($file))    {
1011                      $dataStructArray = t3lib_div::xml2array(t3lib_div::getUrl($file));
1012                  } else $dataStructArray = 'The file "'.substr($ds_array[$srcPointer],5).'" in ds-array key "'.$srcPointer.'" was not found ("'.$file.'")';    // Error message.
1013              } else {
1014                  $dataStructArray = t3lib_div::xml2array($ds_array[$srcPointer]);
1015              }
1016  
1017          } elseif ($ds_pointerField) {    // If pointer field AND possibly a table/field is set:
1018                  // Value of field pointed to:
1019              $srcPointer = $row[$ds_pointerField];
1020  
1021                  // Searching recursively back if 'ds_pointerField_searchParent' is defined (typ. a page rootline, or maybe a tree-table):
1022              if ($ds_searchParentField && !$srcPointer)    {
1023                  $rr = t3lib_BEfunc::getRecord($table,$row['uid'],'uid,'.$ds_searchParentField);    // Get the "pid" field - we cannot know that it is in the input record! ###NOTE_A###
1024                  if ($WSOL)    {
1025                      t3lib_BEfunc::workspaceOL($table,$rr);
1026                      t3lib_BEfunc::fixVersioningPid($table,$rr,TRUE);    // Added "TRUE" 23/03/06 before 4.0. (Also to similar call below!).  Reason: When t3lib_refindex is scanning the system in Live workspace all Pages with FlexForms will not find their inherited datastructure. Thus all references from workspaces are removed! Setting TRUE means that versioning PID doesn't check workspace of the record. I can't see that this should give problems anywhere. See more information inside t3lib_refindex!
1027                  }
1028                  $uidAcc=array();    // Used to avoid looping, if any should happen.
1029                  $subFieldPointer = $conf['ds_pointerField_searchParent_subField'];
1030                  while(!$srcPointer)        {
1031  
1032                      $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1033                                      'uid,'.$ds_pointerField.','.$ds_searchParentField.($subFieldPointer?','.$subFieldPointer:''),
1034                                      $table,
1035                                      'uid='.intval($newRecordPidValue ? $newRecordPidValue : $rr[$ds_searchParentField]).t3lib_BEfunc::deleteClause($table)    ###NOTE_A###
1036                                  );
1037                      $newRecordPidValue = 0;
1038                      $rr = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
1039  
1040                          // break if no result from SQL db or if looping...
1041                      if (!is_array($rr) || isset($uidAcc[$rr['uid']]))    break;
1042                      $uidAcc[$rr['uid']]=1;
1043  
1044                      if ($WSOL)    {
1045                          t3lib_BEfunc::workspaceOL($table,$rr);
1046                          t3lib_BEfunc::fixVersioningPid($table,$rr,TRUE);
1047                      }
1048                      $srcPointer = ($subFieldPointer && $rr[$subFieldPointer]) ? $rr[$subFieldPointer] : $rr[$ds_pointerField];
1049                  }
1050              }
1051  
1052                  // If there is a srcPointer value:
1053              if ($srcPointer)    {
1054                  if (t3lib_div::testInt($srcPointer))    {    // If integer, then its a record we will look up:
1055                      list($tName,$fName) = explode(':',$ds_tableField,2);
1056                      if ($tName && $fName && is_array($GLOBALS['TCA'][$tName]))    {
1057                          $dataStructRec = t3lib_BEfunc::getRecord($tName, $srcPointer);
1058                          if ($WSOL)    {
1059                              t3lib_BEfunc::workspaceOL($tName,$dataStructRec);
1060                          }
1061                          $dataStructArray = t3lib_div::xml2array($dataStructRec[$fName]);
1062                      } else $dataStructArray = 'No tablename ('.$tName.') or fieldname ('.$fName.') was found an valid!';
1063                  } else {    // Otherwise expect it to be a file:
1064                      $file = t3lib_div::getFileAbsFileName($srcPointer);
1065                      if ($file && @is_file($file))    {
1066                          $dataStructArray = t3lib_div::xml2array(t3lib_div::getUrl($file));
1067                      } else $dataStructArray='The file "'.$srcPointer.'" was not found ("'.$file.'")';    // Error message.
1068                  }
1069              } else $dataStructArray='No source value in fieldname "'.$ds_pointerField.'"';    // Error message.
1070          } else $dataStructArray='No proper configuration!';
1071  
1072              // Hook for post-processing the Flexform DS. Introduces the possibility to configure Flexforms via TSConfig
1073          if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['getFlexFormDSClass'])) {
1074              foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['getFlexFormDSClass'] as $classRef) {
1075                  $hookObj = &t3lib_div::getUserObj($classRef);
1076                  if (method_exists($hookObj, 'getFlexFormDS_postProcessDS')) {
1077                      $hookObj->getFlexFormDS_postProcessDS($dataStructArray, $conf, $row, $table, $fieldName);
1078                  }
1079              }
1080          }
1081  
1082          return $dataStructArray;
1083      }
1084  
1085  
1086  
1087  
1088  
1089  
1090  
1091  
1092  
1093  
1094  
1095  
1096  
1097  
1098  
1099  
1100  
1101  
1102      /*******************************************
1103       *
1104       * Caching related
1105       *
1106       *******************************************/
1107  
1108      /**
1109       * Stores the string value $data in the 'cache_hash' table with the hash key, $hash, and visual/symbolic identification, $ident
1110       * IDENTICAL to the function by same name found in t3lib_page:
1111       * Usage: 2
1112       *
1113       * @param    string        32 bit hash string (eg. a md5 hash of a serialized array identifying the data being stored)
1114       * @param    string        The data string. If you want to store an array, then just serialize it first.
1115       * @param    string        $ident is just a textual identification in order to inform about the content! May be 20 characters long.
1116       * @return    void
1117       */
1118  	function storeHash($hash,$data,$ident)    {
1119          $insertFields = array(
1120              'hash' => $hash,
1121              'content' => $data,
1122              'ident' => $ident,
1123              'tstamp' => time()
1124          );
1125          $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash'));
1126          $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_hash', $insertFields);
1127      }
1128  
1129      /**
1130       * Retrieves the string content stored with hash key, $hash, in cache_hash
1131       * IDENTICAL to the function by same name found in t3lib_page:
1132       * Usage: 2
1133       *
1134       * @param    string        Hash key, 32 bytes hex
1135       * @param    integer        $expTime represents the expire time in seconds. For instance a value of 3600 would allow cached content within the last hour, otherwise nothing is returned.
1136       * @return    string
1137       */
1138  	function getHash($hash,$expTime=0)    {
1139              // if expTime is not set, the hash will never expire
1140          $expTime = intval($expTime);
1141          if ($expTime)    {
1142              $whereAdd = ' AND tstamp > '.(time()-$expTime);
1143          }
1144          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash').$whereAdd);
1145          if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
1146              return $row['content'];
1147          }
1148      }
1149  
1150  
1151  
1152  
1153  
1154  
1155  
1156  
1157      /*******************************************
1158       *
1159       * TypoScript related
1160       *
1161       *******************************************/
1162  
1163      /**
1164       * Returns the Page TSconfig for page with id, $id
1165       * Requires class "t3lib_TSparser"
1166       * Usage: 26 (spec. in ext info_pagetsconfig)
1167       *
1168       * @param    integer        Page uid for which to create Page TSconfig
1169       * @param    array        If $rootLine is an array, that is used as rootline, otherwise rootline is just calculated
1170       * @param    boolean        If $returnPartArray is set, then the array with accumulated Page TSconfig is returned non-parsed. Otherwise the output will be parsed by the TypoScript parser.
1171       * @return    array        Page TSconfig
1172       * @see t3lib_TSparser
1173       */
1174  	function getPagesTSconfig($id,$rootLine='',$returnPartArray=0)    {
1175          $id=intval($id);
1176          if (!is_array($rootLine))    {
1177              $rootLine = t3lib_BEfunc::BEgetRootLine($id,'',TRUE);
1178          }
1179          ksort($rootLine);    // Order correctly
1180          $TSdataArray = array();
1181          $TSdataArray['defaultPageTSconfig']=$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'];    // Setting default configuration:
1182          foreach($rootLine as $k => $v)    {
1183              $TSdataArray['uid_'.$v['uid']]=$v['TSconfig'];
1184          }
1185          $TSdataArray = t3lib_TSparser::checkIncludeLines_array($TSdataArray);
1186          if ($returnPartArray)    {
1187              return $TSdataArray;
1188          }
1189  
1190              // Parsing the user TS (or getting from cache)
1191          $userTS = implode($TSdataArray,chr(10).'[GLOBAL]'.chr(10));
1192          $hash = md5('pageTS:'.$userTS);
1193          $cachedContent = t3lib_BEfunc::getHash($hash,0);
1194          $TSconfig = array();
1195          if (isset($cachedContent))    {
1196              $TSconfig = unserialize($cachedContent);
1197          } else {
1198              $parseObj = t3lib_div::makeInstance('t3lib_TSparser');
1199              $parseObj->parse($userTS);
1200              $TSconfig = $parseObj->setup;
1201              t3lib_BEfunc::storeHash($hash,serialize($TSconfig),'PAGES_TSconfig');
1202          }
1203  
1204              // get User TSconfig overlay
1205          $userTSconfig = $GLOBALS['BE_USER']->userTS['page.'];
1206          if (is_array($userTSconfig))    {
1207              $TSconfig = t3lib_div::array_merge_recursive_overrule($TSconfig, $userTSconfig);
1208          }
1209          return $TSconfig;
1210      }
1211  
1212      /**
1213       * Updates Page TSconfig for a page with $id
1214       * The function seems to take $pageTS as an array with properties and compare the values with those that already exists for the "object string", $TSconfPrefix, for the page, then sets those values which were not present.
1215       * $impParams can be supplied as already known Page TSconfig, otherwise it's calculated.
1216       *
1217       * THIS DOES NOT CHECK ANY PERMISSIONS. SHOULD IT?
1218       * More documentation is needed.
1219       *
1220       * Usage: 1 (ext. direct_mail)
1221       *
1222       * @param    integer        Page id
1223       * @param    array        Page TS array to write
1224       * @param    string        Prefix for object paths
1225       * @param    array        [Description needed.]
1226       * @return    void
1227       * @internal
1228       * @see implodeTSParams(), getPagesTSconfig()
1229       */
1230  	function updatePagesTSconfig($id,$pageTS,$TSconfPrefix,$impParams='')    {
1231          $id=intval($id);
1232          if (is_array($pageTS) && $id>0)    {
1233              if (!is_array($impParams))    {
1234                  $impParams =t3lib_BEfunc::implodeTSParams(t3lib_BEfunc::getPagesTSconfig($id));
1235              }
1236              reset($pageTS);
1237              $set=array();
1238              while(list($f,$v)=each($pageTS))    {
1239                  $f = $TSconfPrefix.$f;
1240                  if ((!isset($impParams[$f])&&trim($v)) || strcmp(trim($impParams[$f]),trim($v)))    {
1241                      $set[$f]=trim($v);
1242                  }
1243              }
1244              if (count($set))    {
1245                      // Get page record and TS config lines
1246                  $pRec = t3lib_befunc::getRecord('pages',$id);
1247                  $TSlines = explode(chr(10),$pRec['TSconfig']);
1248                  $TSlines = array_reverse($TSlines);
1249                      // Reset the set of changes.
1250                  reset($set);
1251                  while(list($f,$v)=each($set))    {
1252                      reset($TSlines);
1253                      $inserted=0;
1254                      while(list($ki,$kv)=each($TSlines))    {
1255                          if (substr($kv,0,strlen($f)+1)==$f.'=')    {
1256                              $TSlines[$ki]=$f.'='.$v;
1257                              $inserted=1;
1258                              break;
1259                          }
1260                      }
1261                      if (!$inserted)    {
1262                          $TSlines = array_reverse($TSlines);
1263                          $TSlines[]=$f.'='.$v;
1264                          $TSlines = array_reverse($TSlines);
1265                      }
1266                  }
1267                  $TSlines = array_reverse($TSlines);
1268  
1269                      // store those changes
1270                  $TSconf = implode(chr(10),$TSlines);
1271  
1272                  $GLOBALS['TYPO3_DB']->exec_UPDATEquery('pages', 'uid='.intval($id), array('TSconfig' => $TSconf));
1273              }
1274          }
1275      }
1276  
1277      /**
1278       * Implodes a multi dimensional TypoScript array, $p, into a one-dimentional array (return value)
1279       * Usage: 3
1280       *
1281       * @param    array        TypoScript structure
1282       * @param    string        Prefix string
1283       * @return    array        Imploded TypoScript objectstring/values
1284       */
1285  	function implodeTSParams($p,$k='')    {
1286          $implodeParams=array();
1287          if (is_array($p))    {
1288              reset($p);
1289              while(list($kb,$val)=each($p))    {
1290                  if (is_array($val))    {
1291                      $implodeParams = array_merge($implodeParams,t3lib_BEfunc::implodeTSParams($val,$k.$kb));
1292                  } else {
1293                      $implodeParams[$k.$kb]=$val;
1294                  }
1295              }
1296          }
1297          return $implodeParams;
1298      }
1299  
1300  
1301  
1302  
1303  
1304  
1305  
1306  
1307      /*******************************************
1308       *
1309       * Users / Groups related
1310       *
1311       *******************************************/
1312  
1313      /**
1314       * Returns an array with be_users records of all user NOT DELETED sorted by their username
1315       * Keys in the array is the be_users uid
1316       * Usage: 14 (spec. ext. "beuser" and module "web_perm")
1317       *
1318       * @param    string        Optional $fields list (default: username,usergroup,usergroup_cached_list,uid) can be used to set the selected fields
1319       * @param    string        Optional $where clause (fx. "AND username='pete'") can be used to limit query
1320       * @return    array
1321       */
1322  	function getUserNames($fields='username,usergroup,usergroup_cached_list,uid',$where='')    {
1323          $be_user_Array=Array();
1324  
1325          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, 'be_users', 'pid=0 '.$where.t3lib_BEfunc::deleteClause('be_users'), '', 'username');
1326          while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
1327              $be_user_Array[$row['uid']]=$row;
1328          }
1329          return $be_user_Array;
1330      }
1331  
1332      /**
1333       * Returns an array with be_groups records (title, uid) of all groups NOT DELETED sorted by their title
1334       * Usage: 8 (spec. ext. "beuser" and module "web_perm")
1335       *
1336       * @param    string        Field list
1337       * @param    string        WHERE clause
1338       * @return    array
1339       */
1340  	function getGroupNames($fields='title,uid', $where='')    {
1341          $be_group_Array = Array();
1342          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, 'be_groups', 'pid=0 '.$where.t3lib_BEfunc::deleteClause('be_groups'), '', 'title');
1343          while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
1344              $be_group_Array[$row['uid']] = $row;
1345          }
1346          return $be_group_Array;
1347      }
1348  
1349      /**
1350       * Returns an array with be_groups records (like ->getGroupNames) but:
1351       * - if the current BE_USER is admin, then all groups are returned, otherwise only groups that the current user is member of (usergroup_cached_list) will be returned.
1352       * Usage: 2 (module "web_perm" and ext. taskcenter)
1353       *
1354       * @param    string        Field list; $fields specify the fields selected (default: title,uid)
1355       * @return    array
1356       */
1357  	function getListGroupNames($fields='title,uid')    {
1358          $exQ=' AND hide_in_lists=0';
1359          if (!$GLOBALS['BE_USER']->isAdmin())    {
1360              $exQ.=' AND uid IN ('.($GLOBALS['BE_USER']->user['usergroup_cached_list']?$GLOBALS['BE_USER']->user['usergroup_cached_list']:0).')';
1361          }
1362          return t3lib_BEfunc::getGroupNames($fields,$exQ);
1363      }
1364  
1365      /**
1366       * Returns the array $usernames with the names of all users NOT IN $groupArray changed to the uid (hides the usernames!).
1367       * If $excludeBlindedFlag is set, then these records are unset from the array $usernames
1368       * Takes $usernames (array made by t3lib_BEfunc::getUserNames()) and a $groupArray (array with the groups a certain user is member of) as input
1369       * Usage: 8
1370       *
1371       * @param    array        User names
1372       * @param    array        Group names
1373       * @param    boolean        If $excludeBlindedFlag is set, then these records are unset from the array $usernames
1374       * @return    array        User names, blinded
1375       */
1376  	function blindUserNames($usernames,$groupArray,$excludeBlindedFlag=0)    {
1377          if (is_array($usernames) && is_array($groupArray))    {
1378              while(list($uid,$row)=each($usernames))    {
1379                  $userN=$uid;
1380                  $set=0;
1381                  if ($row['uid']!=$GLOBALS['BE_USER']->user['uid'])    {
1382                      reset($groupArray);
1383                      while(list(,$v)=each($groupArray))    {
1384                          if ($v && t3lib_div::inList($row['usergroup_cached_list'],$v))    {
1385                              $userN = $row['username'];
1386                              $set=1;
1387                          }
1388                      }
1389                  } else {
1390                      $userN = $row['username'];
1391                      $set=1;
1392                  }
1393                  $usernames[$uid]['username']=$userN;
1394                  if ($excludeBlindedFlag && !$set) {unset($usernames[$uid]);}
1395              }
1396          }
1397          return $usernames;
1398      }
1399  
1400      /**
1401       * Corresponds to blindUserNames but works for groups instead
1402       * Usage: 2 (module web_perm)
1403       *
1404       * @param    array        Group names
1405       * @param    array        Group names (reference)
1406       * @param    boolean        If $excludeBlindedFlag is set, then these records are unset from the array $usernames
1407       * @return    array
1408       */
1409  	function blindGroupNames($groups,$groupArray,$excludeBlindedFlag=0)    {
1410          if (is_array($groups) && is_array($groupArray))    {
1411              while(list($uid,$row)=each($groups))    {
1412                  $groupN=$uid;
1413                  $set=0;
1414                  if (t3lib_div::inArray($groupArray,$uid))    {
1415                      $groupN=$row['title'];
1416                      $set=1;
1417                  }
1418                  $groups[$uid]['title']=$groupN;
1419                  if ($excludeBlindedFlag && !$set) {unset($groups[$uid]);}
1420              }
1421          }
1422          return $groups;
1423      }
1424  
1425  
1426  
1427  
1428  
1429  
1430  
1431  
1432  
1433  
1434  
1435  
1436  
1437      /*******************************************
1438       *
1439       * Output related
1440       *
1441       *******************************************/
1442  
1443      /**
1444       * Returns the difference in days between input $tstamp and $EXEC_TIME
1445       * Usage: 2 (class t3lib_BEfunc)
1446       *
1447       * @param    integer        Time stamp, seconds
1448       * @return    integer
1449       */
1450  	function daysUntil($tstamp)    {
1451          $delta_t = $tstamp-$GLOBALS['EXEC_TIME'];
1452          return ceil($delta_t/(3600*24));
1453      }
1454  
1455      /**
1456       * Returns $tstamp formatted as "ddmmyy" (According to $TYPO3_CONF_VARS['SYS']['ddmmyy'])
1457       * Usage: 11
1458       *
1459       * @param    integer        Time stamp, seconds
1460       * @return    string        Formatted time
1461       */
1462  	function date($tstamp)    {
1463          return date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],$tstamp);
1464      }
1465  
1466      /**
1467       * Returns $tstamp formatted as "ddmmyy hhmm" (According to $TYPO3_CONF_VARS['SYS']['ddmmyy'] AND $TYPO3_CONF_VARS['SYS']['hhmm'])
1468       * Usage: 28
1469       *
1470       * @param    integer        Time stamp, seconds
1471       * @return    string        Formatted time
1472       */
1473  	function datetime($value)    {
1474          return date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'].' '.$GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'], $value);
1475      }
1476  
1477      /**
1478       * Returns $value (in seconds) formatted as hh:mm:ss
1479       * For instance $value = 3600 + 60*2 + 3 should return "01:02:03"
1480       * Usage: 1 (class t3lib_BEfunc)
1481       *
1482       * @param    integer        Time stamp, seconds
1483       * @return    string        Formatted time
1484       */
1485  	function time($value)    {
1486          $hh = floor($value/3600);
1487          $min = floor(($value-$hh*3600)/60);
1488          $sec = $value-$hh*3600-$min*60;
1489          $l = sprintf('%02d',$hh).':'.sprintf('%02d',$min).':'.sprintf('%02d',$sec);
1490          return $l;
1491      }
1492  
1493      /**
1494       * Returns the "age" in minutes / hours / days / years of the number of $seconds inputted.
1495       * Usage: 15
1496       *
1497       * @param    integer        $seconds could be the difference of a certain timestamp and time()
1498       * @param    string        $labels should be something like ' min| hrs| days| yrs'. This value is typically delivered by this function call: $GLOBALS["LANG"]->sL("LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears")
1499       * @return    string        Formatted time
1500       */
1501  	function calcAge($seconds,$labels = 'min|hrs|days|yrs')    {
1502          $labelArr = explode('|',$labels);
1503          $prefix='';
1504          if ($seconds<0)    {$prefix='-'; $seconds=abs($seconds);}
1505          if ($seconds<3600)    {
1506              $seconds = round ($seconds/60).' '.trim($labelArr[0]);
1507          } elseif ($seconds<24*3600)    {
1508              $seconds = round ($seconds/3600).' '.trim($labelArr[1]);
1509          } elseif ($seconds<365*24*3600)    {
1510              $seconds = round ($seconds/(24*3600)).' '.trim($labelArr[2]);
1511          } else {
1512              $seconds = round ($seconds/(365*24*3600)).' '.trim($labelArr[3]);
1513          }
1514          return $prefix.$seconds;
1515      }
1516  
1517      /**
1518       * Returns a formatted timestamp if $tstamp is set.
1519       * The date/datetime will be followed by the age in parenthesis.
1520       * Usage: 3
1521       *
1522       * @param    integer        Time stamp, seconds
1523       * @param    integer        1/-1 depending on polarity of age.
1524       * @param    string        $date=="date" will yield "dd:mm:yy" formatting, otherwise "dd:mm:yy hh:mm"
1525       * @return    string
1526       */
1527  	function dateTimeAge($tstamp,$prefix=1,$date='')    {
1528          return $tstamp ?
1529                  ($date=='date' ? t3lib_BEfunc::date($tstamp) : t3lib_BEfunc::datetime($tstamp)).
1530                  ' ('.t3lib_BEfunc::calcAge($prefix*(time()-$tstamp),$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')).')' : '';
1531      }
1532  
1533      /**
1534       * Returns either title='' or alt='' attribute. This depends on the client browser and whether it supports title='' or not (which is the default)
1535       * If no $content is given only the attribute name is returned.
1536       * The returned attribute with content will have a leading space char.
1537       * Warning: Be careful to submit empty $content var - that will return just the attribute name!
1538       * Usage: 0
1539       *
1540       * @param    string        String to set as title-attribute. If no $content is given only the attribute name is returned.
1541       * @param    boolean        If $hsc is set, then content of the attribute is htmlspecialchar()'ed (which is good for XHTML and other reasons...)
1542       * @return    string
1543       * @deprecated        The idea made sense with older browsers, but now all browsers should support the "title" attribute - so just hardcode the title attribute instead!
1544       */
1545  	function titleAttrib($content='',$hsc=0)    {
1546          global $CLIENT;
1547          $attrib= ($CLIENT['BROWSER']=='net'&&$CLIENT['VERSION']<5)||$CLIENT['BROWSER']=='konqu' ? 'alt' : 'title';
1548          return strcmp($content,'')?' '.$attrib.'="'.($hsc?htmlspecialchars($content):$content).'"' : $attrib;
1549      }
1550  
1551      /**
1552       * Returns alt="" and title="" attributes with the value of $content.
1553       * Usage: 7
1554       *
1555       * @param    string        Value for 'alt' and 'title' attributes (will be htmlspecialchars()'ed before output)
1556       * @return    string
1557       */
1558  	function titleAltAttrib($content)    {
1559          $out='';
1560          $out.=' alt="'.htmlspecialchars($content).'"';
1561          $out.=' title="'.htmlspecialchars($content).'"';
1562          return $out;
1563      }
1564  
1565      /**
1566       * Returns a linked image-tag for thumbnail(s)/fileicons/truetype-font-previews from a database row with a list of image files in a field
1567       * All $TYPO3_CONF_VARS['GFX']['imagefile_ext'] extension are made to thumbnails + ttf file (renders font-example)
1568       * Thumbsnails are linked to the show_item.php script which will display further details.
1569       * Usage: 7
1570       *
1571       * @param    array        $row is the database row from the table, $table.
1572       * @param    string        Table name for $row (present in TCA)
1573       * @param    string        $field is pointing to the field with the list of image files
1574       * @param    string        Back path prefix for image tag src="" field
1575       * @param    string        Optional: $thumbScript os by default 'thumbs.php' if you don't set it otherwise
1576       * @param    string        Optional: $uploaddir is the directory relative to PATH_site where the image files from the $field value is found (Is by default set to the entry in $TCA for that field! so you don't have to!)
1577       * @param    boolean        If set, uploaddir is NOT prepended with "../"
1578       * @param    string        Optional: $tparams is additional attributes for the image tags
1579       * @param    integer        Optional: $size is [w]x[h] of the thumbnail. 56 is default.
1580       * @return    string        Thumbnail image tag.
1581       */
1582  	function thumbCode($row,$table,$field,$backPath,$thumbScript='',$uploaddir=NULL,$abs=0,$tparams='',$size='')    {
1583          global $TCA;
1584              // Load table.
1585          t3lib_div::loadTCA($table);
1586  
1587              // Find uploaddir automatically
1588          $uploaddir = (is_null($uploaddir)) ? $TCA[$table]['columns'][$field]['config']['uploadfolder'] : $uploaddir;
1589          $uploaddir = preg_replace('#/$#','',$uploaddir);
1590  
1591              // Set thumbs-script:
1592          if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'])    {
1593              $thumbScript='gfx/notfound_thumb.gif';
1594          } elseif(!$thumbScript)    {
1595              $thumbScript='thumbs.php';
1596          }
1597              // Check and parse the size parameter
1598          $sizeParts=array();
1599          if ($size = trim($size)) {
1600              $sizeParts = explode('x', $size.'x'.$size);
1601              if(!intval($sizeParts[0])) $size='';
1602          }
1603  
1604              // Traverse files:
1605          $thumbs = explode(',', $row[$field]);
1606          $thumbData='';
1607          while(list(,$theFile)=each($thumbs))    {
1608              if (trim($theFile))    {
1609                  $fI = t3lib_div::split_fileref($theFile);
1610                  $ext = $fI['fileext'];
1611                          // New 190201 start
1612                  $max=0;
1613                  if (t3lib_div::inList('gif,jpg,png',$ext)) {
1614                      $imgInfo=@getimagesize(PATH_site.$uploaddir.'/'.$theFile);
1615                      if (is_array($imgInfo))    {$max = max($imgInfo[0],$imgInfo[1]);}
1616                  }
1617                      // use the original image if it's size fits to the thumbnail size
1618                  if ($max && $max<=(count($sizeParts)&&max($sizeParts)?max($sizeParts):56))    {
1619                      $theFile = $url = ($abs?'':'../').($uploaddir?$uploaddir.'/':'').trim($theFile);
1620                      $onClick = 'top.launchView(\''.$theFile.'\',\'\',\''.$backPath.'\');return false;';
1621                      $thumbData.= '<a href="#" onclick="'.htmlspecialchars($onClick).'"><img src="'.$backPath.$url.'" '.$imgInfo[3].' hspace="2" border="0" title="'.trim($url).'"'.$tparams.' alt="" /></a> ';
1622                          // New 190201 stop
1623                  } elseif ($ext=='ttf' || t3lib_div::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],$ext)) {
1624                      $theFile_abs = PATH_site.($uploaddir?$uploaddir.'/':'').trim($theFile);
1625                      $theFile = ($abs?'':'../').($uploaddir?$uploaddir.'/':'').trim($theFile);
1626  
1627                      $check = basename($theFile_abs).':'.filemtime($theFile_abs).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
1628                      $params = '&file='.rawurlencode($theFile);
1629                      $params.= $size?'&size='.$size:'';
1630                      $params.= '&md5sum='.t3lib_div::shortMD5($check);
1631  
1632                      $url = $thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
1633                      $onClick = 'top.launchView(\''.$theFile.'\',\'\',\''.$backPath.'\');return false;';
1634                      $thumbData.= '<a href="#" onclick="'.htmlspecialchars($onClick).'"><img src="'.htmlspecialchars($backPath.$url).'" hspace="2" border="0" title="'.trim($theFile).'"'.$tparams.' alt="" /></a> ';
1635                  } else {
1636                      $icon = t3lib_BEfunc::getFileIcon($ext);
1637                      $url = 'gfx/fileicons/'.$icon;
1638                      $thumbData.= '<img src="'.$backPath.$url.'" hspace="2" border="0" title="'.trim($theFile).'"'.$tparams.' alt="" /> ';
1639                  }
1640              }
1641          }
1642          return $thumbData;
1643      }
1644  
1645      /**
1646       * Returns single image tag to thumbnail using a thumbnail script (like thumbs.php)
1647       * Usage: 3
1648       *
1649       * @param    string        $thumbScript must point to "thumbs.php" relative to the script position
1650       * @param    string        $theFile must be the proper reference to the file thumbs.php should show
1651       * @param    string        $tparams are additional attributes for the image tag
1652       * @param    integer        $size is the size of the thumbnail send along to "thumbs.php"
1653       * @return    string        Image tag
1654       */
1655  	function getThumbNail($thumbScript,$theFile,$tparams='',$size='')    {
1656          $check = basename($theFile).':'.filemtime($theFile).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
1657          $params = '&file='.rawurlencode($theFile);
1658          $params.= trim($size)?'&size='.trim($size):'';
1659          $params.= '&md5sum='.t3lib_div::shortMD5($check);
1660  
1661          $url = $thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
1662          $th='<img src="'.htmlspecialchars($url).'" title="'.trim(basename($theFile)).'"'.($tparams?" ".$tparams:"").' alt="" />';
1663          return $th;
1664      }
1665  
1666      /**
1667       * Returns title-attribute information for a page-record informing about id, alias, doktype, hidden, starttime, endtime, fe_group etc.
1668       * Usage: 8
1669       *
1670       * @param    array        Input must be a page row ($row) with the proper fields set (be sure - send the full range of fields for the table)
1671       * @param    string        $perms_clause is used to get the record path of the shortcut page, if any (and doktype==4)
1672       * @param    boolean        If $includeAttrib is set, then the 'title=""' attribute is wrapped about the return value, which is in any case htmlspecialchar()'ed already
1673       * @return    string
1674       */
1675  	function titleAttribForPages($row,$perms_clause='',$includeAttrib=1)    {
1676          global $TCA,$LANG;
1677          $parts=array();
1678          $parts[] = 'id='.$row['uid'];
1679          if ($row['alias'])    $parts[]=$LANG->sL($TCA['pages']['columns']['alias']['label']).' '.$row['alias'];
1680          if ($row['pid']<0)    $parts[] = 'v#1.'.$row['t3ver_id'];
1681          if ($row['t3ver_state']==1)    $parts[] = 'PLH WSID#'.$row['t3ver_wsid'];
1682          if ($row['t3ver_state']==-1)    $parts[] = 'New element!';
1683  
1684          if ($row['doktype']=='3')    {
1685              $parts[]=$LANG->sL($TCA['pages']['columns']['url']['label']).' '.$row['url'];
1686          } elseif ($row['doktype']=='4')    {
1687              if ($perms_clause)    {
1688                  $label = t3lib_BEfunc::getRecordPath(intval($row['shortcut']),$perms_clause,20);
1689              } else {
1690                  $lRec = t3lib_BEfunc::getRecordWSOL('pages',intval($row['shortcut']),'title');
1691                  $label = $lRec['title'];
1692              }
1693              if ($row['shortcut_mode']>0)    {
1694                  $label.=', '.$LANG->sL($TCA['pages']['columns']['shortcut_mode']['label']).' '.
1695                              $LANG->sL(t3lib_BEfunc::getLabelFromItemlist('pages','shortcut_mode',$row['shortcut_mode']));
1696              }
1697              $parts[]=$LANG->sL($TCA['pages']['columns']['shortcut']['label']).' '.$label;
1698          } elseif ($row['doktype']=='7')    {
1699              if ($perms_clause)    {
1700                  $label = t3lib_BEfunc::getRecordPath(intval($row['mount_pid']),$perms_clause,20);
1701              } else {
1702                  $lRec = t3lib_BEfunc::getRecordWSOL('pages',intval($row['mount_pid']),'title');
1703                  $label = $lRec['title'];
1704              }
1705              $parts[]=$LANG->sL($TCA['pages']['columns']['mount_pid']['label']).' '.$label;
1706              if ($row['mount_pid_ol'])    {
1707                  $parts[] = $LANG->sL($TCA['pages']['columns']['mount_pid_ol']['label']);
1708              }
1709          }
1710          if ($row['nav_hide'])    $parts[] = ereg_replace(':$','',$LANG->sL($TCA['pages']['columns']['nav_hide']['label']));
1711          if ($row['hidden'])    $parts[] = $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.hidden');
1712          if ($row['starttime'])    $parts[] = $LANG->sL($TCA['pages']['columns']['starttime']['label']).' '.t3lib_BEfunc::dateTimeAge($row['starttime'],-1,'date');
1713          if ($row['endtime'])    $parts[] = $LANG->sL($TCA['pages']['columns']['endtime']['label']).' '.t3lib_BEfunc::dateTimeAge($row['endtime'],-1,'date');
1714          if ($row['fe_group'])    {
1715              $fe_groups = array();
1716              foreach (t3lib_div::intExplode(',',$row['fe_group']) as $fe_group)    {
1717                  if ($fe_group<0)    {
1718                      $fe_groups[] = $LANG->sL(t3lib_BEfunc::getLabelFromItemlist('pages','fe_group',$fe_group));
1719                  } else {
1720                      $lRec = t3lib_BEfunc::getRecordWSOL('fe_groups',$fe_group,'title');
1721                      $fe_groups[] = $lRec['title'];
1722                  }
1723              }
1724              $label = implode(', ',$fe_groups);
1725              $parts[] = $LANG->sL($TCA['pages']['columns']['fe_group']['label']).' '.$label;
1726          }
1727          $out = htmlspecialchars(implode(' - ',$parts));
1728          return $includeAttrib ? 'title="'.$out.'"' : $out;
1729      }
1730  
1731      /**
1732       * Returns title-attribute information for ANY record (from a table defined in TCA of course)
1733       * The included information depends on features of the table, but if hidden, starttime, endtime and fe_group fields are configured for, information about the record status in regard to these features are is included.
1734       * "pages" table can be used as well and will return the result of ->titleAttribForPages() for that page.
1735       * Usage: 10
1736       *
1737       * @param    array        Table row; $row is a row from the table, $table
1738       * @param    string        Table name
1739       * @return    string
1740       */
1741  	function getRecordIconAltText($row,$table='pages')    {
1742          if ($table=='pages')    {
1743              $out = t3lib_BEfunc::titleAttribForPages($row,'',0);
1744          } else {
1745              $ctrl = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'];
1746  
1747              $out='id='.$row['uid'];    // Uid is added
1748              if ($table=='pages' && $row['alias'])    {
1749                  $out.=' / '.$row['alias'];
1750              }
1751              if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS'] && $row['pid']<0)    {
1752                  $out.=' - v#1.'.$row['t3ver_id'];
1753              }
1754              if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS'])    {
1755                  if ($row['t3ver_state']==1)    $out.= ' - PLH WSID#'.$row['t3ver_wsid'];
1756                  if ($row['t3ver_state']==-1)    $out.= ' - New element!';
1757              }
1758  
1759              if ($ctrl['disabled'])    {        // Hidden ...
1760                  $out.=($row[$ctrl['disabled']]?' - '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.hidden'):'');
1761              }
1762              if ($ctrl['starttime'])    {
1763                  if ($row[$ctrl['starttime']] > $GLOBALS['EXEC_TIME'])    {
1764                      $out.=' - '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.starttime').':'.t3lib_BEfunc::date($row[$ctrl['starttime']]).' ('.t3lib_BEfunc::daysUntil($row[$ctrl['starttime']]).' '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.days').')';
1765                  }
1766              }
1767              if ($row[$ctrl['endtime']])    {
1768                  $out.=' - '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.endtime').': '.t3lib_BEfunc::date($row[$ctrl['endtime']]).' ('.t3lib_BEfunc::daysUntil($row[$ctrl['endtime']]).' '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.days').')';
1769              }
1770          }
1771          return htmlspecialchars($out);
1772      }
1773  
1774      /**
1775       * Returns the label of the first found entry in an "items" array from $TCA (tablename=$table/fieldname=$col) where the value is $key
1776       * Usage: 9
1777       *
1778       * @param    string        Table name, present in $TCA
1779       * @param    string        Field name, present in $TCA
1780       * @param    string        items-array value to match
1781       * @return    string        Label for item entry
1782       */
1783  	function getLabelFromItemlist($table,$col,$key)    {
1784          global $TCA;
1785              // Load full TCA for $table
1786          t3lib_div::loadTCA($table);
1787  
1788              // Check, if there is an "items" array:
1789          if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$col]) && is_array($TCA[$table]['columns'][$col]['config']['items']))    {
1790                  // Traverse the items-array...
1791              reset($TCA[$table]['columns'][$col]['config']['items']);
1792              while(list($k,$v)=each($TCA[$table]['columns'][$col]['config']['items']))    {
1793                      // ... and return the first found label where the value was equal to $key
1794                  if (!strcmp($v[1],$key))    return $v[0];
1795              }
1796          }
1797      }
1798  
1799      /**
1800       * Returns the label-value for fieldname $col in table, $table
1801       * If $printAllWrap is set (to a "wrap") then it's wrapped around the $col value IF THE COLUMN $col DID NOT EXIST in TCA!, eg. $printAllWrap='<b>|</b>' and the fieldname was 'not_found_field' then the return value would be '<b>not_found_field</b>'
1802       * Usage: 17
1803       *
1804       * @param    string        Table name, present in $TCA
1805       * @param    string        Field name
1806       * @param    string        Wrap value - set function description
1807       * @return    string
1808       */
1809  	function getItemLabel($table,$col,$printAllWrap='')    {
1810          global $TCA;
1811              // Load full TCA for $table
1812          t3lib_div::loadTCA($table);
1813              // Check if column exists
1814          if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$col]))    {
1815                  // Re
1816              return $TCA[$table]['columns'][$col]['label'];
1817          }
1818          if ($printAllWrap)    {
1819              $parts = explode('|',$printAllWrap);
1820              return $parts[0].$col.$parts[1];
1821          }
1822      }
1823  
1824      /**
1825       * Returns the "title"-value in record, $row, from table, $table
1826       * The field(s) from which the value is taken is determined by the "ctrl"-entries 'label', 'label_alt' and 'label_alt_force'
1827       * Usage: 26
1828       *
1829       * @param    string        Table name, present in TCA
1830       * @param    array        Row from table
1831       * @param    boolean        If set, result is prepared for output: The output is cropped to a limited lenght (depending on BE_USER->uc['titleLen']) and if no value is found for the title, '<em>[No title]</em>' is returned (localized). Further, the output is htmlspecialchars()'ed
1832       * @param    boolean        If set, the function always returns an output. If no value is found for the title, '[No title]' is returned (localized).
1833       * @return    string
1834       */
1835  	function getRecordTitle($table,$row,$prep=FALSE,$forceResult=TRUE)    {
1836          global $TCA;
1837          if (is_array($TCA[$table]))    {
1838  
1839                  // If configured, call userFunc
1840              if ($TCA[$table]['ctrl']['label_userFunc'])    {
1841                  $params['table'] = $table;
1842                  $params['row'] = $row;
1843                  $params['title'] = '';
1844  
1845                  t3lib_div::callUserFunction($TCA[$table]['ctrl']['label_userFunc'],$params,$this);
1846                  $t = $params['title'];
1847              } else {
1848  
1849                      // No userFunc: Build label
1850                  $t = $row[$TCA[$table]['ctrl']['label']];
1851                  if ($TCA[$table]['ctrl']['label_alt'] && ($TCA[$table]['ctrl']['label_alt_force'] || !strcmp($t,'')))    {
1852                      $altFields=t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['label_alt'],1);
1853                      $tA=array();
1854                      if (!empty($t))    $tA[] = $t;
1855                      foreach ($altFields as $fN)    {
1856                          $t = trim(strip_tags($row[$fN]));
1857                          if (strcmp($t,''))    {
1858                              $t = t3lib_BEfunc::getProcessedValue($table,$fN,$t);
1859                              if (!$TCA[$table]['ctrl']['label_alt_force'])    {
1860                                  break;
1861                              }
1862                              $tA[] = $t;
1863                          }
1864                      }
1865                      if ($TCA[$table]['ctrl']['label_alt_force'])    {
1866                          $t=implode(', ',$tA);
1867                      }
1868                  }
1869              }
1870  
1871                  // If the current result is empty, set it to '[No title]' (localized) and prepare for output if requested
1872              if ($prep || $forceResult)    {
1873                  if ($prep) {
1874                      $t = t3lib_BEfunc::getRecordTitlePrep($t);
1875                  }
1876                  if (!strcmp(trim($t),'')) {
1877                      $t = t3lib_BEfunc::getNoRecordTitle($prep);
1878                  }
1879              }
1880  
1881              return $t;
1882          }
1883      }
1884  
1885      /**
1886       * Crops a title string to a limited lenght and if it really was cropped, wrap it in a <span title="...">|</span>,
1887       * which offers a tooltip with the original title when moving mouse over it.
1888       *
1889       * @param    string        $title: The title string to be cropped
1890       * @param    integer        $titleLength: Crop title after this length - if not set, BE_USER->uc['titleLen'] is used
1891       * @return    string        The processed title string, wrapped in <span title="...">|</span> if cropped
1892       */
1893  	function getRecordTitlePrep($title, $titleLength=0) {
1894              // If $titleLength is not a valid positive integer, use BE_USER->uc['titleLen']:
1895          if (!$titleLength || !t3lib_div::testInt($titleLength) || $titleLength < 0) {
1896              $titleLength = $GLOBALS['BE_USER']->uc['titleLen'];
1897          }
1898          $titleOrig = htmlspecialchars($title);
1899          $title = htmlspecialchars(t3lib_div::fixed_lgd_cs($title, $titleLength));
1900              // If title was cropped, offer a tooltip:
1901          if ($titleOrig != $title) {
1902              $title = '<span title="'.$titleOrig.'">'.$title.'</span>';
1903          }
1904          return $title;
1905      }
1906  
1907      /**
1908       * Get a localized [No title] string, wrapped in <em>|</em> if $prep is true.
1909       *
1910       * @param    boolean        $prep: Wrap result in <em>|</em>
1911       * @return    string        Localized [No title] string
1912       */
1913  	function getNoRecordTitle($prep=FALSE) {
1914          $noTitle = '['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title',1).']';
1915          if ($prep) $noTitle = '<em>'.$noTitle.'</em>';
1916          return $noTitle;
1917      }
1918  
1919      /**
1920       * Returns a human readable output of a value from a record
1921       * For instance a database record relation would be looked up to display the title-value of that record. A checkbox with a "1" value would be "Yes", etc.
1922       * $table/$col is tablename and fieldname
1923       * REMEMBER to pass the output through htmlspecialchars() if you output it to the browser! (To protect it from XSS attacks and be XHTML compliant)
1924       * Usage: 24
1925       *
1926       * @param    string        Table name, present in TCA
1927       * @param    string        Field name, present in TCA
1928       * @param    string        $value is the value of that field from a selected record
1929       * @param    integer        $fixed_lgd_chars is the max amount of characters the value may occupy
1930       * @param    boolean        $defaultPassthrough flag means that values for columns that has no conversion will just be pass through directly (otherwise cropped to 200 chars or returned as "N/A")
1931       * @param    boolean        If set, no records will be looked up, UIDs are just shown.
1932       * @param    integer        uid of the current record
1933       * @param    boolean        If t3lib_BEfunc::getRecordTitle is used to process the value, this parameter is forwarded.
1934       * @return    string
1935       */
1936  	function getProcessedValue($table,$col,$value,$fixed_lgd_chars=0,$defaultPassthrough=0,$noRecordLookup=FALSE,$uid=0,$forceResult=TRUE)    {
1937          global $TCA;
1938          global $TYPO3_CONF_VARS;
1939              // Load full TCA for $table
1940          t3lib_div::loadTCA($table);
1941              // Check if table and field is configured:
1942          if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$col]))    {
1943                  // Depending on the fields configuration, make a meaningful output value.
1944              $theColConf = $TCA[$table]['columns'][$col]['config'];
1945  
1946                  /*****************
1947                   *HOOK: pre-processing the human readable output from a record
1948                   ****************/
1949              if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['preProcessValue'])) {
1950              foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['preProcessValue'] as $_funcRef) {
1951                      t3lib_div::callUserFunction($_funcRef,$theColConf,$this);
1952                  }
1953              }
1954  
1955              $l='';
1956              switch((string)$theColConf['type'])    {
1957                  case 'radio':
1958                      $l=t3lib_BEfunc::getLabelFromItemlist($table,$col,$value);
1959                      $l=$GLOBALS['LANG']->sL($l);
1960                  break;
1961                  case 'select':
1962                      if ($theColConf['MM'])    {
1963                          // Display the title of MM related records in lists
1964                          if ($noRecordLookup)    {
1965                              $MMfield = $theColConf['foreign_table'].'.uid';
1966                          } else    {
1967                              $MMfields = array($theColConf['foreign_table'].'.'.$TCA[$theColConf['foreign_table']]['ctrl']['label']);
1968                              foreach (t3lib_div::trimExplode(',', $TCA[$theColConf['foreign_table']]['ctrl']['label_alt'], 1) as $f)    {
1969                                  $MMfields[] = $theColConf['foreign_table'].'.'.$f;
1970                              }
1971                              $MMfield = join(',',$MMfields);
1972                          }
1973  
1974                          $dbGroup = t3lib_div::makeInstance('t3lib_loadDBGroup');
1975                          $dbGroup->start($value, $theColConf['foreign_table'], $theColConf['MM'], $uid, $table, $theColConf);
1976                          $selectUids = $dbGroup->tableArray[$theColConf['foreign_table']];
1977  
1978                          if (is_array($selectUids) && count($selectUids)>0) {
1979                              $MMres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1980                                  'uid, '.$MMfield,
1981                                  $theColConf['foreign_table'],
1982                                  'uid IN ('.implode(',', $selectUids).')'
1983                              );
1984                              while($MMrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($MMres))    {
1985                                  $mmlA[] = ($noRecordLookup?$MMrow['uid']:t3lib_BEfunc::getRecordTitle($theColConf['foreign_table'], $MMrow, FALSE, $forceResult));
1986                              }
1987                              if (is_array($mmlA)) {
1988                                  $l=implode('; ',$mmlA);
1989                              } else {
1990                                  $l = '';
1991                              }
1992                          } else {
1993                              $l = 'n/A';
1994                          }
1995                      } else {
1996                          $l = t3lib_BEfunc::getLabelFromItemlist($table,$col,$value);
1997                          $l = $GLOBALS['LANG']->sL($l);
1998                          if ($theColConf['foreign_table'] && !$l && $TCA[$theColConf['foreign_table']])    {
1999                              if ($noRecordLookup)    {
2000                                  $l = $value;
2001                              } else {
2002                                  $rParts = t3lib_div::trimExplode(',',$value,1);
2003                                  reset($rParts);
2004                                  $lA = array();
2005                                  while(list(,$rVal)=each($rParts))    {
2006                                      $rVal = intval($rVal);
2007                                      if ($rVal>0) {
2008                                          $r=t3lib_BEfunc::getRecordWSOL($theColConf['foreign_table'],$rVal);
2009                                      } else {
2010                                          $r=t3lib_BEfunc::getRecordWSOL($theColConf['neg_foreign_table'],-$rVal);
2011                                      }
2012                                      if (is_array($r))    {
2013                                          $lA[]=$GLOBALS['LANG']->sL($rVal>0?$theColConf['foreign_table_prefix']:$theColConf['neg_foreign_table_prefix']).t3lib_BEfunc::getRecordTitle($rVal>0?$theColConf['foreign_table']:$theColConf['neg_foreign_table'],$r,FALSE,$forceResult);
2014                                      } else {
2015                                          $lA[]=$rVal?'['.$rVal.'!]':'';
2016                                      }
2017                                  }
2018                                  $l = implode(', ',$lA);
2019                              }
2020                          }
2021                      }
2022                  break;
2023                  case 'group':
2024                      $l = implode(', ',t3lib_div::trimExplode(',',$value,1));
2025                  break;
2026                  case 'check':
2027                      if (!is_array($theColConf['items']) || count($theColConf['items'])==1)    {
2028                          $l = $value ? 'Yes' : '';
2029                      } else {
2030                          reset($theColConf['items']);
2031                          $lA=Array();
2032                          while(list($key,$val)=each($theColConf['items']))    {
2033                              if ($value & pow(2,$key))    {$lA[]=$GLOBALS['LANG']->sL($val[0]);}
2034                          }
2035                          $l = implode(', ',$lA);
2036                      }
2037                  break;
2038                  case 'input':
2039                      if ($value)    {
2040                          if (t3lib_div::inList($theColConf['eval'],'date'))    {
2041                              $l = t3lib_BEfunc::date($value).' ('.(time()-$value>0?'-':'').t3lib_BEfunc::calcAge(abs(time()-$value), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')).')';
2042                          } elseif (t3lib_div::inList($theColConf['eval'],'time'))    {
2043                              $l = t3lib_BEfunc::time($value);
2044                          } elseif (t3lib_div::inList($theColConf['eval'],'datetime'))    {
2045                              $l = t3lib_BEfunc::datetime($value);
2046                          } else {
2047                              $l = $value;
2048                          }
2049                      }
2050                  break;
2051                  case 'flex':
2052                      $l = strip_tags($value);
2053                  break;
2054                  default:
2055                      if ($defaultPassthrough)    {
2056                          $l=$value;
2057                      } elseif ($theColConf['MM'])    {
2058                          $l='N/A';
2059                      } elseif ($value)    {
2060                          $l=t3lib_div::fixed_lgd_cs(strip_tags($value),200);
2061                      }
2062                  break;
2063              }
2064  
2065                  /*****************
2066                   *HOOK: post-processing the human readable output from a record
2067                   ****************/
2068              if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['postProcessValue'])) {
2069              foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['postProcessValue'] as $_funcRef) {
2070                      $params = array(
2071                          'value' => $l,
2072                          'colConf' => $theColConf
2073                      );
2074                      $l = t3lib_div::callUserFunction($_funcRef,$params,$this);
2075                  }
2076              }
2077  
2078              if ($fixed_lgd_chars)    {
2079                  return t3lib_div::fixed_lgd_cs($l,$fixed_lgd_chars);
2080              } else {
2081                  return $l;
2082              }
2083          }
2084      }
2085  
2086      /**
2087       * Same as ->getProcessedValue() but will go easy on fields like "tstamp" and "pid" which are not configured in TCA - they will be formatted by this function instead.
2088       * Usage: 2
2089       *
2090       * @param    string        Table name, present in TCA
2091       * @param    string        Field name
2092       * @param    string        Field value
2093       * @param    integer        $fixed_lgd_chars is the max amount of characters the value may occupy
2094       * @param    integer        uid of the current record
2095       * @param    boolean        If t3lib_BEfunc::getRecordTitle is used to process the value, this parameter is forwarded.
2096       * @return    string
2097       * @see getProcessedValue()
2098       */
2099  	function getProcessedValueExtra($table,$fN,$fV,$fixed_lgd_chars=0,$uid=0,$forceResult=TRUE)    {
2100          global $TCA;
2101          $fVnew = t3lib_BEfunc::getProcessedValue($table,$fN,$fV,$fixed_lgd_chars,0,0,$uid,$forceResult);
2102          if (!isset($fVnew))    {
2103              if (is_array($TCA[$table]))    {
2104                  if ($fN==$TCA[$table]['ctrl']['tstamp'] || $fN==$TCA[$table]['ctrl']['crdate'])    {
2105                      $fVnew = t3lib_BEfunc::datetime($fV);
2106                  } elseif ($fN=='pid'){
2107                      $fVnew = t3lib_BEfunc::getRecordPath($fV,'1=1',20);    // Fetches the path with no regard to the users permissions to select pages.
2108                  } else {
2109                      $fVnew = $fV;
2110                  }
2111              }
2112          }
2113          return $fVnew;
2114      }
2115  
2116      /**
2117       * Returns file icon name (from $FILEICONS) for the fileextension $ext
2118       * Usage: 10
2119       *
2120       * @param    string        File extension, lowercase
2121       * @return    string        File icon filename
2122       */
2123  	function getFileIcon($ext)    {
2124          return $GLOBALS['FILEICONS'][$ext] ? $GLOBALS['FILEICONS'][$ext] : $GLOBALS['FILEICONS']['default'];
2125      }
2126  
2127      /**
2128       * Returns fields for a table, $table, which would typically be interesting to select
2129       * This includes uid, the fields defined for title, icon-field.
2130       * Returned as a list ready for query ($prefix can be set to eg. "pages." if you are selecting from the pages table and want the table name prefixed)
2131       * Usage: 3
2132       *
2133       * @param    string        Table name, present in TCA
2134       * @param    string        Table prefix
2135       * @param    array        Preset fields (must include prefix if that is used)
2136       * @return    string        List of fields.
2137       */
2138  	function getCommonSelectFields($table,$prefix='',$fields = array())    {
2139          global $TCA;
2140          $fields[] = $prefix.'uid';
2141          $fields[] = $prefix.$TCA[$table]['ctrl']['label'];
2142  
2143          if ($TCA[$table]['ctrl']['label_alt'])    {
2144              $secondFields = t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['label_alt'],1);
2145              foreach($secondFields as $fieldN)    {
2146                  $fields[] = $prefix.$fieldN;
2147              }
2148          }
2149          if ($TCA[$table]['ctrl']['versioningWS'])    {
2150              $fields[] = $prefix.'t3ver_id';
2151              $fields[] = $prefix.'t3ver_state';
2152              $fields[] = $prefix.'t3ver_wsid';
2153              $fields[] = $prefix.'t3ver_count';
2154          }
2155  
2156          if ($TCA[$table]['ctrl']['selicon_field'])    $fields[] = $prefix.$TCA[$table]['ctrl']['selicon_field'];
2157          if ($TCA[$table]['ctrl']['typeicon_column'])    $fields[] = $prefix.$TCA[$table]['ctrl']['typeicon_column'];
2158  
2159          if (is_array($TCA[$table]['ctrl']['enablecolumns']))        {
2160              if ($TCA[$table]['ctrl']['enablecolumns']['disabled'])    $fields[] = $prefix.$TCA[$table]['ctrl']['enablecolumns']['disabled'];
2161              if ($TCA[$table]['ctrl']['enablecolumns']['starttime'])    $fields[] = $prefix.$TCA[$table]['ctrl']['enablecolumns']['starttime'];
2162              if ($TCA[$table]['ctrl']['enablecolumns']['endtime'])    $fields[] = $prefix.$TCA[$table]['ctrl']['enablecolumns']['endtime'];
2163              if ($TCA[$table]['ctrl']['enablecolumns']['fe_group'])    $fields[] = $prefix.$TCA[$table]['ctrl']['enablecolumns']['fe_group'];
2164          }
2165  
2166          return implode(',', array_unique($fields));
2167      }
2168  
2169      /**
2170       * Makes a form for configuration of some values based on configuration found in the array $configArray, with default values from $defaults and a data-prefix $dataPrefix
2171       * <form>-tags must be supplied separately
2172       * Needs more documentation and examples, in particular syntax for configuration array. See Inside TYPO3. That's were you can expect to find example, if anywhere.
2173       * Usage: 1 (ext. direct_mail)
2174       *
2175       * @param    array        Field configuration code.
2176       * @param    array        Defaults
2177       * @param    string        Prefix for formfields
2178       * @return    string        HTML for a form.
2179       */
2180  	function makeConfigForm($configArray,$defaults,$dataPrefix)    {
2181          $params = $defaults;
2182          if (is_array($configArray))    {
2183              reset($configArray);
2184              $lines=array();
2185              while(list($fname,$config)=each($configArray))    {
2186                  if (is_array($config))    {
2187                      $lines[$fname]='<strong>'.htmlspecialchars($config[1]).'</strong><br />';
2188                      $lines[$fname].=$config[2].'<br />';
2189                      switch($config[0])    {
2190                          case 'string':
2191                          case 'short':
2192                              $formEl = '<input type="text" name="'.$dataPrefix.'['.$fname.']" value="'.$params[$fname].'"'.$GLOBALS['TBE_TEMPLATE']->formWidth($config[0]=='short'?24:48).' />';
2193                          break;
2194                          case 'check':
2195                              $formEl = '<input type="hidden" name="'.$dataPrefix.'['.$fname.']" value="0" /><input type="checkbox" name="'.$dataPrefix.'['.$fname.']" value="1"'.($params[$fname]?' checked="checked"':'').' />';
2196                          break;
2197                          case 'comment':
2198                              $formEl = '';
2199                          break;
2200                          case 'select':
2201                              reset($config[3]);
2202                              $opt=array();
2203                              while(list($k,$v)=each($config[3]))    {
2204                                  $opt[]='<option value="'.htmlspecialchars($k).'"'.($params[$fname]==$k?' selected="selected"':'').'>'.htmlspecialchars($v).'</option>';
2205                              }
2206                              $formEl = '<select name="'.$dataPrefix.'['.$fname.']">'.implode('',$opt).'</select>';
2207                          break;
2208                          default:
2209                              debug($config);
2210                          break;
2211                      }
2212                      $lines[$fname].=$formEl;
2213                      $lines[$fname].='<br /><br />';
2214                  } else {
2215                      $lines[$fname]='<hr />';
2216                      if ($config)    $lines[$fname].='<strong>'.strtoupper(htmlspecialchars($config)).'</strong><br />';
2217                      if ($config)    $lines[$fname].='<br />';
2218                  }
2219              }
2220          }
2221          $out = implode('',$lines);
2222          $out.='<input type="submit" name="submit" value="Update configuration" />';
2223          return $out;
2224      }
2225  
2226  
2227  
2228  
2229  
2230  
2231  
2232  
2233  
2234  
2235  
2236  
2237  
2238      /*******************************************
2239       *
2240       * Backend Modules API functions
2241       *
2242       *******************************************/
2243  
2244      /**
2245       * Returns help-text icon if configured for.
2246       * TCA_DESCR must be loaded prior to this function and $BE_USER must have 'edit_showFieldHelp' set to 'icon', otherwise nothing is returned
2247       * Usage: 6
2248       *
2249       * @param    string        Table name
2250       * @param    string        Field name
2251       * @param    string        Back path
2252       * @param    boolean        Force display of icon nomatter BE_USER setting for help
2253       * @return    string        HTML content for a help icon/text
2254       */
2255  	function helpTextIcon($table,$field,$BACK_PATH,$force=0)    {
2256          global $TCA_DESCR,$BE_USER;
2257          if (is_array($TCA_DESCR[$table]) && is_array($TCA_DESCR[$table]['columns'][$field]) && ($BE_USER->uc['edit_showFieldHelp']=='icon' || $force))    {
2258              $onClick = 'vHWin=window.open(\''.$BACK_PATH.'view_help.php?tfID='.($table.'.'.$field).'\',\'viewFieldHelp\',\'height=400,width=600,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;';
2259              return '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
2260                      '<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/helpbubble.gif','width="14" height="14"').' hspace="2" border="0" class="typo3-csh-icon" alt="" />'.
2261                      '</a>';
2262          }
2263      }
2264  
2265      /**
2266       * Returns CSH help text (description), if configured for.
2267       * TCA_DESCR must be loaded prior to this function and $BE_USER must have "edit_showFieldHelp" set to "text", otherwise nothing is returned
2268       * Will automatically call t3lib_BEfunc::helpTextIcon() to get the icon for the text.
2269       * Usage: 4
2270       *
2271       * @param    string        Table name
2272       * @param    string        Field name
2273       * @param    string        Back path
2274       * @param    string        Additional style-attribute content for wrapping table
2275       * @return    string        HTML content for help text
2276       */
2277  	function helpText($table,$field,$BACK_PATH,$styleAttrib='')    {
2278          global $TCA_DESCR,$BE_USER;
2279          if (is_array($TCA_DESCR[$table]) && is_array($TCA_DESCR[$table]['columns'][$field]) && $BE_USER->uc['edit_showFieldHelp']=='text')    {
2280              $fDat = $TCA_DESCR[$table]['columns'][$field];
2281  
2282                  // Get Icon:
2283              $editIcon = t3lib_BEfunc::helpTextIcon(
2284                                      $table,
2285                                      $field,
2286                                      $BACK_PATH,
2287                                      TRUE
2288                                  );
2289                  // Add title?
2290              $onClick = 'vHWin=window.open(\''.$BACK_PATH.'view_help.php?tfID='.($table.'.'.$field).'\',\'viewFieldHelp\',\'height=400,width=600,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;';
2291              $text =
2292                      ($fDat['alttitle'] ? '<h4><a href="#" onclick="'.htmlspecialchars($onClick).'">'.$fDat['alttitle'].'</a></h4>' : '').
2293                      $fDat['description'];
2294  
2295                  // More information to get?
2296              if ($fDat['image_descr'] || $fDat['seeAlso'] || $fDat['details'] || $fDat['syntax'])    { // || $fDat['image'];
2297                  $text.=' <a href="#" onclick="'.htmlspecialchars($onClick).'">'.
2298                          '<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/rel_db.gif','width="13" height="12"').' class="absmiddle typo3-csh-more" alt="" />'.
2299                          '</a>';
2300              }
2301  
2302                  // Additional styles?
2303              $params = $styleAttrib ? ' style="'.$styleAttrib.'"' : '';
2304  
2305                  // Compile table with CSH information:
2306              return '<table border="0" cellpadding="2" cellspacing="0" class="typo3-csh-inline"'.$params.'>
2307                          <tr>
2308                              <td valign="top" width="14">'.$editIcon.'</td>
2309                              <td valign="top">'.$text.'</td>
2310                          </tr>
2311                      </table>';
2312          }
2313      }
2314  
2315      /**
2316       * API for getting CSH icons/text for use in backend modules.
2317       * TCA_DESCR will be loaded if it isn't already
2318       * Usage: ?
2319       *
2320       * @param    string        Table name ('_MOD_'+module name)
2321       * @param    string        Field name (CSH locallang main key)
2322       * @param    string        Back path
2323       * @param    string        Wrap code for icon-mode, splitted by "|". Not used for full-text mode.
2324       * @param    boolean        If set, the full text will never be shown (only icon). Useful for places where it will break the page if the table with full text is shown.
2325       * @param    string        Additional style-attribute content for wrapping table (full text mode only)
2326       * @return    string        HTML content for help text
2327       * @see helpText(), helpTextIcon()
2328       */
2329  	function cshItem($table,$field,$BACK_PATH,$wrap='',$onlyIconMode=FALSE, $styleAttrib='')    {
2330          global $TCA_DESCR, $LANG, $BE_USER;
2331          if ($BE_USER->uc['edit_showFieldHelp'])    {
2332              $LANG->loadSingleTableDescription($table);
2333  
2334              if (is_array($TCA_DESCR[$table]))    {
2335                      // Creating CSH icon and short description:
2336                  $fullText = t3lib_BEfunc::helpText($table,$field,$BACK_PATH,$styleAttrib);
2337                  $icon = t3lib_BEfunc::helpTextIcon($table,$field,$BACK_PATH,$onlyIconMode);
2338  
2339                  if ($fullText && !$onlyIconMode)    {
2340                      $output = $GLOBALS['LANG']->hscAndCharConv($fullText, false);
2341                  } else {
2342                      #$output = '<span style="position:absolute; filter: alpha(opacity=50); -moz-opacity: 0.50;">'.$icon.'</span>';
2343                      $output = $icon;
2344  
2345                      if ($output && $wrap)    {
2346                          $wrParts = explode('|',$wrap);
2347                          $output = $wrParts[0].$output.$wrParts[1];
2348                      }
2349                  }
2350  
2351                  return $output;
2352              }
2353          }
2354      }
2355  
2356      /**
2357       * Returns a JavaScript string (for an onClick handler) which will load the alt_doc.php script that shows the form for editing of the record(s) you have send as params.
2358       * REMEMBER to always htmlspecialchar() content in href-properties to ampersands get converted to entities (XHTML requirement and XSS precaution)
2359       * Usage: 35
2360       *
2361       * @param    string        $params is parameters sent along to alt_doc.php. This requires a much more details description which you must seek in Inside TYPO3s documentation of the alt_doc.php API. And example could be '&edit[pages][123]=edit' which will show edit form for page record 123.
2362       * @param    string        $backPath must point back to the TYPO3_mainDir directory (where alt_doc.php is)
2363       * @param    string        $requestUri is an optional returnUrl you can set - automatically set to REQUEST_URI.
2364       * @return    string
2365       * @see template::issueCommand()
2366       */
2367  	function editOnClick($params,$backPath='',$requestUri='')    {
2368          $retUrl = 'returnUrl='.($requestUri==-1?"'+T3_THIS_LOCATION+'":rawurlencode($requestUri?$requestUri:t3lib_div::getIndpEnv('REQUEST_URI')));
2369          return "window.location.href='".$backPath."alt_doc.php?".$retUrl.$params."'; return false;";
2370      }
2371  
2372      /**
2373       * Returns a JavaScript string for viewing the page id, $id
2374       * It will detect the correct domain name if needed and provide the link with the right back path. Also it will re-use any window already open.
2375       * Usage: 8
2376       *
2377       * @param    integer        $id is page id
2378       * @param    string        $backpath must point back to TYPO3_mainDir (where the site is assumed to be one level above)
2379       * @param    array        If root line is supplied the function will look for the first found domain record and use that URL instead (if found)
2380       * @param    string        $anchor is optional anchor to the URL
2381       * @param    string        $altUrl is an alternative URL which - if set - will make all other parameters ignored: The function will just return the window.open command wrapped around this URL!
2382       * @param    string        Additional GET variables.
2383       * @param    boolean        If true, then the preview window will gain the focus.
2384       * @return    string
2385       */
2386  	function viewOnClick($id,$backPath='',$rootLine='',$anchor='',$altUrl='',$addGetVars='',$switchFocus=TRUE)    {
2387          if ($altUrl)    {
2388              $url = $altUrl;
2389          } else {
2390  
2391              if ($GLOBALS['BE_USER']->workspace!=0)    {
2392                  $url = t3lib_div::getIndpEnv('TYPO3_SITE_URL').TYPO3_mainDir.'mod/user/ws/wsol_preview.php?id='.$id.$addGetVars.$anchor;
2393              } else {
2394                  if ($rootLine)    {
2395                      $parts = parse_url(t3lib_div::getIndpEnv('TYPO3_SITE_URL'));
2396                      if (t3lib_BEfunc::getDomainStartPage($parts['host'],$parts['path']))    {
2397                          $preUrl_temp = t3lib_BEfunc::firstDomainRecord($rootLine);
2398                      }
2399                  }
2400                  $preUrl = $preUrl_temp ? (t3lib_div::getIndpEnv('TYPO3_SSL') ? 'https://' : 'http://').$preUrl_temp : $backPath.'..';
2401                  $url = $preUrl.'/index.php?id='.$id.$addGetVars.$anchor;
2402              }
2403          }
2404  
2405          return "previewWin=window.open('".$url."','newTYPO3frontendWindow');".
2406                  ($switchFocus ? 'previewWin.focus();' : '');
2407      }
2408  
2409      /**
2410       * Returns the merged User/Page TSconfig for page id, $id.
2411       * Please read details about module programming elsewhere!
2412       * Usage: 15
2413       *
2414       * @param    integer        Page uid
2415       * @param    string        $TSref is an object string which determines the path of the TSconfig to return.
2416       * @return    array
2417       */
2418  	function getModTSconfig($id,$TSref)    {
2419          $pageTS_modOptions = $GLOBALS['BE_USER']->getTSConfig($TSref,t3lib_BEfunc::getPagesTSconfig($id));
2420          $BE_USER_modOptions = $GLOBALS['BE_USER']->getTSConfig($TSref);
2421          $modTSconfig = t3lib_div::array_merge_recursive_overrule($pageTS_modOptions,$BE_USER_modOptions);
2422          return $modTSconfig;
2423      }
2424  
2425      /**
2426       * Returns a selector box "function menu" for a module
2427       * Requires the JS function jumpToUrl() to be available
2428       * See Inside TYPO3 for details about how to use / make Function menus
2429       * Usage: 50
2430       *
2431       * @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=...
2432       * @param    string        $elementName it the form elements name, probably something like "SET[...]"
2433       * @param    string        $currentValue is the value to be selected currently.
2434       * @param    array        $menuItems is an array with the menu items for the selector box
2435       * @param    string        $script is the script to send the &id to, if empty it's automatically found
2436       * @param    string        $addParams is additional parameters to pass to the script.
2437       * @return    string        HTML code for selector box
2438       */
2439  	function getFuncMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='')    {
2440          if (is_array($menuItems))    {
2441              if (!is_array($mainParams)) {
2442                  $mainParams = array('id' => $mainParams);
2443              }
2444              $mainParams = t3lib_div::implodeArrayForUrl('',$mainParams);
2445  
2446              if (!$script) {
2447                  $script = basename(PATH_thisScript);
2448                  $mainParams.= (t3lib_div::_GET('M') ? '&M='.rawurlencode(t3lib_div::_GET('M')) : '');
2449              }
2450  
2451              $options = array();
2452              foreach($menuItems as $value => $label)    {
2453                  $options[] = '<option value="'.htmlspecialchars($value).'"'.(!strcmp($currentValue,$value)?' selected="selected"':'').'>'.
2454                                  t3lib_div::deHSCentities(htmlspecialchars($label)).
2455                                  '</option>';
2456              }
2457              if (count($options))    {
2458                  $onChange = 'jumpToUrl(\''.$script.'?'.$mainParams.$addparams.'&'.$elementName.'=\'+this.options[this.selectedIndex].value,this);';
2459                  return '
2460  
2461                      <!-- Function Menu of module -->
2462                      <select name="'.$elementName.'" onchange="'.htmlspecialchars($onChange).'">
2463                          '.implode('
2464                          ',$options).'
2465                      </select>
2466                              ';
2467              }
2468          }
2469      }
2470  
2471      /**
2472       * Checkbox function menu.
2473       * Works like ->getFuncMenu() but takes no $menuItem array since this is a simple checkbox.
2474       * Usage: 34
2475       *
2476       * @param    mixed        $mainParams $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=...
2477       * @param    string        $elementName it the form elements name, probably something like "SET[...]"
2478       * @param    string        $currentValue is the value to be selected currently.
2479       * @param    string        $script is the script to send the &id to, if empty it's automatically found
2480       * @param    string        $addParams is additional parameters to pass to the script.
2481       * @param    string        Additional attributes for the checkbox input tag
2482       * @return    string        HTML code for checkbox
2483       * @see getFuncMenu()
2484       */
2485  	function getFuncCheck($mainParams,$elementName,$currentValue,$script='',$addparams='',$tagParams='')    {
2486          if (!is_array($mainParams)) {
2487              $mainParams = array('id' => $mainParams);
2488          }
2489          $mainParams = t3lib_div::implodeArrayForUrl('',$mainParams);
2490  
2491          if (!$script) {basename(PATH_thisScript);}
2492          $onClick = 'jumpToUrl(\''.$script.'?'.$mainParams.$addparams.'&'.$elementName.'=\'+(this.checked?1:0),this);';
2493          return '<input type="checkbox" name="'.$elementName.'"'.($currentValue?' checked="checked"':'').' onclick="'.htmlspecialchars($onClick).'"'.($tagParams?' '.$tagParams:'').' />';
2494      }
2495  
2496      /**
2497       * Input field function menu
2498       * Works like ->getFuncMenu() / ->getFuncCheck() but displays a input field instead which updates the script "onchange"
2499       * Usage: 1
2500       *
2501       * @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=...
2502       * @param    string        $elementName it the form elements name, probably something like "SET[...]"
2503       * @param    string        $currentValue is the value to be selected currently.
2504       * @param    integer        Relative size of input field, max is 48
2505       * @param    string        $script is the script to send the &id to, if empty it's automatically found
2506       * @param    string        $addParams is additional parameters to pass to the script.
2507       * @return    string        HTML code for input text field.
2508       * @see getFuncMenu()
2509       */
2510  	function getFuncInput($mainParams,$elementName,$currentValue,$size=10,$script="",$addparams="")    {
2511          if (!is_array($mainParams)) {
2512              $mainParams = array('id' => $mainParams);
2513          }
2514          $mainParams = t3lib_div::implodeArrayForUrl('',$mainParams);
2515  
2516          if (!$script) {basename(PATH_thisScript);}
2517          $onChange = 'jumpToUrl(\''.$script.'?'.$mainParams.$addparams.'&'.$elementName.'=\'+escape(this.value),this);';
2518          return '<input type="text"'.$GLOBALS['TBE_TEMPLATE']->formWidth($size).' name="'.$elementName.'" value="'.htmlspecialchars($currentValue).'" onchange="'.htmlspecialchars($onChange).'" />';
2519      }
2520  
2521      /**
2522       * Removes menu items from $itemArray if they are configured to be removed by TSconfig for the module ($modTSconfig)
2523       * See Inside TYPO3 about how to program modules and use this API.
2524       * Usage: 4
2525       *
2526       * @param    array        Module TS config array
2527       * @param    array        Array of items from which to remove items.
2528       * @param    string        $TSref points to the "object string" in $modTSconfig
2529       * @return    array        The modified $itemArray is returned.
2530       */
2531  	function unsetMenuItems($modTSconfig,$itemArray,$TSref)    {
2532              // Getting TS-config options for this module for the Backend User:
2533          $conf = $GLOBALS['BE_USER']->getTSConfig($TSref,$modTSconfig);
2534          if (is_array($conf['properties']))    {
2535              reset($conf['properties']);
2536              while(list($key,$val)=each($conf['properties']))    {
2537                  if (!$val)    {
2538                      unset($itemArray[$key]);
2539                  }
2540              }
2541          }
2542          return $itemArray;
2543      }
2544  
2545      /**
2546       * Call to update the page tree frame (or something else..?) after
2547       * t3lib_BEfunc::getSetUpdateSignal('updatePageTree') -> will set the page tree to be updated.
2548       * t3lib_BEfunc::getSetUpdateSignal() -> will return some JavaScript that does the update (called in the typo3/template.php file, end() function)
2549       * Usage: 11
2550       *
2551       * @param    string        Whether to set or clear the update signal. When setting, this value contains strings telling WHAT to set. At this point it seems that the value "updatePageTree" is the only one it makes sense to set.
2552       * @return    string        HTML code (<script> section)
2553       */
2554  	function getSetUpdateSignal($set='')    {
2555          global $BE_USER;
2556          $key = 't3lib_BEfunc::getSetUpdateSignal';
2557          $out='';
2558          if ($set)    {
2559              $modData=array();
2560              $modData['set']=$set;
2561              $BE_USER->pushModuleData($key,$modData);
2562          } else {
2563              $modData = $BE_USER->getModuleData($key,'ses');
2564              if (trim($modData['set']))    {
2565                  $l=explode(',',$modData['set']);
2566                  while(list(,$v)=each($l))    {
2567                      switch($v)    {
2568                          case 'updatePageTree':
2569                          case 'updateFolderTree':
2570                              $out.='
2571                      <script type="text/javascript">
2572                      /*<![CDATA[*/
2573                              if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav)    {
2574                                  top.content.nav_frame.refresh_nav();
2575                              }
2576                      /*]]>*/
2577                      </script>';
2578                          break;
2579                      }
2580                  }
2581                  $modData=array();
2582                  $modData['set']='';
2583                  $BE_USER->pushModuleData($key,$modData);
2584              }
2585          }
2586          return $out;
2587      }
2588  
2589  
2590      /**
2591       * Returns an array which is most backend modules becomes MOD_SETTINGS containing values from function menus etc. determining the function of the module.
2592       * This is kind of session variable management framework for the backend users.
2593       * If a key from MOD_MENU is set in the CHANGED_SETTINGS array (eg. a value is passed to the script from the outside), this value is put into the settings-array
2594       * Ultimately, see Inside TYPO3 for how to use this function in relation to your modules.
2595       * Usage: 23
2596       *
2597       * @param    array        MOD_MENU is an array that defines the options in menus.
2598       * @param    array        CHANGED_SETTINGS represents the array used when passing values to the script from the menus.
2599       * @param    string        modName is the name of this module. Used to get the correct module data.
2600       * @param    string        If type is 'ses' then the data is stored as session-lasting data. This means that it'll be wiped out the next time the user logs in.
2601       * @param    string        dontValidateList can be used to list variables that should not be checked if their value is found in the MOD_MENU array. Used for dynamically generated menus.
2602       * @param    string        List of default values from $MOD_MENU to set in the output array (only if the values from MOD_MENU are not arrays)
2603       * @return    array        The array $settings, which holds a key for each MOD_MENU key and the values of each key will be within the range of values for each menuitem
2604       */
2605  	function getModuleData($MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='')    {
2606  
2607          if ($modName && is_string($modName))    {
2608                      // GETTING stored user-data from this module:
2609              $settings = $GLOBALS['BE_USER']->getModuleData($modName,$type);
2610  
2611              $changed=0;
2612              if (!is_array($settings))    {
2613                  $changed=1;
2614                  $settings=array();
2615              }
2616              if (is_array($MOD_MENU))    {
2617                  foreach ($MOD_MENU as $key=>$var)    {
2618                          // If a global var is set before entering here. eg if submitted, then it's substituting the current value the array.
2619                      if (is_array($CHANGED_SETTINGS) && isset($CHANGED_SETTINGS[$key]) && strcmp($settings[$key],$CHANGED_SETTINGS[$key]))    {
2620                          $settings[$key] = (string)$CHANGED_SETTINGS[$key];
2621                          $changed=1;
2622                      }
2623                          // If the $var is an array, which denotes the existence of a menu, we check if the value is permitted
2624                      if (is_array($var) && (!$dontValidateList || !t3lib_div::inList($dontValidateList,$key)))    {
2625                              // If the setting is an array or not present in the menu-array, MOD_MENU, then the default value is inserted.
2626                          if (is_array($settings[$key]) || !isset($MOD_MENU[$key][$settings[$key]]))    {
2627                              $settings[$key]=(string)key($var);
2628                              $changed=1;
2629                          }
2630                      }
2631                      if ($setDefaultList && !is_array($var))    {    // Sets default values (only strings/checkboxes, not menus)
2632                          if (t3lib_div::inList($setDefaultList,$key) && !isset($settings[$key]))    {
2633                              $settings[$key]=$var;
2634                          }
2635                      }
2636                  }
2637              } else {die ('No menu!');}
2638  
2639              if ($changed)    {
2640                  $GLOBALS['BE_USER']->pushModuleData($modName,$settings);
2641              }
2642  
2643              return  $settings;
2644          } else {die ('Wrong module name: "'.$modName.'"');}
2645      }
2646  
2647  
2648  
2649  
2650  
2651  
2652  
2653  
2654  
2655  
2656  
2657  
2658  
2659      /*******************************************
2660       *
2661       * Core
2662       *
2663       *******************************************/
2664  
2665      /**
2666       * Set preview keyword, eg:
2667       *     $previewUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL').'index.php?ADMCMD_prev='.t3lib_BEfunc::compilePreviewKeyword('id='.$pageId.'&L='.$language.'&ADMCMD_view=1&ADMCMD_editIcons=1&ADMCMD_previewWS='.$this->workspace, $GLOBALS['BE_USER']->user['uid'], 120);
2668       *
2669       * todo for sys_preview:
2670       * - Add a comment which can be shown to previewer in frontend in some way (plus maybe ability to write back, take other action?)
2671       * - Add possibility for the preview keyword to work in the backend as well: So it becomes a quick way to a certain action of sorts?
2672       *
2673       * @param    string        Get variables to preview, eg. 'id=1150&L=0&ADMCMD_view=1&ADMCMD_editIcons=1&ADMCMD_previewWS=8'
2674       * @param    string        32 byte MD5 hash keyword for the URL: "?ADMCMD_prev=[keyword]"
2675       * @param    integer        Time-To-Live for keyword
2676       * @return    string        Returns keyword to use in URL for ADMCMD_prev=
2677       */
2678  	function compilePreviewKeyword($getVarsStr, $beUserUid, $ttl=172800)    {
2679          $field_array = array(
2680              'keyword' => md5(uniqid(microtime())),
2681              'tstamp' => time(),
2682              'endtime' => time()+$ttl,
2683              'config' => serialize(array(
2684                  'getVars' => $getVarsStr,
2685                  'BEUSER_uid' => $beUserUid
2686              ))
2687          );
2688  
2689          $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_preview', $field_array);
2690  
2691          return $field_array['keyword'];
2692      }
2693  
2694      /**
2695       * Unlock or Lock a record from $table with $uid
2696       * If $table and $uid is not set, then all locking for the current BE_USER is removed!
2697       * Usage: 5
2698       *
2699       * @param    string        Table name
2700       * @param    integer        Record uid
2701       * @param    integer        Record pid
2702       * @return    void
2703       * @internal
2704       * @see t3lib_transferData::lockRecord(), alt_doc.php, db_layout.php, db_list.php, wizard_rte.php
2705       */
2706  	function lockRecords($table='',$uid=0,$pid=0)    {
2707          $user_id = intval($GLOBALS['BE_USER']->user['uid']);
2708          if ($table && $uid)    {
2709              $fields_values = array(
2710                  'userid' => $user_id,
2711                  'tstamp' => $GLOBALS['EXEC_TIME'],
2712                  'record_table' => $table,
2713                  'record_uid' => $uid,
2714                  'username' => $GLOBALS['BE_USER']->user['username'],
2715                  'record_pid' => $pid
2716              );
2717  
2718              $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_lockedrecords', $fields_values);
2719          } else {
2720              $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_lockedrecords', 'userid='.intval($user_id));
2721          }
2722      }
2723  
2724      /**
2725       * Returns information about whether the record from table, $table, with uid, $uid is currently locked (edited by another user - which should issue a warning).
2726       * Notice: Locking is not strictly carried out since locking is abandoned when other backend scripts are activated - which means that a user CAN have a record "open" without having it locked. So this just serves as a warning that counts well in 90% of the cases, which should be sufficient.
2727       * Usage: 5
2728       *
2729       * @param    string        Table name
2730       * @param    integer        Record uid
2731       * @return    array
2732       * @internal
2733       * @see class.db_layout.inc, alt_db_navframe.php, alt_doc.php, db_layout.php
2734       */
2735  	function isRecordLocked($table,$uid)    {
2736          global $LOCKED_RECORDS;
2737          if (!is_array($LOCKED_RECORDS))    {
2738              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
2739                              '*',
2740                              'sys_lockedrecords',
2741                              'sys_lockedrecords.userid!='.intval($GLOBALS['BE_USER']->user['uid']).'
2742                                  AND sys_lockedrecords.tstamp > '.($GLOBALS['EXEC_TIME']-2*3600)
2743                          );
2744              while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
2745                  $LOCKED_RECORDS[$row['record_table'].':'.$row['record_uid']]=$row;
2746                  $LOCKED_RECORDS[$row['record_table'].':'.$row['record_uid']]['msg']=sprintf(
2747                      $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.lockedRecord'),
2748                      $row['username'],
2749                      t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME']-$row['tstamp'],$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears'))
2750                  );
2751                  if ($row['record_pid'] && !isset($LOCKED_RECORDS[$row['record_table'].':'.$row['record_pid']]))    {
2752                      $LOCKED_RECORDS['pages:'.$row['record_pid']]['msg']=sprintf(
2753                          $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.lockedRecord_content'),
2754                          $row['username'],
2755                          t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME']-$row['tstamp'],$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears'))
2756                      );
2757                  }
2758              }
2759          }
2760          return $LOCKED_RECORDS[$table.':'.$uid];
2761      }
2762  
2763      /**
2764       * Returns select statement for MM relations (as used by TCEFORMs etc)
2765       * Usage: 3
2766       *
2767       * @param    array        Configuration array for the field, taken from $TCA
2768       * @param    string        Field name
2769       * @param    array        TSconfig array from which to get further configuration settings for the field name
2770       * @param    string        Prefix string for the key "*foreign_table_where" from $fieldValue array
2771       * @return    string        Part of query
2772       * @internal
2773       * @see t3lib_transferData::renderRecord(), t3lib_TCEforms::foreignTable()
2774       */
2775  	function exec_foreign_table_where_query($fieldValue,$field='',$TSconfig=array(),$prefix='')    {
2776          global $TCA;
2777          $foreign_table = $fieldValue['config'][$prefix.'foreign_table'];
2778          $rootLevel = $TCA[$foreign_table]['ctrl']['rootLevel'];
2779  
2780          $fTWHERE = $fieldValue['config'][$prefix.'foreign_table_where'];
2781          if (strstr($fTWHERE,'###REC_FIELD_'))    {
2782              $fTWHERE_parts = explode('###REC_FIELD_',$fTWHERE);
2783              while(list($kk,$vv)=each($fTWHERE_parts))    {
2784                  if ($kk)    {
2785                      $fTWHERE_subpart = explode('###',$vv,2);
2786                      $fTWHERE_parts[$kk]=$TSconfig['_THIS_ROW'][$fTWHERE_subpart[0]].$fTWHERE_subpart[1];
2787                  }
2788              }
2789              $fTWHERE = implode('',$fTWHERE_parts);
2790          }
2791  
2792          $fTWHERE = str_replace('###CURRENT_PID###',intval($TSconfig['_CURRENT_PID']),$fTWHERE);
2793          $fTWHERE = str_replace('###THIS_UID###',intval($TSconfig['_THIS_UID']),$fTWHERE);
2794          $fTWHERE = str_replace('###THIS_CID###',intval($TSconfig['_THIS_CID']),$fTWHERE);
2795          $fTWHERE = str_replace('###STORAGE_PID###',intval($TSconfig['_STORAGE_PID']),$fTWHERE);
2796          $fTWHERE = str_replace('###SITEROOT###',intval($TSconfig['_SITEROOT']),$fTWHERE);
2797          $fTWHERE = str_replace('###PAGE_TSCONFIG_ID###',intval($TSconfig[$field]['PAGE_TSCONFIG_ID']),$fTWHERE);
2798          $fTWHERE = str_replace('###PAGE_TSCONFIG_IDLIST###',$GLOBALS['TYPO3_DB']->cleanIntList($TSconfig[$field]['PAGE_TSCONFIG_IDLIST']),$fTWHERE);
2799          $fTWHERE = str_replace('###PAGE_TSCONFIG_STR###',$GLOBALS['TYPO3_DB']->quoteStr($TSconfig[$field]['PAGE_TSCONFIG_STR'], $foreign_table),$fTWHERE);
2800  
2801              // rootLevel = -1 is not handled 'properly' here - it goes as if it was rootLevel = 1 (that is pid=0)
2802          $wgolParts = $GLOBALS['TYPO3_DB']->splitGroupOrderLimit($fTWHERE);
2803          if ($rootLevel)    {
2804              $queryParts = array(
2805                  'SELECT' => t3lib_BEfunc::getCommonSelectFields($foreign_table,$foreign_table.'.'),
2806                  'FROM' => $foreign_table,
2807                  'WHERE' => $foreign_table.'.pid=0 '.
2808                              t3lib_BEfunc::deleteClause($foreign_table).' '.
2809                              $wgolParts['WHERE'],
2810                  'GROUPBY' => $wgolParts['GROUPBY'],
2811                  'ORDERBY' => $wgolParts['ORDERBY'],
2812                  'LIMIT' => $wgolParts['LIMIT']
2813              );
2814          } else {
2815              $pageClause = $GLOBALS['BE_USER']->getPagePermsClause(1);
2816              if ($foreign_table!='pages')    {
2817                  $queryParts = array(
2818                      'SELECT' => t3lib_BEfunc::getCommonSelectFields($foreign_table,$foreign_table.'.'),
2819                      'FROM' => $foreign_table.',pages',
2820                      'WHERE' => 'pages.uid='.$foreign_table.'.pid
2821                                  AND pages.deleted=0 '.
2822                                  t3lib_BEfunc::deleteClause($foreign_table).
2823                                  ' AND '.$pageClause.' '.
2824                                  $wgolParts['WHERE'],
2825                      'GROUPBY' => $wgolParts['GROUPBY'],
2826                      'ORDERBY' => $wgolParts['ORDERBY'],
2827                      'LIMIT' => $wgolParts['LIMIT']
2828                  );
2829              } else {
2830                  $queryParts = array(
2831                      'SELECT' => t3lib_BEfunc::getCommonSelectFields($foreign_table,$foreign_table.'.'),
2832                      'FROM' => 'pages',
2833                      'WHERE' => 'pages.deleted=0
2834                                  AND '.$pageClause.' '.
2835                                  $wgolParts['WHERE'],
2836                      'GROUPBY' => $wgolParts['GROUPBY'],
2837                      'ORDERBY' => $wgolParts['ORDERBY'],
2838                      'LIMIT' => $wgolParts['LIMIT']
2839                  );
2840              }
2841          }
2842  
2843          return $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
2844      }
2845  
2846      /**
2847       * Returns TSConfig for the TCEFORM object in Page TSconfig.
2848       * Used in TCEFORMs
2849       * Usage: 4
2850       *
2851       * @param    string        Table name present in TCA
2852       * @param    array        Row from table
2853       * @return    array
2854       * @see t3lib_transferData::renderRecord(), t3lib_TCEforms::setTSconfig(), SC_wizard_list::main(), SC_wizard_add::main()
2855       */
2856  	function getTCEFORM_TSconfig($table,$row) {
2857          t3lib_BEfunc::fixVersioningPid($table,$row);
2858  
2859          $res = array();
2860          $typeVal = t3lib_BEfunc::getTCAtypeValue($table,$row);
2861  
2862              // Get main config for the table
2863          list($TScID,$cPid) = t3lib_BEfunc::getTSCpid($table,$row['uid'],$row['pid']);
2864  
2865          $rootLine = t3lib_BEfunc::BEgetRootLine($TScID,'',TRUE);
2866          if ($TScID>=0)    {
2867              $tempConf = $GLOBALS['BE_USER']->getTSConfig('TCEFORM.'.$table,t3lib_BEfunc::getPagesTSconfig($TScID,$rootLine));
2868              if (is_array($tempConf['properties']))    {
2869                  while(list($key,$val)=each($tempConf['properties']))    {
2870                      if (is_array($val))    {
2871                          $fieldN = substr($key,0,-1);
2872                          $res[$fieldN] = $val;
2873                          unset($res[$fieldN]['types.']);
2874                          if (strcmp($typeVal,'') && is_array($val['types.'][$typeVal.'.']))    {
2875                              $res[$fieldN] = t3lib_div::array_merge_recursive_overrule($res[$fieldN],$val['types.'][$typeVal.'.']);
2876                          }
2877                      }
2878                  }
2879              }
2880          }
2881          $res['_CURRENT_PID']=$cPid;
2882          $res['_THIS_UID']=$row['uid'];
2883          $res['_THIS_CID']=$row['cid'];
2884          $res['_THIS_ROW']=$row;    // So the row will be passed to foreign_table_where_query()
2885  
2886          reset($rootLine);
2887          while(list(,$rC)=each($rootLine))    {
2888              if (!$res['_STORAGE_PID'])    $res['_STORAGE_PID']=intval($rC['storage_pid']);
2889              if (!$res['_SITEROOT'])    $res['_SITEROOT']=$rC['is_siteroot']?intval($rC['uid']):0;
2890          }
2891  
2892          return $res;
2893      }
2894  
2895      /**
2896       * Find the real PID of the record (with $uid from $table). This MAY be impossible if the pid is set as a reference to the former record or a page (if two records are created at one time).
2897       * NOTICE: Make sure that the input PID is never negative because the record was an offline version! Therefore, you should always use t3lib_BEfunc::fixVersioningPid($table,$row); on the data you input before calling this function!
2898       * Usage: 2
2899       *
2900       * @param    string        Table name
2901       * @param    integer        Record uid
2902       * @param    integer        Record pid, could be negative then pointing to a record from same table whose pid to find and return.
2903       * @return    integer
2904       * @internal
2905       * @see t3lib_TCEmain::copyRecord(), getTSCpid()
2906       */
2907  	function getTSconfig_pidValue($table,$uid,$pid)    {
2908  
2909          if (t3lib_div::testInt($pid))    {    // If pid is an integer this takes precedence in our lookup.
2910              $thePidValue = intval($pid);
2911              if ($thePidValue<0)    {    // If ref to another record, look that record up.
2912                  $pidRec = t3lib_BEfunc::getRecord($table,abs($thePidValue),'pid');
2913                  $thePidValue = is_array($pidRec) ? $pidRec['pid'] : -2;    // Returns -2 if the record did not exist.
2914              }
2915              // ... else the pos/zero pid is just returned here.
2916          } else {    // No integer pid and we are forced to look up the $pid
2917              $rr = t3lib_BEfunc::getRecord($table,$uid);    // Try to fetch the record pid from uid. If the uid is 'NEW...' then this will of course return nothing...
2918  
2919              if (is_array($rr))    {
2920                      // First check if the pid is -1 which means it is a workspaced element. Get the "real" record:
2921                  if ($rr['pid']=='-1')    {
2922                      $rr = t3lib_BEfunc::getRecord($table,$rr['t3ver_oid'],'pid');
2923                      if (is_array($rr))    {
2924                          $thePidValue = $rr['pid'];
2925                      }
2926                  } else {
2927                      $thePidValue = $rr['pid'];    // Returning the "pid" of the record
2928                  }
2929              }
2930  
2931              if (!$thePidValue)    $thePidValue = -1;    // Returns -1 if the record with this pid was not found.
2932          }
2933  
2934          return $thePidValue;
2935      }
2936  
2937      /**
2938       * Return $uid if $table is pages and $uid is integer - otherwise the $pid
2939       * Usage: 1
2940       *
2941       * @param    string        Table name
2942       * @param    integer        Record uid
2943       * @param    integer        Record pid
2944       * @return    integer
2945       * @internal
2946       * @see t3lib_TCEforms::getTSCpid()
2947       */
2948  	function getPidForModTSconfig($table,$uid,$pid)    {
2949          $retVal = ($table=='pages' && t3lib_div::testInt($uid)) ? $uid : $pid;
2950          return $retVal;
2951      }
2952  
2953      /**
2954       * Returns the REAL pid of the record, if possible. If both $uid and $pid is strings, then pid=-1 is returned as an error indication.
2955       * Usage: 8
2956       *
2957       * @param    string        Table name
2958       * @param    integer        Record uid
2959       * @param    integer        Record pid
2960       * @return    array        Array of two integers; first is the REAL PID of a record and if its a new record negative values are resolved to the true PID, second value is the PID value for TSconfig (uid if table is pages, otherwise the pid)
2961       * @internal
2962       * @see t3lib_TCEmain::setHistory(), t3lib_TCEmain::process_datamap()
2963       */
2964  	function getTSCpid($table,$uid,$pid)    {
2965              // If pid is negative (referring to another record) the pid of the other record is fetched and returned.
2966          $cPid = t3lib_BEfunc::getTSconfig_pidValue($table,$uid,$pid);
2967              // $TScID is the id of $table=pages, else it's the pid of the record.
2968          $TScID = t3lib_BEfunc::getPidForModTSconfig($table,$uid,$cPid);
2969  
2970          return array($TScID,$cPid);
2971      }
2972  
2973      /**
2974       * Returns first found domain record "domainName" (without trailing slash) if found in the input $rootLine
2975       * Usage: 2
2976       *
2977       * @param    array        Root line array
2978       * @return    string        Domain name, if found.
2979       */
2980  	function firstDomainRecord($rootLine)    {
2981          if (t3lib_extMgm::isLoaded('cms'))    {
2982              reset($rootLine);
2983              while(list(,$row)=each($rootLine))    {
2984                  $dRec = t3lib_BEfunc::getRecordsByField('sys_domain','pid',$row['uid'],' AND redirectTo=\'\' AND hidden=0', '', 'sorting');
2985                  if (is_array($dRec))    {
2986                      reset($dRec);
2987                      $dRecord = current($dRec);
2988                      return ereg_replace('\/$','',$dRecord['domainName']);
2989                  }
2990              }
2991          }
2992      }
2993  
2994      /**
2995       * Returns the sys_domain record for $domain, optionally with $path appended.
2996       * Usage: 2
2997       *
2998       * @param    string        Domain name
2999       * @param    string        Appended path
3000       * @return    array        Domain record, if found
3001       */
3002  	function getDomainStartPage($domain, $path='')    {
3003          if (t3lib_extMgm::isLoaded('cms'))    {
3004              $domain = explode(':',$domain);
3005              $domain = strtolower(ereg_replace('\.$','',$domain[0]));
3006                  // path is calculated.
3007              $path = trim(ereg_replace('\/[^\/]*$','',$path));
3008                  // stuff:
3009              $domain.=$path;
3010  
3011              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('sys_domain.*', 'pages,sys_domain', '
3012                  pages.uid=sys_domain.pid
3013                  AND sys_domain.hidden=0
3014                  AND (sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain, 'sys_domain').' or sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain.'/', 'sys_domain').')'.
3015                  t3lib_BEfunc::deleteClause('pages'),
3016                  '', '', '1');
3017              $result = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
3018              $GLOBALS['TYPO3_DB']->sql_free_result($res);
3019              return $result;
3020          }
3021      }
3022  
3023      /**
3024       * Returns overlayered RTE setup from an array with TSconfig. Used in TCEforms and TCEmain
3025       * Usage: 8
3026       *
3027       * @param    array        The properties of Page TSconfig in the key "RTE."
3028       * @param    string        Table name
3029       * @param    string        Field name
3030       * @param    string        Type value of the current record (like from CType of tt_content)
3031       * @return    array        Array with the configuration for the RTE
3032       * @internal
3033       */
3034  	function RTEsetup($RTEprop,$table,$field,$type='')    {
3035          $thisConfig = is_array($RTEprop['default.']) ? $RTEprop['default.'] : array();
3036          $thisFieldConf = $RTEprop['config.'][$table.'.'][$field.'.'];
3037          if (is_array($thisFieldConf))    {
3038              unset($thisFieldConf['types.']);
3039              $thisConfig = t3lib_div::array_merge_recursive_overrule($thisConfig,$thisFieldConf);
3040          }
3041          if ($type && is_array($RTEprop['config.'][$table.'.'][$field.'.']['types.'][$type.'.']))    {
3042              $thisConfig = t3lib_div::array_merge_recursive_overrule($thisConfig,$RTEprop['config.'][$table.'.'][$field.'.']['types.'][$type.'.']);
3043          }
3044          return $thisConfig;
3045      }
3046  
3047      /**
3048       * Returns first possible RTE object if available.
3049       * Usage: $RTEobj = &t3lib_BEfunc::RTEgetObj();
3050       *
3051       * @return    mixed        If available, returns RTE object, otherwise an array of messages from possible RTEs
3052       */
3053      function &RTEgetObj()    {
3054  
3055              // If no RTE object has been set previously, try to create it:
3056          if (!isset($GLOBALS['T3_VAR']['RTEobj']))    {
3057  
3058                  // Set the object string to blank by default:
3059              $GLOBALS['T3_VAR']['RTEobj'] = array();
3060  
3061                  // Traverse registered RTEs:
3062              if (is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_reg']))    {
3063                  foreach($GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_reg'] as $extKey => $rteObjCfg)    {
3064                      $rteObj = &t3lib_div::getUserObj($rteObjCfg['objRef']);
3065                      if (is_object($rteObj))    {
3066                          if ($rteObj->isAvailable())    {
3067                              $GLOBALS['T3_VAR']['RTEobj'] = &$rteObj;
3068                              break;
3069                          } else {
3070                              $GLOBALS['T3_VAR']['RTEobj'] = array_merge($GLOBALS['T3_VAR']['RTEobj'], $rteObj->errorLog);
3071                          }
3072                      }
3073                  }
3074              }
3075  
3076              if (!count($GLOBALS['T3_VAR']['RTEobj']))    {
3077                  $GLOBALS['T3_VAR']['RTEobj'][] = 'No RTEs configured at all';
3078              }
3079          }
3080  
3081              // Return RTE object (if any!)
3082          return $GLOBALS['T3_VAR']['RTEobj'];
3083      }
3084  
3085      /**
3086       * Returns soft-reference parser for the softRef processing type
3087       * Usage: $softRefObj = &t3lib_BEfunc::softRefParserObj('[parser key]');
3088       *
3089       * @param    string        softRef parser key
3090       * @return    mixed        If available, returns Soft link parser object.
3091       */
3092      function &softRefParserObj($spKey)    {
3093  
3094              // If no softRef parser object has been set previously, try to create it:
3095          if (!isset($GLOBALS['T3_VAR']['softRefParser'][$spKey]))    {
3096  
3097                  // Set the object string to blank by default:
3098              $GLOBALS['T3_VAR']['softRefParser'][$spKey] = '';
3099  
3100                  // Now, try to create parser object:
3101              $objRef = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser'][$spKey] ?
3102                              $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser'][$spKey] :
3103                              $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser_GL'][$spKey];
3104              if ($objRef)    {
3105                  $softRefParserObj = &t3lib_div::getUserObj($objRef,'');
3106                  if (is_object($softRefParserObj))    {
3107                      $GLOBALS['T3_VAR']['softRefParser'][$spKey] = &$softRefParserObj;
3108                  }
3109              }
3110          }
3111  
3112              // Return RTE object (if any!)
3113          return $GLOBALS['T3_VAR']['softRefParser'][$spKey];
3114      }
3115  
3116      /**
3117       * Returns array of soft parser references
3118       *
3119       * @param    string        softRef parser list
3120       * @param    string        Table name
3121       * @param    string        Field name
3122       * @return    array        Array where the parser key is the key and the value is the parameter string
3123       */
3124  	function explodeSoftRefParserList($parserList)    {
3125  
3126              // Looking for global parsers:
3127          if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser_GL']))    {
3128              $parserList = implode(',',array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser_GL'])).','.$parserList;
3129          }
3130  
3131              // Return immediately if list is blank:
3132          if (!strlen($parserList))    return FALSE;
3133  
3134              // Otherwise parse the list:
3135          $keyList = t3lib_div::trimExplode(',', $parserList, 1);
3136          $output = array();
3137  
3138          foreach($keyList as $val)    {
3139              $reg = array();
3140              if (ereg('^([[:alnum:]_-]+)\[(.*)\]$', $val, $reg))    {
3141                  $output[$reg[1]] = t3lib_div::trimExplode(';', $reg[2], 1);
3142              } else {
3143                  $output[$val] = '';
3144              }
3145          }
3146          return $output;
3147      }
3148  
3149      /**
3150       * Returns true if $modName is set and is found as a main- or submodule in $TBE_MODULES array
3151       * Usage: 1
3152       *
3153       * @param    string        Module name
3154       * @return    boolean
3155       */
3156  	function isModuleSetInTBE_MODULES($modName)    {
3157          reset($GLOBALS['TBE_MODULES']);
3158          $loaded=array();
3159          while(list($mkey,$list)=each($GLOBALS['TBE_MODULES']))    {
3160              $loaded[$mkey]=1;
3161              if (trim($list))    {
3162                  $subList = t3lib_div::trimExplode(',',$list,1);
3163                  while(list(,$skey)=each($subList))    {
3164                      $loaded[$mkey.'_'.$skey]=1;
3165                  }
3166              }
3167          }
3168          return $modName && isset($loaded[$modName]);
3169      }
3170  
3171      /**
3172       * Counting references to a record/file
3173       *
3174       * @param    string        Table name (or "_FILE" if its a file)
3175       * @param    string        Reference: If table, then integer-uid, if _FILE, then file reference (relative to PATH_site)
3176       * @param    string        Message with %s, eg. "There were %s records pointing to this file!"
3177       * @return    string        Output string (or integer count value if no msg string specified)
3178       */
3179  	function referenceCount($table,$ref,$msg='')    {
3180  
3181          if ($table=='_FILE') {
3182  
3183              if (t3lib_div::isFirstPartOfStr($ref,PATH_site))    {
3184                  $ref = substr($ref,strlen(PATH_site));
3185              } else return '';
3186  
3187                  // Look up the path:
3188              list($res) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
3189                  'count(*) as count',
3190                  'sys_refindex',
3191                  'ref_table='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_refindex').
3192                      ' AND ref_string='.$GLOBALS['TYPO3_DB']->fullQuoteStr($ref,'sys_refindex').
3193                      ' AND deleted=0'
3194              );
3195  
3196          } else {
3197                  // Look up the path:
3198              list($res) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
3199                  'count(*) as count',
3200                  'sys_refindex',
3201                  'ref_table='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_refindex').
3202                      ' AND ref_uid='.intval($ref).
3203                      ' AND deleted=0'
3204              );
3205          }
3206  
3207          return $res['count'] ? ($msg ? sprintf($msg,$res['count']) : $res['count']) : '';
3208      }
3209  
3210  
3211  
3212  
3213  
3214  
3215  
3216  
3217  
3218  
3219  
3220  
3221  
3222  
3223      /*******************************************
3224       *
3225       * Workspaces / Versioning
3226       *
3227       *******************************************/
3228  
3229      /**
3230       * Select all versions of a record, ordered by version id (DESC)
3231       *
3232       * @param    string        Table name to select from
3233       * @param    integer        Record uid for which to find versions.
3234       * @param    string        Field list to select
3235       * @param    integer        Workspace ID, if zero all versions regardless of workspace is found.
3236       * @param    boolean        If set, deleted-flagged versions are included! (Only for clean-up script!)
3237       * @return    array        Array of versions of table/uid
3238       */
3239  	function selectVersionsOfRecord($table, $uid, $fields='*', $workspace=0, $includeDeletedRecords=FALSE)    {
3240          global $TCA;
3241  
3242          if ($TCA[$table] && $TCA[$table]['ctrl']['versioningWS'])    {
3243  
3244                  // Select all versions of record:
3245              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
3246                  $fields,
3247                  $table,
3248                  '((t3ver_oid='.intval($uid).($workspace!=0?' AND t3ver_wsid='.intval($workspace):'').') OR uid='.intval($uid).')'.
3249                      ($includeDeletedRecords ? '' : t3lib_BEfunc::deleteClause($table)),
3250                  '',
3251                  't3ver_id DESC'
3252              );
3253  
3254                  // Add rows to output array:
3255              $realPid = 0;
3256              $outputRows = array();
3257              while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
3258                  if ($uid==$row['uid'])    {
3259                      $row['_CURRENT_VERSION']=TRUE;
3260                      $realPid = $row['pid'];
3261                  }
3262                  $outputRows[] = $row;
3263              }
3264  
3265                  // Set real-pid:
3266              foreach($outputRows as $idx => $oRow)    {
3267                  $outputRows[$idx]['_REAL_PID'] = $realPid;
3268              }
3269  
3270              return $outputRows;
3271          }
3272      }
3273  
3274      /**
3275       * Find page-tree PID for versionized record
3276       * Will look if the "pid" value of the input record is -1 and if the table supports versioning - if so, it will translate the -1 PID into the PID of the original record
3277       * Used whenever you are tracking something back, like making the root line.
3278       * Will only translate if the workspace of the input record matches that of the current user (unless flag set)
3279       * Principle; Record offline! => Find online?
3280       *
3281       * @param    string        Table name
3282       * @param    array        Record array passed by reference. As minimum, "pid" and "uid" fields must exist! "t3ver_oid" and "t3ver_wsid" is nice and will save you a DB query.
3283       * @param    boolean        Ignore workspace match
3284       * @return    void        (Passed by ref). If the record had its pid corrected to the online versions pid, then "_ORIG_pid" is set to the original pid value (-1 of course). The field "_ORIG_pid" is used by various other functions to detect if a record was in fact in a versionized branch.
3285       * @see t3lib_page::fixVersioningPid()
3286       */
3287  	function fixVersioningPid($table,&$rr,$ignoreWorkspaceMatch=FALSE)    {
3288          global $TCA;
3289  
3290              // Check that the input record is an offline version from a table that supports versioning:
3291          if (is_array($rr) && $rr['pid']==-1 && $TCA[$table]['ctrl']['versioningWS'])    {
3292  
3293                  // Check values for t3ver_oid and t3ver_wsid:
3294              if (isset($rr['t3ver_oid']) && isset($rr['t3ver_wsid']))    {    // If "t3ver_oid" is already a field, just set this:
3295                  $oid = $rr['t3ver_oid'];
3296                  $wsid = $rr['t3ver_wsid'];
3297              } else {    // Otherwise we have to expect "uid" to be in the record and look up based on this:
3298                  $newPidRec = t3lib_BEfunc::getRecord($table,$rr['uid'],'t3ver_oid,t3ver_wsid');
3299                  if (is_array($newPidRec))    {
3300                      $oid = $newPidRec['t3ver_oid'];
3301                      $wsid = $newPidRec['t3ver_wsid'];
3302                  }
3303              }
3304  
3305                  // If ID of current online version is found, look up the PID value of that:
3306              if ($oid && ($ignoreWorkspaceMatch || !strcmp((int)$wsid,$GLOBALS['BE_USER']->workspace)))    {
3307                  $oidRec = t3lib_BEfunc::getRecord($table,$oid,'pid');
3308                  if (is_array($oidRec))    {
3309                      $rr['_ORIG_pid'] = $rr['pid'];
3310                      $rr['pid'] = $oidRec['pid'];
3311                  }
3312              }
3313          }
3314      }
3315  
3316      /**
3317       * Workspace Preview Overlay
3318       * Generally ALWAYS used when records are selected based on uid or pid. If records are selected on other fields than uid or pid (eg. "email = ....") then usage might produce undesired results and that should be evaluated on individual basis.
3319       * Principle; Record online! => Find offline?
3320       *
3321       * @param    string        Table name
3322       * @param    array        Record array passed by reference. As minimum, the "uid", "pid" and "t3ver_swapmode" (pages) fields must exist! Fake fields cannot exist since the fields in the array is used as field names in the SQL look up.
3323       * @param    integer        Workspace ID, if not specified will use $GLOBALS['BE_USER']->workspace
3324       * @return    void        (Passed by ref).
3325       * @see fixVersioningPid()
3326       */
3327  	function workspaceOL($table,&$row,$wsid=-99)    {
3328  
3329              // Initialize workspace ID:
3330          if ($wsid == -99)    $wsid = $GLOBALS['BE_USER']->workspace;
3331  
3332              // Check if workspace is different from zero and record is set:
3333          if ($wsid!==0 && is_array($row))    {
3334              $wsAlt = t3lib_BEfunc::getWorkspaceVersionOfRecord($wsid, $table, $row['uid'], implode(',',array_keys($row)));
3335  
3336                  // If version was found, swap the default record with that one.
3337              if (is_array($wsAlt))    {
3338  
3339                      // Always correct PID from -1 to what it should be:
3340                  if (isset($wsAlt['pid']))    {
3341                      $wsAlt['_ORIG_pid'] = $wsAlt['pid'];    // Keep the old (-1) - indicates it was a version...
3342                      $wsAlt['pid'] = $row['pid'];        // Set in the online versions PID.
3343                  }
3344  
3345                      // For versions of single elements or page+content, swap UID and PID:
3346                  if ($table!=='pages' || $wsAlt['t3ver_swapmode']<=0)    {
3347                      $wsAlt['_ORIG_uid'] = $wsAlt['uid'];
3348                      $wsAlt['uid'] = $row['uid'];
3349  
3350                          // Backend css class:
3351                      $wsAlt['_CSSCLASS'] = $table==='pages' && $wsAlt['t3ver_swapmode']==0 ? 'ver-page' : 'ver-element';
3352                  } else {    // This is only for page-versions with BRANCH below!
3353                      $wsAlt['_ONLINE_uid'] = $row['uid'];
3354  
3355                          // Backend css class:
3356                      $wsAlt['_CSSCLASS'] = 'ver-branchpoint';
3357                      $wsAlt['_SUBCSSCLASS'] = 'ver-branch';
3358                  }
3359  
3360                      // Changing input record to the workspace version alternative:
3361                  $row = $wsAlt;
3362              }
3363          }
3364      }
3365  
3366      /**
3367       * Select the workspace version of a record, if exists
3368       *
3369       * @param    integer        Workspace ID
3370       * @param    string        Table name to select from
3371       * @param    integer        Record uid for which to find workspace version.
3372       * @param    string        Field list to select
3373       * @return    array        If found, return record, otherwise false
3374       */
3375  	function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields='*')    {
3376          global $TCA;
3377  
3378          if ($workspace!==0 && $TCA[$table] && $TCA[$table]['ctrl']['versioningWS'])    {
3379  
3380                  // Select workspace version of record:
3381              $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
3382                  $fields,
3383                  $table,
3384                  'pid=-1 AND
3385                   t3ver_oid='.intval($uid).' AND
3386                   t3ver_wsid='.intval($workspace).
3387                      t3lib_BEfunc::deleteClause($table)
3388              );
3389  
3390              if (is_array($rows[0]))    return $rows[0];
3391          }
3392  
3393          return FALSE;
3394      }
3395  
3396      /**
3397       * Returns live version of record
3398       *
3399       * @param    string        Table name
3400       * @param    integer        Record UID of draft, offline version
3401       * @param    string        Field list, default is *
3402       * @return    array        If found, the record, otherwise nothing.
3403       */
3404  	function getLiveVersionOfRecord($table,$uid,$fields='*')    {
3405          global $TCA;
3406  
3407              // Check that table supports versioning:
3408          if ($TCA[$table] && $TCA[$table]['ctrl']['versioningWS'])    {
3409              $rec = t3lib_BEfunc::getRecord($table,$uid,'pid,t3ver_oid');
3410  
3411              if ($rec['pid']==-1)    {
3412                  return t3lib_BEfunc::getRecord($table,$rec['t3ver_oid'],$fields);
3413              }
3414          }
3415      }
3416  
3417      /**
3418       * Will fetch the rootline for the pid, then check if anywhere in the rootline there is a branch point and if so everything is allowed of course.
3419       * Alternatively; if the page of the PID itself is a version and swapmode is zero (page+content) then tables from versioning_followPages are allowed as well.
3420       *
3421       * @param    integer        Page id inside of which you want to edit/create/delete something.
3422       * @param    string        Table name you are checking for. If you don't give the table name ONLY "branch" types are found and returned true. Specifying table you might also get a positive response if the pid is a "page" versioning type AND the table has "versioning_followPages" set.
3423       * @param    boolean        If set, the keyword "branchpoint" or "first" is not returned by rather the "t3ver_stage" value of the branch-point.
3424       * @return    mixed        Returns either "branchpoint" (if branch) or "first" (if page) or false if nothing. Alternatively, it returns the value of "t3ver_stage" for the branchpoint (if any)
3425       */
3426  	function isPidInVersionizedBranch($pid, $table='',$returnStage=FALSE)    {
3427          $rl = t3lib_BEfunc::BEgetRootLine($pid);
3428          $c = 0;
3429  
3430          foreach($rl as $rec)    {
3431              if ($rec['_ORIG_pid']==-1)    {
3432                      // In any case: is it a branchpoint, then OK...
3433                  if ($rec['t3ver_swapmode']>0)    {
3434                      return $returnStage ? (int)$rec['t3ver_stage'] : 'branchpoint';    // OK, we are in a versionized branch
3435                  } elseif ($c==0 && $rec['t3ver_swapmode']==0 && $table && $GLOBALS['TCA'][$table]['ctrl']['versioning_followPages'])    {    // First level: So $table must be versioning_followPages
3436                      return $returnStage ? (int)$rec['t3ver_stage'] : 'first';    // OK, we are in a versionized branch
3437                  }
3438              }
3439              $c++;
3440          }
3441      }
3442  
3443      /**
3444       * Will return where clause de-selecting new-versions from other workspaces.
3445       *
3446       * @param    string        Table name
3447       * @return    string        Where clause if applicable.
3448       */
3449  	function versioningPlaceholderClause($table)    {
3450          if ($GLOBALS['BE_USER']->workspace!==0 && $GLOBALS['TCA'][$table] && $GLOBALS['TCA'][$table]['ctrl']['versioningWS'])    {
3451              return ' AND ('.$table.'.t3ver_state!=1 OR '.$table.'.t3ver_wsid='.intval($GLOBALS['BE_USER']->workspace).')';
3452          }
3453      }
3454  
3455      /**
3456       * Count number of versions on a page
3457       *
3458       * @param    integer        Workspace ID
3459       * @param    integer        Page ID
3460       * @param    boolean        If set, then all tables and not only "versioning_followPages" are found (except other pages)
3461       * @return    array        Overview of records
3462       */
3463  	function countVersionsOfRecordsOnPage($workspace,$pageId, $allTables=FALSE)    {
3464          $output = array();
3465          if ($workspace!=0)    {
3466              foreach($GLOBALS['TCA'] as $tableName => $cfg)    {
3467                  if ($tableName!='pages' && $cfg['ctrl']['versioningWS'] && ($cfg['ctrl']['versioning_followPages'] || $allTables))    {
3468  
3469                          // Select all records from this table in the database from the workspace
3470                          // This joins the online version with the offline version as tables A and B
3471                      $output[$tableName] = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows (
3472                          'B.uid as live_uid, A.uid as offline_uid',
3473                          $tableName.' A,'.$tableName.' B',
3474                          'A.pid=-1'.    // Table A is the offline version and pid=-1 defines offline
3475                              ' AND B.pid='.intval($pageId).
3476                              ' AND A.t3ver_wsid='.intval($workspace).
3477                              ' AND A.t3ver_oid=B.uid'.    // ... and finally the join between the two tables.
3478                              t3lib_BEfunc::deleteClause($tableName,'A').
3479                              t3lib_BEfunc::deleteClause($tableName,'B')
3480                      );
3481  
3482                      if (!is_array($output[$tableName]) || !count($output[$tableName]))    {
3483                          unset($output[$tableName]);
3484                      }
3485                  }
3486              }
3487          }
3488          return $output;
3489      }
3490  
3491      /**
3492       * Performs mapping of new uids to new versions UID in case of import inside a workspace.
3493       *
3494       * @param    string        Table name
3495       * @param    integer        Record uid (of live record placeholder)
3496       * @return    integer        Uid of offline version if any, otherwise live uid.
3497       */
3498  	function wsMapId($table,$uid)    {
3499          if ($wsRec = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace,$table,$uid,'uid'))    {
3500              return $wsRec['uid'];
3501          } else {
3502              return $uid;
3503          }
3504      }
3505  
3506  
3507  
3508  
3509  
3510  
3511  
3512      /*******************************************
3513       *
3514       * Miscellaneous
3515       *
3516       *******************************************/
3517  
3518      /**
3519       * Print error message with header, text etc.
3520       * Usage: 19
3521       *
3522       * @param    string        Header string
3523       * @param    string        Content string
3524       * @param    boolean        Will return an alert() with the content of header and text.
3525       * @param    boolean        Print header.
3526       * @return    void
3527       */
3528  	function typo3PrintError($header,$text,$js='',$head=1)    {
3529              // This prints out a TYPO3 error message.
3530              // If $js is set the message will be output in JavaScript
3531          if ($js)    {
3532              echo "alert('".t3lib_div::slashJS($header.'\n'.$text)."');";
3533          } else {
3534              echo $head?'<html>
3535                  <head>
3536                      <title>Error!</title>
3537                  </head>
3538                  <body bgcolor="white" topmargin="0" leftmargin="0" marginwidth="0" marginheight="0">':'';
3539              echo '<div align="center">
3540                      <table border="0" cellspacing="0" cellpadding="0" width="333">
3541                          <tr>
3542                              <td align="center">'.
3543                                  ($GLOBALS['TBE_STYLES']['logo_login']?'<img src="'.$GLOBALS['BACK_PATH'].$GLOBALS['TBE_STYLES']['logo_login'].'" alt="" />':'<img src="'.$GLOBALS['BACK_PATH'].'gfx/typo3logo.gif" width="123" height="34" vspace="10" />').
3544                              '</td>
3545                          </tr>
3546                          <tr>
3547                              <td bgcolor="black">
3548                                  <table width="100%" border="0" cellspacing="1" cellpadding="10">
3549                                      <tr>
3550                                          <td bgcolor="#F4F0E8">
3551                                              <font face="verdana,arial,helvetica" size="2">';
3552              echo '<b><center><font size="+1">'.$header.'</font></center></b><br />'.$text;
3553              echo '                            </font>
3554                                          </td>
3555                                      </tr>
3556                                  </table>
3557                              </td>
3558                          </tr>
3559                      </table>
3560                  </div>';
3561              echo $head?'
3562                  </body>
3563              </html>':'';
3564          }
3565      }
3566  
3567      /**
3568       * Prints TYPO3 Copyright notice for About Modules etc. modules.
3569       *
3570       * @return    void
3571       */
3572  	function TYPO3_copyRightNotice()    {
3573          global $TYPO3_CONF_VARS;
3574  
3575              // COPYRIGHT NOTICE:
3576          $loginCopyrightWarrantyProvider = strip_tags(trim($TYPO3_CONF_VARS['SYS']['loginCopyrightWarrantyProvider']));
3577          $loginCopyrightWarrantyURL = strip_tags(trim($TYPO3_CONF_VARS['SYS']['loginCopyrightWarrantyURL']));
3578  
3579          if (strlen($loginCopyrightWarrantyProvider)>=2 && strlen($loginCopyrightWarrantyURL)>=10)    {
3580              $warrantyNote='Warranty is supplied by '.htmlspecialchars($loginCopyrightWarrantyProvider).'; <a href="'.htmlspecialchars($loginCopyrightWarrantyURL).'" target="_blank">click for details.</a>';
3581          } else {
3582              $warrantyNote='TYPO3 comes with ABSOLUTELY NO WARRANTY; <a href="http://typo3.com/1316.0.html" target="_blank">click for details.</a>';
3583          }
3584          $cNotice = '<a href="http://typo3.com/" target="_blank"><img src="gfx/loginlogo_transp.gif" width="75" vspace="2" hspace="4" height="19" alt="TYPO3 logo" align="left" />TYPO3 CMS ver. '.htmlspecialchars(TYPO3_version).'</a>. Copyright &copy; '.htmlspecialchars(TYPO3_copyright_year).' Kasper Sk&aring;rh&oslash;j. Extensions are copyright of their respective owners. Go to <a href="http://typo3.com/" target="_blank">http://typo3.com/</a> for details.
3585          '.strip_tags($warrantyNote,'<a>').' This is free software, and you are welcome to redistribute it under certain conditions; <a href="http://typo3.com/1316.0.html" target="_blank">click for details</a>. Obstructing the appearance of this notice is prohibited by law.';
3586  
3587          return $cNotice;
3588      }
3589  
3590      /**
3591       * Display some warning messages if this installation is obviously insecure!!
3592       * These warnings are only displayed to admin users
3593       *
3594       * @return    void
3595       */
3596  	function displayWarningMessages()    {
3597          if ($GLOBALS['BE_USER']->isAdmin())    {
3598              $warnings = array();
3599  
3600                  // Check if the Install Tool Password is still default: joh316
3601              if ($GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']==md5('joh316'))    {
3602                  $warnings[] = 'The password of your Install Tool is still using the default value "joh316"';
3603              }
3604  
3605                  // Check if there is still a default user 'admin' with password 'password' (MD5sum = 5f4dcc3b5aa765d61d8327deb882cf99)
3606              $where_clause = 'username='.$GLOBALS['TYPO3_DB']->fullQuoteStr('admin','be_users').' AND password='.$GLOBALS['TYPO3_DB']->fullQuoteStr('5f4dcc3b5aa765d61d8327deb882cf99','be_users').t3lib_BEfunc::deleteClause('be_users');
3607              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('username, password', 'be_users', $where_clause);
3608              if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))    {
3609                  $warnings[] = 'The backend user "admin" with password "password" is still existing';
3610              }
3611  
3612                  // Check if the Install Tool is enabled
3613              $enableInstallToolFile = PATH_site.'typo3conf/ENABLE_INSTALL_TOOL';
3614              if (@is_file($enableInstallToolFile))    {
3615                  $warnings[] = 'The Install Tool is enabled. Make sure to delete the file "'.$enableInstallToolFile.'" when you have finished setting up TYPO3';
3616              }
3617  
3618                  // Check if the encryption key is empty
3619              if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] == '')    {
3620                  $url = 'install/index.php?redirect_url=index.php'.urlencode('?TYPO3_INSTALL[type]=config#set_encryptionKey');
3621                  $warnings[] = 'The encryption key is not set! Set it in <a href="'.$url.'">$TYPO3_CONF_VARS[SYS][encryptionKey]</a>';
3622              }
3623  
3624                  // Check if there are still updates to perform
3625              if (!t3lib_div::compat_version(TYPO3_branch))    {
3626                  $url = 'install/index.php?redirect_url=index.php'.urlencode('?TYPO3_INSTALL[type]=update');
3627                  $warnings[] = 'This installation is not configured for the TYPO3 version it is running. You probably did so by intention, in this case you can safely ignore this message. If unsure, visit the <a href="'.$url.'" target="_blank">Update Wizard</a> in the Install Tool to see which changes would be affected.';
3628              }
3629  
3630                  // Check if sys_refindex is empty
3631              list($count) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('count(*) as rcount','sys_refindex','1=1');
3632              if (!$count['rcount'])    {
3633                  $warnings[] = 'The Reference Index table is empty which is likely to be the case because you just upgraded your TYPO3 source. Please go to Tools>DB Check and update the reference index.';
3634              }
3635  
3636              if (count($warnings))    {
3637                  $style = ' style="margin-bottom:10px;"';
3638                  $content = '<table border="0" cellpadding="0" cellspacing="0" class="warningbox"><tr><td>'.
3639                      $GLOBALS['TBE_TEMPLATE']->icons(3).'Important notice!<br /><ul><li'.$style.'>'.
3640                      implode('</li><li'.$style.'>', $warnings).'</li></ul>'.
3641                      'It is highly recommended that you change this immediately.'.
3642                      '</td></tr></table>';
3643  
3644                  unset($warnings);
3645                  return $content;
3646              }
3647          }
3648          return '<p>&nbsp;</p>';
3649      }
3650  
3651      /**
3652       * Returns "web" if the $path (absolute) is within the DOCUMENT ROOT - and thereby qualifies as a "web" folder.
3653       * Usage: 4
3654       *
3655       * @param    string        Path to evaluate
3656       * @return    boolean
3657       */
3658  	function getPathType_web_nonweb($path)    {
3659          return t3lib_div::isFirstPartOfStr($path,t3lib_div::getIndpEnv('TYPO3_DOCUMENT_ROOT')) ? 'web' : '';
3660      }
3661  
3662      /**
3663       * Creates ADMCMD parameters for the "viewpage" extension / "cms" frontend
3664       * Usage: 1
3665       *
3666       * @param    array        Page record
3667       * @return    string        Query-parameters
3668       * @internal
3669       */
3670  	function ADMCMD_previewCmds($pageinfo)    {
3671          if ($pageinfo['fe_group']>0)    {
3672              $simUser = '&ADMCMD_simUser='.$pageinfo['fe_group'];
3673          }
3674          if ($pageinfo['starttime']>time())    {
3675              $simTime = '&ADMCMD_simTime='.$pageinfo['starttime'];
3676          }
3677          if ($pageinfo['endtime']<time() && $pageinfo['endtime']!=0)    {
3678              $simTime = '&ADMCMD_simTime='.($pageinfo['endtime']-1);
3679          }
3680          return $simUser.$simTime;
3681      }
3682  
3683      /**
3684       * Returns an array with key=>values based on input text $params
3685       * $params is exploded by line-breaks and each line is supposed to be on the syntax [key] = [some value]
3686       * These pairs will be parsed into an array an returned.
3687       * Usage: 1
3688       *
3689       * @param    string        String of parameters on multiple lines to parse into key-value pairs (see function description)
3690       * @return    array
3691       */
3692  	function processParams($params)    {
3693          $paramArr=array();
3694          $lines=explode(chr(10),$params);
3695          while(list(,$val)=each($lines))    {
3696              $val = trim($val);
3697              if ($val)    {
3698                  $pair = explode('=',$val,2);
3699                  $paramArr[trim($pair[0])] = trim($pair[1]);
3700              }
3701          }
3702          return $paramArr;
3703      }
3704  
3705      /**
3706       * Returns "list of backend modules". Most likely this will be obsolete soon / removed. Don't use.
3707       * Usage: 3
3708       *
3709       * @param    array        Module names in array. Must be "addslashes()"ed
3710       * @param    string        Perms clause for SQL query
3711       * @param    string        Backpath
3712       * @param    string        The URL/script to jump to (used in A tag)
3713       * @return    array        Two keys, rows and list
3714       * @internal
3715       * @deprecated
3716       * @obsolete
3717       */
3718  	function getListOfBackendModules($name,$perms_clause,$backPath='',$script='index.php')    {
3719          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'doktype!=255 AND module IN (\''.implode('\',\'',$name).'\') AND'.$perms_clause.t3lib_BEfunc::deleteClause('pages'));
3720          if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res))    return false;
3721  
3722          $out='';
3723          $theRows=array();
3724          while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
3725              $theRows[]=$row;
3726              $out.='<span class="nobr"><a href="'.htmlspecialchars($script.'?id='.$row['uid']).'">'.
3727                      t3lib_iconWorks::getIconImage('pages',$row,$backPath,'title="'.htmlspecialchars(t3lib_BEfunc::getRecordPath($row['uid'],$perms_clause,20)).'" align="top"').
3728                      htmlspecialchars($row['title']).
3729                      '</a></span><br />';
3730          }
3731          return array('rows'=>$theRows,'list'=>$out);
3732      }
3733  }
3734  ?>


Généré le : Sun Nov 25 17:13:16 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics