"TYPO3 4.0.1: typo3_src-4.0.1/t3lib/class.t3lib_page.php Source File", "datetime" => "Sat Dec 2 19:22:18 2006", "date" => "2 Dec 2006", "doxygenversion" => "1.4.6", "projectname" => "TYPO3 4.0.1", "projectnumber" => "4.0.1" ); get_header($doxygen_vars); ?>

class.t3lib_page.php

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.' IS NULL';  // If the field is NULL, then OK
01013                 $orChecks[]=$field.'=\'0\'';    // If the field contsains zero, then OK
01014 
01015                 foreach($memberGroups as $value)        {
01016                         $orChecks[] = $GLOBALS['TYPO3_DB']->listQuery($field, $value, $table);
01017                 }
01018 
01019                 return ' AND ('.implode(' OR ',$orChecks).')';
01020         }
01021 
01022 
01023 
01024 
01025 
01026 
01027 
01028 
01029 
01030 
01031 
01032 
01033 
01034 
01035 
01036         /*********************************
01037          *
01038          * Versioning Preview
01039          *
01040          **********************************/
01041 
01054         function fixVersioningPid($table,&$rr)  {
01055                 global $TCA;
01056 
01057                 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!
01058 
01059                                 // Check values for t3ver_oid and t3ver_wsid:
01060                         if (isset($rr['t3ver_oid']) && isset($rr['t3ver_wsid']))        {       // If "t3ver_oid" is already a field, just set this:
01061                                 $oid = $rr['t3ver_oid'];
01062                                 $wsid = $rr['t3ver_wsid'];
01063                         } else {        // Otherwise we have to expect "uid" to be in the record and look up based on this:
01064                                 $newPidRec = $this->getRawRecord($table,$rr['uid'],'t3ver_oid,t3ver_wsid',TRUE);
01065                                 if (is_array($newPidRec))       {
01066                                         $oid = $newPidRec['t3ver_oid'];
01067                                         $wsid = $newPidRec['t3ver_wsid'];
01068                                 }
01069                         }
01070 
01071                                 // If workspace ids matches and ID of current online version is found, look up the PID value of that:
01072                         if ($oid && !strcmp((int)$wsid,$this->versioningWorkspaceId))   {
01073                                 $oidRec = $this->getRawRecord($table,$oid,'pid',TRUE);
01074 
01075                                 if (is_array($oidRec))  {
01076                                         # 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!
01077                                         $rr['_ORIG_pid'] = $rr['pid'];
01078                                         $rr['pid'] = $oidRec['pid'];
01079                                 }
01080                         }
01081                 }
01082         }
01083 
01095         function versionOL($table,&$row)        {
01096                 global $TCA;
01097 
01098                 if ($this->versioningPreview && is_array($row)) {
01099                         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()
01100                                 if (is_array($wsAlt))   {
01101 
01102                                                 // Always fix PID (like in fixVersioningPid() above). [This is usually not the important factor for versioning OL]
01103                                         $wsAlt['_ORIG_pid'] = $wsAlt['pid'];    // Keep the old (-1) - indicates it was a version...
01104                                         $wsAlt['pid'] = $row['pid'];            // Set in the online versions PID.
01105 
01106                                                 // "element" and "page" type versions:
01107                                                 // For versions of single elements or page+content, preserve online UID and PID (this will produce true "overlay" of element _content_, not any references)
01108                                                 // For page+content the "_ORIG_uid" should actually be used as PID for selection of tables with "versioning_followPages" enabled.
01109                                         if ($table!=='pages' || $wsAlt['t3ver_swapmode']<=0)    {
01110                                                 $wsAlt['_ORIG_uid'] = $wsAlt['uid'];
01111                                                 $wsAlt['uid'] = $row['uid'];
01112 
01113                                                         // Translate page alias as well so links are pointing to the _online_ page:
01114                                                 if ($table==='pages')   {
01115                                                         $wsAlt['alias'] = $row['alias'];
01116                                                 }
01117                                         } else {
01118                                                         // "branch" versions:
01119                                                         // Keeping overlay uid and pid so references are changed. This is only for page-versions with BRANCH below!
01120                                                 $wsAlt['_ONLINE_uid'] = $row['uid'];    // The UID of the versionized record is kept and the uid of the online version is stored
01121                                         }
01122 
01123                                                 // Changing input record to the workspace version alternative:
01124                                         $row = $wsAlt;
01125 
01126                                                 // Check if it is deleted in workspace:
01127                                         if ((int)$row['t3ver_state']===2)       {
01128                                                 $row = FALSE;   // Unset record if it turned out to be deleted in workspace
01129                                         }
01130                                 } else {
01131                                                 // No version found, then check if t3ver_state =1 (online version is dummy-representation)
01132                                         if ($wsAlt==-1 || (int)$row['t3ver_state']===1) {
01133                                                 $row = FALSE;   // Unset record if it turned out to be "hidden"
01134                                         }
01135                                 }
01136                         }
01137                 }
01138         }
01139 
01150         function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields='*')     {
01151                 global $TCA;
01152 
01153                 if ($workspace!==0 && ($table=='pages' || $TCA[$table]['ctrl']['versioningWS']))        {       // Have to hardcode it for "pages" table since TCA is not loaded at this moment!
01154 
01155                                 // Setting up enableFields for version record:
01156                         if ($table=='pages')    {
01157                                 $enFields = $this->versioningPreview_where_hid_del;
01158                         } else {
01159                                 $enFields = $this->enableFields($table,-1,array(),TRUE);
01160                         }
01161 
01162                                 // Select workspace version of record, only testing for deleted.
01163                         list($newrow) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01164                                 $fields,
01165                                 $table,
01166                                 'pid=-1 AND
01167                                  t3ver_oid='.intval($uid).' AND
01168                                  t3ver_wsid='.intval($workspace).
01169                                         $this->deleteClause($table)
01170                         );
01171 
01172                                 // If version found, check if it could have been selected with enableFields on as well:
01173                         if (is_array($newrow))  {
01174                                 if ($GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01175                                         'uid',
01176                                         $table,
01177                                         'pid=-1 AND
01178                                                 t3ver_oid='.intval($uid).' AND
01179                                                 t3ver_wsid='.intval($workspace).
01180                                                 $enFields
01181                                 )) {
01182                                         return $newrow; // Return offline version, tested for its enableFields.
01183                                 } else {
01184                                         return -1;      // Return -1 because version was de-selected due to its enableFields.
01185                                 }
01186                         } else {
01187                                         // OK, so no workspace version was found. Then check if online version can be selected with full enable fields and if so, return 1:
01188                                 if ($GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01189                                         'uid',
01190                                         $table,
01191                                         'uid='.intval($uid).$enFields
01192                                 ))      {
01193                                         return 1;       // Means search was done, but no version found.
01194                                 } else {
01195                                         return -1;      // Return -1 because the current record was de-selected due to its enableFields.
01196                                 }
01197                         }
01198                 }
01199 
01200                 return FALSE;   // No look up in database because versioning not enabled / or workspace not offline
01201         }
01202 }
01203 
01204 
01205 
01206 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php'])      {
01207         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php']);
01208 }
01209 ?>