Implemented versioning API, phase 1 (tcemain). See changelog
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_befunc.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2004 Kasper Skaarhoj (kasper@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$
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 <kasper@typo3.com>
40 */
41 /**
42 * [CLASS/FUNCTION INDEX of SCRIPT]
43 *
44 *
45 *
46 * 162: class t3lib_BEfunc
47 *
48 * SECTION: SQL-related, selecting records, searching
49 * 182: function deleteClause($table)
50 * 205: function getRecord($table,$uid,$fields='*',$where='')
51 * 227: function getRecordRaw($table,$where='',$fields='*')
52 * 249: function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='')
53 * 281: function searchQuery($searchWords,$fields,$table='')
54 * 296: function listQuery($field,$value)
55 * 308: function splitTable_Uid($str)
56 * 323: function getSQLselectableList($in_list,$tablename,$default_tablename)
57 * 351: function BEenableFields($table,$inv=0)
58 *
59 * SECTION: SQL-related, DEPRECIATED functions
60 * 415: function mm_query($select,$local_table,$mm_table,$foreign_table,$whereClause='',$groupBy='',$orderBy='',$limit='')
61 * 437: function DBcompileInsert($table,$fields_values)
62 * 451: function DBcompileUpdate($table,$where,$fields_values)
63 *
64 * SECTION: Page tree, TCA related
65 * 480: function BEgetRootLine($uid,$clause='')
66 * 526: function openPageTree($pid,$clearExpansion)
67 * 571: function getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
68 * 608: function getExcludeFields()
69 * 642: function readPageAccess($id,$perms_clause)
70 * 671: function getTCAtypes($table,$rec,$useFieldNameAsKey=0)
71 * 724: function getTCAtypeValue($table,$rec)
72 * 747: function getSpecConfParts($str, $defaultExtras)
73 * 777: function getSpecConfParametersFromArray($pArr)
74 * 803: function getFlexFormDS($conf,$row,$table)
75 *
76 * SECTION: Caching related
77 * 907: function storeHash($hash,$data,$ident)
78 * 927: function getHash($hash,$expTime)
79 *
80 * SECTION: TypoScript related
81 * 963: function getPagesTSconfig($id,$rootLine='',$returnPartArray=0)
82 * 1014: function updatePagesTSconfig($id,$pageTS,$TSconfPrefix,$impParams='')
83 * 1069: function implodeTSParams($p,$k='')
84 *
85 * SECTION: Users / Groups related
86 * 1106: function getUserNames($fields='username,usergroup,usergroup_cached_list,uid',$where='')
87 * 1124: function getGroupNames($fields='title,uid', $where='')
88 * 1141: function getListGroupNames($fields='title,uid')
89 * 1160: function blindUserNames($usernames,$groupArray,$excludeBlindedFlag=0)
90 * 1193: function blindGroupNames($groups,$groupArray,$excludeBlindedFlag=0)
91 *
92 * SECTION: Output related
93 * 1236: function daysUntil($tstamp)
94 * 1248: function date($tstamp)
95 * 1259: function datetime($value)
96 * 1271: function time($value)
97 * 1287: function calcAge($seconds,$labels)
98 * 1313: function dateTimeAge($tstamp,$prefix=1,$date='')
99 * 1331: function titleAttrib($content='',$hsc=0)
100 * 1344: function titleAltAttrib($content)
101 * 1368: function thumbCode($row,$table,$field,$backPath,$thumbScript='',$uploaddir='',$abs=0,$tparams='',$size='')
102 * 1436: function getThumbNail($thumbScript,$theFile,$tparams='',$size='')
103 * 1453: function titleAttribForPages($row,$perms_clause='',$includeAttrib=1)
104 * 1511: function getRecordIconAltText($row,$table='pages')
105 * 1545: function getLabelFromItemlist($table,$col,$key)
106 * 1571: function getItemLabel($table,$col,$printAllWrap='')
107 * 1596: function getRecordTitle($table,$row,$prep=0)
108 * 1632: function getProcessedValue($table,$col,$value,$fixed_lgd_chars=0,$defaultPassthrough=0)
109 * 1726: function getProcessedValueExtra($table,$fN,$fV,$fixed_lgd_chars=0)
110 * 1750: function getFileIcon($ext)
111 * 1764: function getCommonSelectFields($table,$prefix)
112 * 1790: function makeConfigForm($configArray,$defaults,$dataPrefix)
113 *
114 * SECTION: Backend Modules API functions
115 * 1865: function helpTextIcon($table,$field,$BACK_PATH,$force=0)
116 * 1886: function helpText($table,$field,$BACK_PATH)
117 * 1906: function editOnClick($params,$backPath='',$requestUri='')
118 * 1922: function viewOnClick($id,$backPath='',$rootLine='',$anchor='',$altUrl='')
119 * 1948: function getModTSconfig($id,$TSref)
120 * 1969: function getFuncMenu($id,$elementName,$currentValue,$menuItems,$script='',$addparams='')
121 * 1998: function getFuncCheck($id,$elementName,$currentValue,$script='',$addparams='',$tagParams='')
122 * 2018: function getFuncInput($id,$elementName,$currentValue,$size=10,$script="",$addparams="")
123 * 2034: function unsetMenuItems($modTSconfig,$itemArray,$TSref)
124 * 2057: function getSetUpdateSignal($set='')
125 * 2108: function getModuleData($MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='')
126 *
127 * SECTION: Core
128 * 2183: function lockRecords($table='',$uid=0,$pid=0)
129 * 2212: function isRecordLocked($table,$uid)
130 * 2252: function exec_foreign_table_where_query($fieldValue,$field='',$TSconfig=array(),$prefix='')
131 * 2333: function getTCEFORM_TSconfig($table,$row)
132 * 2380: function getTSconfig_pidValue($table,$uid,$pid)
133 * 2408: function getPidForModTSconfig($table,$uid,$pid)
134 * 2424: function getTSCpid($table,$uid,$pid)
135 * 2440: function firstDomainRecord($rootLine)
136 * 2462: function getDomainStartPage($domain, $path='')
137 * 2492: function RTEsetup($RTEprop,$table,$field,$type='')
138 * 2510: function &RTEgetObj()
139 * 2549: function isModuleSetInTBE_MODULES($modName)
140 *
141 * SECTION: Miscellaneous
142 * 2598: function typo3PrintError($header,$text,$js='',$head=1)
143 * 2644: function getPathType_web_nonweb($path)
144 * 2656: function ADMCMD_previewCmds($pageinfo)
145 * 2678: function processParams($params)
146 * 2704: function getListOfBackendModules($name,$perms_clause,$backPath='',$script='index.php')
147 *
148 * TOTAL FUNCTIONS: 80
149 * (This index is automatically created/updated by the extension "extdeveval")
150 *
151 */
152
153
154 /**
155 * Standard functions available for the TYPO3 backend.
156 * Don't instantiate - call functions with "t3lib_BEfunc::" prefixed the function name.
157 *
158 * @author Kasper Skaarhoj <kasper@typo3.com>
159 * @package TYPO3
160 * @subpackage t3lib
161 */
162 class t3lib_BEfunc {
163
164
165
166 /*******************************************
167 *
168 * SQL-related, selecting records, searching
169 *
170 *******************************************/
171
172
173 /**
174 * Returns the WHERE clause " AND NOT [tablename].[deleted-field]" if a deleted-field is configured in $TCA for the tablename, $table
175 * 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!)
176 * 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.
177 * Usage: 71
178 *
179 * @param string Table name present in $TCA
180 * @return string WHERE clause for filtering out deleted records, eg " AND NOT tablename.deleted"
181 */
182 function deleteClause($table) {
183 global $TCA;
184 if ($TCA[$table]['ctrl']['delete']) {
185 return ' AND NOT '.$table.'.'.$TCA[$table]['ctrl']['delete'];
186 } else {
187 return '';
188 }
189 }
190
191 /**
192 * Gets record with uid=$uid from $table
193 * You can set $field to a list of fields (default is '*')
194 * Additional WHERE clauses can be added by $where (fx. ' AND blabla=1')
195 * Will automatically check if records has been deleted and if so, not return anything.
196 * $table must be found in $TCA
197 * Usage: 99
198 *
199 * @param string Table name present in $TCA
200 * @param integer UID of record
201 * @param string List of fields to select
202 * @param string Additional WHERE clause, eg. " AND blablabla=0"
203 * @return array Returns the row if found, otherwise nothing
204 */
205 function getRecord($table,$uid,$fields='*',$where='') {
206 if ($GLOBALS['TCA'][$table]) {
207 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, 'uid='.intval($uid).t3lib_BEfunc::deleteClause($table).$where);
208 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
209 return $row;
210 }
211 }
212 }
213
214 /**
215 * Returns the first record found from $table with $where as WHERE clause
216 * This function does NOT check if a record has the deleted flag set.
217 * $table does NOT need to be configured in $TCA
218 * The query used is simply this:
219 * $query='SELECT '.$fields.' FROM '.$table.' WHERE '.$where;
220 * Usage: 5 (ext: sys_todos)
221 *
222 * @param string Table name (not necessarily in TCA)
223 * @param string WHERE clause
224 * @param string $fields is a list of fields to select, default is '*'
225 * @return array First row found, if any
226 */
227 function getRecordRaw($table,$where='',$fields='*') {
228 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, $where);
229 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
230 return $row;
231 }
232 }
233
234 /**
235 * Returns records from table, $theTable, where a field ($theField) equals the value, $theValue
236 * The records are returned in an array
237 * If no records were selected, the function returns nothing
238 * Usage: 8
239 *
240 * @param string Table name present in $TCA
241 * @param string Field to select on
242 * @param string Value that $theField must match
243 * @param string Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
244 * @param string Optional GROUP BY field(s), if none, supply blank string.
245 * @param string Optional ORDER BY field(s), if none, supply blank string.
246 * @param string Optional LIMIT value ([begin,]max), if none, supply blank string.
247 * @return mixed Multidimensional array with selected records (if any is selected)
248 */
249 function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='') {
250 global $TCA;
251 if (is_array($TCA[$theTable])) {
252 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
253 '*',
254 $theTable,
255 $theField.'="'.$GLOBALS['TYPO3_DB']->quoteStr($theValue, $theTable).'"'.
256 t3lib_BEfunc::deleteClause($theTable).' '.
257 $whereClause, // whereClauseMightContainGroupOrderBy
258 $groupBy,
259 $orderBy,
260 $limit
261 );
262 $rows = array();
263 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
264 $rows[] = $row;
265 }
266 $GLOBALS['TYPO3_DB']->sql_free_result($res);
267 if (count($rows)) return $rows;
268 }
269 }
270
271 /**
272 * Find page-tree PID for versionized record
273 * 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
274 *
275 * @param string Table name
276 * @param array Record array passed by reference. As minimum, "pid" and "uid" fields must exist! "t3ver_oid" is nice and will save you a DB query.
277 * @return void (Passed by ref).
278 */
279 function fixVersioningPid($table,&$rr) {
280 global $TCA;
281
282 if ($rr['pid']==-1 && $TCA[$table]['ctrl']['versioning']) {
283 if ($rr['t3ver_oid']>0) { // If "t3ver_oid" is already a field, just set this:
284 $oid = $rr['t3ver_oid'];
285 } else { // Otherwise we have to expect "uid" to be in the record and look up based on this:
286 $newPidRec = t3lib_BEfunc::getRecord($table,$rr['uid'],'t3ver_oid');
287 if (is_array($newPidRec)) {
288 $oid = $newPidRec['t3ver_oid'];
289 }
290 }
291
292 // If ID of current online version is found, look up the PID value of that:
293 if ($oid) {
294 $oidRec = t3lib_BEfunc::getRecord($table,$oid,'pid');
295 if (is_array($oidRec)) {
296 $rr['_ORIG_pid'] = $rr['pid'];
297 $rr['pid'] = $oidRec['pid'];
298 }
299 }
300 }
301 }
302
303 /**
304 * 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.
305 * Usage: 0
306 *
307 * @param array Array of search words
308 * @param array Array of fields
309 * @param string Table in which we are searching (for DBAL detection of quoteStr() method)
310 * @return string WHERE clause for search
311 * @depreciated Use $GLOBALS['TYPO3_DB']->searchQuery() directly!
312 */
313 function searchQuery($searchWords,$fields,$table='') {
314 return $GLOBALS['TYPO3_DB']->searchQuery($searchWords,$fields,$table);
315 }
316
317 /**
318 * Returns a WHERE clause that can find a value ($value) in a list field ($field)
319 * 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).
320 * Is nice to look up list-relations to records or files in TYPO3 database tables.
321 * Usage: 0
322 *
323 * @param string Table field name
324 * @param string Value to find in list
325 * @return string WHERE clause for a query
326 * @depreciated Use $GLOBALS['TYPO3_DB']->listQuery() directly!
327 */
328 function listQuery($field,$value) {
329 return $GLOBALS['TYPO3_DB']->listQuery($field,$value,'');
330 }
331
332 /**
333 * Makes an backwards explode on the $str and returns an array with ($table,$uid).
334 * Example: tt_content_45 => array('tt_content',45)
335 * Usage: 1
336 *
337 * @param string [tablename]_[uid] string to explode
338 * @return array
339 */
340 function splitTable_Uid($str) {
341 list($uid,$table) = explode('_',strrev($str),2);
342 return array(strrev($table),strrev($uid));
343 }
344
345 /**
346 * Returns a list of pure integers based on $in_list being a list of records with table-names prepended.
347 * 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.
348 * Usage: 1 (t3lib_userauthgroup)
349 *
350 * @param string Input list
351 * @param string Table name from which ids is returned
352 * @param string $default_tablename denotes what table the number '45' is from (if nothing is prepended on the value)
353 * @return string List of ids
354 */
355 function getSQLselectableList($in_list,$tablename,$default_tablename) {
356 $list = Array();
357 if ((string)trim($in_list)!='') {
358 $tempItemArray = explode(',',trim($in_list));
359 while(list($key,$val)=each($tempItemArray)) {
360 $val = strrev($val);
361 $parts = explode('_',$val,2);
362 if ((string)trim($parts[0])!='') {
363 $theID = intval(strrev($parts[0]));
364 $theTable = trim($parts[1]) ? strrev(trim($parts[1])) : $default_tablename;
365 if ($theTable==$tablename) {$list[]=$theID;}
366 }
367 }
368 }
369 return implode(',',$list);
370 }
371
372 /**
373 * Backend implementation of enableFields()
374 * Notice that "fe_groups" is not selected for - only disabled, starttime and endtime.
375 * Notice that deleted-fields are NOT filtered - you must ALSO call deleteClause in addition.
376 * $GLOBALS["SIM_EXEC_TIME"] is used for date.
377 * Usage: 5
378 *
379 * @param string $table is the table from which to return enableFields WHERE clause. Table name must have a 'ctrl' section in $TCA.
380 * @param boolean $inv means that the query will select all records NOT VISIBLE records (inverted selection)
381 * @return string WHERE clause part
382 */
383 function BEenableFields($table,$inv=0) {
384 $ctrl = $GLOBALS['TCA'][$table]['ctrl'];
385 $query=array();
386 $invQuery=array();
387 if (is_array($ctrl)) {
388 if (is_array($ctrl['enablecolumns'])) {
389 if ($ctrl['enablecolumns']['disabled']) {
390 $field = $table.'.'.$ctrl['enablecolumns']['disabled'];
391 $query[]='NOT '.$field;
392 $invQuery[]=$field;
393 }
394 if ($ctrl['enablecolumns']['starttime']) {
395 $field = $table.'.'.$ctrl['enablecolumns']['starttime'];
396 $query[]='('.$field.'<='.$GLOBALS['SIM_EXEC_TIME'].')';
397 $invQuery[]='('.$field.'!=0 AND '.$field.'>'.$GLOBALS['SIM_EXEC_TIME'].')';
398 }
399 if ($ctrl['enablecolumns']['endtime']) {
400 $field = $table.'.'.$ctrl['enablecolumns']['endtime'];
401 $query[]='('.$field.'=0 OR '.$field.'>'.$GLOBALS['SIM_EXEC_TIME'].')';
402 $invQuery[]='('.$field.'!=0 AND '.$field.'<='.$GLOBALS['SIM_EXEC_TIME'].')';
403 }
404 }
405 }
406 $outQ = ' AND '.($inv ? '('.implode(' OR ',$invQuery).')' : implode(' AND ',$query));
407
408 return $outQ;
409 }
410
411
412
413
414
415
416
417
418
419
420 /*******************************************
421 *
422 * SQL-related, DEPRECIATED functions
423 * (use t3lib_DB functions instead)
424 *
425 *******************************************/
426
427
428 /**
429 * Returns a SELECT query, selecting fields ($select) from two/three tables joined
430 * $local_table and $mm_table is mandatory. $foreign_table is optional.
431 * The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local / [$mm_table].uid_foreign <--> [$foreign_table].uid
432 * 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.
433 * DEPRECIATED - 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.
434 *
435 * @param string Field list for SELECT
436 * @param string Tablename, local table
437 * @param string Tablename, relation table
438 * @param string Tablename, foreign table
439 * @param string Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
440 * @param string Optional GROUP BY field(s), if none, supply blank string.
441 * @param string Optional ORDER BY field(s), if none, supply blank string.
442 * @param string Optional LIMIT value ([begin,]max), if none, supply blank string.
443 * @return string Full SQL query
444 * @depreciated
445 * @see t3lib_DB::exec_SELECT_mm_query()
446 */
447 function mm_query($select,$local_table,$mm_table,$foreign_table,$whereClause='',$groupBy='',$orderBy='',$limit='') {
448 $query = $GLOBALS['TYPO3_DB']->SELECTquery(
449 $select,
450 $local_table.','.$mm_table.($foreign_table?','.$foreign_table:''),
451 $local_table.'.uid='.$mm_table.'.uid_local'.($foreign_table?' AND '.$foreign_table.'.uid='.$mm_table.'.uid_foreign':'').' '.
452 $whereClause, // whereClauseMightContainGroupOrderBy
453 $groupBy,
454 $orderBy,
455 $limit
456 );
457 return $query;
458 }
459
460 /**
461 * Creates an INSERT SQL-statement for $table from the array with field/value pairs $fields_values.
462 * DEPRECIATED - $GLOBALS['TYPO3_DB']->INSERTquery() directly instead! But better yet, use $GLOBALS['TYPO3_DB']->exec_INSERTquery()
463 *
464 * @param string Table name
465 * @param array Field values as key=>value pairs.
466 * @return string Full SQL query for INSERT
467 * @depreciated
468 */
469 function DBcompileInsert($table,$fields_values) {
470 return $GLOBALS['TYPO3_DB']->INSERTquery($table, $fields_values);
471 }
472
473 /**
474 * Creates an UPDATE SQL-statement for $table where $where-clause (typ. 'uid=...') from the array with field/value pairs $fields_values.
475 * DEPRECIATED - $GLOBALS['TYPO3_DB']->UPDATEquery() directly instead! But better yet, use $GLOBALS['TYPO3_DB']->exec_UPDATEquery()
476 *
477 * @param string Database tablename
478 * @param string WHERE clause, eg. "uid=1"
479 * @param array Field values as key=>value pairs.
480 * @return string Full SQL query for UPDATE
481 * @depreciated
482 */
483 function DBcompileUpdate($table,$where,$fields_values) {
484 return $GLOBALS['TYPO3_DB']->UPDATEquery($table, $where, $fields_values);
485 }
486
487
488
489
490
491
492
493
494
495
496 /*******************************************
497 *
498 * Page tree, TCA related
499 *
500 *******************************************/
501
502 /**
503 * 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.
504 * By default deleted pages are filtered.
505 * 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.
506 * Usage: 1
507 *
508 * @param integer Page id for which to create the root line.
509 * @param string $clause can be used to select other criteria. It would typically be where-clauses that stops the proces if we meet a page, the user has no reading access to.
510 * @return array Root line array, all the way to the page tree root (or as far as $clause allows!)
511 */
512 function BEgetRootLine($uid,$clause='') {
513 $loopCheck = 100;
514 $theRowArray = Array();
515 $output=Array();
516 while ($uid!=0 && $loopCheck>0) {
517 $loopCheck--;
518 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
519 'pid,uid,title,TSconfig,is_siteroot,storage_pid',
520 'pages',
521 'uid='.intval($uid).' '.
522 t3lib_BEfunc::deleteClause('pages').' '.
523 $clause // whereClauseMightContainGroupOrderBy
524 );
525 if ($GLOBALS['TYPO3_DB']->sql_error()) {
526 debug($GLOBALS['TYPO3_DB']->sql_error(),1);
527 }
528 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
529 t3lib_BEfunc::fixVersioningPid('pages',$row);
530 $uid = $row['pid'];
531 $theRowArray[]=$row;
532 } else {
533 break;
534 }
535 }
536 if ($uid==0) {$theRowArray[]=Array('uid'=>0,'title'=>'');}
537 if (is_array($theRowArray)) {
538 reset($theRowArray);
539 $c=count($theRowArray);
540 while(list($key,$val)=each($theRowArray)) {
541 $c--;
542 $output[$c]['uid'] = $val['uid'];
543 $output[$c]['pid'] = $val['pid'];
544 if (isset($val['_ORIG_pid'])) $output[$c]['_ORIG_pid'] = $val['_ORIG_pid'];
545 $output[$c]['title'] = $val['title'];
546 $output[$c]['TSconfig'] = $val['TSconfig'];
547 $output[$c]['is_siteroot'] = $val['is_siteroot'];
548 $output[$c]['storage_pid'] = $val['storage_pid'];
549 }
550 }
551 return $output;
552 }
553
554 /**
555 * Opens the page tree to the specified page id
556 *
557 * @param integer Page id.
558 * @param boolean If set, then other open branches are closed.
559 * @return void
560 */
561 function openPageTree($pid,$clearExpansion) {
562 global $BE_USER;
563
564 // Get current expansion data:
565 if ($clearExpansion) {
566 $expandedPages = array();
567 } else {
568 $expandedPages = unserialize($BE_USER->uc['browseTrees']['browsePages']);
569 }
570
571 // Get rootline:
572 $rL = t3lib_BEfunc::BEgetRootLine($pid);
573
574 // First, find out what mount index to use (if more than one DB mount exists):
575 $mountIndex = 0;
576 $mountKeys = array_flip($BE_USER->returnWebmounts());
577 foreach($rL as $rLDat) {
578 if (isset($mountKeys[$rLDat['uid']])) {
579 $mountIndex = $mountKeys[$rLDat['uid']];
580 break;
581 }
582 }
583
584 // Traverse rootline and open paths:
585 foreach($rL as $rLDat) {
586 $expandedPages[$mountIndex][$rLDat['uid']] = 1;
587 }
588
589 // Write back:
590 $BE_USER->uc['browseTrees']['browsePages'] = serialize($expandedPages);
591 $BE_USER->writeUC();
592 }
593
594 /**
595 * Returns the path (visually) of a page $uid, fx. "/First page/Second page/Another subpage"
596 * Each part of the path will be limited to $titleLimit characters
597 * Deleted pages are filtered out.
598 * Usage: 15
599 *
600 * @param integer Page uid for which to create record path
601 * @param string $clause is additional where clauses, eg. "
602 * @param integer Title limit
603 * @param integer Title limit of Full title (typ. set to 1000 or so)
604 * @return mixed Path of record (string) OR array with short/long title if $fullTitleLimit is set.
605 */
606 function getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0) {
607 if (!$titleLimit) { $titleLimit=1000; }
608
609 $loopCheck = 100;
610 $output = $fullOutput = '/';
611 while ($uid!=0 && $loopCheck>0) {
612 $loopCheck--;
613 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
614 'uid,pid,title',
615 'pages',
616 'uid='.intval($uid).
617 t3lib_BEfunc::deleteClause('pages').
618 (strlen(trim($clause)) ? ' AND '.$clause : '')
619 );
620 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
621 t3lib_BEfunc::fixVersioningPid('pages',$row);
622
623 if ($row['_ORIG_pid']) {
624 $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...
625 }
626 $uid = $row['pid'];
627 $output = '/'.t3lib_div::fixed_lgd_cs(strip_tags($row['title']),$titleLimit).$output;
628 if ($fullTitleLimit) $fullOutput = '/'.t3lib_div::fixed_lgd_cs(strip_tags($row['title']),$fullTitleLimit).$fullOutput;
629 } else {
630 break;
631 }
632 }
633
634 if ($fullTitleLimit) {
635 return array($output, $fullOutput);
636 } else {
637 return $output;
638 }
639 }
640
641 /**
642 * Returns an array with the exclude-fields as defined in TCA
643 * Used for listing the exclude-fields in be_groups forms
644 * Usage: 2 (t3lib_tceforms + t3lib_transferdata)
645 *
646 * @return array Array of arrays with excludeFields (fieldname, table:fieldname) from all TCA entries
647 */
648 function getExcludeFields() {
649 global $TCA;
650 // All TCA keys:
651 $theExcludeArray = Array();
652 $tc_keys = array_keys($TCA);
653 foreach($tc_keys as $table) {
654 // Load table
655 t3lib_div::loadTCA($table);
656 // All field names configured:
657 if (is_array($TCA[$table]['columns'])) {
658 $f_keys = array_keys($TCA[$table]['columns']);
659 foreach($f_keys as $field) {
660 if ($TCA[$table]['columns'][$field]['exclude']) {
661 // Get Human Readable names of fields and table:
662 $Fname=$GLOBALS['LANG']->sl($TCA[$table]['ctrl']['title']).': '.$GLOBALS['LANG']->sl($TCA[$table]['columns'][$field]['label']);
663 // add entry:
664 $theExcludeArray[] = Array($Fname , $table.':'.$field);
665 }
666 }
667 }
668 }
669 return $theExcludeArray;
670 }
671
672 /**
673 * Returns an array with explicit Allow/Deny fields.
674 * Used for listing these field/value pairs in be_groups forms
675 *
676 * @return array Array with information from all of $TCA
677 */
678 function getExplicitAuthFieldValues() {
679 global $TCA;
680
681 // Initialize:
682 $adLabel = array(
683 'ALLOW' => $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xml:labels.allow'),
684 'DENY' => $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xml:labels.deny'),
685 );
686
687 // All TCA keys:
688 $allowDenyOptions = Array();
689 $tc_keys = array_keys($TCA);
690 foreach($tc_keys as $table) {
691
692 // Load table
693 t3lib_div::loadTCA($table);
694
695 // All field names configured:
696 if (is_array($TCA[$table]['columns'])) {
697 $f_keys = array_keys($TCA[$table]['columns']);
698 foreach($f_keys as $field) {
699 $fCfg = $TCA[$table]['columns'][$field]['config'];
700 if ($fCfg['type']=='select' && $fCfg['authMode']) {
701
702 // Check for items:
703 if (is_array($fCfg['items'])) {
704 // Get Human Readable names of fields and table:
705 $allowDenyOptions[$table.':'.$field]['tableFieldLabel'] = $GLOBALS['LANG']->sl($TCA[$table]['ctrl']['title']).': '.$GLOBALS['LANG']->sl($TCA[$table]['columns'][$field]['label']);
706
707 // Check for items:
708 foreach($fCfg['items'] as $iVal) {
709 if (strcmp($iVal[1],'')) { // Values '' is not controlled by this setting.
710
711 // Find iMode:
712 $iMode = '';
713 switch((string)$fCfg['authMode']) {
714 case 'explicitAllow':
715 $iMode = 'ALLOW';
716 break;
717 case 'explicitDeny':
718 $iMode = 'DENY';
719 break;
720 case 'individual':
721 if (!strcmp($iVal[4],'EXPL_ALLOW')) {
722 $iMode = 'ALLOW';
723 } elseif (!strcmp($iVal[4],'EXPL_DENY')) {
724 $iMode = 'DENY';
725 }
726 break;
727 }
728
729 // Set iMode:
730 if ($iMode) {
731 $allowDenyOptions[$table.':'.$field]['items'][$iVal[1]] = array($iMode, $GLOBALS['LANG']->sl($iVal[0]), $adLabel[$iMode]);
732 }
733 }
734 }
735 }
736 }
737 }
738 }
739 }
740
741 return $allowDenyOptions;
742 }
743
744 /**
745 * Returns an array with system languages:
746 *
747 * @return array Array with languages
748 */
749 function getSystemLanguages() {
750
751 // Initialize, add default language:
752 $sysLanguages = array();
753 $sysLanguages[] = array('Default language', 0);
754
755 // Traverse languages
756 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,title,flag','sys_language','pid=0'.t3lib_BEfunc::deleteClause('sys_language'));
757 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
758 $sysLanguages[] = array($row['title'].' ['.$row['uid'].']', $row['uid'], ($row['flag'] ? '../t3lib/gfx/flags/'.$row['flag'] : ''));
759 }
760
761 return $sysLanguages;
762 }
763
764 /**
765 * 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.
766 * If $id is zero a pseudo root-page with "_thePath" set is returned IF the current BE_USER is admin.
767 * In any case ->isInWebMount must return true for the user (regardless of $perms_clause)
768 * Usage: 21
769 *
770 * @param integer Page uid for which to check read-access
771 * @param string $perms_clause is typically a value generated with $BE_USER->getPagePermsClause(1);
772 * @return array Returns page record if OK, otherwise false.
773 */
774 function readPageAccess($id,$perms_clause) {
775 if ((string)$id!='') {
776 $id = intval($id);
777 if (!$id) {
778 if ($GLOBALS['BE_USER']->isAdmin()) {
779 $path = '/';
780 $pageinfo['_thePath'] = $path;
781 return $pageinfo;
782 }
783 } else {
784 $pageinfo = t3lib_BEfunc::getRecord('pages',$id,'*',($perms_clause ? ' AND '.$perms_clause : ''));
785 if ($pageinfo['uid'] && $GLOBALS['BE_USER']->isInWebMount($id,$perms_clause)) {
786 list($pageinfo['_thePath'],$pageinfo['_thePathFull']) = t3lib_BEfunc::getRecordPath(intval($pageinfo['uid']), $perms_clause, 15, 1000);
787 return $pageinfo;
788 }
789 }
790 }
791 return false;
792 }
793
794 /**
795 * Returns the "types" configuration parsed into an array for the record, $rec, from table, $table
796 * Usage: 6
797 *
798 * @param string Table name (present in TCA)
799 * @param array Record from $table
800 * @param boolean If $useFieldNameAsKey is set, then the fieldname is associative keys in the return array, otherwise just numeric keys.
801 * @return array
802 */
803 function getTCAtypes($table,$rec,$useFieldNameAsKey=0) {
804 global $TCA;
805
806 t3lib_div::loadTCA($table);
807 if ($TCA[$table]) {
808
809 // Get type value:
810 $fieldValue = t3lib_BEfunc::getTCAtypeValue($table,$rec);
811
812 // Get typesConf
813 $typesConf = $TCA[$table]['types'][$fieldValue];
814
815 // Get fields list and traverse it
816 $fieldList = explode(',', $typesConf['showitem']);
817 $altFieldList = array();
818
819 // Traverse fields in types config and parse the configuration into a nice array:
820 foreach($fieldList as $k => $v) {
821 list($pFieldName, $pAltTitle, $pPalette, $pSpec) = t3lib_div::trimExplode(';', $v);
822 $defaultExtras = is_array($TCA[$table]['columns'][$pFieldName]) ? $TCA[$table]['columns'][$pFieldName]['defaultExtras'] : '';
823 $specConfParts = t3lib_BEfunc::getSpecConfParts($pSpec, $defaultExtras);
824
825 $fieldList[$k]=array(
826 'field' => $pFieldName,
827 'title' => $pAltTitle,
828 'palette' => $pPalette,
829 'spec' => $specConfParts,
830 'origString' => $v
831 );
832 if ($useFieldNameAsKey) {
833 $altFieldList[$fieldList[$k]['field']] = $fieldList[$k];
834 }
835 }
836 if ($useFieldNameAsKey) {
837 $fieldList = $altFieldList;
838 }
839
840 // Return array:
841 return $fieldList;
842 }
843 }
844
845 /**
846 * Returns the "type" value of $rec from $table which can be used to look up the correct "types" rendering section in $TCA
847 * If no "type" field is configured in the "ctrl"-section of the $TCA for the table, zero is used.
848 * 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)
849 * Usage: 7
850 *
851 * @param string Table name present in TCA
852 * @param array Record from $table
853 * @return string Field value
854 * @see getTCAtypes()
855 */
856 function getTCAtypeValue($table,$rec) {
857 global $TCA;
858
859 // 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.
860 t3lib_div::loadTCA($table);
861 if ($TCA[$table]) {
862 $field = $TCA[$table]['ctrl']['type'];
863 $fieldValue = $field ? ($rec[$field] ? $rec[$field] : 0) : 0;
864 if (!is_array($TCA[$table]['types'][$fieldValue])) $fieldValue = 1;
865 return $fieldValue;
866 }
867 }
868
869 /**
870 * Parses a part of the field lists in the "types"-section of $TCA arrays, namely the "special configuration" at index 3 (position 4)
871 * Elements are splitted by ":" and within those parts, parameters are splitted by "|".
872 * 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
873 * Usage: 5
874 *
875 * @param string Content from the "types" configuration of TCA (the special configuration) - see description of function
876 * @param string The ['defaultExtras'] value from field configuration
877 * @return array
878 */
879 function getSpecConfParts($str, $defaultExtras) {
880
881 // Add defaultExtras:
882 $specConfParts = t3lib_div::trimExplode(':', $defaultExtras.':'.$str, 1);
883
884 if (count($specConfParts)) {
885 foreach($specConfParts as $k2 => $v2) {
886 unset($specConfParts[$k2]);
887 if (ereg('(.*)\[(.*)\]',$v2,$reg)) {
888 $specConfParts[trim($reg[1])] = array(
889 'parameters' => t3lib_div::trimExplode('|', $reg[2], 1)
890 );
891 } else {
892 $specConfParts[trim($v2)] = 1;
893 }
894 }
895 } else {
896 $specConfParts = array();
897 }
898 return $specConfParts;
899 }
900
901 /**
902 * Takes an array of "[key]=[value]" strings and returns an array with the keys set as keys pointing to the value.
903 * Better see it in action! Find example in Inside TYPO3
904 * Usage: 6
905 *
906 * @param array Array of "[key]=[value]" strings to convert.
907 * @return array
908 */
909 function getSpecConfParametersFromArray($pArr) {
910 $out=array();
911 if (is_array($pArr)) {
912 reset($pArr);
913 while(list($k,$v)=each($pArr)) {
914 $parts=explode('=',$v,2);
915 if (count($parts)==2) {
916 $out[trim($parts[0])]=trim($parts[1]);
917 } else {
918 $out[$k]=$v;
919 }
920 }
921 }
922 return $out;
923 }
924
925 /**
926 * Finds the Data Structure for a FlexForm field
927 * Usage: 5
928 *
929 * @param array Field config array
930 * @param array Record data
931 * @param string The table name
932 * @return mixed If array, the data structure was found and returned as an array. Otherwise (string) it is an error message.
933 * @see t3lib_TCEforms::getSingleField_typeFlex()
934 */
935 function getFlexFormDS($conf,$row,$table) {
936
937 // Get pointer field etc from TCA-config:
938 $ds_pointerField = $conf['ds_pointerField'];
939 $ds_array = $conf['ds'];
940 $ds_tableField = $conf['ds_tableField'];
941 $ds_searchParentField = $conf['ds_pointerField_searchParent'];
942
943 // Find source value:
944 $dataStructArray='';
945 if (is_array($ds_array)) { // If there is a data source array, that takes precedence
946 // If a pointer field is set, take the value from that field in the $row array and use as key.
947 if ($ds_pointerField) {
948 $srcPointer = $row[$ds_pointerField];
949 $srcPointer = isset($ds_array[$srcPointer]) ? $srcPointer : 'default';
950 } else $srcPointer='default';
951
952 // 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.
953 if (substr($ds_array[$srcPointer],0,5)=='FILE:') {
954 $file = t3lib_div::getFileAbsFileName(substr($ds_array[$srcPointer],5));
955 if ($file && @is_file($file)) {
956 $dataStructArray = t3lib_div::xml2array(t3lib_div::getUrl($file));
957 } else $dataStructArray = 'The file "'.substr($dsSrc,5).'" in ds-array key "'.$srcPointer.'" was not found ("'.$file.'")'; // Error message.
958 } else {
959 $dataStructArray = t3lib_div::xml2array($ds_array[$srcPointer]);
960 }
961
962 } elseif ($ds_pointerField) { // If pointer field AND possibly a table/field is set:
963 // Value of field pointed to:
964 $srcPointer = $row[$ds_pointerField];
965
966 // Searching recursively back if 'ds_pointerField_searchParent' is defined (typ. a page rootline, or maybe a tree-table):
967 if ($ds_searchParentField && !$srcPointer) {
968 $rr = t3lib_BEfunc::getRecord($table,$row['uid'],'uid,'.$ds_searchParentField); // Get the "pid" field - we cannot know that it is in the input record!
969 t3lib_BEfunc::fixVersioningPid($table,$rr);
970 $uidAcc=array(); // Used to avoid looping, if any should happen.
971 $subFieldPointer = $conf['ds_pointerField_searchParent_subField'];
972 while(!$srcPointer) {
973 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
974 'uid,'.$ds_pointerField.','.$ds_searchParentField.($subFieldPointer?','.$subFieldPointer:''),
975 $table,
976 'uid='.intval($rr[$ds_searchParentField]).t3lib_BEfunc::deleteClause($table)
977 );
978 $rr = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
979
980 // break if no result from SQL db or if looping...
981 if (!is_array($rr) || isset($uidAcc[$rr['uid']])) break;
982 $uidAcc[$rr['uid']]=1;
983
984 t3lib_BEfunc::fixVersioningPid($table,$rr);
985 $srcPointer = ($subFieldPointer && $rr[$subFieldPointer]) ? $rr[$subFieldPointer] : $rr[$ds_pointerField];
986 }
987 }
988
989 // If there is a srcPointer value:
990 if ($srcPointer) {
991 if (t3lib_div::testInt($srcPointer)) { // If integer, then its a record we will look up:
992 list($tName,$fName) = explode(':',$ds_tableField,2);
993 if ($tName && $fName && is_array($GLOBALS['TCA'][$tName])) {
994 $dataStructRec = t3lib_BEfunc::getRecord($tName, $srcPointer);
995 $dataStructArray = t3lib_div::xml2array($dataStructRec[$fName]);
996 } else $dataStructArray = 'No tablename ('.$tName.') or fieldname ('.$fName.') was found an valid!';
997 } else { // Otherwise expect it to be a file:
998 $file = t3lib_div::getFileAbsFileName($srcPointer);
999 if ($file && @is_file($file)) {
1000 $dataStructArray = t3lib_div::xml2array(t3lib_div::getUrl($file));
1001 } else $dataStructArray='The file "'.$srcPointer.'" was not found ("'.$file.'")'; // Error message.
1002 }
1003 } else $dataStructArray='No source value in fieldname "'.$ds_pointerField.'"'; // Error message.
1004 } else $dataStructArray='No proper configuration!';
1005 return $dataStructArray;
1006 }
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025 /*******************************************
1026 *
1027 * Caching related
1028 *
1029 *******************************************/
1030
1031 /**
1032 * Stores the string value $data in the 'cache_hash' table with the hash key, $hash, and visual/symbolic identification, $ident
1033 * IDENTICAL to the function by same name found in t3lib_page:
1034 * Usage: 2
1035 *
1036 * @param string Hash key, 32 bytes hex
1037 * @param string $data must be serialized before function call
1038 * @param string Visual/symbolic identification (informational only)
1039 * @return void
1040 */
1041 function storeHash($hash,$data,$ident) {
1042 $insertFields = array(
1043 'hash' => $hash,
1044 'content' => $data,
1045 'ident' => $ident,
1046 'tstamp' => time()
1047 );
1048 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_hash', 'hash="'.$GLOBALS['TYPO3_DB']->quoteStr($hash, 'cache_hash').'"');
1049 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_hash', $insertFields);
1050 }
1051
1052 /**
1053 * Retrieves the string content stored with hash key, $hash, in cache_hash
1054 * IDENTICAL to the function by same name found in t3lib_page:
1055 * Usage: 2
1056 *
1057 * @param string Hash key, 32 bytes hex
1058 * @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.
1059 * @return string
1060 */
1061 function getHash($hash,$expTime) {
1062 // if expTime is not set, the hash will never expire
1063 $expTime = intval($expTime);
1064 if ($expTime) {
1065 $whereAdd = ' AND tstamp > '.(time()-$expTime);
1066 }
1067 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_hash', 'hash="'.$GLOBALS['TYPO3_DB']->quoteStr($hash, 'cache_hash').'"'.$whereAdd);
1068 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1069 return $row['content'];
1070 }
1071 }
1072
1073
1074
1075
1076
1077
1078
1079
1080 /*******************************************
1081 *
1082 * TypoScript related
1083 *
1084 *******************************************/
1085
1086 /**
1087 * Returns the Page TSconfig for page with id, $id
1088 * Requires class "t3lib_TSparser"
1089 * Usage: 26 (spec. in ext info_pagetsconfig)
1090 *
1091 * @param integer Page uid for which to create Page TSconfig
1092 * @param array If $rootLine is an array, that is used as rootline, otherwise rootline is just calculated
1093 * @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.
1094 * @return array Page TSconfig
1095 * @see t3lib_TSparser
1096 */
1097 function getPagesTSconfig($id,$rootLine='',$returnPartArray=0) {
1098 $id=intval($id);
1099 if (!is_array($rootLine)) {
1100 $rootLine = t3lib_BEfunc::BEgetRootLine($id,'');
1101 }
1102 ksort($rootLine); // Order correctly, changed 030102
1103 reset($rootLine);
1104 $TSdataArray = array();
1105 $TSdataArray['defaultPageTSconfig']=$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig']; // Setting default configuration:
1106 while(list($k,$v)=each($rootLine)) {
1107 $TSdataArray['uid_'.$v['uid']]=$v['TSconfig'];
1108 }
1109 $TSdataArray = t3lib_TSparser::checkIncludeLines_array($TSdataArray);
1110 if ($returnPartArray) {
1111 return $TSdataArray;
1112 }
1113
1114 // Parsing the user TS (or getting from cache)
1115 $userTS = implode($TSdataArray,chr(10).'[GLOBAL]'.chr(10));
1116 $hash = md5('pageTS:'.$userTS);
1117 $cachedContent = t3lib_BEfunc::getHash($hash,0);
1118 $TSconfig = array();
1119 if (isset($cachedContent)) {
1120 $TSconfig = unserialize($cachedContent);
1121 } else {
1122 $parseObj = t3lib_div::makeInstance('t3lib_TSparser');
1123 $parseObj->parse($userTS);
1124 $TSconfig = $parseObj->setup;
1125 t3lib_BEfunc::storeHash($hash,serialize($TSconfig),'PAGES_TSconfig');
1126 }
1127 return $TSconfig;
1128 }
1129
1130 /**
1131 * Updates Page TSconfig for a page with $id
1132 * 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.
1133 * $impParams can be supplied as already known Page TSconfig, otherwise it's calculated.
1134 *
1135 * THIS DOES NOT CHECK ANY PERMISSIONS. SHOULD IT?
1136 * More documentation is needed.
1137 *
1138 * Usage: 1 (ext. direct_mail)
1139 *
1140 * @param integer Page id
1141 * @param array Page TS array to write
1142 * @param string Prefix for object paths
1143 * @param array [Description needed.]
1144 * @return void
1145 * @internal
1146 * @see implodeTSParams(), getPagesTSconfig()
1147 */
1148 function updatePagesTSconfig($id,$pageTS,$TSconfPrefix,$impParams='') {
1149 $id=intval($id);
1150 if (is_array($pageTS) && $id>0) {
1151 if (!is_array($impParams)) {
1152 $impParams =t3lib_BEfunc::implodeTSParams(t3lib_BEfunc::getPagesTSconfig($id));
1153 }
1154 reset($pageTS);
1155 $set=array();
1156 while(list($f,$v)=each($pageTS)) {
1157 $f = $TSconfPrefix.$f;
1158 if ((!isset($impParams[$f])&&trim($v)) || strcmp(trim($impParams[$f]),trim($v))) {
1159 $set[$f]=trim($v);
1160 }
1161 }
1162 if (count($set)) {
1163 // Get page record and TS config lines
1164 $pRec = t3lib_befunc::getRecord('pages',$id);
1165 $TSlines = explode(chr(10),$pRec['TSconfig']);
1166 $TSlines = array_reverse($TSlines);
1167 // Reset the set of changes.
1168 reset($set);
1169 while(list($f,$v)=each($set)) {
1170 reset($TSlines);
1171 $inserted=0;
1172 while(list($ki,$kv)=each($TSlines)) {
1173 if (substr($kv,0,strlen($f)+1)==$f.'=') {
1174 $TSlines[$ki]=$f.'='.$v;
1175 $inserted=1;
1176 break;
1177 }
1178 }
1179 if (!$inserted) {
1180 $TSlines = array_reverse($TSlines);
1181 $TSlines[]=$f.'='.$v;
1182 $TSlines = array_reverse($TSlines);
1183 }
1184 }
1185 $TSlines = array_reverse($TSlines);
1186
1187 // store those changes
1188 $TSconf = implode(chr(10),$TSlines);
1189
1190 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('pages', 'uid='.intval($id), array('TSconfig' => $TSconf));
1191 }
1192 }
1193 }
1194
1195 /**
1196 * Implodes a multi dimensional TypoScript array, $p, into a one-dimentional array (return value)
1197 * Usage: 3
1198 *
1199 * @param array TypoScript structure
1200 * @param string Prefix string
1201 * @return array Imploded TypoScript objectstring/values
1202 */
1203 function implodeTSParams($p,$k='') {
1204 $implodeParams=array();
1205 if (is_array($p)) {
1206 reset($p);
1207 while(list($kb,$val)=each($p)) {
1208 if (is_array($val)) {
1209 $implodeParams = array_merge($implodeParams,t3lib_BEfunc::implodeTSParams($val,$k.$kb));
1210 } else {
1211 $implodeParams[$k.$kb]=$val;
1212 }
1213 }
1214 }
1215 return $implodeParams;
1216 }
1217
1218
1219
1220
1221
1222
1223
1224
1225 /*******************************************
1226 *
1227 * Users / Groups related
1228 *
1229 *******************************************/
1230
1231 /**
1232 * Returns an array with be_users records of all user NOT DELETED sorted by their username
1233 * Keys in the array is the be_users uid
1234 * Usage: 14 (spec. ext. "beuser" and module "web_perm")
1235 *
1236 * @param string Optional $fields list (default: username,usergroup,usergroup_cached_list,uid) can be used to set the selected fields
1237 * @param string Optional $where clause (fx. "AND username='pete'") can be used to limit query
1238 * @return array
1239 */
1240 function getUserNames($fields='username,usergroup,usergroup_cached_list,uid',$where='') {
1241 $be_user_Array=Array();
1242
1243 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, 'be_users', 'pid=0 '.$where.t3lib_BEfunc::deleteClause('be_users'), '', 'username');
1244 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1245 $be_user_Array[$row['uid']]=$row;
1246 }
1247 return $be_user_Array;
1248 }
1249
1250 /**
1251 * Returns an array with be_groups records (title, uid) of all groups NOT DELETED sorted by their title
1252 * Usage: 8 (spec. ext. "beuser" and module "web_perm")
1253 *
1254 * @param string Field list
1255 * @param string WHERE clause
1256 * @return array
1257 */
1258 function getGroupNames($fields='title,uid', $where='') {
1259 $be_group_Array = Array();
1260 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, 'be_groups', 'pid=0 '.$where.t3lib_BEfunc::deleteClause('be_groups'), '', 'title');
1261 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1262 $be_group_Array[$row['uid']] = $row;
1263 }
1264 return $be_group_Array;
1265 }
1266
1267 /**
1268 * Returns an array with be_groups records (like ->getGroupNames) but:
1269 * - 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.
1270 * Usage: 2 (module "web_perm" and ext. taskcenter)
1271 *
1272 * @param string Field list; $fields specify the fields selected (default: title,uid)
1273 * @return array
1274 */
1275 function getListGroupNames($fields='title,uid') {
1276 $exQ=' AND hide_in_lists=0';
1277 if (!$GLOBALS['BE_USER']->isAdmin()) {
1278 $exQ.=' AND uid IN ('.($GLOBALS['BE_USER']->user['usergroup_cached_list']?$GLOBALS['BE_USER']->user['usergroup_cached_list']:0).')';
1279 }
1280 return t3lib_BEfunc::getGroupNames($fields,$exQ);
1281 }
1282
1283 /**
1284 * Returns the array $usernames with the names of all users NOT IN $groupArray changed to the uid (hides the usernames!).
1285 * If $excludeBlindedFlag is set, then these records are unset from the array $usernames
1286 * Takes $usernames (array made by t3lib_BEfunc::getUserNames()) and a $groupArray (array with the groups a certain user is member of) as input
1287 * Usage: 8
1288 *
1289 * @param array User names
1290 * @param array Group names
1291 * @param boolean If $excludeBlindedFlag is set, then these records are unset from the array $usernames
1292 * @return array User names, blinded
1293 */
1294 function blindUserNames($usernames,$groupArray,$excludeBlindedFlag=0) {
1295 if (is_array($usernames) && is_array($groupArray)) {
1296 while(list($uid,$row)=each($usernames)) {
1297 $userN=$uid;
1298 $set=0;
1299 if ($row['uid']!=$GLOBALS['BE_USER']->user['uid']) {
1300 reset($groupArray);
1301 while(list(,$v)=each($groupArray)) {
1302 if ($v && t3lib_div::inList($row['usergroup_cached_list'],$v)) {
1303 $userN = $row['username'];
1304 $set=1;
1305 }
1306 }
1307 } else {
1308 $userN = $row['username'];
1309 $set=1;
1310 }
1311 $usernames[$uid]['username']=$userN;
1312 if ($excludeBlindedFlag && !$set) {unset($usernames[$uid]);}
1313 }
1314 }
1315 return $usernames;
1316 }
1317
1318 /**
1319 * Corresponds to blindUserNames but works for groups instead
1320 * Usage: 2 (module web_perm)
1321 *
1322 * @param array Group names
1323 * @param array Group names (reference)
1324 * @param boolean If $excludeBlindedFlag is set, then these records are unset from the array $usernames
1325 * @return array
1326 */
1327 function blindGroupNames($groups,$groupArray,$excludeBlindedFlag=0) {
1328 if (is_array($groups) && is_array($groupArray)) {
1329 while(list($uid,$row)=each($groups)) {
1330 $groupN=$uid;
1331 $set=0;
1332 if (t3lib_div::inArray($groupArray,$uid)) {
1333 $groupN=$row['title'];
1334 $set=1;
1335 }
1336 $groups[$uid]['title']=$groupN;
1337 if ($excludeBlindedFlag && !$set) {unset($groups[$uid]);}
1338 }
1339 }
1340 return $groups;
1341 }
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355 /*******************************************
1356 *
1357 * Output related
1358 *
1359 *******************************************/
1360
1361
1362
1363 /**
1364 * Returns the difference in days between input $tstamp and $EXEC_TIME
1365 * Usage: 2 (class t3lib_BEfunc)
1366 *
1367 * @param integer Time stamp, seconds
1368 * @return integer
1369 */
1370 function daysUntil($tstamp) {
1371 $delta_t = $tstamp-$GLOBALS['EXEC_TIME'];
1372 return ceil($delta_t/(3600*24));
1373 }
1374
1375 /**
1376 * Returns $tstamp formatted as "ddmmyy" (According to $TYPO3_CONF_VARS['SYS']['ddmmyy'])
1377 * Usage: 11
1378 *
1379 * @param integer Time stamp, seconds
1380 * @return string Formatted time
1381 */
1382 function date($tstamp) {
1383 return Date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],$tstamp);
1384 }
1385
1386 /**
1387 * Returns $tstamp formatted as "ddmmyy hhmm" (According to $TYPO3_CONF_VARS['SYS']['ddmmyy'] AND $TYPO3_CONF_VARS['SYS']['hhmm'])
1388 * Usage: 28
1389 *
1390 * @param integer Time stamp, seconds
1391 * @return string Formatted time
1392 */
1393 function datetime($value) {
1394 return Date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'].' '.$GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],$value);
1395 }
1396
1397 /**
1398 * Returns $value (in seconds) formatted as hh:mm:ss
1399 * For instance $value = 3600 + 60*2 + 3 should return "01:02:03"
1400 * Usage: 1 (class t3lib_BEfunc)
1401 *
1402 * @param integer Time stamp, seconds
1403 * @return string Formatted time
1404 */
1405 function time($value) {
1406 $hh = floor($value/3600);
1407 $min = floor(($value-$hh*3600)/60);
1408 $sec = $value-$hh*3600-$min*60;
1409 $l = sprintf('%02d',$hh).':'.sprintf('%02d',$min).':'.sprintf('%02d',$sec);
1410 return $l;
1411 }
1412
1413 /**
1414 * Returns the "age" in minutes / hours / days / years of the number of $seconds inputted.
1415 * Usage: 15
1416 *
1417 * @param integer $seconds could be the difference of a certain timestamp and time()
1418 * @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")
1419 * @return string Formatted time
1420 */
1421 function calcAge($seconds,$labels = 'min|hrs|days|yrs') {
1422 $labelArr = explode('|',$labels);
1423 $prefix='';
1424 if ($seconds<0) {$prefix='-'; $seconds=abs($seconds);}
1425 if ($seconds<3600) {
1426 $seconds = round ($seconds/60).' '.trim($labelArr[0]);
1427 } elseif ($seconds<24*3600) {
1428 $seconds = round ($seconds/3600).' '.trim($labelArr[1]);
1429 } elseif ($seconds<365*24*3600) {
1430 $seconds = round ($seconds/(24*3600)).' '.trim($labelArr[2]);
1431 } else {
1432 $seconds = round ($seconds/(365*24*3600)).' '.trim($labelArr[3]);
1433 }
1434 return $prefix.$seconds;
1435 }
1436
1437 /**
1438 * Returns a formatted timestamp if $tstamp is set.
1439 * The date/datetime will be followed by the age in parenthesis.
1440 * Usage: 3
1441 *
1442 * @param integer Time stamp, seconds
1443 * @param integer 1/-1 depending on polarity of age.
1444 * @param string $date=="date" will yield "dd:mm:yy" formatting, otherwise "dd:mm:yy hh:mm"
1445 * @return string
1446 */
1447 function dateTimeAge($tstamp,$prefix=1,$date='') {
1448 return $tstamp ?
1449 ($date=='date' ? t3lib_BEfunc::date($tstamp) : t3lib_BEfunc::datetime($tstamp)).
1450 ' ('.t3lib_BEfunc::calcAge($prefix*(time()-$tstamp),$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')).')' : '';
1451 }
1452
1453 /**
1454 * Returns either title='' or alt='' attribute. This depends on the client browser and whether it supports title='' or not (which is the default)
1455 * If no $content is given only the attribute name is returned.
1456 * The returned attribute with content will have a leading space char.
1457 * Warning: Be careful to submit empty $content var - that will return just the attribute name!
1458 * Usage: 0
1459 *
1460 * @param string String to set as title-attribute. If no $content is given only the attribute name is returned.
1461 * @param boolean If $hsc is set, then content of the attribute is htmlspecialchar()'ed (which is good for XHTML and other reasons...)
1462 * @return string
1463 * @depreciated The idea made sense with older browsers, but now all browsers should support the "title" attribute - so just hardcode the title attribute instead!
1464 */
1465 function titleAttrib($content='',$hsc=0) {
1466 global $CLIENT;
1467 $attrib= ($CLIENT['BROWSER']=='net'&&$CLIENT['VERSION']<5)||$CLIENT['BROWSER']=='konqu' ? 'alt' : 'title';
1468 return strcmp($content,'')?' '.$attrib.'="'.($hsc?htmlspecialchars($content):$content).'"' : $attrib;
1469 }
1470
1471 /**
1472 * Returns alt="" and title="" attributes with the value of $content.
1473 * Usage: 7
1474 *
1475 * @param string Value for 'alt' and 'title' attributes (will be htmlspecialchars()'ed before output)
1476 * @return string
1477 */
1478 function titleAltAttrib($content) {
1479 $out='';
1480 $out.=' alt="'.htmlspecialchars($content).'"';
1481 $out.=' title="'.htmlspecialchars($content).'"';
1482 return $out;
1483 }
1484
1485 /**
1486 * 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
1487 * All $TYPO3_CONF_VARS['GFX']['imagefile_ext'] extension are made to thumbnails + ttf file (renders font-example)
1488 * Thumbsnails are linked to the show_item.php script which will display further details.
1489 * Usage: 7
1490 *
1491 * @param array $row is the database row from the table, $table.
1492 * @param string Table name for $row (present in TCA)
1493 * @param string $field is pointing to the field with the list of image files
1494 * @param string Back path prefix for image tag src="" field
1495 * @param string Optional: $thumbScript os by default 'thumbs.php' if you don't set it otherwise
1496 * @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!)
1497 * @param boolean If set, uploaddir is NOT prepended with "../"
1498 * @param string Optional: $tparams is additional attributes for the image tags
1499 * @param integer Optional: $size is [w]x[h] of the thumbnail. 56 is default.
1500 * @return string Thumbnail image tag.
1501 */
1502 function thumbCode($row,$table,$field,$backPath,$thumbScript='',$uploaddir=NULL,$abs=0,$tparams='',$size='') {
1503 global $TCA;
1504 // Load table.
1505 t3lib_div::loadTCA($table);
1506
1507 // Find uploaddir automatically
1508 $uploaddir = (is_null($uploaddir)) ? $TCA[$table]['columns'][$field]['config']['uploadfolder'] : $uploaddir;
1509 $uploaddir = preg_replace('#/$#','',$uploaddir);
1510
1511 // Set thumbs-script:
1512 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails']) {
1513 $thumbScript='gfx/notfound_thumb.gif';
1514 } elseif(!$thumbScript) {
1515 $thumbScript='thumbs.php';
1516 }
1517 // Check and parse the size parameter
1518 $sizeParts=array();
1519 if ($size = trim($size)) {
1520 $sizeParts = explode('x', $size.'x'.$size);
1521 if(!intval($sizeParts[0])) $size='';
1522 }
1523
1524 // Traverse files:
1525 $thumbs = explode(',', $row[$field]);
1526 $thumbData='';
1527 while(list(,$theFile)=each($thumbs)) {
1528 if (trim($theFile)) {
1529 $fI = t3lib_div::split_fileref($theFile);
1530 $ext = $fI['fileext'];
1531 // New 190201 start
1532 $max=0;
1533 if (t3lib_div::inList('gif,jpg,png',$ext)) {
1534 $imgInfo=@getimagesize(PATH_site.$uploaddir.'/'.$theFile);
1535 if (is_array($imgInfo)) {$max = max($imgInfo[0],$imgInfo[1]);}
1536 }
1537 // use the original image if it's size fits to the thumbnail size
1538 if ($max && $max<=(count($sizeParts)&&max($sizeParts)?max($sizeParts):56)) {
1539 $url = $uploaddir.'/'.trim($theFile);
1540 $theFile = '../'.$url;
1541 $onClick='top.launchView(\''.$theFile.'\',\'\',\''.$backPath.'\');return false;';
1542 $thumbData.='<a href="#" onclick="'.htmlspecialchars($onClick).'"><img src="../'.$backPath.$url.'" '.$imgInfo[3].' hspace="2" border="0" title="'.trim($url).'"'.$tparams.' alt="" /></a> ';
1543 // New 190201 stop
1544 } elseif ($ext=='ttf' || t3lib_div::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],$ext)) {
1545 $theFile = ($abs?'':'../').($uploaddir?$uploaddir.'/':'').trim($theFile);
1546 $params = '&file='.rawurlencode($theFile);
1547 $params .= $size?'&size='.$size:'';
1548 $url = $thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
1549 $onClick='top.launchView(\''.$theFile.'\',\'\',\''.$backPath.'\');return false;';
1550 $thumbData.='<a href="#" onclick="'.htmlspecialchars($onClick).'"><img src="'.htmlspecialchars($backPath.$url).'" hspace="2" border="0" title="'.trim($theFile).'"'.$tparams.' alt="" /></a> ';
1551 } else {
1552 $icon = t3lib_BEfunc::getFileIcon($ext);
1553 $url = 'gfx/fileicons/'.$icon;
1554 $thumbData.='<img src="'.$backPath.$url.'" hspace="2" border="0" title="'.trim($theFile).'"'.$tparams.' alt="" /> ';
1555 }
1556 }
1557 }
1558 return $thumbData;
1559 }
1560
1561 /**
1562 * Returns single image tag to thumbnail using a thumbnail script (like thumbs.php)
1563 * Usage: 3
1564 *
1565 * @param string $thumbScript must point to "thumbs.php" relative to the script position
1566 * @param string $theFile must be the proper reference to the file thumbs.php should show
1567 * @param string $tparams are additional attributes for the image tag
1568 * @param integer $size is the size of the thumbnail send along to "thumbs.php"
1569 * @return string Image tag
1570 */
1571 function getThumbNail($thumbScript,$theFile,$tparams='',$size='') {
1572 $params = '&file='.rawurlencode($theFile);
1573 $params .= trim($size)?'&size='.trim($size):'';
1574 $url = $thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
1575 $th='<img src="'.htmlspecialchars($url).'" title="'.trim(basename($theFile)).'"'.($tparams?" ".$tparams:"").' alt="" />';
1576 return $th;
1577 }
1578
1579 /**
1580 * Returns title-attribute information for a page-record informing about id, alias, doktype, hidden, starttime, endtime, fe_group etc.
1581 * Usage: 8
1582 *
1583 * @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)
1584 * @param string $perms_clause is used to get the record path of the shortcut page, if any (and doktype==4)
1585 * @param boolean If $includeAttrib is set, then the 'title=""' attribute is wrapped about the return value, which is in any case htmlspecialchar()'ed already
1586 * @return string
1587 */
1588 function titleAttribForPages($row,$perms_clause='',$includeAttrib=1) {
1589 global $TCA,$LANG;
1590 $parts=array();
1591 $parts[] = 'id='.$row['uid'];
1592 if ($row['alias']) $parts[]=$LANG->sL($TCA['pages']['columns']['alias']['label']).' '.$row['alias'];
1593 if ($row['t3ver_id']) $parts[] = 'v#'.$row['t3ver_id'];
1594 if ($row['doktype']=='3') {
1595 $parts[]=$LANG->sL($TCA['pages']['columns']['url']['label']).' '.$row['url'];
1596 } elseif ($row['doktype']=='4') {
1597 if ($perms_clause) {
1598 $label = t3lib_BEfunc::getRecordPath(intval($row['shortcut']),$perms_clause,20);
1599 } else {
1600 $lRec = t3lib_BEfunc::getRecord('pages',intval($row['shortcut']),'title');
1601 $label = $lRec['title'];
1602 }
1603 if ($row['shortcut_mode']>0) {
1604 $label.=', '.$LANG->sL($TCA['pages']['columns']['shortcut_mode']['label']).' '.
1605 $LANG->sL(t3lib_BEfunc::getLabelFromItemlist('pages','shortcut_mode',$row['shortcut_mode']));
1606 }
1607 $parts[]=$LANG->sL($TCA['pages']['columns']['shortcut']['label']).' '.$label;
1608 } elseif ($row['doktype']=='7') {
1609 if ($perms_clause) {
1610 $label = t3lib_BEfunc::getRecordPath(intval($row['mount_pid']),$perms_clause,20);
1611 } else {
1612 $lRec = t3lib_BEfunc::getRecord('pages',intval($row['mount_pid']),'title');
1613 $label = $lRec['title'];
1614 }
1615 $parts[]=$LANG->sL($TCA['pages']['columns']['mount_pid']['label']).' '.$label;
1616 if ($row['mount_pid_ol']) {
1617 $parts[] = $LANG->sL($TCA['pages']['columns']['mount_pid_ol']['label']);
1618 }
1619 }
1620 if ($row['nav_hide']) $parts[] = ereg_replace(':$','',$LANG->sL($TCA['pages']['columns']['nav_hide']['label']));
1621 if ($row['hidden']) $parts[] = $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.hidden');
1622 if ($row['starttime']) $parts[] = $LANG->sL($TCA['pages']['columns']['starttime']['label']).' '.t3lib_BEfunc::dateTimeAge($row['starttime'],-1,'date');
1623 if ($row['endtime']) $parts[] = $LANG->sL($TCA['pages']['columns']['endtime']['label']).' '.t3lib_BEfunc::dateTimeAge($row['endtime'],-1,'date');
1624 if ($row['fe_group']) {
1625 if ($row['fe_group']<0) {
1626 $label = $LANG->sL(t3lib_BEfunc::getLabelFromItemlist('pages','fe_group',$row['fe_group']));
1627 } else {
1628 $lRec = t3lib_BEfunc::getRecord('fe_groups',$row['fe_group'],'title');
1629 $label = $lRec['title'];
1630 }
1631 $parts[] = $LANG->sL($TCA['pages']['columns']['fe_group']['label']).' '.$label;
1632 }
1633 $out = htmlspecialchars(implode(' - ',$parts));
1634 return $includeAttrib ? 'title="'.$out.'"' : $out;
1635 }
1636
1637 /**
1638 * Returns title-attribute information for ANY record (from a table defined in TCA of course)
1639 * 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.
1640 * "pages" table can be used as well and will return the result of ->titleAttribForPages() for that page.
1641 * Usage: 10
1642 *
1643 * @param array Table row; $row is a row from the table, $table
1644 * @param string Table name
1645 * @return string
1646 */
1647 function getRecordIconAltText($row,$table='pages') {
1648 if ($table=='pages') {
1649 $out = t3lib_BEfunc::titleAttribForPages($row,'',0);
1650 } else {
1651 $ctrl = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'];
1652
1653 $out='id='.$row['uid']; // Uid is added
1654 if ($table=='pages' && $row['alias']) {
1655 $out.=' / '.$row['alias'];
1656 }
1657 if ($GLOBALS['TCA'][$table]['ctrl']['versioning'] && $row['t3ver_id']) {
1658 $out.=' - v#'.$row['t3ver_id'];
1659 }
1660 if ($ctrl['disabled']) { // Hidden ...
1661 $out.=($row[$ctrl['disabled']]?' - '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.hidden'):'');
1662 }
1663 if ($ctrl['starttime']) {
1664 if ($row[$ctrl['starttime']] > $GLOBALS['EXEC_TIME']) {
1665 $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').')';
1666 }
1667 }
1668 if ($row[$ctrl['endtime']]) {
1669 $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').')';
1670 }
1671 }
1672 return htmlspecialchars($out);
1673 }
1674
1675 /**
1676 * Returns the label of the first found entry in an "items" array from $TCA (tablename=$table/fieldname=$col) where the value is $key
1677 * Usage: 9
1678 *
1679 * @param string Table name, present in $TCA
1680 * @param string Field name, present in $TCA
1681 * @param string items-array value to match
1682 * @return string Label for item entry
1683 */
1684 function getLabelFromItemlist($table,$col,$key) {
1685 global $TCA;
1686 // Load full TCA for $table
1687 t3lib_div::loadTCA($table);
1688
1689 // Check, if there is an "items" array:
1690 if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$col]) && is_array($TCA[$table]['columns'][$col]['config']['items'])) {
1691 // Traverse the items-array...
1692 reset($TCA[$table]['columns'][$col]['config']['items']);
1693 while(list($k,$v)=each($TCA[$table]['columns'][$col]['config']['items'])) {
1694 // ... and return the first found label where the value was equal to $key
1695 if (!strcmp($v[1],$key)) return $v[0];
1696 }
1697 }
1698 }
1699
1700 /**
1701 * Returns the label-value for fieldname $col in table, $table
1702 * 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>'
1703 * Usage: 17
1704 *
1705 * @param string Table name, present in $TCA
1706 * @param string Field name
1707 * @param string Wrap value - set function description
1708 * @return string
1709 */
1710 function getItemLabel($table,$col,$printAllWrap='') {
1711 global $TCA;
1712 // Load full TCA for $table
1713 t3lib_div::loadTCA($table);
1714 // Check if column exists
1715 if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$col])) {
1716 // Re
1717 return $TCA[$table]['columns'][$col]['label'];
1718 }
1719 if ($printAllWrap) {
1720 $parts = explode('|',$printAllWrap);
1721 return $parts[0].$col.$parts[1];
1722 }
1723 }
1724
1725 /**
1726 * Returns the "title"-value in record, $row, from table, $table
1727 * The field(s) from which the value is taken is determined by the "ctrl"-entries 'label', 'label_alt' and 'label_alt_force'
1728 * Usage: 26
1729 *
1730 * @param string Table name, present in TCA
1731 * @param array Row from table
1732 * @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
1733 * @return string
1734 */
1735 function getRecordTitle($table,$row,$prep=0) {
1736 global $TCA;
1737 if (is_array($TCA[$table])) {
1738 $t = $row[$TCA[$table]['ctrl']['label']];
1739 if ($TCA[$table]['ctrl']['label_alt'] && ($TCA[$table]['ctrl']['label_alt_force'] || !strcmp($t,''))) {
1740 $altFields=t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['label_alt'],1);
1741 $tA=array();
1742 $tA[]=$t;
1743 while(list(,$fN)=each($altFields)) {
1744 $t = $tA[] = trim(strip_tags($row[$fN]));
1745 if (strcmp($t,'') && !$TCA[$table]['ctrl']['label_alt_force']) break;
1746 }
1747 if ($TCA[$table]['ctrl']['label_alt_force']) $t=implode(', ',$tA);
1748 }
1749 if ($prep) {
1750 $t = htmlspecialchars(t3lib_div::fixed_lgd_cs($t,$GLOBALS['BE_USER']->uc['titleLen']));
1751 if (!strcmp(trim($t),'')) $t='<em>['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title',1).']</em>';
1752 }
1753 return $t;
1754 }
1755 }
1756
1757 /**
1758 * Returns a human readable output of a value from a record
1759 * 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.
1760 * $table/$col is tablename and fieldname
1761 * REMEMBER to pass the output through htmlspecialchars() if you output it to the browser! (To protect it from XSS attacks and be XHTML compliant)
1762 * Usage: 24
1763 *
1764 * @param string Table name, present in TCA
1765 * @param string Field name, present in TCA
1766 * @param string $value is the value of that field from a selected record
1767 * @param integer $fixed_lgd_chars is the max amount of characters the value may occupy
1768 * @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")
1769 * @return string
1770 */
1771 function getProcessedValue($table,$col,$value,$fixed_lgd_chars=0,$defaultPassthrough=0) {
1772 global $TCA;
1773 // Load full TCA for $table
1774 t3lib_div::loadTCA($table);
1775 // Check if table and field is configured:
1776 if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$col])) {
1777 // Depending on the fields configuration, make a meaningful output value.
1778 $theColConf = $TCA[$table]['columns'][$col]['config'];
1779 $l='';
1780 switch((string)$theColConf['type']) {
1781 case 'radio':
1782 $l=t3lib_BEfunc::getLabelFromItemlist($table,$col,$value);
1783 break;
1784 case 'select':
1785 if ($theColConf['MM']) {
1786 $l='N/A';
1787 } else {
1788 $l=t3lib_BEfunc::getLabelFromItemlist($table,$col,$value);
1789 $l=$GLOBALS['LANG']->sL($l);
1790 if ($theColConf['foreign_table'] && !$l && $TCA[$theColConf['foreign_table']]) {
1791 $rParts = t3lib_div::trimExplode(',',$value,1);
1792 reset($rParts);
1793 $lA=array();
1794 while(list(,$rVal)=each($rParts)) {
1795 $rVal = intval($rVal);
1796 if ($rVal>0) {
1797 $r=t3lib_BEfunc::getRecord($theColConf['foreign_table'],$rVal);
1798 } else {
1799 $r=t3lib_BEfunc::getRecord($theColConf['neg_foreign_table'],-$rVal);
1800 }
1801 if (is_array($r)) {
1802 $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);
1803 } else {
1804 $lA[]=$rVal?'['.$rVal.'!]':'';
1805 }
1806 }
1807 $l=implode(',',$lA);
1808 }
1809 }
1810 break;
1811 case 'check':
1812 if (!is_array($theColConf['items']) || count($theColConf['items'])==1) {
1813 $l = $value ? 'Yes' : '';
1814 } else {
1815 reset($theColConf['items']);
1816 $lA=Array();
1817 while(list($key,$val)=each($theColConf['items'])) {
1818 if ($value & pow(2,$key)) {$lA[]=$GLOBALS['LANG']->sL($val[0]);}
1819 }
1820 $l = implode($lA,', ');
1821 }
1822 break;
1823 case 'input':
1824 if ($value) {
1825 if (t3lib_div::inList($theColConf['eval'],'date')) {
1826 $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')).')';
1827 } elseif (t3lib_div::inList($theColConf['eval'],'time')) {
1828 $l = t3lib_BEfunc::time($value);
1829 } elseif (t3lib_div::inList($theColConf['eval'],'datetime')) {
1830 $l = t3lib_BEfunc::datetime($value);
1831 } else {
1832 $l = $value;
1833 }
1834 }
1835 break;
1836 default:
1837 if ($defaultPassthrough) {
1838 $l=$value;
1839 } elseif ($theColConf['MM']) {
1840 $l='N/A';
1841 } elseif ($value) {
1842 $l=t3lib_div::fixed_lgd_cs(strip_tags($value),200);
1843 }
1844 break;
1845 }
1846 if ($fixed_lgd_chars) {
1847 return t3lib_div::fixed_lgd_cs($l,$fixed_lgd_chars);
1848 } else {
1849 return $l;
1850 }
1851 }
1852 }
1853
1854 /**
1855 * 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.
1856 * Usage: 2
1857 *
1858 * @param string Table name, present in TCA
1859 * @param string Field name
1860 * @param string Field value
1861 * @param integer $fixed_lgd_chars is the max amount of characters the value may occupy
1862 * @return string
1863 * @see getProcessedValue()
1864 */
1865 function getProcessedValueExtra($table,$fN,$fV,$fixed_lgd_chars=0) {
1866 global $TCA;
1867 $fVnew = t3lib_BEfunc::getProcessedValue($table,$fN,$fV,$fixed_lgd_chars);
1868 if (!isset($fVnew)) {
1869 if (is_array($TCA[$table])) {
1870 if ($fN==$TCA[$table]['ctrl']['tstamp'] || $fN==$TCA[$table]['ctrl']['crdate']) {
1871 $fVnew = t3lib_BEfunc::datetime($fV);
1872 } elseif ($fN=='pid'){
1873 $fVnew = t3lib_BEfunc::getRecordPath($fV,'1',20); // Fetches the path with no regard to the users permissions to select pages.
1874 } else {
1875 $fVnew = $fV;
1876 }
1877 }
1878 }
1879 return $fVnew;
1880 }
1881
1882 /**
1883 * Returns file icon name (from $FILEICONS) for the fileextension $ext
1884 * Usage: 10
1885 *
1886 * @param string File extension, lowercase
1887 * @return string File icon filename
1888 */
1889 function getFileIcon($ext) {
1890 return $GLOBALS['FILEICONS'][$ext] ? $GLOBALS['FILEICONS'][$ext] : $GLOBALS['FILEICONS']['default'];
1891 }
1892
1893 /**
1894 * Returns fields for a table, $table, which would typically be interesting to select
1895 * This includes uid, the fields defined for title, icon-field.
1896 * 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)
1897 * Usage: 3
1898 *
1899 * @param string Table name, present in TCA
1900 * @param string Table prefix
1901 * @return string List of fields.
1902 */
1903 function getCommonSelectFields($table,$prefix) {
1904 global $TCA;
1905 $fields = array();
1906 $fields[] = $prefix.'uid';
1907 $fields[] = $prefix.$TCA[$table]['ctrl']['label'];
1908
1909 if ($TCA[$table]['ctrl']['label_alt']) {
1910 $secondFields = t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['label_alt'],1);
1911 foreach($secondFields as $fieldN) {
1912 $fields[] = $prefix.$fieldN;
1913 }
1914 }
1915 if ($TCA[$table]['ctrl']['versioning']) {
1916 $fields[] = $prefix.'t3ver_id';
1917 }
1918
1919 if ($TCA[$table]['ctrl']['selicon_field']) $fields[] = $prefix.$TCA[$table]['ctrl']['selicon_field'];
1920 if ($TCA[$table]['ctrl']['typeicon_column']) $fields[] = $prefix.$TCA[$table]['ctrl']['typeicon_column'];
1921
1922 if (is_array($TCA[$table]['ctrl']['enablecolumns'])) {
1923 if ($TCA[$table]['ctrl']['enablecolumns']['disabled']) $fields[] = $prefix.$TCA[$table]['ctrl']['enablecolumns']['disabled'];
1924 if ($TCA[$table]['ctrl']['enablecolumns']['starttime']) $fields[] = $prefix.$TCA[$table]['ctrl']['enablecolumns']['starttime'];
1925 if ($TCA[$table]['ctrl']['enablecolumns']['endtime']) $fields[] = $prefix.$TCA[$table]['ctrl']['enablecolumns']['endtime'];
1926 if ($TCA[$table]['ctrl']['enablecolumns']['fe_group']) $fields[] = $prefix.$TCA[$table]['ctrl']['enablecolumns']['fe_group'];
1927 }
1928
1929 return implode(',',array_unique($fields));
1930 }
1931
1932 /**
1933 * 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
1934 * <form>-tags must be supplied separately
1935 * 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.
1936 * Usage: 1 (ext. direct_mail)
1937 *
1938 * @param array Field configuration code.
1939 * @param array Defaults
1940 * @param string Prefix for formfields
1941 * @return string HTML for a form.
1942 */
1943 function makeConfigForm($configArray,$defaults,$dataPrefix) {
1944 $params = $defaults;
1945 if (is_array($configArray)) {
1946 reset($configArray);
1947 $lines=array();
1948 while(list($fname,$config)=each($configArray)) {
1949 if (is_array($config)) {
1950 $lines[$fname]='<strong>'.htmlspecialchars($config[1]).'</strong><br />';
1951 $lines[$fname].=$config[2].'<br />';
1952 switch($config[0]) {
1953 case 'string':
1954 case 'short':
1955 $formEl = '<input type="text" name="'.$dataPrefix.'['.$fname.']" value="'.$params[$fname].'"'.$GLOBALS['TBE_TEMPLATE']->formWidth($config[0]=='short'?24:48).' />';
1956 break;
1957 case 'check':
1958 $formEl = '<input type="hidden" name="'.$dataPrefix.'['.$fname.']" value="0" /><input type="checkbox" name="'.$dataPrefix.'['.$fname.']" value="1"'.($params[$fname]?' checked="checked"':'').' />';
1959 break;
1960 case 'comment':
1961 $formEl = '';
1962 break;
1963 case 'select':
1964 reset($config[3]);
1965 $opt=array();
1966 while(list($k,$v)=each($config[3])) {
1967 $opt[]='<option value="'.htmlspecialchars($k).'"'.($params[$fname]==$k?' selected="selected"':'').'>'.htmlspecialchars($v).'</option>';
1968 }
1969 $formEl = '<select name="'.$dataPrefix.'['.$fname.']">'.implode('',$opt).'</select>';
1970 break;
1971 default:
1972 debug($config);
1973 break;
1974 }
1975 $lines[$fname].=$formEl;
1976 $lines[$fname].='<br /><br />';
1977 } else {
1978 $lines[$fname]='<hr />';
1979 if ($config) $lines[$fname].='<strong>'.strtoupper(htmlspecialchars($config)).'</strong><br />';
1980 if ($config) $lines[$fname].='<br />';
1981 }
1982 }
1983 }
1984 $out = implode('',$lines);
1985 $out.='<input type="submit" name="submit" value="Update configuration" />';
1986 return $out;
1987 }
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001 /*******************************************
2002 *
2003 * Backend Modules API functions
2004 *
2005 *******************************************/
2006
2007 /**
2008 * Returns help-text icon if configured for.
2009 * TCA_DESCR must be loaded prior to this function and $BE_USER must have 'edit_showFieldHelp' set to 'icon', otherwise nothing is returned
2010 * Usage: 6
2011 *
2012 * @param string Table name
2013 * @param string Field name
2014 * @param string Back path
2015 * @param boolean Force display of icon nomatter BE_USER setting for help
2016 * @return string HTML content for a help icon/text
2017 */
2018 function helpTextIcon($table,$field,$BACK_PATH,$force=0) {
2019 global $TCA_DESCR,$BE_USER;
2020 if (is_array($TCA_DESCR[$table]) && is_array($TCA_DESCR[$table]['columns'][$field]) && ($BE_USER->uc['edit_showFieldHelp']=='icon' || $force)) {
2021 $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;';
2022 return '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
2023 '<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/helpbubble.gif','width="14" height="14"').' hspace="2" border="0" class="typo3-csh-icon" alt="" />'.
2024 '</a>';
2025 }
2026 }
2027
2028 /**
2029 * Returns CSH help text (description), if configured for.
2030 * TCA_DESCR must be loaded prior to this function and $BE_USER must have "edit_showFieldHelp" set to "text", otherwise nothing is returned
2031 * Will automatically call t3lib_BEfunc::helpTextIcon() to get the icon for the text.
2032 * Usage: 4
2033 *
2034 * @param string Table name
2035 * @param string Field name
2036 * @param string Back path
2037 * @param string Additional style-attribute content for wrapping table
2038 * @return string HTML content for help text
2039 */
2040 function helpText($table,$field,$BACK_PATH,$styleAttrib='') {
2041 global $TCA_DESCR,$BE_USER;
2042 if (is_array($TCA_DESCR[$table]) && is_array($TCA_DESCR[$table]['columns'][$field]) && $BE_USER->uc['edit_showFieldHelp']=='text') {
2043 $fDat = $TCA_DESCR[$table]['columns'][$field];
2044
2045 // Get Icon:
2046 $editIcon = t3lib_BEfunc::helpTextIcon(
2047 $table,
2048 $field,
2049 $BACK_PATH,
2050 TRUE
2051 );
2052 // Add title?
2053 $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;';
2054 $text =
2055 ($fDat['alttitle'] ? '<h4><a href="#" onclick="'.htmlspecialchars($onClick).'">'.$fDat['alttitle'].'</a></h4>' : '').
2056 $fDat['description'];
2057
2058 // More information to get?
2059 if ($fDat['image_descr'] || $fDat['seeAlso'] || $fDat['details'] || $fDat['syntax']) { // || $fDat['image'];
2060 $text.=' <a href="#" onclick="'.htmlspecialchars($onClick).'">'.
2061 '<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/rel_db.gif','width="13" height="12"').' class="absmiddle typo3-csh-more" alt="" />'.
2062 '</a>';
2063 }
2064
2065 // Additional styles?
2066 $params = $styleAttrib ? ' style="'.$styleAttrib.'"' : '';
2067
2068 // Compile table with CSH information:
2069 return '<table border="0" cellpadding="2" cellspacing="0" class="typo3-csh-inline"'.$params.'>
2070 <tr>
2071 <td valign="top" width="14">'.$editIcon.'</td>
2072 <td valign="top">'.$text.'</td>
2073 </tr>
2074 </table>';
2075 }
2076 }
2077
2078 /**
2079 * API for getting CSH icons/text for use in backend modules.
2080 * TCA_DESCR will be loaded if it isn't already
2081 * Usage: ?
2082 *
2083 * @param string Table name ('_MOD_'+module name)
2084 * @param string Field name (CSH locallang main key)
2085 * @param string Back path
2086 * @param string Wrap code for icon-mode, splitted by "|". Not used for full-text mode.
2087 * @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.
2088 * @param string Additional style-attribute content for wrapping table (full text mode only)
2089 * @return string HTML content for help text
2090 * @see helpText(), helpTextIcon()
2091 */
2092 function cshItem($table,$field,$BACK_PATH,$wrap='',$onlyIconMode=FALSE, $styleAttrib='') {
2093 global $TCA_DESCR, $LANG, $BE_USER;
2094 if ($BE_USER->uc['edit_showFieldHelp']) {
2095 $LANG->loadSingleTableDescription($table);
2096
2097 if (is_array($TCA_DESCR[$table])) {
2098 // Creating CSH icon and short description:
2099 $fullText = t3lib_BEfunc::helpText($table,$field,$BACK_PATH,$styleAttrib);
2100 $icon = t3lib_BEfunc::helpTextIcon($table,$field,$BACK_PATH,$onlyIconMode);
2101
2102 if ($fullText && !$onlyIconMode) {
2103 $output = $fullText;
2104 } else {
2105 #$output = '<span style="position:absolute; filter: alpha(opacity=50); -moz-opacity: 0.50;">'.$icon.'</span>';
2106 $output = $icon;
2107
2108 if ($output && $wrap) {
2109 $wrParts = explode('|',$wrap);
2110 $output = $wrParts[0].$output.$wrParts[1];
2111 }
2112 }
2113
2114 return $output;
2115 }
2116 }
2117 }
2118
2119 /**
2120 * 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.
2121 * REMEMBER to always htmlspecialchar() content in href-properties to ampersands get converted to entities (XHTML requirement and XSS precaution)
2122 * Usage: 35
2123 *
2124 * @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.
2125 * @param string $backPath must point back to the TYPO3_mainDir directory (where alt_doc.php is)
2126 * @param string $requestUri is an optional returnUrl you can set - automatically set to REQUEST_URI.
2127 * @return string
2128 * @see template::issueCommand()
2129 */
2130 function editOnClick($params,$backPath='',$requestUri='') {
2131 $retUrl = 'returnUrl='.($requestUri==-1?"'+T3_THIS_LOCATION+'":rawurlencode($requestUri?$requestUri:t3lib_div::getIndpEnv('REQUEST_URI')));
2132 return "document.location='".$backPath."alt_doc.php?".$retUrl.$params."'; return false;";
2133 }
2134
2135 /**
2136 * Returns a JavaScript string for viewing the page id, $id
2137 * 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.
2138 * Usage: 8
2139 *
2140 * @param integer $id is page id
2141 * @param string $backpath must point back to TYPO3_mainDir (where the site is assumed to be one level above)
2142 * @param array If root line is supplied the function will look for the first found domain record and use that URL instead (if found)
2143 * @param string $anchor is optional anchor to the URL
2144 * @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!
2145 * @param string Additional GET variables.
2146 * @return string
2147 */
2148 function viewOnClick($id,$backPath='',$rootLine='',$anchor='',$altUrl='',$addGetVars='') {
2149 if ($altUrl) {
2150 $url = $altUrl;
2151 } else {
2152 if ($rootLine) {
2153 $parts = parse_url(t3lib_div::getIndpEnv('TYPO3_SITE_URL'));
2154 if (t3lib_BEfunc::getDomainStartPage($parts['host'],$parts['path'])) {
2155 $preUrl_temp = t3lib_BEfunc::firstDomainRecord($rootLine);
2156 }
2157 }
2158 $preUrl = $preUrl_temp ? 'http://'.$preUrl_temp : $backPath.'..';
2159 $url = $preUrl.'/index.php?id='.$id.$addGetVars.$anchor;
2160 }
2161
2162 return "previewWin=window.open('".$url."','newTypo3FrontendWindow','status=1,menubar=1,resizable=1,location=1,scrollbars=1,toolbar=1');previewWin.focus();";
2163 }
2164
2165 /**
2166 * Returns the merged User/Page TSconfig for page id, $id.
2167 * Please read details about module programming elsewhere!
2168 * Usage: 15
2169 *
2170 * @param integer Page uid
2171 * @param string $TSref is an object string which determines the path of the TSconfig to return.
2172 * @return array
2173 */
2174 function getModTSconfig($id,$TSref) {
2175 $pageTS_modOptions = $GLOBALS['BE_USER']->getTSConfig($TSref,t3lib_BEfunc::getPagesTSconfig($id));
2176 $BE_USER_modOptions = $GLOBALS['BE_USER']->getTSConfig($TSref);
2177 $modTSconfig = t3lib_div::array_merge_recursive_overrule($pageTS_modOptions,$BE_USER_modOptions);
2178 return $modTSconfig;
2179 }
2180
2181 /**
2182 * Returns a selector box "function menu" for a module
2183 * Requires the JS function jumpToUrl() to be available
2184 * See Inside TYPO3 for details about how to use / make Function menus
2185 * Usage: 50
2186 *
2187 * @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=...
2188 * @param string $elementName it the form elements name, probably something like "SET[...]"
2189 * @param string $currentValue is the value to be selected currently.
2190 * @param array $menuItems is an array with the menu items for the selector box
2191 * @param string $script is the script to send the &id to, if empty it's automatically found
2192 * @param string $addParams is additional parameters to pass to the script.
2193 * @return string HTML code for selector box
2194 */
2195 function getFuncMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='') {
2196 if (is_array($menuItems)) {
2197 if (!is_array($mainParams)) {
2198 $mainParams = array('id' => $mainParams);
2199 }
2200 $mainParams = t3lib_div::implodeArrayForUrl('',$mainParams);
2201
2202 if (!$script) { $script=basename(PATH_thisScript); }
2203
2204 $options = array();
2205 foreach($menuItems as $value => $label) {
2206 $options[] = '<option value="'.htmlspecialchars($value).'"'.(!strcmp($currentValue,$value)?' selected="selected"':'').'>'.
2207 t3lib_div::deHSCentities(htmlspecialchars($label)).
2208 '</option>';
2209 }
2210 if (count($options)) {
2211 $onChange = 'jumpToUrl(\''.$script.'?'.$mainParams.$addparams.'&'.$elementName.'=\'+this.options[this.selectedIndex].value,this);';
2212 return '
2213
2214 <!-- Function Menu of module -->
2215 <select name="'.$elementName.'" onchange="'.htmlspecialchars($onChange).'">
2216 '.implode('
2217 ',$options).'
2218 </select>
2219 ';
2220 }
2221 }
2222 }
2223
2224 /**
2225 * Checkbox function menu.
2226 * Works like ->getFuncMenu() but takes no $menuItem array since this is a simple checkbox.
2227 * Usage: 34
2228 *
2229 * @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=...
2230 * @param string $elementName it the form elements name, probably something like "SET[...]"
2231 * @param string $currentValue is the value to be selected currently.
2232 * @param string $script is the script to send the &id to, if empty it's automatically found
2233 * @param string $addParams is additional parameters to pass to the script.
2234 * @param string Additional attributes for the checkbox input tag
2235 * @return string HTML code for checkbox
2236 * @see getFuncMenu()
2237 */
2238 function getFuncCheck($mainParams,$elementName,$currentValue,$script='',$addparams='',$tagParams='') {
2239 if (!is_array($mainParams)) {
2240 $mainParams = array('id' => $mainParams);
2241 }
2242 $mainParams = t3lib_div::implodeArrayForUrl('',$mainParams);
2243
2244 if (!$script) {basename(PATH_thisScript);}
2245 $onClick = 'jumpToUrl(\''.$script.'?'.$mainParams.$addparams.'&'.$elementName.'=\'+(this.checked?1:0),this);';
2246 return '<input type="checkbox" name="'.$elementName.'"'.($currentValue?' checked="checked"':'').' onclick="'.htmlspecialchars($onClick).'"'.($tagParams?' '.$tagParams:'').' />';
2247 }
2248
2249 /**
2250 * Input field function menu
2251 * Works like ->getFuncMenu() / ->getFuncCheck() but displays a input field instead which updates the script "onchange"
2252 * Usage: 1
2253 *
2254 * @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=...
2255 * @param string $elementName it the form elements name, probably something like "SET[...]"
2256 * @param string $currentValue is the value to be selected currently.
2257 * @param integer Relative size of input field, max is 48
2258 * @param string $script is the script to send the &id to, if empty it's automatically found
2259 * @param string $addParams is additional parameters to pass to the script.
2260 * @return string HTML code for input text field.
2261 * @see getFuncMenu()
2262 */
2263 function getFuncInput($mainParams,$elementName,$currentValue,$size=10,$script="",$addparams="") {
2264 if (!is_array($mainParams)) {
2265 $mainParams = array('id' => $mainParams);
2266 }
2267 $mainParams = t3lib_div::implodeArrayForUrl('',$mainParams);
2268
2269 if (!$script) {basename(PATH_thisScript);}
2270 $onChange = 'jumpToUrl(\''.$script.'?'.$mainParams.$addparams.'&'.$elementName.'=\'+escape(this.value),this);';
2271 return '<input type="text"'.$GLOBALS['TBE_TEMPLATE']->formWidth($size).' name="'.$elementName.'" value="'.htmlspecialchars($currentValue).'" onchange="'.htmlspecialchars($onChange).'" />';
2272 }
2273
2274 /**
2275 * Removes menu items from $itemArray if they are configured to be removed by TSconfig for the module ($modTSconfig)
2276 * See Inside TYPO3 about how to program modules and use this API.
2277 * Usage: 4
2278 *
2279 * @param array Module TS config array
2280 * @param array Array of items from which to remove items.
2281 * @param string $TSref points to the "object string" in $modTSconfig
2282 * @return array The modified $itemArray is returned.
2283 */
2284 function unsetMenuItems($modTSconfig,$itemArray,$TSref) {
2285 // Getting TS-config options for this module for the Backend User:
2286 $conf = $GLOBALS['BE_USER']->getTSConfig($TSref,$modTSconfig);
2287 if (is_array($conf['properties'])) {
2288 reset($conf['properties']);
2289 while(list($key,$val)=each($conf['properties'])) {
2290 if (!$val) {
2291 unset($itemArray[$key]);
2292 }
2293 }
2294 }
2295 return $itemArray;
2296 }
2297
2298 /**
2299 * Call to update the page tree frame (or something else..?) after
2300 * t3lib_BEfunc::getSetUpdateSignal('updatePageTree') -> will set the page tree to be updated.
2301 * t3lib_BEfunc::getSetUpdateSignal() -> will return some JavaScript that does the update (called in the typo3/template.php file, end() function)
2302 * Usage: 11
2303 *
2304 * @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.
2305 * @return string HTML code (<script> section)
2306 */
2307 function getSetUpdateSignal($set='') {
2308 global $BE_USER;
2309 $key = 't3lib_BEfunc::getSetUpdateSignal';
2310 $out='';
2311 if ($set) {
2312 $modData=array();
2313 $modData['set']=$set;
2314 $BE_USER->pushModuleData($key,$modData);
2315 } else {
2316 $modData = $BE_USER->getModuleData($key,'ses');
2317 if (trim($modData['set'])) {
2318 $l=explode(',',$modData['set']);
2319 while(list(,$v)=each($l)) {
2320 switch($v) {
2321 case 'updatePageTree':
2322 case 'updateFolderTree':
2323 $out.='
2324 <script type="text/javascript">
2325 /*<![CDATA[*/
2326 if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav) {
2327 top.content.nav_frame.refresh_nav();
2328 }
2329 /*]]>*/
2330 </script>';
2331 break;
2332 }
2333 }
2334 $modData=array();
2335 $modData['set']='';
2336 $BE_USER->pushModuleData($key,$modData);
2337 }
2338 }
2339 return $out;
2340 }
2341
2342
2343 /**
2344 * Returns an array which is most backend modules becomes MOD_SETTINGS containing values from function menus etc. determining the function of the module.
2345 * This is kind of session variable management framework for the backend users.
2346 * 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
2347 * Ultimately, see Inside TYPO3 for how to use this function in relation to your modules.
2348 * Usage: 23
2349 *
2350 * @param array MOD_MENU is an array that defines the options in menus.
2351 * @param array CHANGED_SETTINGS represents the array used when passing values to the script from the menus.
2352 * @param string modName is the name of this module. Used to get the correct module data.
2353 * @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.
2354 * @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.
2355 * @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)
2356 * @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
2357 */
2358 function getModuleData($MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='') {
2359
2360 if ($modName && is_string($modName)) {
2361 // GETTING stored user-data from this module:
2362 $settings = $GLOBALS['BE_USER']->getModuleData($modName,$type);
2363
2364 $changed=0;
2365 if (!is_array($settings)) {
2366 $changed=1;
2367 $settings=array();
2368 }
2369 if (is_array($MOD_MENU)) {
2370 reset($MOD_MENU);
2371 while(list($key,$var)=each($MOD_MENU)) {
2372 // If a global var is set before entering here. eg if submitted, then it's substituting the current value the array.
2373 if (is_array($CHANGED_SETTINGS) && isset($CHANGED_SETTINGS[$key]) && strcmp($settings[$key],$CHANGED_SETTINGS[$key])) {
2374 $settings[$key] = (string)$CHANGED_SETTINGS[$key];
2375 $changed=1;
2376 }
2377 // If the $var is an array, which denotes the existence of a menu, we check if the value is permitted
2378 if (is_array($var) && (!$dontValidateList || !t3lib_div::inList($dontValidateList,$key))) {
2379 // If the setting is an array or not present in the menu-array, MOD_MENU, then the default value is inserted.
2380 if (is_array($settings[$key]) || !isset($MOD_MENU[$key][$settings[$key]])) {
2381 $settings[$key]=(string)key($var);
2382 $changed=1;
2383 }
2384 }
2385 if ($setDefaultList && !is_array($var)) { // Sets default values (only strings/checkboxes, not menus)
2386 if (t3lib_div::inList($setDefaultList,$key) && !isset($settings[$key])) {
2387 $settings[$key]=$var;
2388 }
2389 }
2390 }
2391 } else {die ('No menu!');}
2392
2393 if ($changed) {
2394 $GLOBALS['BE_USER']->pushModuleData($modName,$settings);
2395 }
2396
2397 return $settings;
2398 } else {die ('Wrong module name: "'.$modName.'"');}
2399 }
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413 /*******************************************
2414 *
2415 * Core
2416 *
2417 *******************************************/
2418
2419
2420
2421 /**
2422 * Unlock or Lock a record from $table with $uid
2423 * If $table and $uid is not set, then all locking for the current BE_USER is removed!
2424 * Usage: 5
2425 *
2426 * @param string Table name
2427 * @param integer Record uid
2428 * @param integer Record pid
2429 * @return void
2430 * @internal
2431 * @see t3lib_transferData::lockRecord(), alt_doc.php, db_layout.php, db_list.php, wizard_rte.php
2432 */
2433 function lockRecords($table='',$uid=0,$pid=0) {
2434 $user_id = intval($GLOBALS['BE_USER']->user['uid']);
2435 if ($table && $uid) {
2436 $fields_values = array(
2437 'userid' => $user_id,
2438 'tstamp' => $GLOBALS['EXEC_TIME'],
2439 'record_table' => $table,
2440 'record_uid' => $uid,
2441 'username' => $GLOBALS['BE_USER']->user['username'],
2442 'record_pid' => $pid
2443 );
2444
2445 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_lockedrecords', $fields_values);
2446 } else {
2447 $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_lockedrecords', 'userid='.intval($user_id));
2448 }
2449 }
2450
2451 /**
2452 * Returns information about whether the record from table, $table, with uid, $uid is currently locked (edited by another user - which should issue a warning).
2453 * 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.
2454 * Usage: 5
2455 *
2456 * @param string Table name
2457 * @param integer Record uid
2458 * @return array
2459 * @internal
2460 * @see class.db_layout.inc, alt_db_navframe.php, alt_doc.php, db_layout.php
2461 */
2462 function isRecordLocked($table,$uid) {
2463 global $LOCKED_RECORDS;
2464 if (!is_array($LOCKED_RECORDS)) {
2465 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
2466 '*',
2467 'sys_lockedrecords',
2468 'sys_lockedrecords.userid!='.intval($GLOBALS['BE_USER']->user['uid']).'
2469 AND sys_lockedrecords.tstamp > '.($GLOBALS['EXEC_TIME']-2*3600)
2470 );
2471 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
2472 $LOCKED_RECORDS[$row['record_table'].':'.$row['record_uid']]=$row;
2473 $LOCKED_RECORDS[$row['record_table'].':'.$row['record_uid']]['msg']=sprintf(
2474 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.lockedRecord'),
2475 $row['username'],
2476 t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME']-$row['tstamp'],$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears'))
2477 );
2478 if ($row['record_pid'] && !isset($LOCKED_RECORDS[$row['record_table'].':'.$row['record_pid']])) {
2479 $LOCKED_RECORDS['pages:'.$row['record_pid']]['msg']=sprintf(
2480 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.lockedRecord_content'),
2481 $row['username'],
2482 t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME']-$row['tstamp'],$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears'))
2483 );
2484 }
2485 }
2486 }
2487 return $LOCKED_RECORDS[$table.':'.$uid];
2488 }
2489
2490 /**
2491 * Returns select statement for MM relations (as used by TCEFORMs etc)
2492 * Usage: 3
2493 *
2494 * @param array Configuration array for the field, taken from $TCA
2495 * @param string Field name
2496 * @param array TSconfig array from which to get further configuration settings for the field name
2497 * @param string Prefix string for the key "*foreign_table_where" from $fieldValue array
2498 * @return string Part of query
2499 * @internal
2500 * @see t3lib_transferData::renderRecord(), t3lib_TCEforms::foreignTable()
2501 */
2502 function exec_foreign_table_where_query($fieldValue,$field='',$TSconfig=array(),$prefix='') {
2503 global $TCA;
2504 $foreign_table = $fieldValue['config'][$prefix.'foreign_table'];
2505 $rootLevel = $TCA[$foreign_table]['ctrl']['rootLevel'];
2506
2507 $fTWHERE = $fieldValue['config'][$prefix.'foreign_table_where'];
2508 if (strstr($fTWHERE,'###REC_FIELD_')) {
2509 $fTWHERE_parts = explode('###REC_FIELD_',$fTWHERE);
2510 while(list($kk,$vv)=each($fTWHERE_parts)) {
2511 if ($kk) {
2512 $fTWHERE_subpart = explode('###',$vv,2);
2513 $fTWHERE_parts[$kk]=$TSconfig['_THIS_ROW'][$fTWHERE_subpart[0]].$fTWHERE_subpart[1];
2514 }
2515 }
2516 $fTWHERE = implode('',$fTWHERE_parts);
2517 }
2518
2519 $fTWHERE = str_replace('###CURRENT_PID###',intval($TSconfig['_CURRENT_PID']),$fTWHERE);
2520 $fTWHERE = str_replace('###THIS_UID###',intval($TSconfig['_THIS_UID']),$fTWHERE);
2521 $fTWHERE = str_replace('###THIS_CID###',intval($TSconfig['_THIS_CID']),$fTWHERE);
2522 $fTWHERE = str_replace('###STORAGE_PID###',intval($TSconfig['_STORAGE_PID']),$fTWHERE);
2523 $fTWHERE = str_replace('###SITEROOT###',intval($TSconfig['_SITEROOT']),$fTWHERE);
2524 $fTWHERE = str_replace('###PAGE_TSCONFIG_ID###',intval($TSconfig[$field]['PAGE_TSCONFIG_ID']),$fTWHERE);
2525 $fTWHERE = str_replace('###PAGE_TSCONFIG_IDLIST###',$GLOBALS['TYPO3_DB']->cleanIntList($TSconfig[$field]['PAGE_TSCONFIG_IDLIST']),$fTWHERE);
2526 $fTWHERE = str_replace('###PAGE_TSCONFIG_STR###',$GLOBALS['TYPO3_DB']->quoteStr($TSconfig[$field]['PAGE_TSCONFIG_STR'], $foreign_table),$fTWHERE);
2527
2528 // rootLevel = -1 is not handled 'properly' here - it goes as if it was rootLevel = 1 (that is pid=0)
2529 $wgolParts = $GLOBALS['TYPO3_DB']->splitGroupOrderLimit($fTWHERE);
2530 if ($rootLevel) {
2531 $queryParts = array(
2532 'SELECT' => t3lib_BEfunc::getCommonSelectFields($foreign_table,$foreign_table.'.'),
2533 'FROM' => $foreign_table,
2534 'WHERE' => $foreign_table.'.pid=0 '.
2535 t3lib_BEfunc::deleteClause($foreign_table).' '.
2536 $wgolParts['WHERE'],
2537 'GROUPBY' => $wgolParts['GROUPBY'],
2538 'ORDERBY' => $wgolParts['ORDERBY'],
2539 'LIMIT' => $wgolParts['LIMIT']
2540 );
2541 } else {
2542 $pageClause = $GLOBALS['BE_USER']->getPagePermsClause(1);
2543 if ($foreign_table!='pages') {
2544 $queryParts = array(
2545 'SELECT' => t3lib_BEfunc::getCommonSelectFields($foreign_table,$foreign_table.'.'),
2546 'FROM' => $foreign_table.',pages',
2547 'WHERE' => 'pages.uid='.$foreign_table.'.pid
2548 AND NOT pages.deleted '.
2549 t3lib_BEfunc::deleteClause($foreign_table).
2550 ' AND '.$pageClause.' '.
2551 $wgolParts['WHERE'],
2552 'GROUPBY' => $wgolParts['GROUPBY'],
2553 'ORDERBY' => $wgolParts['ORDERBY'],
2554 'LIMIT' => $wgolParts['LIMIT']
2555 );
2556 } else {
2557 $queryParts = array(
2558 'SELECT' => t3lib_BEfunc::getCommonSelectFields($foreign_table,$foreign_table.'.'),
2559 'FROM' => 'pages',
2560 'WHERE' => 'NOT pages.deleted
2561 AND '.$pageClause.' '.
2562 $wgolParts['WHERE'],
2563 'GROUPBY' => $wgolParts['GROUPBY'],
2564 'ORDERBY' => $wgolParts['ORDERBY'],
2565 'LIMIT' => $wgolParts['LIMIT']
2566 );
2567 }
2568 }
2569
2570 return $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
2571 }
2572
2573 /**
2574 * Returns TSConfig for the TCEFORM object in Page TSconfig.
2575 * Used in TCEFORMs
2576 * Usage: 4
2577 *
2578 * @param string Table name present in TCA
2579 * @param array Row from table
2580 * @return array
2581 * @see t3lib_transferData::renderRecord(), t3lib_TCEforms::setTSconfig(), SC_wizard_list::main(), SC_wizard_add::main()
2582 */
2583 function getTCEFORM_TSconfig($table,$row) {
2584 $res = array();
2585 $typeVal = t3lib_BEfunc::getTCAtypeValue($table,$row);
2586
2587 // Get main config for the table
2588 list($TScID,$cPid) = t3lib_BEfunc::getTSCpid($table,$row['uid'],$row['pid']);
2589
2590 $rootLine = t3lib_BEfunc::BEgetRootLine($TScID,'');
2591 if ($TScID>=0) {
2592 $tempConf = $GLOBALS['BE_USER']->getTSConfig('TCEFORM.'.$table,t3lib_BEfunc::getPagesTSconfig($TScID,$rootLine));
2593 if (is_array($tempConf['properties'])) {
2594 while(list($key,$val)=each($tempConf['properties'])) {
2595 if (is_array($val)) {
2596 $fieldN = substr($key,0,-1);
2597 $res[$fieldN] = $val;
2598 unset($res[$fieldN]['types.']);
2599 if (strcmp($typeVal,'') && is_array($val['types.'][$typeVal.'.'])) {
2600 $res[$fieldN] = t3lib_div::array_merge_recursive_overrule($res[$fieldN],$val['types.'][$typeVal.'.']);
2601 }
2602 }
2603 }
2604 }
2605 }
2606 $res['_CURRENT_PID']=$cPid;
2607 $res['_THIS_UID']=$row['uid'];
2608 $res['_THIS_CID']=$row['cid'];
2609 $res['_THIS_ROW']=$row; // So the row will be passed to foreign_table_where_query()
2610 reset($rootLine);
2611 while(list(,$rC)=each($rootLine)) {
2612 if (!$res['_STORAGE_PID']) $res['_STORAGE_PID']=intval($rC['storage_pid']);
2613 if (!$res['_SITEROOT']) $res['_SITEROOT']=$rC['is_siteroot']?intval($rC['uid']):0;
2614 }
2615
2616 return $res;
2617 }
2618
2619 /**
2620 * 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).
2621 * Usage: 2
2622 *
2623 * @param string Table name
2624 * @param integer Record uid
2625 * @param integer Record pid
2626 * @return integer
2627 * @internal
2628 * @see t3lib_TCEmain::copyRecord(), getTSCpid()
2629 */
2630 function getTSconfig_pidValue($table,$uid,$pid) {
2631 if (t3lib_div::testInt($pid)) { // If pid is an integer this takes precedence in our lookup.
2632 $thePidValue = intval($pid);
2633 if ($thePidValue<0) { // If ref to another record, look that record up.
2634 $pidRec = t3lib_BEfunc::getRecord($table,abs($thePidValue),'pid');
2635 $thePidValue= is_array($pidRec) ? $pidRec['pid'] : -2; // Returns -2 if the record did not exist.
2636 }
2637 // ... else the pos/zero pid is just returned here.
2638 } else { // No integer pid and we are forced to look up the $pid
2639 $rr = t3lib_BEfunc::getRecord($table,$uid,'pid'); // Try to fetch the record pid from uid. If the uid is 'NEW...' then this will of course return nothing...
2640 if (is_array($rr)) {
2641 $thePidValue = $rr['pid']; // Returning the 'pid' of the record
2642 } else $thePidValue=-1; // Returns -1 if the record with the pid was not found.
2643 }
2644 return $thePidValue;
2645 }
2646
2647 /**
2648 * Return $uid if $table is pages and $uid is integer - otherwise the $pid
2649 * Usage: 1
2650 *
2651 * @param string Table name
2652 * @param integer Record uid
2653 * @param integer Record pid
2654 * @return integer
2655 * @internal
2656 * @see t3lib_TCEforms::getTSCpid()
2657 */
2658 function getPidForModTSconfig($table,$uid,$pid) {
2659 $retVal = ($table=='pages' && t3lib_div::testInt($uid)) ? $uid : $pid;
2660 return $retVal;
2661 }
2662
2663 /**
2664 * 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.
2665 * Usage: 8
2666 *
2667 * @param string Table name
2668 * @param integer Record uid
2669 * @param integer Record pid
2670 * @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)
2671 * @internal
2672 * @see t3lib_TCEmain::setHistory(), t3lib_TCEmain::process_datamap()
2673 */
2674 function getTSCpid($table,$uid,$pid) {
2675 // If pid is negative (referring to another record) the pid of the other record is fetched and returned.
2676 $cPid = t3lib_BEfunc::getTSconfig_pidValue($table,$uid,$pid);
2677 // $TScID is the id of $table=pages, else it's the pid of the record.
2678 $TScID = t3lib_BEfunc::getPidForModTSconfig($table,$uid,$cPid);
2679
2680 return array($TScID,$cPid);
2681 }
2682
2683 /**
2684 * Returns first found domain record "domainName" (without trailing slash) if found in the input $rootLine
2685 * Usage: 2
2686 *
2687 * @param array Root line array
2688 * @return string Domain name, if found.
2689 */
2690 function firstDomainRecord($rootLine) {
2691 if (t3lib_extMgm::isLoaded('cms')) {
2692 reset($rootLine);
2693 while(list(,$row)=each($rootLine)) {
2694 $dRec = t3lib_BEfunc::getRecordsByField('sys_domain','pid',$row['uid'],' AND redirectTo="" AND hidden=0', '', 'sorting');
2695 if (is_array($dRec)) {
2696 reset($dRec);
2697 $dRecord = current($dRec);
2698 return ereg_replace('\/$','',$dRecord['domainName']);
2699 }
2700 }
2701 }
2702 }
2703
2704 /**
2705 * Returns the sys_domain record for $domain, optionally with $path appended.
2706 * Usage: 2
2707 *
2708 * @param string Domain name
2709 * @param string Appended path
2710 * @return array Domain record, if found
2711 */
2712 function getDomainStartPage($domain, $path='') {
2713 if (t3lib_extMgm::isLoaded('cms')) {
2714 $domain = explode(':',$domain);
2715 $domain = strtolower(ereg_replace('\.$','',$domain[0]));
2716 // path is calculated.
2717 $path = trim(ereg_replace('\/[^\/]*$','',$path));
2718 // stuff:
2719 $domain.=$path;
2720
2721 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('sys_domain.*', 'pages,sys_domain', '
2722 pages.uid=sys_domain.pid
2723 AND NOT sys_domain.hidden
2724 AND (sys_domain.domainName="'.$GLOBALS['TYPO3_DB']->quoteStr($domain, 'sys_domain').'" or sys_domain.domainName="'.$GLOBALS['TYPO3_DB']->quoteStr($domain.'/', 'sys_domain').'")'.
2725 t3lib_BEfunc::deleteClause('pages'),
2726 '', '', '1');
2727 return $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
2728 }
2729 }
2730
2731 /**
2732 * Select all versions of a record, ordered by version id (DESC)
2733 *
2734 * @param string Table name to select from
2735 * @param integer Record uid for which to find versions.
2736 * @param string Field list to select
2737 * @return array Array of versions of table/uid
2738 */
2739 function selectVersionsOfRecord($table, $uid, $fields='*') {
2740 global $TCA;
2741
2742 if ($TCA[$table] && $TCA[$table]['ctrl']['versioning']) {
2743
2744 // Select all versions of record:
2745 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
2746 $fields,
2747 $table,
2748 '(t3ver_oid='.intval($uid).' || uid='.intval($uid).')'.
2749 t3lib_BEfunc::deleteClause($table),
2750 '',
2751 't3ver_id DESC'
2752 );
2753
2754 // Add rows to output array:
2755 $outputRows = array();
2756 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
2757 if ($uid==$row['uid']) {
2758 $row['_CURRENT_VERSION']=TRUE;
2759 }
2760 $outputRows[] = $row;
2761 }
2762
2763 return $outputRows;
2764 }
2765 }
2766
2767 /**
2768 * Returns overlayered RTE setup from an array with TSconfig. Used in TCEforms and TCEmain
2769 * Usage: 8
2770 *
2771 * @param array The properties of Page TSconfig in the key "RTE."
2772 * @param string Table name
2773 * @param string Field name
2774 * @param string Type value of the current record (like from CType of tt_content)
2775 * @return array Array with the configuration for the RTE
2776 * @internal
2777 */
2778 function RTEsetup($RTEprop,$table,$field,$type='') {
2779 $thisConfig = is_array($RTEprop['default.']) ? $RTEprop['default.'] : array();
2780 $thisFieldConf = $RTEprop['config.'][$table.'.'][$field.'.'];
2781 if (is_array($thisFieldConf)) {
2782 unset($thisFieldConf['types.']);
2783 $thisConfig = t3lib_div::array_merge_recursive_overrule($thisConfig,$thisFieldConf);
2784 }
2785 if ($type && is_array($RTEprop['config.'][$table.'.'][$field.'.']['types.'][$type.'.'])) {
2786 $thisConfig = t3lib_div::array_merge_recursive_overrule($thisConfig,$RTEprop['config.'][$table.'.'][$field.'.']['types.'][$type.'.']);
2787 }
2788 return $thisConfig;
2789 }
2790
2791 /**
2792 * Returns first possible RTE object if available.
2793 *
2794 * @return mixed If available, returns RTE object, otherwise an array of messages from possible RTEs
2795 */
2796 function &RTEgetObj() {
2797
2798 // If no RTE object has been set previously, try to create it:
2799 if (!isset($GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'])) {
2800
2801 // Set the object string to blank by default:
2802 $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'] = array();
2803
2804 // Traverse registered RTEs:
2805 if (is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_reg'])) {
2806 foreach($GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_reg'] as $extKey => $rteObjCfg) {
2807 $rteObj = &t3lib_div::getUserObj($rteObjCfg['objRef']);
2808 if (is_object($rteObj)) {
2809 if ($rteObj->isAvailable()) {
2810 $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'] = &$rteObj;
2811 break;
2812 } else {
2813 $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'] = array_merge($GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'], $rteObj->errorLog);
2814 }
2815 }
2816 }
2817 }
2818
2819 if (!count($GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'])) {
2820 $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'][] = 'No RTEs configured at all';
2821 }
2822 }
2823
2824 // Return RTE object (if any!)
2825 return $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'];
2826 }
2827
2828 /**
2829 * Returns true if $modName is set and is found as a main- or submodule in $TBE_MODULES array
2830 * Usage: 1
2831 *
2832 * @param string Module name
2833 * @return boolean
2834 */
2835 function isModuleSetInTBE_MODULES($modName) {
2836 reset($GLOBALS['TBE_MODULES']);
2837 $loaded=array();
2838 while(list($mkey,$list)=each($GLOBALS['TBE_MODULES'])) {
2839 $loaded[$mkey]=1;
2840 if (trim($list)) {
2841 $subList = t3lib_div::trimExplode(',',$list,1);
2842 while(list(,$skey)=each($subList)) {
2843 $loaded[$mkey.'_'.$skey]=1;
2844 }
2845 }
2846 }
2847 return $modName && isset($loaded[$modName]);
2848 }
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867 /*******************************************
2868 *
2869 * Miscellaneous
2870 *
2871 *******************************************/
2872
2873
2874 /**
2875 * Print error message with header, text etc.
2876 * Usage: 19
2877 *
2878 * @param string Header string
2879 * @param string Content string
2880 * @param boolean Will return an alert() with the content of header and text.
2881 * @param boolean Print header.
2882 * @return void
2883 */
2884 function typo3PrintError($header,$text,$js='',$head=1) {
2885 // This prints out a TYPO3 error message.
2886 // If $js is set the message will be output in JavaScript
2887 if ($js) {
2888 echo "alert('".t3lib_div::slashJS($header.'\n'.$text)."');";
2889 } else {
2890 echo $head?'<html>
2891 <head>
2892 <title>Error!</title>
2893 </head>
2894 <body bgcolor="white" topmargin="0" leftmargin="0" marginwidth="0" marginheight="0">':'';
2895 echo '<div align="center">
2896 <table border="0" cellspacing="0" cellpadding="0" width="333">
2897 <tr>
2898 <td align="center">'.
2899 ($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="333" height="43" vspace="10" />').
2900 '</td>
2901 </tr>
2902 <tr>
2903 <td bgcolor="black">
2904 <table width="100%" border="0" cellspacing="1" cellpadding="10">
2905 <tr>
2906 <td bgcolor="#F4F0E8">
2907 <font face="verdana,arial,helvetica" size="2">';
2908 echo '<b><center><font size="+1">'.$header.'</font></center></b><br />'.$text;
2909 echo ' </font>
2910 </td>
2911 </tr>
2912 </table>
2913 </td>
2914 </tr>
2915 </table>
2916 </div>';
2917 echo $head?'
2918 </body>
2919 </html>':'';
2920 }
2921 }
2922
2923 /**
2924 * Prints TYPO3 Copyright notice for About Modules etc. modules.
2925 *
2926 * @return void
2927 */
2928 function TYPO3_copyRightNotice() {
2929 global $TYPO3_CONF_VARS;
2930
2931 // COPYRIGHT NOTICE:
2932 $loginCopyrightWarrantyProvider = strip_tags(trim($TYPO3_CONF_VARS['SYS']['loginCopyrightWarrantyProvider']));
2933 $loginCopyrightWarrantyURL = strip_tags(trim($TYPO3_CONF_VARS['SYS']['loginCopyrightWarrantyURL']));
2934
2935 if (strlen($loginCopyrightWarrantyProvider)>=2 && strlen($loginCopyrightWarrantyURL)>=10) {
2936 $warrantyNote='Warranty is supplied by '.htmlspecialchars($loginCopyrightWarrantyProvider).'; <a href="'.htmlspecialchars($loginCopyrightWarrantyURL).'" target="_blank">click for details.</a>';
2937 } else {
2938 $warrantyNote='TYPO3 comes with ABSOLUTELY NO WARRANTY; <a href="http://typo3.com/1316.0.html" target="_blank">click for details.</a>';
2939 }
2940 $cNotice = '<a href="http://typo3.com/" target="_blank"><img src="gfx/loginlogo_transp.gif" width="75" vspace="2" height="19" alt="TYPO3 logo" align="left" />TYPO3 CMS ver. '.htmlspecialchars($GLOBALS['TYPO_VERSION']).'</a>. Copyright &copy; 1998-2004 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.
2941 '.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.';
2942
2943 return $cNotice;
2944 }
2945
2946 /**
2947 * Returns "web" if the $path (absolute) is within the DOCUMENT ROOT - and thereby qualifies as a "web" folder.
2948 * Usage: 4
2949 *
2950 * @param string Path to evaluate
2951 * @return boolean
2952 */
2953 function getPathType_web_nonweb($path) {
2954 return t3lib_div::isFirstPartOfStr($path,t3lib_div::getIndpEnv('TYPO3_DOCUMENT_ROOT')) ? 'web' : '';
2955 }
2956
2957 /**
2958 * Creates ADMCMD parameters for the "viewpage" extension / "cms" frontend
2959 * Usage: 1
2960 *
2961 * @param array Page record
2962 * @return string Query-parameters
2963 * @internal
2964 */
2965 function ADMCMD_previewCmds($pageinfo) {
2966 if ($pageinfo['fe_group']>0) {
2967 $simUser = '&ADMCMD_simUser='.$pageinfo['fe_group'];
2968 }
2969 if ($pageinfo['starttime']>time()) {
2970 $simTime = '&ADMCMD_simTime='.$pageinfo['starttime'];
2971 }
2972 if ($pageinfo['endtime']<time() && $pageinfo['endtime']!=0) {
2973 $simTime = '&ADMCMD_simTime='.($pageinfo['endtime']-1);
2974 }
2975 return $simUser.$simTime;
2976 }
2977
2978 /**
2979 * Returns an array with key=>values based on input text $params
2980 * $params is exploded by line-breaks and each line is supposed to be on the syntax [key] = [some value]
2981 * These pairs will be parsed into an array an returned.
2982 * Usage: 1
2983 *
2984 * @param string String of parameters on multiple lines to parse into key-value pairs (see function description)
2985 * @return array
2986 */
2987 function processParams($params) {
2988 $paramArr=array();
2989 $lines=explode(chr(10),$params);
2990 while(list(,$val)=each($lines)) {
2991 $val = trim($val);
2992 if ($val) {
2993 $pair = explode('=',$val,2);
2994 $paramArr[trim($pair[0])] = trim($pair[1]);
2995 }
2996 }
2997 return $paramArr;
2998 }
2999
3000 /**
3001 * Returns "list of backend modules". Most likely this will be obsolete soon / removed. Don't use.
3002 * Usage: 3
3003 *
3004 * @param array Module names in array. Must be "addslashes()"ed
3005 * @param string Perms clause for SQL query
3006 * @param string Backpath
3007 * @param string The URL/script to jump to (used in A tag)
3008 * @return array Two keys, rows and list
3009 * @internal
3010 * @depreciated
3011 * @obsolete
3012 */
3013 function getListOfBackendModules($name,$perms_clause,$backPath='',$script='index.php') {
3014 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'doktype!=255 AND module IN ("'.implode('","',$name).'") AND'.$perms_clause.t3lib_BEfunc::deleteClause('pages'));
3015 if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res)) return false;
3016
3017 $out='';
3018 $theRows=array();
3019 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
3020 $theRows[]=$row;
3021 $out.='<span class="nobr"><a href="'.htmlspecialchars($script.'?id='.$row['uid']).'">'.
3022 t3lib_iconWorks::getIconImage('pages',$row,$backPath,'title="'.htmlspecialchars(t3lib_BEfunc::getRecordPath($row['uid'],$perms_clause,20)).'" align="top"').
3023 htmlspecialchars($row['title']).
3024 '</a></span><br />';
3025 }
3026 return array('rows'=>$theRows,'list'=>$out);