Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00109 class t3lib_pageSelect { 00110 var $urltypes = Array('','http://','ftp://','mailto:','https://'); 00111 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 00112 var $where_groupAccess = ''; // Clause for fe_group access 00113 var $sys_language_uid = 0; 00114 00115 // Versioning preview related: 00116 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!!! 00117 var $versioningWorkspaceId = 0; // Workspace ID for preview 00118 00119 00120 00121 // Internal, dynamic: 00122 var $error_getRootLine = ''; // Error string set by getRootLine() 00123 var $error_getRootLine_failPid = 0; // Error uid set by getRootLine() 00124 00125 00134 function init($show_hidden) { 00135 $this->where_groupAccess = ''; 00136 $this->where_hid_del = ' AND pages.deleted=0 '; 00137 if (!$show_hidden) { 00138 $this->where_hid_del.= 'AND pages.hidden=0 '; 00139 } 00140 $this->where_hid_del.= 'AND (pages.starttime<='.$GLOBALS['SIM_EXEC_TIME'].') AND (pages.endtime=0 OR pages.endtime>'.$GLOBALS['SIM_EXEC_TIME'].') '; 00141 00142 // Filter out new place-holder pages in case we are NOT in a versioning preview (that means we are online!) 00143 if (!$this->versioningPreview) { 00144 $this->where_hid_del.= ' AND NOT(pages.t3ver_state=1)'; 00145 } else { 00146 // 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. 00147 $this->versioningPreview_where_hid_del = $this->where_hid_del; // Copy where_hid_del to other variable (used in relation to versionOL()) 00148 $this->where_hid_del = ' AND pages.deleted=0 '; // Clear where_hid_del 00149 } 00150 } 00151 00152 00153 00154 00155 00156 00157 00158 00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 /******************************************* 00169 * 00170 * Selecting page records 00171 * 00172 ******************************************/ 00173 00184 function getPage($uid, $disableGroupAccessCheck=FALSE) { 00185 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid='.intval($uid).$this->where_hid_del.($disableGroupAccessCheck ? '' : $this->where_groupAccess)); 00186 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00187 $this->versionOL('pages',$row); 00188 if (is_array($row)) return $this->getPageOverlay($row); 00189 } 00190 return Array(); 00191 } 00192 00200 function getPage_noCheck($uid) { 00201 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid='.intval($uid).$this->deleteClause('pages')); 00202 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00203 $this->versionOL('pages',$row); 00204 if (is_array($row)) return $this->getPageOverlay($row); 00205 } 00206 return Array(); 00207 } 00208 00216 function getFirstWebPage($uid) { 00217 $output = ''; 00218 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'pid='.intval($uid).$this->where_hid_del.$this->where_groupAccess, '', 'sorting', '1'); 00219 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00220 $this->versionOL('pages',$row); 00221 if (is_array($row)) $output = $this->getPageOverlay($row); 00222 } 00223 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00224 return $output; 00225 } 00226 00234 function getPageIdFromAlias($alias) { 00235 $alias = strtolower($alias); 00236 $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!) 00237 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00238 return $row['uid']; 00239 } 00240 return 0; 00241 } 00242 00250 function getPageOverlay($pageInput,$lUid=-1) { 00251 00252 // Initialize: 00253 if ($lUid<0) $lUid = $this->sys_language_uid; 00254 $row = NULL; 00255 00256 // If language UID is different from zero, do overlay: 00257 if ($lUid) { 00258 $fieldArr = explode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']); 00259 if (is_array($pageInput)) { 00260 $page_id = $pageInput['uid']; // Was the whole record 00261 $fieldArr = array_intersect($fieldArr,array_keys($pageInput)); // Make sure that only fields which exist in the incoming record are overlaid! 00262 } else { 00263 $page_id = $pageInput; // Was the id 00264 } 00265 00266 if (count($fieldArr)) { 00267 /* 00268 NOTE to enabledFields('pages_language_overlay'): 00269 Currently the showHiddenRecords of TSFE set will allow pages_language_overlay records to be selected as they are child-records of a page. 00270 However you may argue that the showHiddenField flag should determine this. But that's not how it's done right now. 00271 */ 00272 00273 // Selecting overlay record: 00274 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00275 implode(',',$fieldArr), 00276 'pages_language_overlay', 00277 'pid='.intval($page_id).' 00278 AND sys_language_uid='.intval($lUid). 00279 $this->enableFields('pages_language_overlay'), 00280 '', 00281 '', 00282 '1' 00283 ); 00284 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00285 $this->versionOL('pages_language_overlay',$row); 00286 00287 if (is_array($row)) { 00288 $row['_PAGES_OVERLAY'] = TRUE; 00289 00290 // Unset vital fields that are NOT allowed to be overlaid: 00291 unset($row['uid']); 00292 unset($row['pid']); 00293 } 00294 } 00295 } 00296 00297 // Create output: 00298 if (is_array($pageInput)) { 00299 return is_array($row) ? array_merge($pageInput,$row) : $pageInput; // If the input was an array, simply overlay the newfound array and return... 00300 } else { 00301 return is_array($row) ? $row : array(); // always an array in return 00302 } 00303 } 00304 00314 function getRecordOverlay($table,$row,$sys_language_content,$OLmode='') { 00315 global $TCA; 00316 00317 if ($row['uid']>0 && $row['pid']>0) { 00318 if ($TCA[$table] && $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField']) { 00319 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....) 00320 00321 // Will try to overlay a record only if the sys_language_content value is larger than zero. 00322 if ($sys_language_content>0) { 00323 00324 // Must be default language or [All], otherwise no overlaying: 00325 if ($row[$TCA[$table]['ctrl']['languageField']]<=0) { 00326 00327 // Select overlay record: 00328 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00329 '*', 00330 $table, 00331 'pid='.intval($row['pid']). 00332 ' AND '.$TCA[$table]['ctrl']['languageField'].'='.intval($sys_language_content). 00333 ' AND '.$TCA[$table]['ctrl']['transOrigPointerField'].'='.intval($row['uid']). 00334 $this->enableFields($table), 00335 '', 00336 '', 00337 '1' 00338 ); 00339 $olrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00340 $this->versionOL($table,$olrow); 00341 #debug($row); 00342 #debug($olrow); 00343 // Merge record content by traversing all fields: 00344 if (is_array($olrow)) { 00345 foreach($row as $fN => $fV) { 00346 if ($fN!='uid' && $fN!='pid' && isset($olrow[$fN])) { 00347 00348 if ($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$fN]!='exclude' 00349 && ($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$fN]!='mergeIfNotBlank' || strcmp(trim($olrow[$fN]),''))) { 00350 $row[$fN] = $olrow[$fN]; 00351 } 00352 } elseif ($fN=='uid') { 00353 $row['_LOCALIZED_UID'] = $olrow['uid']; 00354 } 00355 } 00356 } 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. 00357 unset($row); 00358 } 00359 00360 // 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. 00361 } elseif ($sys_language_content!=$row[$TCA[$table]['ctrl']['languageField']]) { 00362 unset($row); 00363 } 00364 } else { 00365 // When default language is displayed, we never want to return a record carrying another language!: 00366 if ($row[$TCA[$table]['ctrl']['languageField']]>0) { 00367 unset($row); 00368 } 00369 } 00370 } 00371 } 00372 } 00373 00374 return $row; 00375 } 00376 00377 00378 00379 00380 00381 00382 00383 00384 00385 00386 00387 00388 00389 00390 00391 00392 00393 00394 /******************************************* 00395 * 00396 * Page related: Menu, Domain record, Root line 00397 * 00398 ******************************************/ 00399 00413 function getMenu($uid,$fields='*',$sortField='sorting',$addWhere='',$checkShortcuts=1) { 00414 00415 $output = Array(); 00416 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, 'pages', 'pid='.intval($uid).$this->where_hid_del.$this->where_groupAccess.' '.$addWhere, '', $sortField); 00417 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00418 $this->versionOL('pages',$row); 00419 00420 if (is_array($row)) { 00421 // Keep mount point: 00422 $origUid = $row['uid']; 00423 $mount_info = $this->getMountPointInfo($origUid, $row); // $row MUST have "uid", "pid", "doktype", "mount_pid", "mount_pid_ol" fields in it 00424 if (is_array($mount_info) && $mount_info['overlay']) { // There is a valid mount point. 00425 $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! 00426 if (count($mp_row)) { 00427 $row = $mp_row; 00428 $row['_MP_PARAM'] = $mount_info['MPvar']; 00429 } 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! 00430 } 00431 00432 // if shortcut, look up if the target exists and is currently visible 00433 if ($row['doktype'] == 4 && ($row['shortcut'] || $row['shortcut_mode']) && $checkShortcuts) { 00434 if ($row['shortcut_mode'] == 0) { 00435 $searchField = 'uid'; 00436 $searchUid = intval($row['shortcut']); 00437 } else { // check subpages - first subpage or random subpage 00438 $searchField = 'pid'; 00439 // If a shortcut mode is set and no valid page is given to select subpags from use the actual page. 00440 $searchUid = intval($row['shortcut'])?intval($row['shortcut']):$row['uid']; 00441 } 00442 $res2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', $searchField.'='.$searchUid.$this->where_hid_del.$this->where_groupAccess.' '.$addWhere, '', $sortField); 00443 if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res2)) { 00444 unset($row); 00445 } 00446 $GLOBALS['TYPO3_DB']->sql_free_result($res2); 00447 } elseif ($row['doktype'] == 4 && $checkShortcuts) { 00448 // Neither shortcut target nor mode is set. Remove the page from the menu. 00449 unset($row); 00450 } 00451 00452 // Add to output array after overlaying language: 00453 if (is_array($row)) { 00454 $output[$origUid] = $this->getPageOverlay($row); 00455 } 00456 } 00457 } 00458 return $output; 00459 } 00460 00471 function getDomainStartPage($domain, $path='',$request_uri='') { 00472 $domain = explode(':',$domain); 00473 $domain = strtolower(ereg_replace('\.$','',$domain[0])); 00474 // Removing extra trailing slashes 00475 $path = trim(ereg_replace('\/[^\/]*$','',$path)); 00476 // Appending to domain string 00477 $domain.= $path; 00478 $domain = ereg_replace('\/*$','',$domain); 00479 00480 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00481 'pages.uid,sys_domain.redirectTo,sys_domain.prepend_params', 00482 'pages,sys_domain', 00483 'pages.uid=sys_domain.pid 00484 AND sys_domain.hidden=0 00485 AND (sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain, 'sys_domain').' OR sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain.'/', 'sys_domain').') '. 00486 $this->where_hid_del.$this->where_groupAccess, 00487 '', 00488 '', 00489 1 00490 ); 00491 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00492 if ($row['redirectTo']) { 00493 $rURL = $row['redirectTo']; 00494 if ($row['prepend_params']) { 00495 $rURL = ereg_replace('\/$','',$rURL); 00496 $prependStr = ereg_replace('^\/','',substr($request_uri,strlen($path))); 00497 $rURL.= '/'.$prependStr; 00498 } 00499 Header('Location: '.t3lib_div::locationHeaderUrl($rURL)); 00500 exit; 00501 } else { 00502 return $row['uid']; 00503 } 00504 } 00505 } 00506 00519 function getRootLine($uid, $MP='', $ignoreMPerrors=FALSE) { 00520 00521 // Initialize: 00522 $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,'.$GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields']); 00523 $this->error_getRootLine = ''; 00524 $this->error_getRootLine_failPid = 0; 00525 00526 // Splitting the $MP parameters if present 00527 $MPA = array(); 00528 if ($MP) { 00529 $MPA = explode(',',$MP); 00530 reset($MPA); 00531 while(list($MPAk) = each($MPA)) { 00532 $MPA[$MPAk] = explode('-', $MPA[$MPAk]); 00533 } 00534 } 00535 00536 $loopCheck = 0; 00537 $theRowArray = Array(); 00538 $uid = intval($uid); 00539 00540 while ($uid!=0 && $loopCheck<20) { // Max 20 levels in the page tree. 00541 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid='.intval($uid).' AND pages.deleted=0 AND pages.doktype!=255'); 00542 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00543 $this->versionOL('pages',$row); 00544 $this->fixVersioningPid('pages',$row); 00545 00546 if (is_array($row)) { 00547 // 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: 00548 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'] && $row['doktype']==7 && !$ignoreMPerrors) { 00549 $mount_info = $this->getMountPointInfo($row['uid'], $row); 00550 if ($loopCheck>0 || $mount_info['overlay']) { 00551 $this->error_getRootLine = 'Illegal Mount Point found in rootline'; 00552 return array(); 00553 } 00554 } 00555 00556 $uid = $row['pid']; // Next uid 00557 00558 if (count($MPA) && $GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) { 00559 $curMP = end($MPA); 00560 if (!strcmp($row['uid'],$curMP[0])) { 00561 00562 array_pop($MPA); 00563 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid='.intval($curMP[1]).' AND pages.deleted=0 AND pages.doktype!=255'); 00564 $mp_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00565 00566 $this->versionOL('pages',$mp_row); 00567 $this->fixVersioningPid('pages',$mp_row); 00568 00569 if (is_array($mp_row)) { 00570 $mount_info = $this->getMountPointInfo($mp_row['uid'], $mp_row); 00571 if (is_array($mount_info) && $mount_info['mount_pid']==$curMP[0]) { 00572 $uid = $mp_row['pid']; // Setting next uid 00573 00574 if ($mount_info['overlay']) { // Symlink style: Keep mount point (current row). 00575 $row['_MOUNT_OL'] = TRUE; // Set overlay mode: 00576 $row['_MOUNT_PAGE'] = array( 00577 'uid' => $mp_row['uid'], 00578 'pid' => $mp_row['pid'], 00579 'title' => $mp_row['title'], 00580 ); 00581 } else { // Normal operation: Insert the mount page row in rootline instead mount point. 00582 if ($loopCheck>0) { 00583 $row = $mp_row; 00584 } else { 00585 $this->error_getRootLine = 'Current Page Id is a mounted page of the overlay type and cannot be accessed directly!'; 00586 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!) 00587 } 00588 } 00589 00590 $row['_MOUNTED_FROM'] = $curMP[0]; 00591 $row['_MP_PARAM'] = $mount_info['MPvar']; 00592 } else { 00593 $this->error_getRootLine = 'MP var was corrupted'; 00594 return array(); // The MP variables did NOT connect proper mount points: 00595 } 00596 } else { 00597 $this->error_getRootLine = 'No moint point record found according to PID in MP var'; 00598 return array(); // The second PID in MP var was NOT a valid page. 00599 } 00600 } 00601 } 00602 } 00603 // Add row to rootline with language overlaid: 00604 $theRowArray[] = $this->getPageOverlay($row); 00605 } else { 00606 $this->error_getRootLine = 'Broken rootline'; 00607 $this->error_getRootLine_failPid = $uid; 00608 return array(); // broken rootline. 00609 } 00610 00611 $loopCheck++; 00612 } 00613 00614 // If the MPA array is NOT empty, we have to return an error; All MP elements were not resolved! 00615 if (count($MPA)) { 00616 $this->error_getRootLine = 'MP value remain!'; 00617 return array(); 00618 } 00619 00620 // Create output array (with reversed order of numeric keys): 00621 $output = Array(); 00622 $c = count($theRowArray); 00623 foreach($theRowArray as $key => $val) { 00624 $c--; 00625 $output[$c] = $val; 00626 } 00627 00628 return $output; 00629 } 00630 00640 function getPathFromRootline($rl,$len=20) { 00641 if (is_array($rl)) { 00642 $c=count($rl); 00643 $path = ''; 00644 for ($a=0;$a<$c;$a++) { 00645 if ($rl[$a]['uid']) { 00646 $path.='/'.t3lib_div::fixed_lgd_cs(strip_tags($rl[$a]['title']),$len); 00647 } 00648 } 00649 return $path; 00650 } 00651 } 00652 00661 function getExtURL($pagerow,$disable=0) { 00662 if ($pagerow['doktype']==3 && !$disable) { 00663 $redirectTo = $this->urltypes[$pagerow['urltype']].$pagerow['url']; 00664 00665 // If relative path, prefix Site URL: 00666 $uI = parse_url($redirectTo); 00667 if (!$uI['scheme'] && substr($redirectTo,0,1)!='/') { // relative path assumed now... 00668 $redirectTo = t3lib_div::getIndpEnv('TYPO3_SITE_URL').$redirectTo; 00669 } 00670 return $redirectTo; 00671 } 00672 } 00673 00685 function getMountPointInfo($pageId, $pageRec=FALSE, $prevMountPids=array(), $firstPageUid=0) { 00686 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) { 00687 00688 // Get pageRec if not supplied: 00689 if (!is_array($pageRec)) { 00690 $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'); 00691 $pageRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00692 $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! 00693 } 00694 00695 // Set first Page uid: 00696 if (!$firstPageUid) $firstPageUid = $pageRec['uid']; 00697 00698 // Look for mount pid value plus other required circumstances: 00699 $mount_pid = intval($pageRec['mount_pid']); 00700 if (is_array($pageRec) && $pageRec['doktype']==7 && $mount_pid>0 && !in_array($mount_pid, $prevMountPids)) { 00701 00702 // Get the mount point record (to verify its general existence): 00703 $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'); 00704 $mount_rec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00705 $this->versionOL('pages',$mount_rec); 00706 00707 if (is_array($mount_rec)) { 00708 // Look for recursive mount point: 00709 $prevMountPids[] = $mount_pid; 00710 $recursiveMountPid = $this->getMountPointInfo($mount_pid, $mount_rec, $prevMountPids, $firstPageUid); 00711 00712 // Return mount point information: 00713 return $recursiveMountPid ? 00714 $recursiveMountPid : 00715 array( 00716 'mount_pid' => $mount_pid, 00717 'overlay' => $pageRec['mount_pid_ol'], 00718 'MPvar' => $mount_pid.'-'.$firstPageUid, 00719 'mount_point_rec' => $pageRec, 00720 'mount_pid_rec' => $mount_rec, 00721 ); 00722 } else { 00723 return -1; // Means, there SHOULD have been a mount point, but there was none! 00724 } 00725 } 00726 } 00727 00728 return FALSE; 00729 } 00730 00731 00732 00733 00734 00735 00736 00737 00738 00739 00740 00741 00742 00743 00744 00745 00746 00747 /********************************* 00748 * 00749 * Selecting records in general 00750 * 00751 **********************************/ 00752 00762 function checkRecord($table,$uid,$checkPage=0) { 00763 global $TCA; 00764 $uid=intval($uid); 00765 if (is_array($TCA[$table])) { 00766 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($uid).$this->enableFields($table)); 00767 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00768 $this->versionOL($table,$row); 00769 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00770 00771 if (is_array($row)) { 00772 if ($checkPage) { 00773 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'uid='.intval($row['pid']).$this->enableFields('pages')); 00774 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) { 00775 return $row; 00776 } else { 00777 return 0; 00778 } 00779 } else { 00780 return $row; 00781 } 00782 } 00783 } 00784 } 00785 } 00786 00797 function getRawRecord($table,$uid,$fields='*',$noWSOL=FALSE) { 00798 global $TCA; 00799 $uid = intval($uid); 00800 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()... 00801 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, 'uid='.intval($uid).$this->deleteClause($table)); 00802 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00803 if (!$noWSOL) { 00804 $this->versionOL($table,$row); 00805 } 00806 if (is_array($row)) return $row; 00807 } 00808 } 00809 } 00810 00823 function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='') { 00824 global $TCA; 00825 if (is_array($TCA[$theTable])) { 00826 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00827 '*', 00828 $theTable, 00829 $theField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($theValue, $theTable). 00830 $this->deleteClause($theTable).' '. 00831 $whereClause, // whereClauseMightContainGroupOrderBy 00832 $groupBy, 00833 $orderBy, 00834 $limit 00835 ); 00836 $rows = array(); 00837 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00838 #$this->versionOL($theTable,$row); // not used since records here are fetched based on other fields than uid! 00839 if (is_array($row)) $rows[] = $row; 00840 } 00841 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00842 if (count($rows)) return $rows; 00843 } 00844 } 00845 00846 00847 00848 00849 00850 00851 00852 00853 00854 00855 00856 00857 00858 00859 /********************************* 00860 * 00861 * Caching and standard clauses 00862 * 00863 **********************************/ 00864 00875 function getHash($hash,$expTime=0) { 00876 // 00877 $expTime = intval($expTime); 00878 if ($expTime) { 00879 $whereAdd = ' AND tstamp > '.(time()-$expTime); 00880 } 00881 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash').$whereAdd); 00882 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00883 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00884 return $row['content']; 00885 } 00886 } 00887 00898 function storeHash($hash,$data,$ident) { 00899 $insertFields = array( 00900 'hash' => $hash, 00901 'content' => $data, 00902 'ident' => $ident, 00903 'tstamp' => time() 00904 ); 00905 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash')); 00906 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_hash', $insertFields); 00907 } 00908 00916 function deleteClause($table) { 00917 global $TCA; 00918 if (!strcmp($table,'pages')) { // Hardcode for pages because TCA might not be loaded yet (early frontend initialization) 00919 return ' AND pages.deleted=0'; 00920 } else { 00921 return $TCA[$table]['ctrl']['delete'] ? ' AND '.$table.'.'.$TCA[$table]['ctrl']['delete'].'=0' : ''; 00922 } 00923 } 00924 00936 function enableFields($table,$show_hidden=-1,$ignore_array=array(),$noVersionPreview=FALSE) { 00937 global $TYPO3_CONF_VARS; 00938 00939 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 00940 $show_hidden = $table=='pages' ? $GLOBALS['TSFE']->showHiddenPage : $GLOBALS['TSFE']->showHiddenRecords; 00941 } 00942 if ($show_hidden==-1) $show_hidden=0; // If show_hidden was not changed during the previous evaluation, do it here. 00943 00944 $ctrl = $GLOBALS['TCA'][$table]['ctrl']; 00945 $query=''; 00946 if (is_array($ctrl)) { 00947 00948 // Delete field check: 00949 if ($ctrl['delete']) { 00950 $query.=' AND '.$table.'.'.$ctrl['delete'].'=0'; 00951 } 00952 00953 // Filter out new place-holder records in case we are NOT in a versioning preview (that means we are online!) 00954 if ($ctrl['versioningWS'] && !$this->versioningPreview) { 00955 $query.=' AND '.$table.'.t3ver_state!=1'; // Shadow state for new items MUST be ignored! 00956 } 00957 00958 // Enable fields: 00959 if (is_array($ctrl['enablecolumns'])) { 00960 if (!$this->versioningPreview || !$ctrl['versioningWS'] || $noVersionPreview) { // In case of versioning-preview, enableFields are ignored (checked in versionOL()) 00961 if ($ctrl['enablecolumns']['disabled'] && !$show_hidden && !$ignore_array['disabled']) { 00962 $field = $table.'.'.$ctrl['enablecolumns']['disabled']; 00963 $query.=' AND '.$field.'=0'; 00964 } 00965 if ($ctrl['enablecolumns']['starttime'] && !$ignore_array['starttime']) { 00966 $field = $table.'.'.$ctrl['enablecolumns']['starttime']; 00967 $query.=' AND ('.$field.'<='.$GLOBALS['SIM_EXEC_TIME'].')'; 00968 } 00969 if ($ctrl['enablecolumns']['endtime'] && !$ignore_array['endtime']) { 00970 $field = $table.'.'.$ctrl['enablecolumns']['endtime']; 00971 $query.=' AND ('.$field.'=0 OR '.$field.'>'.$GLOBALS['SIM_EXEC_TIME'].')'; 00972 } 00973 if ($ctrl['enablecolumns']['fe_group'] && !$ignore_array['fe_group']) { 00974 $field = $table.'.'.$ctrl['enablecolumns']['fe_group']; 00975 $query.= t3lib_pageSelect::getMultipleGroupsWhereClause($field, $table); 00976 } 00977 00978 // Call hook functions for additional enableColumns 00979 // It is used by the extension ingmar_accessctrl which enables assigning more than one usergroup to content and page records 00980 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns'])) { 00981 $_params = array( 00982 'table' => $table, 00983 'show_hidden' => $show_hidden, 00984 'ignore_array' => $ignore_array, 00985 'ctrl' => $ctrl 00986 ); 00987 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns'] as $_funcRef) { 00988 $query .= t3lib_div::callUserFunction($_funcRef,$_params,$this); 00989 } 00990 } 00991 } 00992 } 00993 } else { 00994 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.'); 00995 } 00996 00997 return $query; 00998 } 00999 01008 function getMultipleGroupsWhereClause($field, $table) { 01009 $memberGroups = t3lib_div::intExplode(',',$GLOBALS['TSFE']->gr_list); 01010 $orChecks=array(); 01011 $orChecks[]=$field.'=\'\''; // If the field is empty, then OK 01012 $orChecks[]=$field.'=\'0\''; // If the field contsains zero, then OK 01013 01014 foreach($memberGroups as $value) { 01015 $orChecks[] = $GLOBALS['TYPO3_DB']->listQuery($field, $value, $table); 01016 } 01017 01018 return ' AND ('.implode(' OR ',$orChecks).')'; 01019 } 01020 01021 01022 01023 01024 01025 01026 01027 01028 01029 01030 01031 01032 01033 01034 01035 /********************************* 01036 * 01037 * Versioning Preview 01038 * 01039 **********************************/ 01040 01053 function fixVersioningPid($table,&$rr) { 01054 global $TCA; 01055 01056 if ($this->versioningPreview && is_array($rr) && $rr['pid']==-1 && ($table=='pages' || $TCA[$table]['ctrl']['versioningWS'])) { // Have to hardcode it for "pages" table since TCA is not loaded at this moment! 01057 01058 // Check values for t3ver_oid and t3ver_wsid: 01059 if (isset($rr['t3ver_oid']) && isset($rr['t3ver_wsid'])) { // If "t3ver_oid" is already a field, just set this: 01060 $oid = $rr['t3ver_oid']; 01061 $wsid = $rr['t3ver_wsid']; 01062 } else { // Otherwise we have to expect "uid" to be in the record and look up based on this: 01063 $newPidRec = $this->getRawRecord($table,$rr['uid'],'t3ver_oid,t3ver_wsid',TRUE); 01064 if (is_array($newPidRec)) { 01065 $oid = $newPidRec['t3ver_oid']; 01066 $wsid = $newPidRec['t3ver_wsid']; 01067 } 01068 } 01069 01070 // If workspace ids matches and ID of current online version is found, look up the PID value of that: 01071 if ($oid && !strcmp((int)$wsid,$this->versioningWorkspaceId)) { 01072 $oidRec = $this->getRawRecord($table,$oid,'pid',TRUE); 01073 01074 if (is_array($oidRec)) { 01075 # 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! 01076 $rr['_ORIG_pid'] = $rr['pid']; 01077 $rr['pid'] = $oidRec['pid']; 01078 } 01079 } 01080 } 01081 } 01082 01094 function versionOL($table,&$row) { 01095 global $TCA; 01096 01097 if ($this->versioningPreview && is_array($row)) { 01098 if ($wsAlt = $this->getWorkspaceVersionOfRecord($this->versioningWorkspaceId, $table, $row['uid'], implode(',',array_keys($row)))) { // implode(',',array_keys($row)) = Using fields from original record to make sure no additional fields are selected. This is best for eg. getPageOverlay() 01099 if (is_array($wsAlt)) { 01100 01101 // Always fix PID (like in fixVersioningPid() above). [This is usually not the important factor for versioning OL] 01102 $wsAlt['_ORIG_pid'] = $wsAlt['pid']; // Keep the old (-1) - indicates it was a version... 01103 $wsAlt['pid'] = $row['pid']; // Set in the online versions PID. 01104 01105 // "element" and "page" type versions: 01106 // For versions of single elements or page+content, preserve online UID and PID (this will produce true "overlay" of element _content_, not any references) 01107 // For page+content the "_ORIG_uid" should actually be used as PID for selection of tables with "versioning_followPages" enabled. 01108 if ($table!=='pages' || $wsAlt['t3ver_swapmode']<=0) { 01109 $wsAlt['_ORIG_uid'] = $wsAlt['uid']; 01110 $wsAlt['uid'] = $row['uid']; 01111 01112 // Translate page alias as well so links are pointing to the _online_ page: 01113 if ($table==='pages') { 01114 $wsAlt['alias'] = $row['alias']; 01115 } 01116 } else { 01117 // "branch" versions: 01118 // Keeping overlay uid and pid so references are changed. This is only for page-versions with BRANCH below! 01119 $wsAlt['_ONLINE_uid'] = $row['uid']; // The UID of the versionized record is kept and the uid of the online version is stored 01120 } 01121 01122 // Changing input record to the workspace version alternative: 01123 $row = $wsAlt; 01124 01125 // Check if it is deleted in workspace: 01126 if ((int)$row['t3ver_state']===2) { 01127 $row = FALSE; // Unset record if it turned out to be deleted in workspace 01128 } 01129 } else { 01130 // No version found, then check if t3ver_state =1 (online version is dummy-representation) 01131 if ($wsAlt==-1 || (int)$row['t3ver_state']===1) { 01132 $row = FALSE; // Unset record if it turned out to be "hidden" 01133 } 01134 } 01135 } 01136 } 01137 } 01138 01149 function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields='*') { 01150 global $TCA; 01151 01152 if ($workspace!==0 && ($table=='pages' || $TCA[$table]['ctrl']['versioningWS'])) { // Have to hardcode it for "pages" table since TCA is not loaded at this moment! 01153 01154 // Setting up enableFields for version record: 01155 if ($table=='pages') { 01156 $enFields = $this->versioningPreview_where_hid_del; 01157 } else { 01158 $enFields = $this->enableFields($table,-1,array(),TRUE); 01159 } 01160 01161 // Select workspace version of record, only testing for deleted. 01162 list($newrow) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 01163 $fields, 01164 $table, 01165 'pid=-1 AND 01166 t3ver_oid='.intval($uid).' AND 01167 t3ver_wsid='.intval($workspace). 01168 $this->deleteClause($table) 01169 ); 01170 01171 // If version found, check if it could have been selected with enableFields on as well: 01172 if (is_array($newrow)) { 01173 if ($GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 01174 'uid', 01175 $table, 01176 'pid=-1 AND 01177 t3ver_oid='.intval($uid).' AND 01178 t3ver_wsid='.intval($workspace). 01179 $enFields 01180 )) { 01181 return $newrow; // Return offline version, tested for its enableFields. 01182 } else { 01183 return -1; // Return -1 because version was de-selected due to its enableFields. 01184 } 01185 } else { 01186 // OK, so no workspace version was found. Then check if online version can be selected with full enable fields and if so, return 1: 01187 if ($GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 01188 'uid', 01189 $table, 01190 'uid='.intval($uid).$enFields 01191 )) { 01192 return 1; // Means search was done, but no version found. 01193 } else { 01194 return -1; // Return -1 because the current record was de-selected due to its enableFields. 01195 } 01196 } 01197 } 01198 01199 return FALSE; // No look up in database because versioning not enabled / or workspace not offline 01200 } 01201 } 01202 01203 01204 01205 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php']) { 01206 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php']); 01207 } 01208 ?>