![]() |
4.7.0
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00047 class t3lib_pageSelect { 00048 var $urltypes = Array('', 'http://', 'ftp://', 'mailto:', 'https://'); 00049 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 00050 var $where_groupAccess = ''; // Clause for fe_group access 00051 var $sys_language_uid = 0; 00052 00053 // Versioning preview related: 00054 var $versioningPreview = FALSE; // If TRUE, versioning 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!!! 00055 var $versioningWorkspaceId = 0; // Workspace ID for preview 00056 var $workspaceCache = array(); 00057 00058 00059 // Internal, dynamic: 00060 var $error_getRootLine = ''; // Error string set by getRootLine() 00061 var $error_getRootLine_failPid = 0; // Error uid set by getRootLine() 00062 00063 // Internal caching 00064 protected $cache_getRootLine = array(); 00065 protected $cache_getPage = array(); 00066 protected $cache_getPage_noCheck = array(); 00067 protected $cache_getPageIdFromAlias = array(); 00068 protected $cache_getMountPointInfo = array(); 00069 00073 const DOKTYPE_DEFAULT = 1; 00074 const DOKTYPE_LINK = 3; 00075 const DOKTYPE_SHORTCUT = 4; 00076 const DOKTYPE_BE_USER_SECTION = 6; 00077 const DOKTYPE_MOUNTPOINT = 7; 00078 const DOKTYPE_SPACER = 199; 00079 const DOKTYPE_SYSFOLDER = 254; 00080 const DOKTYPE_RECYCLER = 255; 00081 00082 00086 const SHORTCUT_MODE_NONE = 0; 00087 const SHORTCUT_MODE_FIRST_SUBPAGE = 1; 00088 const SHORTCUT_MODE_RANDOM_SUBPAGE = 2; 00089 const SHORTCUT_MODE_PARENT_PAGE = 3; 00090 00099 function init($show_hidden) { 00100 $this->where_groupAccess = ''; 00101 $this->where_hid_del = ' AND pages.deleted=0 '; 00102 if (!$show_hidden) { 00103 $this->where_hid_del .= 'AND pages.hidden=0 '; 00104 } 00105 $this->where_hid_del .= 'AND pages.starttime<=' . $GLOBALS['SIM_ACCESS_TIME'] . ' AND (pages.endtime=0 OR pages.endtime>' . $GLOBALS['SIM_ACCESS_TIME'] . ') '; 00106 00107 // Filter out new/deleted place-holder pages in case we are NOT in a versioning preview (that means we are online!) 00108 if (!$this->versioningPreview) { 00109 $this->where_hid_del .= ' AND NOT pages.t3ver_state>0'; 00110 } else { 00111 // For version previewing, make sure that enable-fields are not de-selecting hidden pages - we need versionOL() to unset them only if the overlay record instructs us to. 00112 $this->versioningPreview_where_hid_del = $this->where_hid_del; // Copy where_hid_del to other variable (used in relation to versionOL()) 00113 $this->where_hid_del = ' AND pages.deleted=0 '; // Clear where_hid_del 00114 } 00115 } 00116 00117 00118 /******************************************* 00119 * 00120 * Selecting page records 00121 * 00122 ******************************************/ 00123 00134 function getPage($uid, $disableGroupAccessCheck = FALSE) { 00135 // Hook to manipulate the page uid for special overlay handling 00136 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPage'])) { 00137 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPage'] as $classRef) { 00138 $hookObject = t3lib_div::getUserObj($classRef); 00139 00140 if (!($hookObject instanceof t3lib_pageSelect_getPageHook)) { 00141 throw new UnexpectedValueException('$hookObject must implement interface t3lib_pageSelect_getPageHook', 1251476766); 00142 } 00143 00144 $hookObject->getPage_preProcess($uid, $disableGroupAccessCheck, $this); 00145 } 00146 } 00147 00148 $accessCheck = $disableGroupAccessCheck ? '' : $this->where_groupAccess; 00149 $cacheKey = md5($accessCheck . '-' . $this->where_hid_del . '-' . $this->sys_language_uid); 00150 00151 if (is_array($this->cache_getPage[$uid][$cacheKey])) { 00152 return $this->cache_getPage[$uid][$cacheKey]; 00153 } 00154 $result = array(); 00155 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid=' . intval($uid) . $this->where_hid_del . $accessCheck); 00156 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00157 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00158 if ($row) { 00159 $this->versionOL('pages', $row); 00160 if (is_array($row)) { 00161 $result = $this->getPageOverlay($row); 00162 } 00163 } 00164 $this->cache_getPage[$uid][$cacheKey] = $result; 00165 return $result; 00166 } 00167 00175 function getPage_noCheck($uid) { 00176 if ($this->cache_getPage_noCheck[$uid]) { 00177 return $this->cache_getPage_noCheck[$uid]; 00178 } 00179 00180 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid=' . intval($uid) . $this->deleteClause('pages')); 00181 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00182 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00183 00184 $result = array(); 00185 if ($row) { 00186 $this->versionOL('pages', $row); 00187 if (is_array($row)) { 00188 $result = $this->getPageOverlay($row); 00189 } 00190 } 00191 $this->cache_getPage_noCheck[$uid] = $result; 00192 00193 return $result; 00194 } 00195 00203 function getFirstWebPage($uid) { 00204 $output = ''; 00205 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'pid=' . intval($uid) . $this->where_hid_del . $this->where_groupAccess, '', 'sorting', '1'); 00206 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00207 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00208 if ($row) { 00209 $this->versionOL('pages', $row); 00210 if (is_array($row)) { 00211 $output = $this->getPageOverlay($row); 00212 } 00213 } 00214 return $output; 00215 } 00216 00224 function getPageIdFromAlias($alias) { 00225 $alias = strtolower($alias); 00226 if ($this->cache_getPageIdFromAlias[$alias]) { 00227 return $this->cache_getPageIdFromAlias[$alias]; 00228 } 00229 $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" because of versioning (means that aliases sent MUST be online!) 00230 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00231 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00232 if ($row) { 00233 $this->cache_getPageIdFromAlias[$alias] = $row['uid']; 00234 return $row['uid']; 00235 } 00236 $this->cache_getPageIdFromAlias[$alias] = 0; 00237 return 0; 00238 } 00239 00247 function getPageOverlay($pageInput, $lUid = -1) { 00248 00249 // Initialize: 00250 if ($lUid < 0) { 00251 $lUid = $this->sys_language_uid; 00252 } 00253 $row = NULL; 00254 00255 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPageOverlay'])) { 00256 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPageOverlay'] as $classRef) { 00257 $hookObject = t3lib_div::getUserObj($classRef); 00258 00259 if (!($hookObject instanceof t3lib_pageSelect_getPageOverlayHook)) { 00260 throw new UnexpectedValueException('$hookObject must implement interface t3lib_pageSelect_getPageOverlayHook', 1269878881); 00261 } 00262 00263 $hookObject->getPageOverlay_preProcess($pageInput, $lUid, $this); 00264 } 00265 } 00266 00267 // If language UID is different from zero, do overlay: 00268 if ($lUid) { 00269 $fieldArr = t3lib_div::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']); 00270 if (is_array($pageInput)) { 00271 $page_id = $pageInput['uid']; // Was the whole record 00272 $fieldArr = array_intersect($fieldArr, array_keys($pageInput)); // Make sure that only fields which exist in the incoming record are overlaid! 00273 } else { 00274 $page_id = $pageInput; // Was the id 00275 } 00276 00277 if (count($fieldArr)) { 00278 /* 00279 NOTE to enabledFields('pages_language_overlay'): 00280 Currently the showHiddenRecords of TSFE set will allow pages_language_overlay records to be selected as they are child-records of a page. 00281 However you may argue that the showHiddenField flag should determine this. But that's not how it's done right now. 00282 */ 00283 00284 // Selecting overlay record: 00285 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00286 implode(',', $fieldArr), 00287 'pages_language_overlay', 00288 'pid=' . intval($page_id) . ' 00289 AND sys_language_uid=' . intval($lUid) . 00290 $this->enableFields('pages_language_overlay'), 00291 '', 00292 '', 00293 '1' 00294 ); 00295 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00296 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00297 $this->versionOL('pages_language_overlay', $row); 00298 00299 if (is_array($row)) { 00300 $row['_PAGES_OVERLAY'] = TRUE; 00301 $row['_PAGES_OVERLAY_UID'] = $row['uid']; 00302 00303 // Unset vital fields that are NOT allowed to be overlaid: 00304 unset($row['uid']); 00305 unset($row['pid']); 00306 } 00307 } 00308 } 00309 00310 // Create output: 00311 if (is_array($pageInput)) { 00312 return is_array($row) ? array_merge($pageInput, $row) : $pageInput; // If the input was an array, simply overlay the newfound array and return... 00313 } else { 00314 return is_array($row) ? $row : array(); // always an array in return 00315 } 00316 } 00317 00327 function getRecordOverlay($table, $row, $sys_language_content, $OLmode = '') { 00328 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) { 00329 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) { 00330 $hookObject = t3lib_div::getUserObj($classRef); 00331 00332 if (!($hookObject instanceof t3lib_pageSelect_getRecordOverlayHook)) { 00333 throw new UnexpectedValueException('$hookObject must implement interface t3lib_pageSelect_getRecordOverlayHook', 1269881658); 00334 } 00335 $hookObject->getRecordOverlay_preProcess($table, $row, $sys_language_content, $OLmode, $this); 00336 } 00337 } 00338 00339 if ($row['uid'] > 0 && $row['pid'] > 0) { 00340 if ($GLOBALS['TCA'][$table] && $GLOBALS['TCA'][$table]['ctrl']['languageField'] 00341 && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']) { 00342 if (!$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable']) { 00343 // Will not be able to work with other tables (Just didn't implement it yet; Requires a scan 00344 // over all tables [ctrl] part for first FIND the table that carries localization information for 00345 // this table (which could even be more than a single table) and then use that. Could be 00346 // implemented, but obviously takes a little more....) 00347 00348 // Will try to overlay a record only if the sys_language_content value is larger than zero. 00349 if ($sys_language_content > 0) { 00350 00351 // Must be default language or [All], otherwise no overlaying: 00352 if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] <= 0) { 00353 00354 // Select overlay record: 00355 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00356 '*', 00357 $table, 00358 'pid=' . intval($row['pid']) . 00359 ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['languageField'] . '=' . intval($sys_language_content) . 00360 ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] . '=' . intval($row['uid']) . 00361 $this->enableFields($table), 00362 '', 00363 '', 00364 '1' 00365 ); 00366 $olrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00367 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00368 $this->versionOL($table, $olrow); 00369 00370 // Merge record content by traversing all fields: 00371 if (is_array($olrow)) { 00372 if (isset($olrow['_ORIG_uid'])) { 00373 $row['_ORIG_uid'] = $olrow['_ORIG_uid']; 00374 } 00375 if (isset($olrow['_ORIG_pid'])) { 00376 $row['_ORIG_pid'] = $olrow['_ORIG_pid']; 00377 } 00378 foreach ($row as $fN => $fV) { 00379 if ($fN != 'uid' && $fN != 'pid' && isset($olrow[$fN])) { 00380 00381 if ($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$fN] != 'exclude' 00382 && ($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$fN] != 'mergeIfNotBlank' || strcmp(trim($olrow[$fN]), ''))) { 00383 $row[$fN] = $olrow[$fN]; 00384 } 00385 } elseif ($fN == 'uid') { 00386 $row['_LOCALIZED_UID'] = $olrow['uid']; 00387 } 00388 } 00389 } elseif ($OLmode === 'hideNonTranslated' && $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] == 0) { 00390 // Unset, if non-translated records should be hidden. ONLY done if the source record 00391 // really is default language and not [All] in which case it is allowed. 00392 unset($row); 00393 } 00394 00395 // 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. 00396 } elseif ($sys_language_content != $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']]) { 00397 unset($row); 00398 } 00399 } else { 00400 // When default language is displayed, we never want to return a record carrying another language! 00401 if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) { 00402 unset($row); 00403 } 00404 } 00405 } 00406 } 00407 } 00408 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) { 00409 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) { 00410 $hookObject = t3lib_div::getUserObj($classRef); 00411 00412 if (!($hookObject instanceof t3lib_pageSelect_getRecordOverlayHook)) { 00413 throw new UnexpectedValueException('$hookObject must implement interface t3lib_pageSelect_getRecordOverlayHook', 1269881659); 00414 } 00415 $hookObject->getRecordOverlay_postProcess($table, $row, $sys_language_content, $OLmode, $this); 00416 } 00417 } 00418 return $row; 00419 } 00420 00421 00422 /******************************************* 00423 * 00424 * Page related: Menu, Domain record, Root line 00425 * 00426 ******************************************/ 00427 00441 function getMenu($uid, $fields = '*', $sortField = 'sorting', $addWhere = '', $checkShortcuts = 1) { 00442 00443 $output = Array(); 00444 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, 'pages', 'pid=' . intval($uid) . $this->where_hid_del . $this->where_groupAccess . ' ' . $addWhere, '', $sortField); 00445 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00446 $this->versionOL('pages', $row, TRUE); 00447 if (is_array($row)) { 00448 // Keep mount point: 00449 $origUid = $row['uid']; 00450 $mount_info = $this->getMountPointInfo($origUid, $row); // $row MUST have "uid", "pid", "doktype", "mount_pid", "mount_pid_ol" fields in it 00451 if (is_array($mount_info) && $mount_info['overlay']) { // There is a valid mount point. 00452 $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! 00453 if (count($mp_row)) { 00454 $row = $mp_row; 00455 $row['_MP_PARAM'] = $mount_info['MPvar']; 00456 } else { 00457 unset($row); 00458 } // 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! 00459 } 00460 00461 // if shortcut, look up if the target exists and is currently visible 00462 if ($row['doktype'] == t3lib_pageSelect::DOKTYPE_SHORTCUT && ($row['shortcut'] || $row['shortcut_mode']) && $checkShortcuts) { 00463 if ($row['shortcut_mode'] == self::SHORTCUT_MODE_NONE) { 00464 // no shortcut_mode set, so target is directly set in $row['shortcut'] 00465 $searchField = 'uid'; 00466 $searchUid = intval($row['shortcut']); 00467 } elseif ($row['shortcut_mode'] == self::SHORTCUT_MODE_FIRST_SUBPAGE || $row['shortcut_mode'] == self::SHORTCUT_MODE_RANDOM_SUBPAGE) { 00468 // check subpages - first subpage or random subpage 00469 $searchField = 'pid'; 00470 // If a shortcut mode is set and no valid page is given to select subpags from use the actual page. 00471 $searchUid = intval($row['shortcut']) ? intval($row['shortcut']) : $row['uid']; 00472 } elseif ($row['shortcut_mode'] == self::SHORTCUT_MODE_PARENT_PAGE) { 00473 // shortcut to parent page 00474 $searchField = 'uid'; 00475 $searchUid = $row['pid']; 00476 } 00477 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows( 00478 'uid', 00479 'pages', 00480 $searchField . '=' . $searchUid . 00481 $this->where_hid_del . 00482 $this->where_groupAccess . 00483 ' ' . $addWhere 00484 ); 00485 if (!$count) { 00486 unset($row); 00487 } 00488 } elseif ($row['doktype'] == t3lib_pageSelect::DOKTYPE_SHORTCUT && $checkShortcuts) { 00489 // Neither shortcut target nor mode is set. Remove the page from the menu. 00490 unset($row); 00491 } 00492 00493 // Add to output array after overlaying language: 00494 if (is_array($row)) { 00495 $output[$origUid] = $this->getPageOverlay($row); 00496 } 00497 } 00498 } 00499 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00500 return $output; 00501 } 00502 00513 function getDomainStartPage($domain, $path = '', $request_uri = '') { 00514 $domain = explode(':', $domain); 00515 $domain = strtolower(preg_replace('/\.$/', '', $domain[0])); 00516 // Removing extra trailing slashes 00517 $path = trim(preg_replace('/\/[^\/]*$/', '', $path)); 00518 // Appending to domain string 00519 $domain .= $path; 00520 $domain = preg_replace('/\/*$/', '', $domain); 00521 00522 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00523 'pages.uid,sys_domain.redirectTo,sys_domain.redirectHttpStatusCode,sys_domain.prepend_params', 00524 'pages,sys_domain', 00525 'pages.uid=sys_domain.pid 00526 AND sys_domain.hidden=0 00527 AND (sys_domain.domainName=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($domain, 'sys_domain') . ' OR sys_domain.domainName=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($domain . '/', 'sys_domain') . ') ' . 00528 $this->where_hid_del . $this->where_groupAccess, 00529 '', 00530 '', 00531 1 00532 ); 00533 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00534 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00535 if ($row) { 00536 if ($row['redirectTo']) { 00537 $redirectUrl = $row['redirectTo']; 00538 if ($row['prepend_params']) { 00539 $redirectUrl = rtrim($redirectUrl, '/'); 00540 $prependStr = ltrim(substr($request_uri, strlen($path)), '/'); 00541 $redirectUrl .= '/' . $prependStr; 00542 } 00543 00544 $statusCode = intval($row['redirectHttpStatusCode']); 00545 if ($statusCode && defined('t3lib_utility_Http::HTTP_STATUS_' . $statusCode)) { 00546 t3lib_utility_Http::redirect($redirectUrl, constant('t3lib_utility_Http::HTTP_STATUS_' . $statusCode)); 00547 } else { 00548 t3lib_utility_Http::redirect($redirectUrl, 't3lib_utility_Http::HTTP_STATUS_301'); 00549 } 00550 exit; 00551 } else { 00552 return $row['uid']; 00553 } 00554 } 00555 } 00556 00569 function getRootLine($uid, $MP = '', $ignoreMPerrors = FALSE) { 00570 $cacheUid = $uid = intval($uid); 00571 $cacheIgnoreMPerrors = ($ignoreMPerrors ? 1 : 0); 00572 00573 if (is_array($this->cache_getRootLine[$cacheUid][$this->sys_language_uid][$MP][$cacheIgnoreMPerrors])) { 00574 return $this->cache_getRootLine[$cacheUid][$this->sys_language_uid][$MP][$cacheIgnoreMPerrors]; 00575 } 00576 00577 // Initialize: 00578 $selFields = t3lib_div::uniqueList('pid,uid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_swapmode,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,backend_layout_next_level,' . $GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields']); 00579 $this->error_getRootLine = ''; 00580 $this->error_getRootLine_failPid = 0; 00581 00582 // Splitting the $MP parameters if present 00583 $MPA = array(); 00584 if ($MP) { 00585 $MPA = explode(',', $MP); 00586 foreach ($MPA as $MPAk => $v) { 00587 $MPA[$MPAk] = explode('-', $MPA[$MPAk]); 00588 } 00589 } 00590 00591 $loopCheck = 0; 00592 $theRowArray = Array(); 00593 00594 while ($uid != 0 && $loopCheck < 99) { // Max 99 levels in the page tree. 00595 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid=' . intval($uid) . ' AND pages.deleted=0 AND pages.doktype<>255'); 00596 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00597 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00598 if ($row) { 00599 $this->versionOL('pages', $row, FALSE, TRUE); 00600 $this->fixVersioningPid('pages', $row); 00601 00602 if (is_array($row)) { 00603 // 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: 00604 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'] && $row['doktype'] == t3lib_pageSelect::DOKTYPE_MOUNTPOINT && !$ignoreMPerrors) { 00605 $mount_info = $this->getMountPointInfo($row['uid'], $row); 00606 if ($loopCheck > 0 || $mount_info['overlay']) { 00607 $this->error_getRootLine = 'Illegal Mount Point found in rootline'; 00608 return array(); 00609 } 00610 } 00611 00612 $uid = $row['pid']; // Next uid 00613 00614 if (count($MPA) && $GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) { 00615 $curMP = end($MPA); 00616 if (!strcmp($row['uid'], $curMP[0])) { 00617 00618 array_pop($MPA); 00619 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid=' . intval($curMP[1]) . ' AND pages.deleted=0 AND pages.doktype<>255'); 00620 $mp_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00621 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00622 00623 $this->versionOL('pages', $mp_row, FALSE, TRUE); 00624 $this->fixVersioningPid('pages', $mp_row); 00625 00626 if (is_array($mp_row)) { 00627 $mount_info = $this->getMountPointInfo($mp_row['uid'], $mp_row); 00628 if (is_array($mount_info) && $mount_info['mount_pid'] == $curMP[0]) { 00629 $uid = $mp_row['pid']; // Setting next uid 00630 00631 if ($mount_info['overlay']) { // Symlink style: Keep mount point (current row). 00632 $row['_MOUNT_OL'] = TRUE; // Set overlay mode: 00633 $row['_MOUNT_PAGE'] = array( 00634 'uid' => $mp_row['uid'], 00635 'pid' => $mp_row['pid'], 00636 'title' => $mp_row['title'], 00637 ); 00638 } else { // Normal operation: Insert the mount page row in rootline instead mount point. 00639 if ($loopCheck > 0) { 00640 $row = $mp_row; 00641 } else { 00642 $this->error_getRootLine = 'Current Page Id is a mounted page of the overlay type and cannot be accessed directly!'; 00643 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!) 00644 } 00645 } 00646 00647 $row['_MOUNTED_FROM'] = $curMP[0]; 00648 $row['_MP_PARAM'] = $mount_info['MPvar']; 00649 } else { 00650 $this->error_getRootLine = 'MP var was corrupted'; 00651 return array(); // The MP variables did NOT connect proper mount points: 00652 } 00653 } else { 00654 $this->error_getRootLine = 'No moint point record found according to PID in MP var'; 00655 return array(); // The second PID in MP var was NOT a valid page. 00656 } 00657 } 00658 } 00659 } 00660 // Add row to rootline with language overlaid: 00661 $theRowArray[] = $this->getPageOverlay($row); 00662 } else { 00663 $this->error_getRootLine = 'Broken rootline (failed on page with uid ' . $uid . ')'; 00664 $this->error_getRootLine_failPid = $uid; 00665 return array(); // broken rootline. 00666 } 00667 00668 $loopCheck++; 00669 } 00670 00671 // If the MPA array is NOT empty, we have to return an error; All MP elements were not resolved! 00672 if (count($MPA)) { 00673 $this->error_getRootLine = 'MP value remain!'; 00674 return array(); 00675 } 00676 00677 // Create output array (with reversed order of numeric keys): 00678 $output = Array(); 00679 $c = count($theRowArray); 00680 foreach ($theRowArray as $key => $val) { 00681 $c--; 00682 $output[$c] = $val; 00683 } 00684 00685 // Note: rootline errors are not cached 00686 $this->cache_getRootLine[$cacheUid][$this->sys_language_uid][$MP][$cacheIgnoreMPerrors] = $output; 00687 return $output; 00688 } 00689 00699 function getPathFromRootline($rl, $len = 20) { 00700 if (is_array($rl)) { 00701 $c = count($rl); 00702 $path = ''; 00703 for ($a = 0; $a < $c; $a++) { 00704 if ($rl[$a]['uid']) { 00705 $path .= '/' . t3lib_div::fixed_lgd_cs(strip_tags($rl[$a]['title']), $len); 00706 } 00707 } 00708 return $path; 00709 } 00710 } 00711 00720 function getExtURL($pagerow, $disable = 0) { 00721 if ($pagerow['doktype'] == t3lib_pageSelect::DOKTYPE_LINK && !$disable) { 00722 $redirectTo = $this->urltypes[$pagerow['urltype']] . $pagerow['url']; 00723 00724 // If relative path, prefix Site URL: 00725 $uI = parse_url($redirectTo); 00726 if (!$uI['scheme'] && substr($redirectTo, 0, 1) != '/') { // relative path assumed now... 00727 $redirectTo = t3lib_div::getIndpEnv('TYPO3_SITE_URL') . $redirectTo; 00728 } 00729 return $redirectTo; 00730 } 00731 } 00732 00744 function getMountPointInfo($pageId, $pageRec = FALSE, $prevMountPids = array(), $firstPageUid = 0) { 00745 $result = FALSE; 00746 00747 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) { 00748 00749 if (isset($this->cache_getMountPointInfo[$pageId])) { 00750 return $this->cache_getMountPointInfo[$pageId]; 00751 } 00752 00753 // Get pageRec if not supplied: 00754 if (!is_array($pageRec)) { 00755 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,pid,doktype,mount_pid,mount_pid_ol,t3ver_state', 'pages', 'uid=' . intval($pageId) . ' AND pages.deleted=0 AND pages.doktype<>255'); 00756 $pageRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00757 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00758 $this->versionOL('pages', $pageRec); // Only look for version overlay if page record is not supplied; This assumes that the input record is overlaid with preview version, if any! 00759 } 00760 00761 // Set first Page uid: 00762 if (!$firstPageUid) { 00763 $firstPageUid = $pageRec['uid']; 00764 } 00765 00766 // Look for mount pid value plus other required circumstances: 00767 $mount_pid = intval($pageRec['mount_pid']); 00768 if (is_array($pageRec) && $pageRec['doktype'] == t3lib_pageSelect::DOKTYPE_MOUNTPOINT && $mount_pid > 0 && !in_array($mount_pid, $prevMountPids)) { 00769 00770 // Get the mount point record (to verify its general existence): 00771 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,pid,doktype,mount_pid,mount_pid_ol,t3ver_state', 'pages', 'uid=' . $mount_pid . ' AND pages.deleted=0 AND pages.doktype<>255'); 00772 $mountRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00773 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00774 $this->versionOL('pages', $mountRec); 00775 00776 if (is_array($mountRec)) { 00777 // Look for recursive mount point: 00778 $prevMountPids[] = $mount_pid; 00779 $recursiveMountPid = $this->getMountPointInfo($mount_pid, $mountRec, $prevMountPids, $firstPageUid); 00780 00781 // Return mount point information: 00782 $result = $recursiveMountPid ? 00783 $recursiveMountPid : 00784 array( 00785 'mount_pid' => $mount_pid, 00786 'overlay' => $pageRec['mount_pid_ol'], 00787 'MPvar' => $mount_pid . '-' . $firstPageUid, 00788 'mount_point_rec' => $pageRec, 00789 'mount_pid_rec' => $mountRec, 00790 ); 00791 } else { 00792 $result = -1; // Means, there SHOULD have been a mount point, but there was none! 00793 } 00794 } 00795 } 00796 00797 $this->cache_getMountPointInfo[$pageId] = $result; 00798 return $result; 00799 } 00800 00801 00802 /********************************* 00803 * 00804 * Selecting records in general 00805 * 00806 **********************************/ 00807 00817 function checkRecord($table, $uid, $checkPage = 0) { 00818 $uid = intval($uid); 00819 if (is_array($GLOBALS['TCA'][$table]) && $uid > 0) { 00820 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid = ' . $uid . $this->enableFields($table)); 00821 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00822 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00823 if ($row) { 00824 $this->versionOL($table, $row); 00825 if (is_array($row)) { 00826 if ($checkPage) { 00827 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'uid=' . intval($row['pid']) . $this->enableFields('pages')); 00828 $numRows = $GLOBALS['TYPO3_DB']->sql_num_rows($res); 00829 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00830 if ($numRows > 0) { 00831 return $row; 00832 } else { 00833 return 0; 00834 } 00835 } else { 00836 return $row; 00837 } 00838 } 00839 } 00840 } 00841 } 00842 00853 function getRawRecord($table, $uid, $fields = '*', $noWSOL = FALSE) { 00854 $uid = intval($uid); 00855 // Excluding pages here so we can ask the function BEFORE TCA gets initialized. Support for this is followed up in deleteClause()... 00856 if ((is_array($GLOBALS['TCA'][$table]) || $table == 'pages') && $uid > 0) { 00857 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, 'uid = ' . $uid . $this->deleteClause($table)); 00858 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00859 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00860 if ($row) { 00861 if (!$noWSOL) { 00862 $this->versionOL($table, $row); 00863 } 00864 if (is_array($row)) { 00865 return $row; 00866 } 00867 } 00868 } 00869 } 00870 00883 function getRecordsByField($theTable, $theField, $theValue, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '') { 00884 if (is_array($GLOBALS['TCA'][$theTable])) { 00885 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00886 '*', 00887 $theTable, 00888 $theField . '=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($theValue, $theTable) . 00889 $this->deleteClause($theTable) . ' ' . 00890 $whereClause, // whereClauseMightContainGroupOrderBy 00891 $groupBy, 00892 $orderBy, 00893 $limit 00894 ); 00895 $rows = array(); 00896 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00897 #$this->versionOL($theTable,$row); // not used since records here are fetched based on other fields than uid! 00898 if (is_array($row)) { 00899 $rows[] = $row; 00900 } 00901 } 00902 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00903 if (count($rows)) { 00904 return $rows; 00905 } 00906 } 00907 } 00908 00909 00910 /********************************* 00911 * 00912 * Caching and standard clauses 00913 * 00914 **********************************/ 00915 00927 public static function getHash($hash, $expTime = 0) { 00928 $hashContent = NULL; 00929 00930 if (is_object($GLOBALS['typo3CacheManager'])) { 00931 $contentHashCache = $GLOBALS['typo3CacheManager']->getCache('cache_hash'); 00932 $cacheEntry = $contentHashCache->get($hash); 00933 00934 if ($cacheEntry) { 00935 $hashContent = $cacheEntry; 00936 } 00937 } 00938 00939 return $hashContent; 00940 } 00941 00954 public static function storeHash($hash, $data, $ident, $lifetime = 0) { 00955 if (is_object($GLOBALS['typo3CacheManager'])) { 00956 $GLOBALS['typo3CacheManager']->getCache('cache_hash')->set( 00957 $hash, 00958 $data, 00959 array('ident_' . $ident), 00960 intval($lifetime) 00961 ); 00962 } 00963 } 00964 00972 function deleteClause($table) { 00973 if (!strcmp($table, 'pages')) { // Hardcode for pages because TCA might not be loaded yet (early frontend initialization) 00974 return ' AND pages.deleted=0'; 00975 } else { 00976 return $GLOBALS['TCA'][$table]['ctrl']['delete'] ? ' AND ' . $table . '.' . $GLOBALS['TCA'][$table]['ctrl']['delete'] . '=0' : ''; 00977 } 00978 } 00979 00991 function enableFields($table, $show_hidden = -1, $ignore_array = array(), $noVersionPreview = FALSE) { 00992 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 00993 $show_hidden = $table == 'pages' ? $GLOBALS['TSFE']->showHiddenPage : $GLOBALS['TSFE']->showHiddenRecords; 00994 } 00995 if ($show_hidden == -1) { 00996 $show_hidden = 0; 00997 } // If show_hidden was not changed during the previous evaluation, do it here. 00998 00999 $ctrl = $GLOBALS['TCA'][$table]['ctrl']; 01000 $query = ''; 01001 if (is_array($ctrl)) { 01002 01003 // Delete field check: 01004 if ($ctrl['delete']) { 01005 $query .= ' AND ' . $table . '.' . $ctrl['delete'] . '=0'; 01006 } 01007 01008 // Filter out new place-holder records in case we are NOT in a versioning preview (that means we are online!) 01009 if ($ctrl['versioningWS'] && !$this->versioningPreview) { 01010 $query .= ' AND ' . $table . '.t3ver_state<=0 AND ' . $table . '.pid<>-1'; // Shadow state for new items MUST be ignored! 01011 } 01012 01013 // Enable fields: 01014 if (is_array($ctrl['enablecolumns'])) { 01015 if (!$this->versioningPreview || !$ctrl['versioningWS'] || $noVersionPreview) { // In case of versioning-preview, enableFields are ignored (checked in versionOL()) 01016 if ($ctrl['enablecolumns']['disabled'] && !$show_hidden && !$ignore_array['disabled']) { 01017 $field = $table . '.' . $ctrl['enablecolumns']['disabled']; 01018 $query .= ' AND ' . $field . '=0'; 01019 } 01020 if ($ctrl['enablecolumns']['starttime'] && !$ignore_array['starttime']) { 01021 $field = $table . '.' . $ctrl['enablecolumns']['starttime']; 01022 $query .= ' AND ' . $field . '<=' . $GLOBALS['SIM_ACCESS_TIME']; 01023 } 01024 if ($ctrl['enablecolumns']['endtime'] && !$ignore_array['endtime']) { 01025 $field = $table . '.' . $ctrl['enablecolumns']['endtime']; 01026 $query .= ' AND (' . $field . '=0 OR ' . $field . '>' . $GLOBALS['SIM_ACCESS_TIME'] . ')'; 01027 } 01028 if ($ctrl['enablecolumns']['fe_group'] && !$ignore_array['fe_group']) { 01029 $field = $table . '.' . $ctrl['enablecolumns']['fe_group']; 01030 $query .= $this->getMultipleGroupsWhereClause($field, $table); 01031 } 01032 01033 // Call hook functions for additional enableColumns 01034 // It is used by the extension ingmar_accessctrl which enables assigning more than one usergroup to content and page records 01035 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns'])) { 01036 $_params = array( 01037 'table' => $table, 01038 'show_hidden' => $show_hidden, 01039 'ignore_array' => $ignore_array, 01040 'ctrl' => $ctrl 01041 ); 01042 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns'] as $_funcRef) { 01043 $query .= t3lib_div::callUserFunction($_funcRef, $_params, $this); 01044 } 01045 } 01046 } 01047 } 01048 } else { 01049 throw new InvalidArgumentException( 01050 'There is no entry in the $TCA array for the table "' . $table . 01051 '". This means that the function enableFields() is ' . 01052 'called with an invalid table name as argument.', 01053 1283790586 01054 ); 01055 } 01056 01057 return $query; 01058 } 01059 01068 function getMultipleGroupsWhereClause($field, $table) { 01069 $memberGroups = t3lib_div::intExplode(',', $GLOBALS['TSFE']->gr_list); 01070 $orChecks = array(); 01071 $orChecks[] = $field . '=\'\''; // If the field is empty, then OK 01072 $orChecks[] = $field . ' IS NULL'; // If the field is NULL, then OK 01073 $orChecks[] = $field . '=\'0\''; // If the field contsains zero, then OK 01074 01075 foreach ($memberGroups as $value) { 01076 $orChecks[] = $GLOBALS['TYPO3_DB']->listQuery($field, $value, $table); 01077 } 01078 01079 return ' AND (' . implode(' OR ', $orChecks) . ')'; 01080 } 01081 01082 01083 /********************************* 01084 * 01085 * Versioning Preview 01086 * 01087 **********************************/ 01088 01101 function fixVersioningPid($table, &$rr) { 01102 if ($this->versioningPreview && is_array($rr) && $rr['pid'] == -1 01103 && ($table == 'pages' || $GLOBALS['TCA'][$table]['ctrl']['versioningWS'])) { 01104 // Have to hardcode it for "pages" table since TCA is not loaded at this moment! 01105 01106 // Check values for t3ver_oid and t3ver_wsid: 01107 if (isset($rr['t3ver_oid']) && isset($rr['t3ver_wsid'])) { // If "t3ver_oid" is already a field, just set this: 01108 $oid = $rr['t3ver_oid']; 01109 $wsid = $rr['t3ver_wsid']; 01110 } else { // Otherwise we have to expect "uid" to be in the record and look up based on this: 01111 $newPidRec = $this->getRawRecord($table, $rr['uid'], 't3ver_oid,t3ver_wsid', TRUE); 01112 if (is_array($newPidRec)) { 01113 $oid = $newPidRec['t3ver_oid']; 01114 $wsid = $newPidRec['t3ver_wsid']; 01115 } 01116 } 01117 01118 // If workspace ids matches and ID of current online version is found, look up the PID value of that: 01119 if ($oid && (($this->versioningWorkspaceId == 0 && $this->checkWorkspaceAccess($wsid)) || !strcmp((int) $wsid, $this->versioningWorkspaceId))) { 01120 $oidRec = $this->getRawRecord($table, $oid, 'pid', TRUE); 01121 01122 if (is_array($oidRec)) { 01123 # SWAP uid as well? Well no, because when fixing a versioning PID happens it is assumed that this is a "branch" type page and therefore the uid should be kept (like in versionOL()). However if the page is NOT a branch version it should not happen - but then again, direct access to that uid should not happen! 01124 $rr['_ORIG_pid'] = $rr['pid']; 01125 $rr['pid'] = $oidRec['pid']; 01126 } 01127 } 01128 } 01129 01130 // changing PID in case of moving pointer: 01131 if ($movePlhRec = $this->getMovePlaceholder($table, $rr['uid'], 'pid')) { 01132 $rr['pid'] = $movePlhRec['pid']; 01133 } 01134 } 01135 01149 function versionOL($table, &$row, $unsetMovePointers = FALSE, $bypassEnableFieldsCheck = FALSE) { 01150 if ($this->versioningPreview && is_array($row)) { 01151 $movePldSwap = $this->movePlhOL($table, $row); // will overlay any movePlhOL found with the real record, which in turn will be overlaid with its workspace version if any. 01152 if ($wsAlt = $this->getWorkspaceVersionOfRecord($this->versioningWorkspaceId, $table, $row['uid'], implode(',', array_keys($row)), $bypassEnableFieldsCheck)) { // implode(',',array_keys($row)) = Using fields from original record to make sure no additional fields are selected. This is best for eg. getPageOverlay() 01153 if (is_array($wsAlt)) { 01154 // Always fix PID (like in fixVersioningPid() above). [This is usually not the important factor for versioning OL] 01155 $wsAlt['_ORIG_pid'] = $wsAlt['pid']; // Keep the old (-1) - indicates it was a version... 01156 $wsAlt['pid'] = $row['pid']; // Set in the online versions PID. 01157 01158 // For versions of single elements or page+content, preserve online UID and PID (this will produce true "overlay" of element _content_, not any references) 01159 // For page+content the "_ORIG_uid" should actually be used as PID for selection of tables with "versioning_followPages" enabled. 01160 $wsAlt['_ORIG_uid'] = $wsAlt['uid']; 01161 $wsAlt['uid'] = $row['uid']; 01162 01163 // Translate page alias as well so links are pointing to the _online_ page: 01164 if ($table === 'pages') { 01165 $wsAlt['alias'] = $row['alias']; 01166 } 01167 01168 // Changing input record to the workspace version alternative: 01169 $row = $wsAlt; 01170 01171 // Check if it is deleted/new 01172 if ((int) $row['t3ver_state'] === 1 || (int) $row['t3ver_state'] === 2) { 01173 $row = FALSE; // Unset record if it turned out to be deleted in workspace 01174 } 01175 01176 // Check if move-pointer in workspace (unless if a move-placeholder is the reason why it appears!): 01177 // You have to specifically set $unsetMovePointers in order to clear these because it is normally a display issue if it should be shown or not. 01178 if ((int) $row['t3ver_state'] === 4 && !$movePldSwap && $unsetMovePointers) { 01179 $row = FALSE; // Unset record if it turned out to be deleted in workspace 01180 } 01181 } else { 01182 // No version found, then check if t3ver_state =1 (online version is dummy-representation) 01183 // Notice, that unless $bypassEnableFieldsCheck is TRUE, the $row is unset if enablefields for BOTH the version AND the online record deselects it. See note for $bypassEnableFieldsCheck 01184 if ($wsAlt <= -1 || (int) $row['t3ver_state'] > 0) { 01185 $row = FALSE; // Unset record if it turned out to be "hidden" 01186 } 01187 } 01188 } 01189 } 01190 } 01191 01201 function movePlhOL($table, &$row) { 01202 if (($table == 'pages' || (int) $GLOBALS['TCA'][$table]['ctrl']['versioningWS'] >= 2) && (int) $row['t3ver_state'] === 3) { 01203 // Only for WS ver 2... (moving) 01204 01205 // If t3ver_move_id is not found, then find it... (but we like best if it is here...) 01206 if (!isset($row['t3ver_move_id'])) { 01207 $moveIDRec = $this->getRawRecord($table, $row['uid'], 't3ver_move_id', TRUE); 01208 $moveID = $moveIDRec['t3ver_move_id']; 01209 } else { 01210 $moveID = $row['t3ver_move_id']; 01211 } 01212 01213 // Find pointed-to record. 01214 if ($moveID) { 01215 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(implode(',', array_keys($row)), $table, 'uid=' . intval($moveID) . $this->enableFields($table)); 01216 $origRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 01217 $GLOBALS['TYPO3_DB']->sql_free_result($res); 01218 if ($origRow) { 01219 $row = $origRow; 01220 return TRUE; 01221 } 01222 } 01223 } 01224 return FALSE; 01225 } 01226 01236 function getMovePlaceholder($table, $uid, $fields = '*') { 01237 if ($this->versioningPreview) { 01238 $workspace = (int) $this->versioningWorkspaceId; 01239 if (($table == 'pages' || (int) $GLOBALS['TCA'][$table]['ctrl']['versioningWS'] >= 2) && $workspace !== 0) { 01240 01241 // Select workspace version of record: 01242 $row = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow( 01243 $fields, 01244 $table, 01245 'pid<>-1 AND 01246 t3ver_state=3 AND 01247 t3ver_move_id=' . intval($uid) . ' AND 01248 t3ver_wsid=' . intval($workspace) . 01249 $this->deleteClause($table) 01250 ); 01251 01252 if (is_array($row)) { 01253 return $row; 01254 } 01255 } 01256 } 01257 return FALSE; 01258 } 01259 01271 function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields = '*', $bypassEnableFieldsCheck = FALSE) { 01272 if ($workspace !== 0) { 01273 // Have to hardcode it for "pages" table since TCA is not loaded at this moment! 01274 01275 // Setting up enableFields for version record: 01276 if ($table == 'pages') { 01277 $enFields = $this->versioningPreview_where_hid_del; 01278 } else { 01279 $enFields = $this->enableFields($table, -1, array(), TRUE); 01280 } 01281 01282 // Select workspace version of record, only testing for deleted. 01283 $newrow = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow( 01284 $fields, 01285 $table, 01286 'pid=-1 AND 01287 t3ver_oid=' . intval($uid) . ' AND 01288 t3ver_wsid=' . intval($workspace) . 01289 $this->deleteClause($table) 01290 ); 01291 01292 // If version found, check if it could have been selected with enableFields on as well: 01293 if (is_array($newrow)) { 01294 if ($bypassEnableFieldsCheck || $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow( 01295 'uid', 01296 $table, 01297 'pid=-1 AND 01298 t3ver_oid=' . intval($uid) . ' AND 01299 t3ver_wsid=' . intval($workspace) . 01300 $enFields 01301 )) { 01302 return $newrow; // Return offline version, tested for its enableFields. 01303 } else { 01304 return -1; // Return -1 because offline version was de-selected due to its enableFields. 01305 } 01306 } else { 01307 // OK, so no workspace version was found. Then check if online version can be selected with full enable fields and if so, return 1: 01308 if ($bypassEnableFieldsCheck || $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow( 01309 'uid', 01310 $table, 01311 'uid=' . intval($uid) . $enFields 01312 )) { 01313 return 1; // Means search was done, but no version found. 01314 } else { 01315 return -2; // Return -2 because the online record was de-selected due to its enableFields. 01316 } 01317 } 01318 } 01319 01320 return FALSE; // No look up in database because versioning not enabled / or workspace not offline 01321 } 01322 01329 function checkWorkspaceAccess($wsid) { 01330 if (!$GLOBALS['BE_USER'] || !t3lib_extMgm::isLoaded('workspaces')) { 01331 return FALSE; 01332 } 01333 if (isset($this->workspaceCache[$wsid])) { 01334 $ws = $this->workspaceCache[$wsid]; 01335 } 01336 else { 01337 if ($wsid > 0) { 01338 // No $GLOBALS['TCA'] yet! 01339 $ws = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', 'sys_workspace', 'uid=' . intval($wsid) . ' AND deleted=0'); 01340 if (!is_array($ws)) { 01341 return FALSE; 01342 } 01343 } 01344 else { 01345 $ws = $wsid; 01346 } 01347 $ws = $GLOBALS['BE_USER']->checkWorkspace($ws); 01348 $this->workspaceCache[$wsid] = $ws; 01349 } 01350 return ($ws['_ACCESS'] != ''); 01351 } 01352 } 01353 01354 01355 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php'])) { 01356 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php']); 01357 } 01358 01359 ?>