class.t3lib_befunc.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 /**
00028  * Standard functions available for the TYPO3 backend.
00029  * You are encouraged to use this class in your own applications (Backend Modules)
00030  *
00031  * Call ALL methods without making an object!
00032  * Eg. to get a page-record 51 do this: 't3lib_BEfunc::getRecord('pages',51)'
00033  *
00034  * $Id: class.t3lib_befunc.php 4486 2008-11-25 08:51:53Z steffenk $
00035  * Usage counts are based on search 22/2 2003 through whole backend source of typo3/
00036  * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
00037  * XHTML compliant
00038  *
00039  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00040  */
00041 /**
00042  * [CLASS/FUNCTION INDEX of SCRIPT]
00043  *
00044  *
00045  *
00046  *  185: class t3lib_BEfunc
00047  *
00048  *              SECTION: SQL-related, selecting records, searching
00049  *  206:     function deleteClause($table,$tableAlias='')
00050  *  230:     function getRecord($table,$uid,$fields='*',$where='',$useDeleteClause=true)
00051  *  253:     function getRecordWSOL($table,$uid,$fields='*',$where='',$useDeleteClause=true)
00052  *  286:     function getRecordRaw($table,$where='',$fields='*')
00053  *  309:     function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='',$useDeleteClause=true)
00054  *  342:     function searchQuery($searchWords,$fields,$table='')
00055  *  357:     function listQuery($field,$value)
00056  *  369:     function splitTable_Uid($str)
00057  *  384:     function getSQLselectableList($in_list,$tablename,$default_tablename)
00058  *  412:     function BEenableFields($table,$inv=0)
00059  *
00060  *              SECTION: SQL-related, DEPRECATED functions
00061  *  476:     function mm_query($select,$local_table,$mm_table,$foreign_table,$whereClause='',$groupBy='',$orderBy='',$limit='')
00062  *  498:     function DBcompileInsert($table,$fields_values)
00063  *  512:     function DBcompileUpdate($table,$where,$fields_values)
00064  *
00065  *              SECTION: Page tree, TCA related
00066  *  542:     function BEgetRootLine($uid,$clause='',$workspaceOL=FALSE)
00067  *  598:     function openPageTree($pid,$clearExpansion)
00068  *  643:     function getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
00069  *  686:     function getExcludeFields()
00070  *  716:     function getExplicitAuthFieldValues()
00071  *  787:     function getSystemLanguages()
00072  *  812:     function readPageAccess($id,$perms_clause)
00073  *  843:     function getTCAtypes($table,$rec,$useFieldNameAsKey=0)
00074  *  896:     function getTCAtypeValue($table,$rec)
00075  *  919:     function getSpecConfParts($str, $defaultExtras)
00076  *  950:     function getSpecConfParametersFromArray($pArr)
00077  *  978:     function getFlexFormDS($conf,$row,$table,$fieldName='',$WSOL=TRUE)
00078  *
00079  *              SECTION: Caching related
00080  * 1105:     function storeHash($hash,$data,$ident)
00081  * 1125:     function getHash($hash)
00082  *
00083  *              SECTION: TypoScript related
00084  * 1161:     function getPagesTSconfig($id,$rootLine='',$returnPartArray=0)
00085  * 1217:     function updatePagesTSconfig($id,$pageTS,$TSconfPrefix,$impParams='')
00086  * 1272:     function implodeTSParams($p,$k='')
00087  *
00088  *              SECTION: Users / Groups related
00089  * 1309:     function getUserNames($fields='username,usergroup,usergroup_cached_list,uid',$where='')
00090  * 1327:     function getGroupNames($fields='title,uid', $where='')
00091  * 1344:     function getListGroupNames($fields='title,uid')
00092  * 1363:     function blindUserNames($usernames,$groupArray,$excludeBlindedFlag=0)
00093  * 1396:     function blindGroupNames($groups,$groupArray,$excludeBlindedFlag=0)
00094  *
00095  *              SECTION: Output related
00096  * 1437:     function daysUntil($tstamp)
00097  * 1449:     function date($tstamp)
00098  * 1460:     function datetime($value)
00099  * 1472:     function time($value)
00100  * 1488:     function calcAge($seconds,$labels = 'min|hrs|days|yrs')
00101  * 1514:     function dateTimeAge($tstamp,$prefix=1,$date='')
00102  * 1532:     function titleAttrib($content='',$hsc=0)
00103  * 1545:     function titleAltAttrib($content)
00104  * 1569:     function thumbCode($row,$table,$field,$backPath,$thumbScript='',$uploaddir=NULL,$abs=0,$tparams='',$size='')
00105  * 1637:     function getThumbNail($thumbScript,$theFile,$tparams='',$size='')
00106  * 1654:     function titleAttribForPages($row,$perms_clause='',$includeAttrib=1)
00107  * 1716:     function getRecordIconAltText($row,$table='pages')
00108  * 1758:     function getLabelFromItemlist($table,$col,$key)
00109  * 1784:     function getItemLabel($table,$col,$printAllWrap='')
00110  * 1809:     function getRecordTitle($table,$row,$prep=0)
00111  * 1847:     function getProcessedValue($table,$col,$value,$fixed_lgd_chars=0,$defaultPassthrough=0,$noRecordLookup=FALSE,$uid=0)
00112  * 2009:     function getProcessedValueExtra($table,$fN,$fV,$fixed_lgd_chars=0,$uid=0)
00113  * 2033:     function getFileIcon($ext)
00114  * 2047:     function getCommonSelectFields($table,$prefix='')
00115  * 2090:     function makeConfigForm($configArray,$defaults,$dataPrefix)
00116  *
00117  *              SECTION: Backend Modules API functions
00118  * 2165:     function helpTextIcon($table,$field,$BACK_PATH,$force=0)
00119  * 2187:     function helpText($table,$field,$BACK_PATH,$styleAttrib='')
00120  * 2239:     function cshItem($table,$field,$BACK_PATH,$wrap='',$onlyIconMode=FALSE, $styleAttrib='')
00121  * 2277:     function editOnClick($params,$backPath='',$requestUri='')
00122  * 2296:     function viewOnClick($id,$backPath='',$rootLine='',$anchor='',$altUrl='',$addGetVars='',$switchFocus=TRUE)
00123  * 2328:     function getModTSconfig($id,$TSref)
00124  * 2349:     function getFuncMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='')
00125  * 2392:     function getFuncCheck($mainParams,$elementName,$currentValue,$script='',$addparams='',$tagParams='')
00126  * 2417:     function getFuncInput($mainParams,$elementName,$currentValue,$size=10,$script="",$addparams="")
00127  * 2438:     function unsetMenuItems($modTSconfig,$itemArray,$TSref)
00128  * 2461:     function getSetUpdateSignal($set='')
00129  * 2512:     function getModuleData($MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='')
00130  *
00131  *              SECTION: Core
00132  * 2585:     function compilePreviewKeyword($getVarsStr, $beUserUid, $ttl=172800)
00133  * 2613:     function lockRecords($table='',$uid=0,$pid=0)
00134  * 2642:     function isRecordLocked($table,$uid)
00135  * 2682:     function exec_foreign_table_where_query($fieldValue,$field='',$TSconfig=array(),$prefix='')
00136  * 2763:     function getTCEFORM_TSconfig($table,$row)
00137  * 2814:     function getTSconfig_pidValue($table,$uid,$pid)
00138  * 2844:     function getPidForModTSconfig($table,$uid,$pid)
00139  * 2860:     function getTSCpid($table,$uid,$pid)
00140  * 2876:     function firstDomainRecord($rootLine)
00141  * 2898:     function getDomainStartPage($domain, $path='')
00142  * 2928:     function RTEsetup($RTEprop,$table,$field,$type='')
00143  * 2947:     function &RTEgetObj()
00144  * 2986:     function &softRefParserObj($spKey)
00145  * 3018:     function explodeSoftRefParserList($parserList)
00146  * 3050:     function isModuleSetInTBE_MODULES($modName)
00147  * 3073:     function referenceCount($table,$ref,$msg='')
00148  *
00149  *              SECTION: Workspaces / Versioning
00150  * 3132:     function selectVersionsOfRecord($table, $uid, $fields='*', $workspace=0)
00151  * 3180:     function fixVersioningPid($table,&$rr,$ignoreWorkspaceMatch=FALSE)
00152  * 3220:     function workspaceOL($table,&$row,$wsid=-99)
00153  * 3268:     function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields='*')
00154  * 3297:     function getLiveVersionOfRecord($table,$uid,$fields='*')
00155  * 3319:     function isPidInVersionizedBranch($pid, $table='',$returnStage=FALSE)
00156  * 3342:     function versioningPlaceholderClause($table)
00157  * 3356:     function countVersionsOfRecordsOnPage($workspace,$pageId, $allTables=FALSE)
00158  * 3391:     function wsMapId($table,$uid)
00159  *
00160  *              SECTION: Miscellaneous
00161  * 3421:     function typo3PrintError($header,$text,$js='',$head=1)
00162  * 3465:     function TYPO3_copyRightNotice()
00163  * 3489:     function displayWarningMessages()
00164  * 3546:     function getPathType_web_nonweb($path)
00165  * 3558:     function ADMCMD_previewCmds($pageinfo)
00166  * 3580:     function processParams($params)
00167  * 3606:     function getListOfBackendModules($name,$perms_clause,$backPath='',$script='index.php')
00168  *
00169  * TOTAL FUNCTIONS: 99
00170  * (This index is automatically created/updated by the extension "extdeveval")
00171  *
00172  */
00173 
00174 require_once (PATH_t3lib.'class.t3lib_loaddbgroup.php');
00175 
00176 
00177 /**
00178  * Standard functions available for the TYPO3 backend.
00179  * Don't instantiate - call functions with "t3lib_BEfunc::" prefixed the function name.
00180  *
00181  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00182  * @package TYPO3
00183  * @subpackage t3lib
00184  */
00185 final class t3lib_BEfunc {
00186 
00187 
00188 
00189     /*******************************************
00190      *
00191      * SQL-related, selecting records, searching
00192      *
00193      *******************************************/
00194 
00195 
00196     /**
00197      * Returns the WHERE clause " AND NOT [tablename].[deleted-field]" if a deleted-field is configured in $TCA for the tablename, $table
00198      * 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!)
00199      * 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.
00200      * Usage: 71
00201      *
00202      * @param   string      Table name present in $TCA
00203      * @param   string      Table alias if any
00204      * @return  string      WHERE clause for filtering out deleted records, eg " AND tablename.deleted=0"
00205      */
00206     public static function deleteClause($table,$tableAlias = '') {
00207         global $TCA;
00208         if ($TCA[$table]['ctrl']['delete']) {
00209             return ' AND '.($tableAlias ? $tableAlias : $table).'.'.$TCA[$table]['ctrl']['delete'].'=0';
00210         } else {
00211             return '';
00212         }
00213     }
00214 
00215     /**
00216      * Gets record with uid = $uid from $table
00217      * You can set $field to a list of fields (default is '*')
00218      * Additional WHERE clauses can be added by $where (fx. ' AND blabla = 1')
00219      * Will automatically check if records has been deleted and if so, not return anything.
00220      * $table must be found in $TCA
00221      * Usage: 99
00222      *
00223      * @param   string      Table name present in $TCA
00224      * @param   integer     UID of record
00225      * @param   string      List of fields to select
00226      * @param   string      Additional WHERE clause, eg. " AND blablabla = 0"
00227      * @param   boolean     Use the deleteClause to check if a record is deleted (default true)
00228      * @return  array       Returns the row if found, otherwise nothing
00229      */
00230     public static function getRecord($table, $uid, $fields = '*', $where = '', $useDeleteClause = true) {
00231         if ($GLOBALS['TCA'][$table]) {
00232             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00233                 $fields,
00234                 $table,
00235                 'uid='.intval($uid).($useDeleteClause ? t3lib_BEfunc::deleteClause($table) : '').$where
00236             );
00237             $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00238             $GLOBALS['TYPO3_DB']->sql_free_result($res);
00239             if ($row) {
00240                 return $row;
00241             }
00242         }
00243     }
00244 
00245     /**
00246      * Like getRecord(), but overlays workspace version if any.
00247      *
00248      * @param   string      Table name present in $TCA
00249      * @param   integer     UID of record
00250      * @param   string      List of fields to select
00251      * @param   string      Additional WHERE clause, eg. " AND blablabla = 0"
00252      * @param   boolean     Use the deleteClause to check if a record is deleted (default true)
00253      * @return  array       Returns the row if found, otherwise nothing
00254      */
00255     public static function getRecordWSOL($table, $uid, $fields = '*', $where = '', $useDeleteClause = true) {
00256         if ($fields !== '*') {
00257             $internalFields = t3lib_div::uniqueList($fields.',uid,pid'.($table == 'pages' ? ',t3ver_swapmode' : ''));
00258             $row = t3lib_BEfunc::getRecord($table, $uid, $internalFields, $where, $useDeleteClause);
00259             t3lib_BEfunc::workspaceOL($table, $row);
00260 
00261             if (is_array ($row)) {
00262                 foreach (array_keys($row) as $key) {
00263                     if (!t3lib_div::inList($fields, $key) && $key{0} !== '_') {
00264                         unset ($row[$key]);
00265                     }
00266                 }
00267             }
00268         } else {
00269             $row = t3lib_BEfunc::getRecord($table, $uid, $fields, $where);
00270             t3lib_BEfunc::workspaceOL($table, $row);
00271         }
00272         return $row;
00273     }
00274 
00275     /**
00276      * Returns the first record found from $table with $where as WHERE clause
00277      * This function does NOT check if a record has the deleted flag set.
00278      * $table does NOT need to be configured in $TCA
00279      * The query used is simply this:
00280      * $query = 'SELECT '.$fields.' FROM '.$table.' WHERE '.$where;
00281      * Usage: 5 (ext: sys_todos)
00282      *
00283      * @param   string      Table name (not necessarily in TCA)
00284      * @param   string      WHERE clause
00285      * @param   string      $fields is a list of fields to select, default is '*'
00286      * @return  array       First row found, if any, FALSE otherwise
00287      */
00288     public static function getRecordRaw($table, $where = '', $fields = '*') {
00289         $row = FALSE;
00290         if (FALSE !== ($res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, $where, '', '', '1'))) {
00291             $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00292             $GLOBALS['TYPO3_DB']->sql_free_result($res);
00293         }
00294         return $row;
00295     }
00296 
00297     /**
00298      * Returns records from table, $theTable, where a field ($theField) equals the value, $theValue
00299      * The records are returned in an array
00300      * If no records were selected, the function returns nothing
00301      * Usage: 8
00302      *
00303      * @param   string      Table name present in $TCA
00304      * @param   string      Field to select on
00305      * @param   string      Value that $theField must match
00306      * @param   string      Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
00307      * @param   string      Optional GROUP BY field(s), if none, supply blank string.
00308      * @param   string      Optional ORDER BY field(s), if none, supply blank string.
00309      * @param   string      Optional LIMIT value ([begin,]max), if none, supply blank string.
00310      * @param   boolean     Use the deleteClause to check if a record is deleted (default true)
00311      * @return  mixed       Multidimensional array with selected records (if any is selected)
00312      */
00313     public static function getRecordsByField($theTable, $theField, $theValue, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '', $useDeleteClause = true) {
00314         global $TCA;
00315         if (is_array($TCA[$theTable])) {
00316             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00317                         '*',
00318                         $theTable,
00319                         $theField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($theValue, $theTable).
00320                             ($useDeleteClause ? t3lib_BEfunc::deleteClause($theTable).' ' : '').
00321                             t3lib_BEfunc::versioningPlaceholderClause($theTable).' '.
00322                             $whereClause,   // whereClauseMightContainGroupOrderBy
00323                         $groupBy,
00324                         $orderBy,
00325                         $limit
00326                     );
00327             $rows = array();
00328             while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00329                 $rows[] = $row;
00330             }
00331             $GLOBALS['TYPO3_DB']->sql_free_result($res);
00332             if (count($rows))   return $rows;
00333         }
00334     }
00335 
00336     /**
00337      * 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.
00338      * Usage: 0
00339      *
00340      * @param   array       Array of search words
00341      * @param   array       Array of fields
00342      * @param   string      Table in which we are searching (for DBAL detection of quoteStr() method)
00343      * @return  string      WHERE clause for search
00344      * @deprecated since TYPO3 4.0 - Use $GLOBALS['TYPO3_DB']->searchQuery() directly!
00345      */
00346     public static function searchQuery($searchWords, $fields, $table = '') {
00347         return $GLOBALS['TYPO3_DB']->searchQuery($searchWords, $fields, $table);
00348     }
00349 
00350     /**
00351      * Returns a WHERE clause that can find a value ($value) in a list field ($field)
00352      * 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).
00353      * Is nice to look up list-relations to records or files in TYPO3 database tables.
00354      * Usage: 0
00355      *
00356      * @param   string      Table field name
00357      * @param   string      Value to find in list
00358      * @return  string      WHERE clause for a query
00359      * @deprecated since TYPO3 4.0 - Use $GLOBALS['TYPO3_DB']->listQuery() directly!
00360      */
00361     public static function listQuery($field, $value) {
00362         return $GLOBALS['TYPO3_DB']->listQuery($field, $value, '');
00363     }
00364 
00365     /**
00366      * Makes an backwards explode on the $str and returns an array with ($table, $uid).
00367      * Example: tt_content_45 => array('tt_content', 45)
00368      * Usage: 1
00369      *
00370      * @param   string      [tablename]_[uid] string to explode
00371      * @return  array
00372      */
00373     public static function splitTable_Uid($str) {
00374         list($uid, $table) = explode('_', strrev($str), 2);
00375         return array(strrev($table), strrev($uid));
00376     }
00377 
00378     /**
00379      * Returns a list of pure integers based on $in_list being a list of records with table-names prepended.
00380      * 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.
00381      * Usage: 1 (t3lib_userauthgroup)
00382      *
00383      * @param   string      Input list
00384      * @param   string      Table name from which ids is returned
00385      * @param   string      $default_tablename denotes what table the number '45' is from (if nothing is prepended on the value)
00386      * @return  string      List of ids
00387      */
00388     public static function getSQLselectableList($in_list, $tablename, $default_tablename) {
00389         $list = Array();
00390         if ((string)trim($in_list)!='') {
00391             $tempItemArray = explode(',', trim($in_list));
00392             while(list($key, $val) = each($tempItemArray)) {
00393                 $val = strrev($val);
00394                 $parts = explode('_', $val, 2);
00395                 if ((string)trim($parts[0])!='') {
00396                     $theID = intval(strrev($parts[0]));
00397                     $theTable = trim($parts[1]) ? strrev(trim($parts[1])) : $default_tablename;
00398                     if ($theTable==$tablename)  {$list[] = $theID;}
00399                 }
00400             }
00401         }
00402         return implode(',', $list);
00403     }
00404 
00405     /**
00406      * Backend implementation of enableFields()
00407      * Notice that "fe_groups" is not selected for - only disabled, starttime and endtime.
00408      * Notice that deleted-fields are NOT filtered - you must ALSO call deleteClause in addition.
00409      * $GLOBALS["SIM_ACCESS_TIME"] is used for date.
00410      * Usage: 5
00411      *
00412      * @param   string      $table is the table from which to return enableFields WHERE clause. Table name must have a 'ctrl' section in $TCA.
00413      * @param   boolean     $inv means that the query will select all records NOT VISIBLE records (inverted selection)
00414      * @return  string      WHERE clause part
00415      */
00416     public static function BEenableFields($table, $inv = 0) {
00417         $ctrl = $GLOBALS['TCA'][$table]['ctrl'];
00418         $query = array();
00419         $invQuery = array();
00420         if (is_array($ctrl)) {
00421             if (is_array($ctrl['enablecolumns'])) {
00422                 if ($ctrl['enablecolumns']['disabled']) {
00423                     $field = $table.'.'.$ctrl['enablecolumns']['disabled'];
00424                     $query[] = $field.'=0';
00425                     $invQuery[] = $field.'!=0';
00426                 }
00427                 if ($ctrl['enablecolumns']['starttime']) {
00428                     $field = $table.'.'.$ctrl['enablecolumns']['starttime'];
00429                     $query[] = '('.$field.'<='.$GLOBALS['SIM_ACCESS_TIME'].')';
00430                     $invQuery[] = '('.$field.'!=0 AND '.$field.'>'.$GLOBALS['SIM_ACCESS_TIME'].')';
00431                 }
00432                 if ($ctrl['enablecolumns']['endtime']) {
00433                     $field = $table.'.'.$ctrl['enablecolumns']['endtime'];
00434                     $query[] = '('.$field.'=0 OR '.$field.'>'.$GLOBALS['SIM_ACCESS_TIME'].')';
00435                     $invQuery[] = '('.$field.'!=0 AND '.$field.'<='.$GLOBALS['SIM_ACCESS_TIME'].')';
00436                 }
00437             }
00438         }
00439         $outQ = ($inv ? '(' . implode(' OR ', $invQuery) . ')' : implode(' AND ', $query));
00440 
00441         return $outQ ? ' AND ' . $outQ : '';
00442     }
00443 
00444     /**
00445      * Fetches the localization for a given record.
00446      *
00447      * @param   string      $table: Table name present in $TCA
00448      * @param   integer     $uid: The uid of the record
00449      * @param   integer     $language: The uid of the language record in sys_language
00450      * @param   string      $andWhereClause: Optional additional WHERE clause (default: '')
00451      * @return  mixed       Multidimensional array with selected records; if none exist, false is returned
00452      */
00453     public function getRecordLocalization($table, $uid, $language, $andWhereClause = '') {
00454         $recordLocalization = false;
00455         if (self::isTableLocalizable($table)) {
00456             $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
00457             $recordLocalization = t3lib_BEfunc::getRecordsByField(
00458                 $table,
00459                 $tcaCtrl['transOrigPointerField'],
00460                 $uid,
00461                 'AND '.$tcaCtrl['languageField'].'='.intval($language).($andWhereClause ? ' '.$andWhereClause : ''),
00462                 '',
00463                 '',
00464                 '1'
00465             );
00466         }
00467         return $recordLocalization;
00468     }
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479     /*******************************************
00480      *
00481      * SQL-related, DEPRECATED functions
00482      * (use t3lib_DB functions instead)
00483      *
00484      *******************************************/
00485 
00486 
00487     /**
00488      * Returns a SELECT query, selecting fields ($select) from two/three tables joined
00489      * $local_table and $mm_table is mandatory. $foreign_table is optional.
00490      * The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local  / [$mm_table].uid_foreign <--> [$foreign_table].uid
00491      * 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.
00492      * 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.
00493      *
00494      * @param   string      Field list for SELECT
00495      * @param   string      Tablename, local table
00496      * @param   string      Tablename, relation table
00497      * @param   string      Tablename, foreign table
00498      * @param   string      Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
00499      * @param   string      Optional GROUP BY field(s), if none, supply blank string.
00500      * @param   string      Optional ORDER BY field(s), if none, supply blank string.
00501      * @param   string      Optional LIMIT value ([begin,]max), if none, supply blank string.
00502      * @return  string      Full SQL query
00503      * @deprecated since TYPO3 4.0
00504      * @see t3lib_DB::exec_SELECT_mm_query()
00505      */
00506     public static function mm_query($select, $local_table, $mm_table, $foreign_table, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '') {
00507         $query = $GLOBALS['TYPO3_DB']->SELECTquery(
00508                     $select,
00509                     $local_table.','.$mm_table.($foreign_table?','.$foreign_table:''),
00510                     $local_table.'.uid='.$mm_table.'.uid_local'.($foreign_table?' AND '.$foreign_table.'.uid='.$mm_table.'.uid_foreign':'').' '.
00511                         $whereClause,   // whereClauseMightContainGroupOrderBy
00512                     $groupBy,
00513                     $orderBy,
00514                     $limit
00515                 );
00516         return $query;
00517     }
00518 
00519     /**
00520      * Creates an INSERT SQL-statement for $table from the array with field/value pairs $fields_values.
00521      * DEPRECATED - $GLOBALS['TYPO3_DB']->INSERTquery() directly instead! But better yet, use $GLOBALS['TYPO3_DB']->exec_INSERTquery()
00522      *
00523      * @param   string      Table name
00524      * @param   array       Field values as key=>value pairs.
00525      * @return  string      Full SQL query for INSERT
00526      * @deprecated since TYPO3 4.0
00527      */
00528     public static function DBcompileInsert($table, $fields_values) {
00529         return $GLOBALS['TYPO3_DB']->INSERTquery($table, $fields_values);
00530     }
00531 
00532     /**
00533      * Creates an UPDATE SQL-statement for $table where $where-clause (typ. 'uid=...') from the array with field/value pairs $fields_values.
00534      * DEPRECATED - $GLOBALS['TYPO3_DB']->UPDATEquery() directly instead! But better yet, use $GLOBALS['TYPO3_DB']->exec_UPDATEquery()
00535      *
00536      * @param   string      Database tablename
00537      * @param   string      WHERE clause, eg. "uid=1"
00538      * @param   array       Field values as key=>value pairs.
00539      * @return  string      Full SQL query for UPDATE
00540      * @deprecated since TYPO3 4.0
00541      */
00542     public static function DBcompileUpdate($table, $where, $fields_values) {
00543         return $GLOBALS['TYPO3_DB']->UPDATEquery($table, $where, $fields_values);
00544     }
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555     /*******************************************
00556      *
00557      * Page tree, TCA related
00558      *
00559      *******************************************/
00560 
00561     /**
00562      * 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.
00563      * By default deleted pages are filtered.
00564      * 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.
00565      * Usage: 1
00566      *
00567      * @param   integer     Page id for which to create the root line.
00568      * @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.
00569      * @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!
00570      * @return  array       Root line array, all the way to the page tree root (or as far as $clause allows!)
00571      */
00572     public static function BEgetRootLine($uid, $clause = '', $workspaceOL = FALSE) {
00573         if (is_array($GLOBALS['T3_VAR']['BEgetRootLine_cache'][$uid][$clause][$workspaceOL?1:0])) {
00574             return $GLOBALS['T3_VAR']['BEgetRootLine_cache'][$uid][$clause][$workspaceOL?1:0];
00575         }
00576         $pid = $uid;
00577         $loopCheck = 100;
00578         $theRowArray = Array();
00579         $output = Array();
00580         while ($uid!=0 && $loopCheck>0) {
00581             $loopCheck--;
00582             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00583                 'pid,uid,title,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_swapmode,t3ver_stage',
00584                 'pages',
00585                 'uid='.intval($uid).' '.
00586                     t3lib_BEfunc::deleteClause('pages').' '.
00587                     $clause     // whereClauseMightContainGroupOrderBy
00588             );
00589             if ($GLOBALS['TYPO3_DB']->sql_error()) {
00590                 debug($GLOBALS['TYPO3_DB']->sql_error(), 1);
00591             }
00592             if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00593                 if($workspaceOL)    t3lib_BEfunc::workspaceOL('pages', $row);
00594                 if (is_array($row)) {
00595                     t3lib_BEfunc::fixVersioningPid('pages', $row);
00596                     $uid = $row['pid'];
00597                     $theRowArray[] = $row;
00598                 } else break;
00599             } else {
00600                 break;
00601             }
00602             $GLOBALS['TYPO3_DB']->sql_free_result($res);
00603         }
00604         if ($uid==0) {$theRowArray[] = Array('uid'=>0, 'title'=>'');}
00605         if (is_array($theRowArray)) {
00606             reset($theRowArray);
00607             $c = count($theRowArray);
00608             while(list($key, $val) = each($theRowArray)) {
00609                 $c--;
00610                 $output[$c]['uid'] = $val['uid'];
00611                 $output[$c]['pid'] = $val['pid'];
00612                 if (isset($val['_ORIG_pid'])) $output[$c]['_ORIG_pid'] = $val['_ORIG_pid'];
00613                 $output[$c]['title'] = $val['title'];
00614                 $output[$c]['TSconfig'] = $val['TSconfig'];
00615                 $output[$c]['is_siteroot'] = $val['is_siteroot'];
00616                 $output[$c]['storage_pid'] = $val['storage_pid'];
00617                 $output[$c]['t3ver_oid'] = $val['t3ver_oid'];
00618                 $output[$c]['t3ver_wsid'] = $val['t3ver_wsid'];
00619                 $output[$c]['t3ver_state'] = $val['t3ver_state'];
00620                 $output[$c]['t3ver_swapmode'] = $val['t3ver_swapmode'];
00621                 $output[$c]['t3ver_stage'] = $val['t3ver_stage'];
00622             }
00623         }
00624         $GLOBALS['T3_VAR']['BEgetRootLine_cache'][$pid][$clause][$workspaceOL?1:0] = $output;
00625 
00626         return $output;
00627     }
00628 
00629     /**
00630      * Opens the page tree to the specified page id
00631      *
00632      * @param   integer     Page id.
00633      * @param   boolean     If set, then other open branches are closed.
00634      * @return  void
00635      */
00636     public static function openPageTree($pid, $clearExpansion) {
00637         global $BE_USER;
00638 
00639             // Get current expansion data:
00640         if ($clearExpansion) {
00641             $expandedPages = array();
00642         } else {
00643             $expandedPages = unserialize($BE_USER->uc['browseTrees']['browsePages']);
00644         }
00645 
00646             // Get rootline:
00647         $rL = t3lib_BEfunc::BEgetRootLine($pid);
00648 
00649             // First, find out what mount index to use (if more than one DB mount exists):
00650         $mountIndex = 0;
00651         $mountKeys = array_flip($BE_USER->returnWebmounts());
00652         foreach($rL as $rLDat) {
00653             if (isset($mountKeys[$rLDat['uid']])) {
00654                 $mountIndex = $mountKeys[$rLDat['uid']];
00655                 break;
00656             }
00657         }
00658 
00659             // Traverse rootline and open paths:
00660         foreach($rL as $rLDat) {
00661             $expandedPages[$mountIndex][$rLDat['uid']] = 1;
00662         }
00663 
00664             // Write back:
00665         $BE_USER->uc['browseTrees']['browsePages'] = serialize($expandedPages);
00666         $BE_USER->writeUC();
00667     }
00668 
00669     /**
00670      * Returns the path (visually) of a page $uid, fx. "/First page/Second page/Another subpage"
00671      * Each part of the path will be limited to $titleLimit characters
00672      * Deleted pages are filtered out.
00673      * Usage: 15
00674      *
00675      * @param   integer     Page uid for which to create record path
00676      * @param   string      $clause is additional where clauses, eg. "
00677      * @param   integer     Title limit
00678      * @param   integer     Title limit of Full title (typ. set to 1000 or so)
00679      * @return  mixed       Path of record (string) OR array with short/long title if $fullTitleLimit is set.
00680      */
00681     public static function getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit = 0) {
00682         if (!$titleLimit) { $titleLimit = 1000; }
00683 
00684         $loopCheck = 100;
00685         $output = $fullOutput = '/';
00686         while ($uid!=0 && $loopCheck>0) {
00687             $loopCheck--;
00688             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00689                         'uid,pid,title,t3ver_oid,t3ver_wsid,t3ver_swapmode',
00690                         'pages',
00691                         'uid='.intval($uid).
00692                             t3lib_BEfunc::deleteClause('pages').
00693                             (strlen(trim($clause)) ? ' AND '.$clause : '')
00694                     );
00695             if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00696                 t3lib_BEfunc::workspaceOL('pages', $row);
00697                 if (is_array($row)) {
00698                     t3lib_BEfunc::fixVersioningPid('pages', $row);
00699 
00700                     if ($row['_ORIG_pid'] && $row['t3ver_swapmode']>0)  {   // Branch points
00701                         $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...
00702                     }
00703                     $uid = $row['pid'];
00704                     $output = '/'.t3lib_div::fixed_lgd_cs(strip_tags($row['title']), $titleLimit).$output;
00705                     if ($fullTitleLimit)    $fullOutput = '/'.t3lib_div::fixed_lgd_cs(strip_tags($row['title']), $fullTitleLimit).$fullOutput;
00706                 } else break;
00707             } else {
00708                 break;
00709             }
00710             $GLOBALS['TYPO3_DB']->sql_free_result($res);
00711         }
00712 
00713         if ($fullTitleLimit) {
00714             return array($output, $fullOutput);
00715         } else {
00716             return $output;
00717         }
00718     }
00719 
00720     /**
00721      * Returns an array with the exclude-fields as defined in TCA
00722      * Used for listing the exclude-fields in be_groups forms
00723      * Usage: 2 (t3lib_tceforms + t3lib_transferdata)
00724      *
00725      * @return  array       Array of arrays with excludeFields (fieldname, table:fieldname) from all TCA entries
00726      */
00727     public static function getExcludeFields() {
00728         global $TCA;
00729             // All TCA keys:
00730         $theExcludeArray = Array();
00731         $tc_keys = array_keys($TCA);
00732         foreach($tc_keys as $table) {
00733                 // Load table
00734             t3lib_div::loadTCA($table);
00735                 // All field names configured:
00736             if (is_array($TCA[$table]['columns'])) {
00737                 $f_keys = array_keys($TCA[$table]['columns']);
00738                 foreach($f_keys as $field) {
00739                     if ($TCA[$table]['columns'][$field]['exclude']) {
00740                             // Get Human Readable names of fields and table:
00741                         $Fname = $GLOBALS['LANG']->sl($TCA[$table]['ctrl']['title']).': '.$GLOBALS['LANG']->sl($TCA[$table]['columns'][$field]['label']);
00742                             // add entry:
00743                         $theExcludeArray[] = Array($Fname, $table.':'.$field);
00744                     }
00745                 }
00746             }
00747         }
00748         return $theExcludeArray;
00749     }
00750 
00751     /**
00752      * Returns an array with explicit Allow/Deny fields.
00753      * Used for listing these field/value pairs in be_groups forms
00754      *
00755      * @return  array       Array with information from all of $TCA
00756      */
00757     public static function getExplicitAuthFieldValues() {
00758         global $TCA;
00759 
00760             // Initialize:
00761         $adLabel = array(
00762             'ALLOW' => $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xml:labels.allow'),
00763             'DENY' => $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xml:labels.deny'),
00764         );
00765 
00766             // All TCA keys:
00767         $allowDenyOptions = Array();
00768         $tc_keys = array_keys($TCA);
00769         foreach($tc_keys as $table) {
00770 
00771                 // Load table
00772             t3lib_div::loadTCA($table);
00773 
00774                 // All field names configured:
00775             if (is_array($TCA[$table]['columns'])) {
00776                 $f_keys = array_keys($TCA[$table]['columns']);
00777                 foreach($f_keys as $field) {
00778                     $fCfg = $TCA[$table]['columns'][$field]['config'];
00779                     if ($fCfg['type']=='select' && $fCfg['authMode'])   {
00780 
00781                             // Check for items:
00782                         if (is_array($fCfg['items'])) {
00783                                 // Get Human Readable names of fields and table:
00784                             $allowDenyOptions[$table.':'.$field]['tableFieldLabel'] = $GLOBALS['LANG']->sl($TCA[$table]['ctrl']['title']).': '.$GLOBALS['LANG']->sl($TCA[$table]['columns'][$field]['label']);
00785 
00786                                 // Check for items:
00787                             foreach($fCfg['items'] as $iVal) {
00788                                 if (strcmp($iVal[1], ''))   {   // Values '' is not controlled by this setting.
00789 
00790                                         // Find iMode:
00791                                     $iMode = '';
00792                                     switch((string)$fCfg['authMode']) {
00793                                         case 'explicitAllow':
00794                                             $iMode = 'ALLOW';
00795                                         break;
00796                                         case 'explicitDeny':
00797                                             $iMode = 'DENY';
00798                                         break;
00799                                         case 'individual':
00800                                             if (!strcmp($iVal[4], 'EXPL_ALLOW')) {
00801                                                 $iMode = 'ALLOW';
00802                                             } elseif (!strcmp($iVal[4], 'EXPL_DENY')) {
00803                                                 $iMode = 'DENY';
00804                                             }
00805                                         break;
00806                                     }
00807 
00808                                         // Set iMode:
00809                                     if ($iMode) {
00810                                         $allowDenyOptions[$table.':'.$field]['items'][$iVal[1]] = array($iMode, $GLOBALS['LANG']->sl($iVal[0]), $adLabel[$iMode]);
00811                                     }
00812                                 }
00813                             }
00814                         }
00815                     }
00816                 }
00817             }
00818         }
00819 
00820         return $allowDenyOptions;
00821     }
00822 
00823     /**
00824      * Returns an array with system languages:
00825      *
00826      * @return  array       Array with languages
00827      */
00828     public static function getSystemLanguages() {
00829 
00830             // Initialize, add default language:
00831         $sysLanguages = array();
00832         $sysLanguages[] = array('Default language', 0);
00833 
00834             // Traverse languages
00835         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,title,flag', 'sys_language', 'pid=0'.t3lib_BEfunc::deleteClause('sys_language'));
00836         while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00837             $sysLanguages[] = array($row['title'].' ['.$row['uid'].']', $row['uid'], ($row['flag'] ? 'flags/'.$row['flag'] : ''));
00838         }
00839         $GLOBALS['TYPO3_DB']->sql_free_result($res);
00840 
00841         return $sysLanguages;
00842     }
00843 
00844     /**
00845      * Determines whether a table is localizable and has the languageField and transOrigPointerField set in $TCA.
00846      *
00847      * @param   string      $table: The table to check
00848      * @return  boolean     Whether a table is localizable
00849      */
00850     public function isTableLocalizable($table) {
00851         $isLocalizable = false;
00852         if (isset($GLOBALS['TCA'][$table]['ctrl']) && is_array($GLOBALS['TCA'][$table]['ctrl'])) {
00853             $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
00854             $isLocalizable = (isset($tcaCtrl['languageField']) && $tcaCtrl['languageField'] && isset($tcaCtrl['transOrigPointerField']) && $tcaCtrl['transOrigPointerField']);
00855         }
00856         return $isLocalizable;
00857     }
00858 
00859     /**
00860      * Returns the value of the property localizationMode in the given $config array ($TCA[<table>]['columns'][<field>]['config']).
00861      * If the table is prepared for localization and no localizationMode is set, 'select' is returned by default.
00862      * If the table is not prepared for localization or not defined at all in $TCA, false is returned.
00863      *
00864      * @param   string      $table: The name of the table to lookup in TCA
00865      * @param   mixed       $fieldOrConfig: The fieldname (string) or the configuration of the field to check (array)
00866      * @return  mixed       If table is localizable, the set localizationMode is returned (if property is not set, 'select' is returned by default); if table is not localizable, false is returned
00867      */
00868     public function getInlineLocalizationMode($table, $fieldOrConfig) {
00869         $localizationMode = false;
00870         if (is_array($fieldOrConfig) && count($fieldOrConfig)) {
00871             $config = $fieldOrConfig;
00872         } elseif (is_string($fieldOrConfig) && isset($GLOBALS['TCA'][$table]['columns'][$fieldOrConfig]['config'])) {
00873             $config = $GLOBALS['TCA'][$table]['columns'][$fieldOrConfig]['config'];
00874         }
00875         if (is_array($config) && isset($config['type']) && $config['type']=='inline' && self::isTableLocalizable($table)) {
00876             $localizationMode = (isset($config['behaviour']['localizationMode']) && $config['behaviour']['localizationMode'] ? $config['behaviour']['localizationMode'] : 'select');
00877                 // The mode 'select' is not possible when child table is not localizable at all:
00878             if ($localizationMode=='select' && !self::isTableLocalizable($config['foreign_table'])) {
00879                 $localizationMode = false;
00880             }
00881         }
00882         return $localizationMode;
00883     }
00884 
00885     /**
00886      * 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.
00887      * If $id is zero a pseudo root-page with "_thePath" set is returned IF the current BE_USER is admin.
00888      * In any case ->isInWebMount must return true for the user (regardless of $perms_clause)
00889      * Usage: 21
00890      *
00891      * @param   integer     Page uid for which to check read-access
00892      * @param   string      $perms_clause is typically a value generated with $BE_USER->getPagePermsClause(1);
00893      * @return  array       Returns page record if OK, otherwise false.
00894      */
00895     public static function readPageAccess($id, $perms_clause) {
00896         if ((string)$id!='') {
00897             $id = intval($id);
00898             if (!$id) {
00899                 if ($GLOBALS['BE_USER']->isAdmin()) {
00900                     $path = '/';
00901                     $pageinfo['_thePath'] = $path;
00902                     return $pageinfo;
00903                 }
00904             } else {
00905                 $pageinfo = t3lib_BEfunc::getRecord('pages', $id, '*', ($perms_clause ? ' AND '.$perms_clause : ''));
00906                 if ($pageinfo['uid'] && $GLOBALS['BE_USER']->isInWebMount($id, $perms_clause)) {
00907                     t3lib_BEfunc::workspaceOL('pages', $pageinfo);
00908                     if (is_array($pageinfo)) {
00909                         t3lib_BEfunc::fixVersioningPid('pages', $pageinfo);
00910                         list($pageinfo['_thePath'], $pageinfo['_thePathFull']) = t3lib_BEfunc::getRecordPath(intval($pageinfo['uid']), $perms_clause, 15, 1000);
00911                         return $pageinfo;
00912                     }
00913                 }
00914             }
00915         }
00916         return false;
00917     }
00918 
00919     /**
00920      * Returns the "types" configuration parsed into an array for the record, $rec, from table, $table
00921      * Usage: 6
00922      *
00923      * @param   string      Table name (present in TCA)
00924      * @param   array       Record from $table
00925      * @param   boolean     If $useFieldNameAsKey is set, then the fieldname is associative keys in the return array, otherwise just numeric keys.
00926      * @return  array
00927      */
00928     public static function getTCAtypes($table, $rec, $useFieldNameAsKey = 0) {
00929         global $TCA;
00930 
00931         t3lib_div::loadTCA($table);
00932         if ($TCA[$table])   {
00933 
00934                 // Get type value:
00935             $fieldValue = t3lib_BEfunc::getTCAtypeValue($table, $rec);
00936 
00937                 // Get typesConf
00938             $typesConf = $TCA[$table]['types'][$fieldValue];
00939 
00940                 // Get fields list and traverse it
00941             $fieldList = explode(',', $typesConf['showitem']);
00942             $altFieldList = array();
00943 
00944                 // Traverse fields in types config and parse the configuration into a nice array:
00945             foreach($fieldList as $k => $v) {
00946                 list($pFieldName, $pAltTitle, $pPalette, $pSpec) = t3lib_div::trimExplode(';', $v);
00947                 $defaultExtras = is_array($TCA[$table]['columns'][$pFieldName]) ? $TCA[$table]['columns'][$pFieldName]['defaultExtras'] : '';
00948                 $specConfParts = t3lib_BEfunc::getSpecConfParts($pSpec, $defaultExtras);
00949 
00950                 $fieldList[$k] = array(
00951                     'field' => $pFieldName,
00952                     'title' => $pAltTitle,
00953                     'palette' => $pPalette,
00954                     'spec' => $specConfParts,
00955                     'origString' => $v
00956                 );
00957                 if ($useFieldNameAsKey) {
00958                     $altFieldList[$fieldList[$k]['field']] = $fieldList[$k];
00959                 }
00960             }
00961             if ($useFieldNameAsKey) {
00962                 $fieldList = $altFieldList;
00963             }
00964 
00965                 // Return array:
00966             return $fieldList;
00967         }
00968     }
00969 
00970     /**
00971      * Returns the "type" value of $rec from $table which can be used to look up the correct "types" rendering section in $TCA
00972      * If no "type" field is configured in the "ctrl"-section of the $TCA for the table, zero is used.
00973      * 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)
00974      * Usage: 7
00975      *
00976      * @param   string      Table name present in TCA
00977      * @param   array       Record from $table
00978      * @return  string      Field value
00979      * @see getTCAtypes()
00980      */
00981     public static function getTCAtypeValue($table, $rec) {
00982         global $TCA;
00983 
00984             // 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.
00985         t3lib_div::loadTCA($table);
00986         if ($TCA[$table]) {
00987             $field = $TCA[$table]['ctrl']['type'];
00988             $fieldValue = $field ? ($rec[$field] ? $rec[$field] : 0) : 0;
00989             if (!is_array($TCA[$table]['types'][$fieldValue]))  $fieldValue = 1;
00990             return $fieldValue;
00991         }
00992     }
00993 
00994     /**
00995      * Parses a part of the field lists in the "types"-section of $TCA arrays, namely the "special configuration" at index 3 (position 4)
00996      * Elements are splitted by ":" and within those parts, parameters are splitted by "|".
00997      * 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
00998      * Usage: 5
00999      *
01000      * @param   string      Content from the "types" configuration of TCA (the special configuration) - see description of function
01001      * @param   string      The ['defaultExtras'] value from field configuration
01002      * @return  array
01003      */
01004     public static function getSpecConfParts($str, $defaultExtras)   {
01005 
01006             // Add defaultExtras:
01007         $specConfParts = t3lib_div::trimExplode(':', $defaultExtras.':'.$str, 1);
01008 
01009         $reg = array();
01010         if (count($specConfParts)) {
01011             foreach($specConfParts as $k2 => $v2) {
01012                 unset($specConfParts[$k2]);
01013                 if (ereg('(.*)\[(.*)\]', $v2, $reg)) {
01014                     $specConfParts[trim($reg[1])] = array(
01015                         'parameters' => t3lib_div::trimExplode('|', $reg[2], 1)
01016                     );
01017                 } else {
01018                     $specConfParts[trim($v2)] = 1;
01019                 }
01020             }
01021         } else {
01022             $specConfParts = array();
01023         }
01024         return $specConfParts;
01025     }
01026 
01027     /**
01028      * Takes an array of "[key] = [value]" strings and returns an array with the keys set as keys pointing to the value.
01029      * Better see it in action! Find example in Inside TYPO3
01030      * Usage: 6
01031      *
01032      * @param   array       Array of "[key] = [value]" strings to convert.
01033      * @return  array
01034      */
01035     public static function getSpecConfParametersFromArray($pArr) {
01036         $out = array();
01037         if (is_array($pArr)) {
01038             reset($pArr);
01039             while(list($k, $v) = each($pArr)) {
01040                 $parts = explode('=', $v, 2);
01041                 if (count($parts)==2) {
01042                     $out[trim($parts[0])] = trim($parts[1]);
01043                 } else {
01044                     $out[$k] = $v;
01045                 }
01046             }
01047         }
01048         return $out;
01049     }
01050 
01051     /**
01052      * Finds the Data Structure for a FlexForm field
01053      * 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.
01054      * Usage: 5
01055      *
01056      * @param   array       Field config array
01057      * @param   array       Record data
01058      * @param   string      The table name
01059      * @param   string      Optional fieldname passed to hook object
01060      * @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.
01061      * @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)
01062      * @return  mixed       If array, the data structure was found and returned as an array. Otherwise (string) it is an error message.
01063      * @see t3lib_TCEforms::getSingleField_typeFlex()
01064      */
01065     public static function getFlexFormDS($conf, $row, $table, $fieldName = '', $WSOL = TRUE, $newRecordPidValue = 0) {
01066         global $TYPO3_CONF_VARS;
01067 
01068             // Get pointer field etc from TCA-config:
01069         $ds_pointerField =  $conf['ds_pointerField'];
01070         $ds_array =         $conf['ds'];
01071         $ds_tableField =    $conf['ds_tableField'];
01072         $ds_searchParentField =     $conf['ds_pointerField_searchParent'];
01073 
01074             // Find source value:
01075         $dataStructArray = '';
01076         if (is_array($ds_array))    {   // If there is a data source array, that takes precedence
01077                 // If a pointer field is set, take the value from that field in the $row array and use as key.
01078             if ($ds_pointerField)   {
01079 
01080                     // Up to two pointer fields can be specified in a comma separated list.
01081                 $pointerFields = t3lib_div::trimExplode(',', $ds_pointerField);
01082                 if(count($pointerFields) == 2) { // If we have two pointer fields, the array keys should contain both field values separated by comma. The asterisk "*" catches all values. For backwards compatibility, it's also possible to specify only the value of the first defined ds_pointerField.
01083                     if($ds_array[$row[$pointerFields[0]].','.$row[$pointerFields[1]]]) {    // Check if we have a DS for the combination of both pointer fields values
01084                         $srcPo