class.t3lib_page.php 39.5 KB
Newer Older
Kasper Skårhøj's avatar
Kasper Skårhøj committed
1
2
3
<?php
/***************************************************************
*  Copyright notice
4
*
5
*  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
Kasper Skårhøj's avatar
Kasper Skårhøj committed
6
7
*  All rights reserved
*
8
*  This script is part of the TYPO3 project. The TYPO3 project is
Kasper Skårhøj's avatar
Kasper Skårhøj committed
9
10
11
12
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
13
*
Kasper Skårhøj's avatar
Kasper Skårhøj committed
14
15
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
16
*  A copy is found in the textfile GPL.txt and important notices to the license
Kasper Skårhøj's avatar
Kasper Skårhøj committed
17
18
*  from the author is found in LICENSE.txt distributed with these scripts.
*
19
*
Kasper Skårhøj's avatar
Kasper Skårhøj committed
20
21
22
23
24
25
26
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
27
/**
Kasper Skårhøj's avatar
Kasper Skårhøj committed
28
29
 * Contains a class with "Page functions" mainly for the frontend
 *
30
31
 * $Id$
 * Revised for TYPO3 3.6 2/2003 by Kasper Skaarhoj
Kasper Skårhøj's avatar
Kasper Skårhøj committed
32
33
 * XHTML-trans compliant
 *
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
34
 * @author	Kasper Skaarhoj <kasperYYYY@typo3.com>
Kasper Skårhøj's avatar
Kasper Skårhøj committed
35
36
37
38
39
40
 */
/**
 * [CLASS/FUNCTION INDEX of SCRIPT]
 *
 *
 *
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
41
42
 *  107: class t3lib_pageSelect
 *  132:     function init($show_hidden)
Kasper Skårhøj's avatar
Kasper Skårhøj committed
43
44
 *
 *              SECTION: Selecting page records
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
45
46
47
48
49
50
 *  171:     function getPage($uid)
 *  187:     function getPage_noCheck($uid)
 *  203:     function getFirstWebPage($uid)
 *  221:     function getPageIdFromAlias($alias)
 *  237:     function getPageOverlay($pageInput,$lUid=-1)
 *  300:     function getRecordOverlay($table,$row,$sys_language_content,$OLmode='')
Kasper Skårhøj's avatar
Kasper Skårhøj committed
51
52
 *
 *              SECTION: Page related: Menu, Domain record, Root line
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
53
54
55
56
57
58
 *  396:     function getMenu($uid,$fields='*',$sortField='sorting',$addWhere='')
 *  431:     function getDomainStartPage($domain, $path='',$request_uri='')
 *  479:     function getRootLine($uid, $MP='', $ignoreMPerrors=FALSE)
 *  597:     function getPathFromRootline($rl,$len=20)
 *  618:     function getExtURL($pagerow,$disable=0)
 *  642:     function getMountPointInfo($pageId, $pageRec=FALSE, $prevMountPids=array(), $firstPageUid=0)
Kasper Skårhøj's avatar
Kasper Skårhøj committed
59
60
 *
 *              SECTION: Selecting records in general
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
61
62
63
 *  719:     function checkRecord($table,$uid,$checkPage=0)
 *  750:     function getRawRecord($table,$uid,$fields='*')
 *  774:     function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='')
Kasper Skårhøj's avatar
Kasper Skårhøj committed
64
65
 *
 *              SECTION: Caching and standard clauses
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
66
67
68
69
 *  826:     function getHash($hash,$expTime=0)
 *  849:     function storeHash($hash,$data,$ident)
 *  867:     function deleteClause($table)
 *  886:     function enableFields($table,$show_hidden=-1,$ignore_array=array())
Kasper Skårhøj's avatar
Kasper Skårhøj committed
70
 *
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
71
72
73
74
75
 *              SECTION: Versioning Preview
 *  954:     function fixVersioningPid($table,&$rr)
 *  986:     function versionOL($table,&$row)
 *
 * TOTAL FUNCTIONS: 22
Kasper Skårhøj's avatar
Kasper Skårhøj committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
 * (This index is automatically created/updated by the extension "extdeveval")
 *
 */


















/**
 * Page functions, a lot of sql/pages-related functions
 * Mainly used in the frontend but also in some cases in the backend.
 * It's important to set the right $where_hid_del in the object so that the functions operate properly
Kasper Skårhøj's avatar
Kasper Skårhøj committed
101
 *
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
102
 * @author	Kasper Skaarhoj <kasperYYYY@typo3.com>
103
104
 * @package TYPO3
 * @subpackage t3lib
Kasper Skårhøj's avatar
Kasper Skårhøj committed
105
106
107
108
 * @see tslib_fe::fetch_the_id()
 */
class t3lib_pageSelect {
	var $urltypes = Array('','http://','ftp://','mailto:');
109
	var $where_hid_del = ' AND pages.deleted=0';	// This is not the final clauses. There will normally be conditions for the hidden,starttime and endtime fields as well. You MUST initialize the object by the init() function
110
111
112
113
114
115
116
	var $sys_language_uid = 0;

		// Versioning preview related:
	var $versioningPreview = FALSE;		// If true, preview of other record versions is allowed. THIS MUST ONLY BE SET IF the page is not cached and truely previewed by a backend user!!!
	var $versionPreviewMap = array(
# EXAMPLE:		'tt_content:421' => 427
	);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
117
118


119
		// Internal, dynamic:
120
121
	var $error_getRootLine = '';		// Error string set by getRootLine()
	var $error_getRootLine_failPid = 0;		// Error uid set by getRootLine()
Kasper Skårhøj's avatar
Kasper Skårhøj committed
122
123
124


	/**
Kasper Skårhøj's avatar
Kasper Skårhøj committed
125
	 * init() MUST be run directly after creating a new template-object
Kasper Skårhøj's avatar
Kasper Skårhøj committed
126
	 * This sets the internal variable $this->where_hid_del to the correct where clause for page records taking deleted/hidden/starttime/endtime into account
Kasper Skårhøj's avatar
Kasper Skårhøj committed
127
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
128
	 * @param	boolean		If $show_hidden is true, the hidden-field is ignored!! Normally this should be false. Is used for previewing.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
129
	 * @return	void
Kasper Skårhøj's avatar
Kasper Skårhøj committed
130
131
132
	 * @see tslib_fe::fetch_the_id(), tx_tstemplateanalyzer::initialize_editor()
	 */
	function init($show_hidden)	{
133
		$this->where_hid_del = ' AND pages.deleted=0 ';
Kasper Skårhøj's avatar
Kasper Skårhøj committed
134
		if (!$show_hidden)	{
135
			$this->where_hid_del.= 'AND pages.hidden=0 ';
Kasper Skårhøj's avatar
Kasper Skårhøj committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
		}
		$this->where_hid_del.= 'AND (pages.starttime<='.$GLOBALS['SIM_EXEC_TIME'].') AND (pages.endtime=0 OR pages.endtime>'.$GLOBALS['SIM_EXEC_TIME'].') ';
	}

















	/*******************************************
	 *
	 * Selecting page records
	 *
	 ******************************************/

	/**
	 * Returns the $row for the page with uid = $uid (observing ->where_hid_del)
	 * Any pages_language_overlay will be applied before the result is returned.
	 * If no page is found an empty array is returned.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
166
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
167
168
169
170
171
	 * @param	integer		The page id to look up.
	 * @return	array		The page row with overlayed localized fields. Empty it no page.
	 * @see getPage_noCheck()
	 */
	function getPage($uid)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
172
173
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid='.intval($uid).$this->where_hid_del);
		if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
174
#??			$this->versionOL('pages',$row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
175
176
177
178
179
180
181
			return $this->getPageOverlay($row);
		}
		return Array();
	}

	/**
	 * Return the $row for the page with uid = $uid WITHOUT checking for ->where_hid_del (start- and endtime or hidden). Only "deleted" is checked!
Kasper Skårhøj's avatar
Kasper Skårhøj committed
182
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
183
184
185
186
187
	 * @param	integer		The page id to look up
	 * @return	array		The page row with overlayed localized fields. Empty it no page.
	 * @see getPage()
	 */
	function getPage_noCheck($uid)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
188
189
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid='.intval($uid).$this->deleteClause('pages'));
		if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
190
#??			$this->versionOL('pages',$row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
191
192
193
194
195
196
197
			return $this->getPageOverlay($row);
		}
		return Array();
	}

	/**
	 * Returns the $row of the first web-page in the tree (for the default menu...)
Kasper Skårhøj's avatar
Kasper Skårhøj committed
198
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
199
200
201
202
203
	 * @param	integer		The page id for which to fetch first subpages (PID)
	 * @return	mixed		If found: The page record (with overlayed localized fields, if any). If NOT found: blank value (not array!)
	 * @see tslib_fe::fetch_the_id()
	 */
	function getFirstWebPage($uid)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
204
205
206
		$output = '';
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'pid='.intval($uid).$this->where_hid_del, '', 'sorting', '1');
		if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
207
#??			$this->versionOL('pages',$row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
208
			$output = $this->getPageOverlay($row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
209
		}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
210
		$GLOBALS['TYPO3_DB']->sql_free_result($res);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
211
212
213
214
215
		return $output;
	}

	/**
	 * Returns a pagerow for the page with alias $alias
Kasper Skårhøj's avatar
Kasper Skårhøj committed
216
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
217
218
219
220
221
	 * @param	string		The alias to look up the page uid for.
	 * @return	integer		Returns page uid (integer) if found, otherwise 0 (zero)
	 * @see tslib_fe::checkAndSetAlias(), tslib_cObj::typoLink()
	 */
	function getPageIdFromAlias($alias)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
222
		$alias = strtolower($alias);
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
223
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'alias='.$GLOBALS['TYPO3_DB']->fullQuoteStr($alias, 'pages').' AND pid>=0 AND pages.deleted=0');	// "AND pid>=0" is because of versioning...
Kasper Skårhøj's avatar
Kasper Skårhøj committed
224
		if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
225
226
227
228
229
230
231
			return $row['uid'];
		}
		return 0;
	}

	/**
	 * Returns the relevant page overlay record fields
Kasper Skårhøj's avatar
Kasper Skårhøj committed
232
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
233
234
235
236
237
	 * @param	mixed		If $pageInput is an integer, it's the pid of the pageOverlay record and thus the page overlay record is returned. If $pageInput is an array, it's a page-record and based on this page record the language record is found and OVERLAYED before the page record is returned.
	 * @param	integer		Language UID if you want to set an alternative value to $this->sys_language_uid which is default. Should be >=0
	 * @return	array		Page row which is overlayed with language_overlay record (or the overlay record alone)
	 */
	function getPageOverlay($pageInput,$lUid=-1)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
238
239
240

			// Initialize:
		if ($lUid<0)	$lUid = $this->sys_language_uid;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
241
		unset($row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
242
243

			// If language UID is different from zero, do overlay:
Kasper Skårhøj's avatar
Kasper Skårhøj committed
244
		if ($lUid)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
245
			$fieldArr = explode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
246
			if (is_array($pageInput))	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
247
248
				$page_id = $pageInput['uid'];	// Was the whole record
				$fieldArr = array_intersect($fieldArr,array_keys($pageInput));		// Make sure that only fields which exist in the incoming record are overlaid!
Kasper Skårhøj's avatar
Kasper Skårhøj committed
249
			} else {
Kasper Skårhøj's avatar
Kasper Skårhøj committed
250
				$page_id = $pageInput;	// Was the id
Kasper Skårhøj's avatar
Kasper Skårhøj committed
251
			}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
252

Kasper Skårhøj's avatar
Kasper Skårhøj committed
253
254
255
256
257
258
			if (count($fieldArr))	{
				/*
					NOTE to enabledFields('pages_language_overlay'):
					Currently the showHiddenRecords of TSFE set will allow pages_language_overlay records to be selected as they are child-records of a page.
					However you may argue that the showHiddenField flag should determine this. But that's not how it's done right now.
				*/
259
260

					// Selecting overlay record:
Kasper Skårhøj's avatar
Kasper Skårhøj committed
261
262
263
264
265
266
267
268
269
270
271
				$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
							implode(',',$fieldArr),
							'pages_language_overlay',
							'pid='.intval($page_id).'
								AND sys_language_uid='.intval($lUid).
								$this->enableFields('pages_language_overlay'),
							'',
							'',
							'1'
						);
				$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
272
273
274
275
				if (is_array($row))	{
					$row['_PAGES_OVERLAY'] = TRUE;
					$this->versionOL('pages_language_overlay',$row);

276
						// Unset vital fields that are NOT allowed to be overlaid:
277
278
279
					unset($row['uid']);
					unset($row['pid']);
				}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
280
281
			}
		}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
282
283

			// Create output:
Kasper Skårhøj's avatar
Kasper Skårhøj committed
284
285
286
287
288
289
290
		if (is_array($pageInput))	{
			return is_array($row) ? array_merge($pageInput,$row) : $pageInput;	// If the input was an array, simply overlay the newfound array and return...
		} else {
			return is_array($row) ? $row : array();	// always an array in return
		}
	}

291
292
293
	/**
	 * Creates language-overlay for records in general (where translation is found in records from the same table)
	 *
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
294
295
296
297
298
	 * @param	string		Table name
	 * @param	array		Record to overlay. Must containt uid, pid and $table]['ctrl']['languageField']
	 * @param	integer		Pointer to the sys_language uid for content on the site.
	 * @param	string		Overlay mode. If "hideNonTranslated" then records without translation will not be returned un-translated but unset (and return value is false)
	 * @return	mixed		Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return false if no translation is found.
299
	 */
Kasper Skårhøj's avatar
Kasper Skårhøj committed
300
	function getRecordOverlay($table,$row,$sys_language_content,$OLmode='')	{
301
302
		global $TCA;

Kasper Skårhøj's avatar
Kasper Skårhøj committed
303
		if ($row['uid']>0 && $row['pid']>0)	{
304
305
			if ($TCA[$table] && $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField'])	{
				if (!$TCA[$table]['ctrl']['transOrigPointerTable'])	{	// Will not be able to work with other tables (Just didn't implement it yet; Requires a scan over all tables [ctrl] part for first FIND the table that carries localization information for this table (which could even be more than a single table) and then use that. Could be implemented, but obviously takes a little more....)
Kasper Skårhøj's avatar
Kasper Skårhøj committed
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

						// Will try to overlay a record only if the sys_language_content value is larger that zero.
					if ($sys_language_content>0)	{

							// Must be default language or [All], otherwise no overlaying:
						if ($row[$TCA[$table]['ctrl']['languageField']]<=0)	{

								// Select overlay record:
							$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
										'*',
										$table,
										'pid='.intval($row['pid']).
											' AND '.$TCA[$table]['ctrl']['languageField'].'='.intval($sys_language_content).
											' AND '.$TCA[$table]['ctrl']['transOrigPointerField'].'='.intval($row['uid']).
											$this->enableFields($table),
										'',
										'',
										'1'
									);
							$olrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
							$this->versionOL($table,$olrow);
	#debug($row);
	#debug($olrow);
								// Merge record content by traversing all fields:
							if (is_array($olrow))	{
								foreach($row as $fN => $fV)	{
									if ($fN!='uid' && $fN!='pid' && isset($olrow[$fN]))	{

										if ($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$fN]!='exclude'
												&& ($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$fN]!='mergeIfNotBlank' || strcmp(trim($olrow[$fN]),'')))	{
											$row[$fN] = $olrow[$fN];
										}
338
339
									}
								}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
340
							} elseif ($OLmode==='hideNonTranslated' && $row[$TCA[$table]['ctrl']['languageField']]==0)	{	// Unset, if non-translated records should be hidden. ONLY done if the source record really is default language and not [All] in which case it is allowed.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
341
								unset($row);
342
							}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
343
344
345
346
347
348
349
350

							// Otherwise, check if sys_language_content is different from the value of the record - that means a japanese site might try to display french content.
						} elseif ($sys_language_content!=$row[$TCA[$table]['ctrl']['languageField']])	{
							unset($row);
						}
					} else {
							// When default language is displayed, we never want to return a record carrying another language!:
						if ($row[$TCA[$table]['ctrl']['languageField']]>0)	{
351
352
353
354
355
356
357
358
359
360
							unset($row);
						}
					}
				}
			}
		}

		return $row;
	}

Kasper Skårhøj's avatar
Kasper Skårhøj committed
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

















	/*******************************************
	 *
	 * Page related: Menu, Domain record, Root line
	 *
	 ******************************************/

	/**
	 * Returns an array with pagerows for subpages with pid=$uid (which is pid here!). This is used for menus.
386
387
	 * If there are mount points in overlay mode the _MP_PARAM field is set to the corret MPvar.
	 * If the $uid being input does in itself require MPvars to define a correct rootline these must be handled externally to this function.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
388
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
389
390
391
392
393
394
395
396
397
	 * @param	integer		The page id for which to fetch subpages (PID)
	 * @param	string		List of fields to select. Default is "*" = all
	 * @param	string		The field to sort by. Default is "sorting"
	 * @param	string		Optional additional where clauses. Like "AND title like '%blabla%'" for instance.
	 * @return	array		Array with key/value pairs; keys are page-uid numbers. values are the corresponding page records (with overlayed localized fields, if any)
	 * @see tslib_fe::getPageShortcut(), tslib_menu::makeMenu(), tx_wizardcrpages_webfunc_2, tx_wizardsortpages_webfunc_2
	 */
	function getMenu($uid,$fields='*',$sortField='sorting',$addWhere='')	{
		$output = Array();
Kasper Skårhøj's avatar
Kasper Skårhøj committed
398
399
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, 'pages', 'pid='.intval($uid).$this->where_hid_del.' '.$addWhere, '', $sortField);
		while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
400
#??			$this->versionOL('pages',$row);
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

				// Keep mount point:
			$origUid = $row['uid'];
			$mount_info = $this->getMountPointInfo($origUid, $row);	// $row MUST have "uid", "pid", "doktype", "mount_pid", "mount_pid_ol" fields in it
			if (is_array($mount_info) && $mount_info['overlay'])	{	// There is a valid mount point.
				$mp_row = $this->getPage($mount_info['mount_pid']);		// Using "getPage" is OK since we need the check for enableFields AND for type 2 of mount pids we DO require a doktype < 200!
				if (count($mp_row))	{
					$row = $mp_row;
					$row['_MP_PARAM'] = $mount_info['MPvar'];
				} else unset($row);	// If the mount point could not be fetched with respect to enableFields, unset the row so it does not become a part of the menu!
			}

				// Add to output array after overlaying language:
			if (is_array($row))	{
				$output[$origUid] = $this->getPageOverlay($row);
			}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
417
418
419
420
421
		}
		return $output;
	}

	/**
Kasper Skårhøj's avatar
Kasper Skårhøj committed
422
	 * Will find the page carrying the domain record matching the input domain.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
423
	 * Might exit after sending a redirect-header IF a found domain record instructs to do so.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
424
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
425
426
427
428
429
430
431
432
433
434
435
436
	 * @param	string		Domain name to search for. Eg. "www.typo3.com". Typical the HTTP_HOST value.
	 * @param	string		Path for the current script in domain. Eg. "/somedir/subdir". Typ. supplied by t3lib_div::getIndpEnv('SCRIPT_NAME')
	 * @param	string		Request URI: Used to get parameters from if they should be appended. Typ. supplied by t3lib_div::getIndpEnv('REQUEST_URI')
	 * @return	mixed		If found, returns integer with page UID where found. Otherwise blank. Might exit if location-header is sent, see description.
	 * @see tslib_fe::findDomainRecord()
	 */
	function getDomainStartPage($domain, $path='',$request_uri='')	{
		$domain = explode(':',$domain);
		$domain = strtolower(ereg_replace('\.$','',$domain[0]));
			// Removing extra trailing slashes
		$path = trim(ereg_replace('\/[^\/]*$','',$path));
			// Appending to domain string
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
437
438
439
		$domain.= $path;
		$domain = ereg_replace('\/*$','',$domain);

Kasper Skårhøj's avatar
Kasper Skårhøj committed
440
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
441
442
443
444
					'pages.uid,sys_domain.redirectTo,sys_domain.prepend_params',
					'pages,sys_domain',
					'pages.uid=sys_domain.pid
						AND sys_domain.hidden=0
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
445
						AND (sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain, 'sys_domain').' OR sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain.'/', 'sys_domain').') '.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
446
447
448
449
450
451
						$this->where_hid_del,
					'',
					'',
					1
				);
		if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
452
453
454
455
456
			if ($row['redirectTo'])	{
				$rURL = $row['redirectTo'];
				if ($row['prepend_params'])	{
					$rURL = ereg_replace('\/$','',$rURL);
					$prependStr = ereg_replace('^\/','',substr($request_uri,strlen($path)));
457
					$rURL.= '/'.$prependStr;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
458
459
460
461
462
463
464
465
466
467
468
469
470
471
				}
				Header('Location: '.t3lib_div::locationHeaderUrl($rURL));
				exit;
			} else {
				return $row['uid'];
			}
		}
	}

	/**
	 * Returns array with fields of the pages from here ($uid) and back to the root
	 * NOTICE: This function only takes deleted pages into account! So hidden, starttime and endtime restricted pages are included no matter what.
	 * Further: If any "recycler" page is found (doktype=255) then it will also block for the rootline)
	 * If you want more fields in the rootline records than default such can be added by listing them in $GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields']
Kasper Skårhøj's avatar
Kasper Skårhøj committed
472
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
473
474
	 * @param	integer		The page uid for which to seek back to the page tree root.
	 * @param	string		Commalist of MountPoint parameters, eg. "1-2,3-4" etc. Normally this value comes from the GET var, MP
475
	 * @param	boolean		If set, some errors related to Mount Points in root line are ignored.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
476
477
478
	 * @return	array		Array with page records from the root line as values. The array is ordered with the outer records first and root record in the bottom. The keys are numeric but in reverse order. So if you traverse/sort the array by the numeric keys order you will get the order from root and out. If an error is found (like eternal looping or invalid mountpoint) it will return an empty array.
	 * @see tslib_fe::getPageAndRootline()
	 */
479
480
481
	function getRootLine($uid, $MP='', $ignoreMPerrors=FALSE)	{

			// Initialize:
482
		$selFields = t3lib_div::uniqueList('pid,uid,t3ver_oid,title,alias,nav_title,media,layout,hidden,starttime,endtime,fe_group,extendToSubpages,doktype,TSconfig,storage_pid,is_siteroot,mount_pid,mount_pid_ol,fe_login_mode,'.$GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields']);
483
		$this->error_getRootLine = '';
484
		$this->error_getRootLine_failPid = 0;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
485
486

			// Splitting the $MP parameters if present
Kasper Skårhøj's avatar
Kasper Skårhøj committed
487
		$MPA = array();
Kasper Skårhøj's avatar
Kasper Skårhøj committed
488
		if ($MP)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
489
			$MPA = explode(',',$MP);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
490
			reset($MPA);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
491
492
			while(list($MPAk) = each($MPA))	{
				$MPA[$MPAk] = explode('-', $MPA[$MPAk]);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
493
494
			}
		}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
495

496
		$loopCheck = 0;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
497
		$theRowArray = Array();
Kasper Skårhøj's avatar
Kasper Skårhøj committed
498
		$uid = intval($uid);
499
500
501

		while ($uid!=0 && $loopCheck<20)	{	// Max 20 levels in the page tree.
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid='.intval($uid).' AND pages.deleted=0 AND pages.doktype!=255');
Kasper Skårhøj's avatar
Kasper Skårhøj committed
502
			if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
503
504
				$this->fixVersioningPid('pages',$row);
#??				$this->versionOL('pages',$row);
505
506
507
508
509
510
511
512
513
514
515
516
517

					// Mount Point page types are allowed ONLY a) if they are the outermost record in rootline and b) if the overlay flag is not set:
				if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'] && $row['doktype']==7 && !$ignoreMPerrors)	{
					$mount_info = $this->getMountPointInfo($row['uid'], $row);
					if ($loopCheck>0 || $mount_info['overlay'])	{
						$this->error_getRootLine = 'Illegal Mount Point found in rootline';
						return array();
					}
				}

				$uid = $row['pid'];	// Next uid

				if (count($MPA) && $GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'])	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
518
					$curMP = end($MPA);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
519
					if (!strcmp($row['uid'],$curMP[0]))	{
520

Kasper Skårhøj's avatar
Kasper Skårhøj committed
521
						array_pop($MPA);
522
523
524
525
						$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid='.intval($curMP[1]).' AND pages.deleted=0 AND pages.doktype!=255');
						$mp_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);

						if (is_array($mp_row))	{
526
527
							$this->fixVersioningPid('pages',$mp_row);
#??							$this->versionOL('pages',$mp_row);
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
							$mount_info = $this->getMountPointInfo($mp_row['uid'], $mp_row);
							if (is_array($mount_info) && $mount_info['mount_pid']==$curMP[0])	{
								$uid = $mp_row['pid'];	// Setting next uid

								if ($mount_info['overlay'])	{	// Symlink style: Keep mount point (current row).
									$row['_MOUNT_OL'] = TRUE;	// Set overlay mode:
									$row['_MOUNT_PAGE'] = array(
										'uid' => $mp_row['uid'],
										'pid' => $mp_row['pid'],
										'title' =>  $mp_row['title'],
									);
								} else {	// Normal operation: Insert the mount page row in rootline instead mount point.
									if ($loopCheck>0)	{
										$row = $mp_row;
									} else {
										$this->error_getRootLine = 'Current Page Id is a mounted page of the overlay type and cannot be accessed directly!';
										return array();	// Matching the page id (first run, $loopCheck = 0) with the MPvar is ONLY allowed if the mount point is the "overlay" type (otherwise it could be forged!)
									}
								}

								$row['_MOUNTED_FROM'] = $curMP[0];
								$row['_MP_PARAM'] = $mount_info['MPvar'];
							} else {
								$this->error_getRootLine = 'MP var was corrupted';
								return array();	// The MP variables did NOT connect proper mount points:
							}
						} else {
							$this->error_getRootLine = 'No moint point record found according to PID in MP var';
							return array();	// The second PID in MP var was NOT a valid page.
						}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
558
559
					}
				}
560
					// Add row to rootline with language overlaid:
Kasper Skårhøj's avatar
Kasper Skårhøj committed
561
				$theRowArray[] = $this->getPageOverlay($row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
562
			} else {
563
				$this->error_getRootLine = 'Broken rootline';
564
				$this->error_getRootLine_failPid = $uid;
565
				return array();	// broken rootline.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
566
			}
567
568
569
570
571
572
573
574

			$loopCheck++;
		}

			// If the MPA array is NOT empty, we have to return an error; All MP elements were not resolved!
		if (count($MPA))	{
			$this->error_getRootLine = 'MP value remain!';
			return array();
Kasper Skårhøj's avatar
Kasper Skårhøj committed
575
576
		}

Kasper Skårhøj's avatar
Kasper Skårhøj committed
577
578
			// Create output array (with reversed order of numeric keys):
		$output = Array();
579
580
581
582
		$c = count($theRowArray);
		foreach($theRowArray as $key => $val)	{
			$c--;
			$output[$c] = $val;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
583
		}
584

Kasper Skårhøj's avatar
Kasper Skårhøj committed
585
586
587
588
589
590
		return $output;
	}

	/**
	 * Creates a "path" string for the input root line array titles.
	 * Used for writing statistics.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
591
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
592
593
594
595
596
597
598
599
600
601
602
	 * @param	array		A rootline array!
	 * @param	integer		The max length of each title from the rootline.
	 * @return	string		The path in the form "/page title/This is another pageti.../Another page"
	 * @see tslib_fe::getConfigArray()
	 */
	function getPathFromRootline($rl,$len=20)	{
		if (is_array($rl))	{
			$c=count($rl);
			$path = '';
			for ($a=0;$a<$c;$a++)	{
				if ($rl[$a]['uid'])	{
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
603
					$path.='/'.t3lib_div::fixed_lgd_cs(strip_tags($rl[$a]['title']),$len);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
604
605
606
607
608
609
610
611
				}
			}
			return $path;
		}
	}

	/**
	 * Returns the URL type for the input page row IF the doktype is 3 and not disabled.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
612
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
613
614
	 * @param	array		The page row to return URL type for
	 * @param	boolean		A flag to simply disable any output from here.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
615
	 * @return	string		The URL type from $this->urltypes array. False if not found or disabled.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
616
617
618
619
	 * @see tslib_fe::checkJumpUrl()
	 */
	function getExtURL($pagerow,$disable=0)	{
		if ($pagerow['doktype']==3 && !$disable)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
620
621
622
623
624
625
626
627
			$redirectTo = $this->urltypes[$pagerow['urltype']].$pagerow['url'];

				// If relative path, prefix Site URL:
			$uI = parse_url($redirectTo);
			if (!$uI['scheme'] && substr($redirectTo,0,1)!='/')	{ // relative path assumed now...
				$redirectTo = t3lib_div::getIndpEnv('TYPO3_SITE_URL').$redirectTo;
			}
			return $redirectTo;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
628
629
630
		}
	}

631
632
633
634
635
	/**
	 * Returns MountPoint id for page
	 * Does a recursive search if the mounted page should be a mount page itself. It has a run-away break so it can't go into infinite loops.
	 *
	 * @param	integer		Page id for which to look for a mount pid. Will be returned only if mount pages are enabled, the correct doktype (7) is set for page and there IS a mount_pid (which has a valid record that is not deleted...)
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
636
	 * @param	array		Optional page record for the page id. If not supplied it will be looked up by the system. Must contain at least uid,pid,doktype,mount_pid,mount_pid_ol
637
638
639
640
641
642
643
	 * @param	array		Array accumulating formerly tested page ids for mount points. Used for recursivity brake.
	 * @param	integer		The first page id.
	 * @return	mixed		Returns FALSE if no mount point was found, "-1" if there should have been one, but no connection to it, otherwise an array with information about mount pid and modes.
	 * @see tslib_menu
	 */
	function getMountPointInfo($pageId, $pageRec=FALSE, $prevMountPids=array(), $firstPageUid=0)	{
		if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'])	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
644

645
646
647
648
				// Get pageRec if not supplied:
			if (!is_array($pageRec))	{
				$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,pid,doktype,mount_pid,mount_pid_ol', 'pages', 'uid='.intval($pageId).' AND pages.deleted=0 AND pages.doktype!=255');
				$pageRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
649
#??				$this->versionOL('pages',$pageRec);
650
			}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
651

652
653
654
655
656
657
658
659
660
661
662
				// Set first Page uid:
			if (!$firstPageUid)	$firstPageUid = $pageRec['uid'];

				// Look for mount pid value plus other required circumstances:
			$mount_pid = intval($pageRec['mount_pid']);
			if (is_array($pageRec) && $pageRec['doktype']==7 && $mount_pid>0 && !in_array($mount_pid, $prevMountPids))	{

					// Get the mount point record (to verify its general existence):
				$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,pid,doktype,mount_pid,mount_pid_ol', 'pages', 'uid='.$mount_pid.' AND pages.deleted=0 AND pages.doktype!=255');
				$mount_rec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
				if (is_array($mount_rec))	{
663
#??					$this->versionOL('pages',$mount_rec);
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683

						// Look for recursive mount point:
					$prevMountPids[] = $mount_pid;
					$recursiveMountPid = $this->getMountPointInfo($mount_pid, $mount_rec, $prevMountPids, $firstPageUid);

						// Return mount point information:
					return $recursiveMountPid ?
								$recursiveMountPid :
								array(
									'mount_pid' => $mount_pid,
									'overlay' => $pageRec['mount_pid_ol'],
									'MPvar' => $mount_pid.'-'.$firstPageUid,
									'mount_point_rec' => $pageRec,
									'mount_pid_rec' => $mount_rec,
								);
				} else {
					return -1;	// Means, there SHOULD have been a mount point, but there was none!
				}
			}
		}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
684

685
686
		return FALSE;
	}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704

















	/*********************************
705
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
706
	 * Selecting records in general
707
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
708
	 **********************************/
709

Kasper Skårhøj's avatar
Kasper Skårhøj committed
710
	/**
Kasper Skårhøj's avatar
Kasper Skårhøj committed
711
	 * Checks if a record exists and is accessible.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
712
	 * The row is returned if everything's OK.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
713
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
714
715
716
717
718
719
720
721
722
	 * @param	string		The table name to search
	 * @param	integer		The uid to look up in $table
	 * @param	boolean		If checkPage is set, it's also required that the page on which the record resides is accessible
	 * @return	mixed		Returns array (the record) if OK, otherwise blank/0 (zero)
	 */
	function checkRecord($table,$uid,$checkPage=0)	{
		global $TCA;
		$uid=intval($uid);
		if (is_array($TCA[$table])) {
Kasper Skårhøj's avatar
Kasper Skårhøj committed
723
724
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($uid).$this->enableFields($table));
			if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
725
#??				$this->versionOL($table,$row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
726
				$GLOBALS['TYPO3_DB']->sql_free_result($res);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
727
				if ($checkPage)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
728
729
					$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'uid='.intval($row['pid']).$this->enableFields('pages'));
					if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
730
731
732
733
734
735
						return $row;
					} else {
						return 0;
					}
				} else {
					return $row;
736
				}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
737
738
739
740
741
742
			}
		}
	}

	/**
	 * Returns record no matter what - except if record is deleted
Kasper Skårhøj's avatar
Kasper Skårhøj committed
743
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
744
745
746
747
748
749
750
751
	 * @param	string		The table name to search
	 * @param	integer		The uid to look up in $table
	 * @param	string		The fields to select, default is "*"
	 * @return	mixed		Returns array (the record) if found, otherwise blank/0 (zero)
	 * @see getPage_noCheck()
	 */
	function getRawRecord($table,$uid,$fields='*')	{
		global $TCA;
752
		$uid = intval($uid);
753
		if (is_array($TCA[$table]) || $table=='pages') {	// Excluding pages here so we can ask the function BEFORE TCA gets initialized. Support for this is followed up in deleteClause()...
Kasper Skårhøj's avatar
Kasper Skårhøj committed
754
755
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, 'uid='.intval($uid).$this->deleteClause($table));
			if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
756
#??				$this->versionOL($table,$row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
757
758
759
760
761
762
763
				return $row;
			}
		}
	}

	/**
	 * Selects records based on matching a field (ei. other than UID) with a value
Kasper Skårhøj's avatar
Kasper Skårhøj committed
764
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
765
766
767
	 * @param	string		The table name to search, eg. "pages" or "tt_content"
	 * @param	string		The fieldname to match, eg. "uid" or "alias"
	 * @param	string		The value that fieldname must match, eg. "123" or "frontpage"
Kasper Skårhøj's avatar
Kasper Skårhøj committed
768
769
770
771
	 * @param	string		Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
	 * @param	string		Optional GROUP BY field(s), if none, supply blank string.
	 * @param	string		Optional ORDER BY field(s), if none, supply blank string.
	 * @param	string		Optional LIMIT value ([begin,]max), if none, supply blank string.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
772
773
	 * @return	mixed		Returns array (the record) if found, otherwise blank/0 (zero)
	 */
Kasper Skårhøj's avatar
Kasper Skårhøj committed
774
	function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='')	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
775
776
		global $TCA;
		if (is_array($TCA[$theTable])) {
Kasper Skårhøj's avatar
Kasper Skårhøj committed
777
778
779
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
						'*',
						$theTable,
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
780
						$theField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($theValue, $theTable).
Kasper Skårhøj's avatar
Kasper Skårhøj committed
781
782
783
784
785
786
787
788
							$this->deleteClause($theTable).' '.
								$whereClause,	// whereClauseMightContainGroupOrderBy
						$groupBy,
						$orderBy,
						$limit
					);
			$rows = array();
			while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
789
#??				$this->versionOL($theTable,$row);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
790
791
				$rows[] = $row;
			}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
792
			$GLOBALS['TYPO3_DB']->sql_free_result($res);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
793
794
795
796
797
798
799
			if (count($rows))	return $rows;
		}
	}




800
801


Kasper Skårhøj's avatar
Kasper Skårhøj committed
802
803
804
805
806
807
808
809
810








	/*********************************
811
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
812
	 * Caching and standard clauses
813
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
814
	 **********************************/
815

Kasper Skårhøj's avatar
Kasper Skårhøj committed
816
817
818
819
	/**
	 * Returns string value stored for the hash string in the table "cache_hash"
	 * Can be used to retrieved a cached value
	 * Can be used from your frontend plugins if you like. Is also used to store the parsed TypoScript template structures. You can call it directly like t3lib_pageSelect::getHash()
Kasper Skårhøj's avatar
Kasper Skårhøj committed
820
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
821
822
823
824
825
826
	 * @param	string		The hash-string which was used to store the data value
	 * @param	integer		Allowed expiretime in seconds. Basically a record is selected only if it is not older than this value in seconds. If expTime is not set, the hashed value will never expire.
	 * @return	string		The "content" field of the "cache_hash" table row.
	 * @see tslib_TStemplate::start(), storeHash()
	 */
	function getHash($hash,$expTime=0)	{
827
			//
Kasper Skårhøj's avatar
Kasper Skårhøj committed
828
829
830
831
		$expTime = intval($expTime);
		if ($expTime)	{
			$whereAdd = ' AND tstamp > '.(time()-$expTime);
		}
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
832
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash').$whereAdd);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
833
834
		if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
			$GLOBALS['TYPO3_DB']->sql_free_result($res);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
835
836
837
838
839
840
841
			return $row['content'];
		}
	}

	/**
	 * Stores a string value in the cache_hash table identified by $hash.
	 * Can be used from your frontend plugins if you like. You can call it directly like t3lib_pageSelect::storeHash()
Kasper Skårhøj's avatar
Kasper Skårhøj committed
842
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
843
844
845
	 * @param	string		32 bit hash string (eg. a md5 hash of a serialized array identifying the data being stored)
	 * @param	string		The data string. If you want to store an array, then just serialize it first.
	 * @param	string		$ident is just a textual identification in order to inform about the content! May be 20 characters long.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
846
	 * @return	void
Kasper Skårhøj's avatar
Kasper Skårhøj committed
847
848
849
	 * @see tslib_TStemplate::start(), getHash()
	 */
	function storeHash($hash,$data,$ident)	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
850
851
852
853
854
855
		$insertFields = array(
			'hash' => $hash,
			'content' => $data,
			'ident' => $ident,
			'tstamp' => time()
		);
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
856
		$GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash'));
Kasper Skårhøj's avatar
Kasper Skårhøj committed
857
		$GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_hash', $insertFields);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
858
859
860
861
	}

	/**
	 * Returns the "AND NOT deleted" clause for the tablename given IF $TCA configuration points to such a field.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
862
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
863
	 * @param	string		Tablename
Kasper Skårhøj's avatar
Kasper Skårhøj committed
864
	 * @return	string
Kasper Skårhøj's avatar
Kasper Skårhøj committed
865
866
867
868
	 * @see enableFields()
	 */
	function deleteClause($table)	{
		global $TCA;
869
870
871
872
873
		if (!strcmp($table,'pages'))	{	// Hardcode for pages...:
			return ' AND deleted=0';
		} else {
			return $TCA[$table]['ctrl']['delete'] ? ' AND '.$TCA[$table]['ctrl']['delete'].'=0' : '';
		}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
874
875
876
877
878
	}

	/**
	 * Returns a part of a WHERE clause which will filter out records with start/end times or hidden/fe_groups fields set to values that should de-select them according to the current time, preview settings or user login. Definitely a frontend function.
	 * Is using the $TCA arrays "ctrl" part where the key "enablefields" determines for each table which of these features applies to that table.
Kasper Skårhøj's avatar
Kasper Skårhøj committed
879
	 *
Kasper Skårhøj's avatar
Kasper Skårhøj committed
880
881
882
883
884
885
886
887
888
	 * @param	string		Table name found in the $TCA array
	 * @param	integer		If $show_hidden is set (0/1), any hidden-fields in records are ignored. NOTICE: If you call this function, consider what to do with the show_hidden parameter. Maybe it should be set? See tslib_cObj->enableFields where it's implemented correctly.
	 * @param	array		Array you can pass where keys can be "disabled", "starttime", "endtime", "fe_group" (keys from "enablefields" in TCA) and if set they will make sure that part of the clause is not added. Thus disables the specific part of the clause. For previewing etc.
	 * @return	string		The clause starting like " AND ...=... AND ...=..."
	 * @see tslib_cObj::enableFields(), deleteClause()
	 */
	function enableFields($table,$show_hidden=-1,$ignore_array=array())	{
		if ($show_hidden==-1 && is_object($GLOBALS['TSFE']))	{	// If show_hidden was not set from outside and if TSFE is an object, set it based on showHiddenPage and showHiddenRecords from TSFE
			$show_hidden = $table=='pages' ? $GLOBALS['TSFE']->showHiddenPage : $GLOBALS['TSFE']->showHiddenRecords;
889
		}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
890
		if ($show_hidden==-1)	$show_hidden=0;	// If show_hidden was not changed during the previous evaluation, do it here.
891

Kasper Skårhøj's avatar
Kasper Skårhøj committed
892
893
894
895
		$ctrl = $GLOBALS['TCA'][$table]['ctrl'];
		$query='';
		if (is_array($ctrl))	{
			if ($ctrl['delete'])	{
896
				$query.=' AND '.$table.'.'.$ctrl['delete'].'=0';
Kasper Skårhøj's avatar
Kasper Skårhøj committed
897
898
899
900
			}
			if (is_array($ctrl['enablecolumns']))	{
				if ($ctrl['enablecolumns']['disabled'] && !$show_hidden && !$ignore_array['disabled'])	{
					$field = $table.'.'.$ctrl['enablecolumns']['disabled'];
901
					$query.=' AND '.$field.'=0';
Kasper Skårhøj's avatar
Kasper Skårhøj committed
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
				}
				if ($ctrl['enablecolumns']['starttime'] && !$ignore_array['starttime'])	{
					$field = $table.'.'.$ctrl['enablecolumns']['starttime'];
					$query.=' AND ('.$field.'<='.$GLOBALS['SIM_EXEC_TIME'].')';
				}
				if ($ctrl['enablecolumns']['endtime'] && !$ignore_array['endtime'])	{
					$field = $table.'.'.$ctrl['enablecolumns']['endtime'];
					$query.=' AND ('.$field.'=0 OR '.$field.'>'.$GLOBALS['SIM_EXEC_TIME'].')';
				}
				if ($ctrl['enablecolumns']['fe_group'] && !$ignore_array['fe_group'])	{
					$field = $table.'.'.$ctrl['enablecolumns']['fe_group'];
					$gr_list = $GLOBALS['TSFE']->gr_list;
					if (!strcmp($gr_list,''))	$gr_list=0;
					$query.=' AND '.$field.' IN ('.$gr_list.')';
				}
917
918
919
920
921
922
923
924
925
926
927
928
929

					// Call hook functions for additional enableColumns
				if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns']))    {
					$_params = array(
						'table' => $table,
						'show_hidden' => $show_hidden,
						'ignore_array' => $ignore_array,
						'ctrl' => $ctrl
					);
					foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns'] as $_funcRef)    {
						$query .= t3lib_div::callUserFunction($_funcRef,$_params,$this);
					}
				}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
930
931
932
933
934
935
936
			}
		} else {
			die ('NO entry in the $TCA-array for the table "'.$table.'". This means that the function enableFields() is called with an invalid table name as argument.');
		}

		return $query;
	}
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000















	/*********************************
	 *
	 * Versioning Preview
	 *
	 **********************************/

	/**
	 * Find page-tree PID for versionized record
	 * 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
	 *
	 * @param	string		Table name
	 * @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.
	 * @return	void		(Passed by ref).
	 * @see t3lib_BEfunc::fixVersioningPid()
	 */
	function fixVersioningPid($table,&$rr)	{
		global $TCA;
# SWAP uid as well???
		if ($this->versioningPreview && $rr['pid']==-1 && ($table=='pages' || $TCA[$table]['ctrl']['versioning']))	{	// Have to hardcode it for "pages" table since TCA is not loaded at this moment!
			if ($rr['t3ver_oid']>0)	{	// If "t3ver_oid" is already a field, just set this:
				$oid = $rr['t3ver_oid'];
			} else {	// Otherwise we have to expect "uid" to be in the record and look up based on this:
				$newPidRec = $this->getRawRecord($table,$rr['uid'],'t3ver_oid');
				if (is_array($newPidRec))	{
					$oid = $newPidRec['t3ver_oid'];
				}
			}

				// If ID of current online version is found, look up the PID value of that:
			if ($oid)	{
				$oidRec = $this->getRawRecord($table,$oid,'pid');
				if (is_array($oidRec))	{
					$rr['_ORIG_pid'] = $rr['pid'];
					$rr['pid'] = $oidRec['pid'];
				}
			}
		}
	}

	/**
	 * Versioning Preview Overlay
	 * ONLY active when backend user is previewing records. MUST NEVER affect a site served which is not previewed by backend users!!!
	 *
	 * @param	string		Table name
	 * @param	array		Record array passed by reference. As minimum, the "uid" field must exist!
	 * @return	void		(Passed by ref).
	 */
	function versionOL($table,&$row)	{
		global $TCA;
For faster browsing, not all history is shown. View entire blame