/src/typo3_src-4.2.0alpha1/t3lib/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         var     $workspaceCache = array();
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/deleted 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>0)';
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,TRUE);
00419                         if (is_array($row))     {
00420                                         // Keep mount point:
00421                                 $origUid = $row['uid'];
00422                                 $mount_info = $this->getMountPointInfo($origUid, $row); // $row MUST have "uid", "pid", "doktype", "mount_pid", "mount_pid_ol" fields in it
00423                                 if (is_array($mount_info) && $mount_info['overlay'])    {       // There is a valid mount point.
00424                                         $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!
00425                                         if (count($mp_row))     {
00426                                                 $row = $mp_row;
00427                                                 $row['_MP_PARAM'] = $mount_info['MPvar'];
00428                                         } 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!
00429                                 }
00430 
00431                                         // if shortcut, look up if the target exists and is currently visible
00432                                 if ($row['doktype'] == 4 && ($row['shortcut'] || $row['shortcut_mode']) && $checkShortcuts)     {
00433                                         if ($row['shortcut_mode'] == 0) {
00434                                                 $searchField = 'uid';
00435                                                 $searchUid = intval($row['shortcut']);
00436                                         } else { // check subpages - first subpage or random subpage
00437                                                 $searchField = 'pid';
00438                                                         // If a shortcut mode is set and no valid page is given to select subpags from use the actual page.
00439                                                 $searchUid = intval($row['shortcut'])?intval($row['shortcut']):$row['uid'];
00440                                         }
00441                                         $res2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', $searchField.'='.$searchUid.$this->where_hid_del.$this->where_groupAccess.' '.$addWhere, '', $sortField);
00442                                         if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res2)) {
00443                                                 unset($row);
00444                                         }
00445                                         $GLOBALS['TYPO3_DB']->sql_free_result($res2);
00446                                 } elseif ($row['doktype'] == 4 && $checkShortcuts)      {
00447                                                 // Neither shortcut target nor mode is set. Remove the page from the menu.
00448                                         unset($row);
00449                                 }
00450 
00451                                         // Add to output array after overlaying language:
00452                                 if (is_array($row))     {
00453                                         $output[$origUid] = $this->getPageOverlay($row);
00454                                 }
00455                         }
00456                 }
00457                 return $output;
00458         }
00459 
00470         function getDomainStartPage($domain, $path='',$request_uri='')  {
00471                 $domain = explode(':',$domain);
00472                 $domain = strtolower(ereg_replace('\.$','',$domain[0]));
00473                         // Removing extra trailing slashes
00474                 $path = trim(ereg_replace('\/[^\/]*$','',$path));
00475                         // Appending to domain string
00476                 $domain.= $path;
00477                 $domain = ereg_replace('\/*$','',$domain);
00478 
00479                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00480                                         'pages.uid,sys_domain.redirectTo,sys_domain.prepend_params',
00481                                         'pages,sys_domain',
00482                                         'pages.uid=sys_domain.pid
00483                                                 AND sys_domain.hidden=0
00484                                                 AND (sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain, 'sys_domain').' OR sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain.'/', 'sys_domain').') '.
00485                                                 $this->where_hid_del.$this->where_groupAccess,
00486                                         '',
00487                                         '',
00488                                         1
00489                                 );
00490                 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00491                         if ($row['redirectTo']) {
00492                                 $rURL = $row['redirectTo'];
00493                                 if ($row['prepend_params'])     {
00494                                         $rURL = ereg_replace('\/$','',$rURL);
00495                                         $prependStr = ereg_replace('^\/','',substr($request_uri,strlen($path)));
00496                                         $rURL.= '/'.$prependStr;
00497                                 }
00498                                 Header('Location: '.t3lib_div::locationHeaderUrl($rURL));
00499                                 exit;
00500                         } else {
00501                                 return $row['uid'];
00502                         }
00503                 }
00504         }
00505 
00518         function getRootLine($uid, $MP='', $ignoreMPerrors=FALSE)       {
00519 
00520                         // Initialize:
00521                 $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']);
00522                 $this->error_getRootLine = '';
00523                 $this->error_getRootLine_failPid = 0;
00524 
00525                         // Splitting the $MP parameters if present
00526                 $MPA = array();
00527                 if ($MP)        {
00528                         $MPA = explode(',',$MP);
00529                         reset($MPA);
00530                         while(list($MPAk) = each($MPA)) {
00531                                 $MPA[$MPAk] = explode('-', $MPA[$MPAk]);
00532                         }
00533                 }
00534 
00535                 $loopCheck = 0;
00536                 $theRowArray = Array();
00537                 $uid = intval($uid);
00538 
00539                 while ($uid!=0 && $loopCheck<20)        {       // Max 20 levels in the page tree.
00540                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid='.intval($uid).' AND pages.deleted=0 AND pages.doktype!=255');
00541                         if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00542                                 $this->versionOL('pages',$row);
00543                                 $this->fixVersioningPid('pages',$row);
00544 
00545                                 if (is_array($row))     {
00546                                                 // 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:
00547                                         if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'] && $row['doktype']==7 && !$ignoreMPerrors)   {
00548                                                 $mount_info = $this->getMountPointInfo($row['uid'], $row);
00549                                                 if ($loopCheck>0 || $mount_info['overlay'])     {
00550                                                         $this->error_getRootLine = 'Illegal Mount Point found in rootline';
00551                                                         return array();
00552                                                 }
00553                                         }
00554 
00555                                         $uid = $row['pid'];     // Next uid
00556 
00557                                         if (count($MPA) && $GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'])      {
00558                                                 $curMP = end($MPA);
00559                                                 if (!strcmp($row['uid'],$curMP[0]))     {
00560 
00561                                                         array_pop($MPA);
00562                                                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid='.intval($curMP[1]).' AND pages.deleted=0 AND pages.doktype!=255');
00563                                                         $mp_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00564 
00565                                                         $this->versionOL('pages',$mp_row);
00566                                                         $this->fixVersioningPid('pages',$mp_row);
00567 
00568                                                         if (is_array($mp_row))  {
00569                                                                 $mount_info = $this->getMountPointInfo($mp_row['uid'], $mp_row);
00570                                                                 if (is_array($mount_info) && $mount_info['mount_pid']==$curMP[0])       {
00571                                                                         $uid = $mp_row['pid'];  // Setting next uid
00572 
00573                                                                         if ($mount_info['overlay'])     {       // Symlink style: Keep mount point (current row).
00574                                                                                 $row['_MOUNT_OL'] = TRUE;       // Set overlay mode:
00575                                                                                 $row['_MOUNT_PAGE'] = array(
00576                                                                                         'uid' => $mp_row['uid'],
00577                                                                                         'pid' => $mp_row['pid'],
00578                                                                                         'title' =>  $mp_row['title'],
00579                                                                                 );
00580                                                                         } else {        // Normal operation: Insert the mount page row in rootline instead mount point.
00581                                                                                 if ($loopCheck>0)       {
00582                                                                                         $row = $mp_row;
00583                                                                                 } else {
00584                                                                                         $this->error_getRootLine = 'Current Page Id is a mounted page of the overlay type and cannot be accessed directly!';
00585                                                                                         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!)
00586                                                                                 }
00587                                                                         }
00588 
00589                                                                         $row['_MOUNTED_FROM'] = $curMP[0];
00590                                                                         $row['_MP_PARAM'] = $mount_info['MPvar'];
00591                                                                 } else {
00592                                                                         $this->error_getRootLine = 'MP var was corrupted';
00593                                                                         return array(); // The MP variables did NOT connect proper mount points:
00594                                                                 }
00595                                                         } else {
00596                                                                 $this->error_getRootLine = 'No moint point record found according to PID in MP var';
00597                                                                 return array(); // The second PID in MP var was NOT a valid page.
00598                                                         }
00599                                                 }
00600                                         }
00601                                 }
00602                                         // Add row to rootline with language overlaid:
00603                                 $theRowArray[] = $this->getPageOverlay($row);
00604                         } else {
00605                                 $this->error_getRootLine = 'Broken rootline';
00606                                 $this->error_getRootLine_failPid = $uid;
00607                                 return array(); // broken rootline.
00608                         }
00609 
00610                         $loopCheck++;
00611                 }
00612 
00613                         // If the MPA array is NOT empty, we have to return an error; All MP elements were not resolved!
00614                 if (count($MPA))        {
00615                         $this->error_getRootLine = 'MP value remain!';
00616                         return array();
00617                 }
00618 
00619                         // Create output array (with reversed order of numeric keys):
00620                 $output = Array();
00621                 $c = count($theRowArray);
00622                 foreach($theRowArray as $key => $val)   {
00623                         $c--;
00624                         $output[$c] = $val;
00625                 }
00626 
00627                 return $output;
00628         }
00629 
00639         function getPathFromRootline($rl,$len=20)       {
00640                 if (is_array($rl))      {
00641                         $c=count($rl);
00642                         $path = '';
00643                         for ($a=0;$a<$c;$a++)   {
00644                                 if ($rl[$a]['uid'])     {
00645                                         $path.='/'.t3lib_div::fixed_lgd_cs(strip_tags($rl[$a]['title']),$len);
00646                                 }
00647                         }
00648                         return $path;
00649                 }
00650         }
00651 
00660         function getExtURL($pagerow,$disable=0) {
00661                 if ($pagerow['doktype']==3 && !$disable)        {
00662                         $redirectTo = $this->urltypes[$pagerow['urltype']].$pagerow['url'];
00663 
00664                                 // If relative path, prefix Site URL:
00665                         $uI = parse_url($redirectTo);
00666                         if (!$uI['scheme'] && substr($redirectTo,0,1)!='/')     { // relative path assumed now...
00667                                 $redirectTo = t3lib_div::getIndpEnv('TYPO3_SITE_URL').$redirectTo;
00668                         }
00669                         return $redirectTo;
00670                 }
00671         }
00672 
00684         function getMountPointInfo($pageId, $pageRec=FALSE, $prevMountPids=array(), $firstPageUid=0)    {
00685                 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'])     {
00686 
00687                                 // Get pageRec if not supplied:
00688                         if (!is_array($pageRec))        {
00689                                 $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');
00690                                 $pageRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00691                                 $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!
00692                         }
00693 
00694                                 // Set first Page uid:
00695                         if (!$firstPageUid)     $firstPageUid = $pageRec['uid'];
00696 
00697                                 // Look for mount pid value plus other required circumstances:
00698                         $mount_pid = intval($pageRec['mount_pid']);
00699                         if (is_array($pageRec) && $pageRec['doktype']==7 && $mount_pid>0 && !in_array($mount_pid, $prevMountPids))      {
00700 
00701                                         // Get the mount point record (to verify its general existence):
00702                                 $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');
00703                                 $mount_rec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00704                                 $this->versionOL('pages',$mount_rec);
00705 
00706                                 if (is_array($mount_rec))       {
00707                                                 // Look for recursive mount point:
00708                                         $prevMountPids[] = $mount_pid;
00709                                         $recursiveMountPid = $this->getMountPointInfo($mount_pid, $mount_rec, $prevMountPids, $firstPageUid);
00710 
00711                                                 // Return mount point information:
00712                                         return $recursiveMountPid ?
00713                                                                 $recursiveMountPid :
00714                                                                 array(
00715                                                                         'mount_pid' => $mount_pid,
00716                                                                         'overlay' => $pageRec['mount_pid_ol'],
00717                                                                         'MPvar' => $mount_pid.'-'.$firstPageUid,
00718                                                                         'mount_point_rec' => $pageRec,
00719                                                                         'mount_pid_rec' => $mount_rec,
00720                                                                 );
00721                                 } else {
00722                                         return -1;      // Means, there SHOULD have been a mount point, but there was none!
00723                                 }
00724                         }
00725                 }
00726 
00727                 return FALSE;
00728         }
00729 
00730 
00731 
00732 
00733 
00734 
00735 
00736 
00737 
00738 
00739 
00740 
00741 
00742 
00743 
00744 
00745 
00746         /*********************************
00747          *
00748          * Selecting records in general
00749          *
00750          **********************************/
00751 
00761         function checkRecord($table,$uid,$checkPage=0)  {
00762                 global $TCA;
00763                 $uid = intval($uid);
00764                 if (is_array($TCA[$table]))     {
00765                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($uid).$this->enableFields($table));
00766                         if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00767                                 $this->versionOL($table,$row);
00768                                 $GLOBALS['TYPO3_DB']->sql_free_result($res);
00769 
00770                                 if (is_array($row))     {
00771                                         if ($checkPage) {
00772                                                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'uid='.intval($row['pid']).$this->enableFields('pages'));
00773                                                 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))   {
00774                                                         return $row;
00775                                                 } else {
00776                                                         return 0;
00777                                                 }
00778                                         } else {
00779                                                 return $row;
00780                                         }
00781                                 }
00782                         }
00783                 }
00784         }
00785 
00796         function getRawRecord($table,$uid,$fields='*',$noWSOL=FALSE)    {
00797                 global $TCA;
00798                 $uid = intval($uid);
00799                 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()...
00800                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, 'uid='.intval($uid).$this->deleteClause($table));
00801                         $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00802                         $GLOBALS['TYPO3_DB']->sql_free_result($res);
00803                         if ($row) {
00804                                 if (!$noWSOL)   {
00805                                         $this->versionOL($table,$row);
00806                                 }
00807                                 if (is_array($row))     return $row;
00808                         }
00809                 }
00810         }
00811 
00824         function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='')     {
00825                 global $TCA;
00826                 if (is_array($TCA[$theTable])) {
00827                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00828                                                 '*',
00829                                                 $theTable,
00830                                                 $theField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($theValue, $theTable).
00831                                                         $this->deleteClause($theTable).' '.
00832                                                                 $whereClause,   // whereClauseMightContainGroupOrderBy
00833                                                 $groupBy,
00834                                                 $orderBy,
00835                                                 $limit
00836                                         );
00837                         $rows = array();
00838                         while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))       {
00839                                 #$this->versionOL($theTable,$row);      // not used since records here are fetched based on other fields than uid!
00840                                 if (is_array($row)) $rows[] = $row;
00841                         }
00842                         $GLOBALS['TYPO3_DB']->sql_free_result($res);
00843                         if (count($rows))       return $rows;
00844                 }
00845         }
00846 
00847 
00848 
00849 
00850 
00851 
00852 
00853 
00854 
00855 
00856 
00857 
00858 
00859 
00860         /*********************************
00861          *
00862          * Caching and standard clauses
00863          *
00864          **********************************/
00865 
00876         function getHash($hash,$expTime=0)      {
00877                         //
00878                 $expTime = intval($expTime);
00879                 if ($expTime)   {
00880                         $whereAdd = ' AND tstamp > '.(time()-$expTime);
00881                 }
00882                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash').$whereAdd);
00883                 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00884                         $GLOBALS['TYPO3_DB']->sql_free_result($res);
00885                         return $row['content'];
00886                 }
00887         }
00888 
00899         function storeHash($hash,$data,$ident)  {
00900                 $insertFields = array(
00901                         'hash' => $hash,
00902                         'content' => $data,
00903                         'ident' => $ident,
00904                         'tstamp' => time()
00905                 );
00906                 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash'));
00907                 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_hash', $insertFields);
00908         }
00909 
00917         function deleteClause($table)   {
00918                 global $TCA;
00919                 if (!strcmp($table,'pages'))    {       // Hardcode for pages because TCA might not be loaded yet (early frontend initialization)
00920                         return ' AND pages.deleted=0';
00921                 } else {
00922                         return $TCA[$table]['ctrl']['delete'] ? ' AND '.$table.'.'.$TCA[$table]['ctrl']['delete'].'=0' : '';
00923                 }
00924         }
00925 
00937         function enableFields($table,$show_hidden=-1,$ignore_array=array(),$noVersionPreview=FALSE)     {
00938                 global $TYPO3_CONF_VARS;
00939 
00940                 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
00941                         $show_hidden = $table=='pages' ? $GLOBALS['TSFE']->showHiddenPage : $GLOBALS['TSFE']->showHiddenRecords;
00942                 }
00943                 if ($show_hidden==-1)   $show_hidden=0; // If show_hidden was not changed during the previous evaluation, do it here.
00944 
00945                 $ctrl = $GLOBALS['TCA'][$table]['ctrl'];
00946                 $query='';
00947                 if (is_array($ctrl))    {
00948 
00949                                 // Delete field check:
00950                         if ($ctrl['delete'])    {
00951                                 $query.=' AND '.$table.'.'.$ctrl['delete'].'=0';
00952                         }
00953 
00954                                 // Filter out new place-holder records in case we are NOT in a versioning preview (that means we are online!)
00955                         if ($ctrl['versioningWS'] && !$this->versioningPreview) {
00956                                 $query.=' AND '.$table.'.t3ver_state<=0';       // Shadow state for new items MUST be ignored!
00957                         }
00958 
00959                                 // Enable fields:
00960                         if (is_array($ctrl['enablecolumns']))   {
00961                                 if (!$this->versioningPreview || !$ctrl['versioningWS'] || $noVersionPreview) { // In case of versioning-preview, enableFields are ignored (checked in versionOL())
00962                                         if ($ctrl['enablecolumns']['disabled'] && !$show_hidden && !$ignore_array['disabled']) {
00963                                                 $field = $table.'.'.$ctrl['enablecolumns']['disabled'];
00964                                                 $query.=' AND '.$field.'=0';
00965                                         }
00966                                         if ($ctrl['enablecolumns']['starttime'] && !$ignore_array['starttime']) {
00967                                                 $field = $table.'.'.$ctrl['enablecolumns']['starttime'];
00968                                                 $query.=' AND ('.$field.'<='.$GLOBALS['SIM_EXEC_TIME'].')';
00969                                         }
00970                                         if ($ctrl['enablecolumns']['endtime'] && !$ignore_array['endtime']) {
00971                                                 $field = $table.'.'.$ctrl['enablecolumns']['endtime'];
00972                                                 $query.=' AND ('.$field.'=0 OR '.$field.'>'.$GLOBALS['SIM_EXEC_TIME'].')';
00973                                         }
00974                                         if ($ctrl['enablecolumns']['fe_group'] && !$ignore_array['fe_group']) {
00975                                                 $field = $table.'.'.$ctrl['enablecolumns']['fe_group'];
00976                                                 $query.= $this->getMultipleGroupsWhereClause($field, $table);
00977                                         }
00978 
00979                                         // Call hook functions for additional enableColumns
00980                                         // It is used by the extension ingmar_accessctrl which enables assigning more than one usergroup to content and page records
00981                                         if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns']))    {
00982                                                 $_params = array(
00983                                                         'table' => $table,
00984                                                         'show_hidden' => $show_hidden,
00985                                                         'ignore_array' => $ignore_array,
00986                                                         'ctrl' => $ctrl
00987                                                 );
00988                                                 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns'] as $_funcRef)    {
00989                                                         $query .= t3lib_div::callUserFunction($_funcRef,$_params,$this);
00990                                                 }
00991                                         }
00992                                 }
00993                         }
00994                 } else {
00995                         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.');
00996                 }
00997 
00998                 return $query;
00999         }
01000 
01009         function getMultipleGroupsWhereClause($field, $table)   {
01010                 $memberGroups = t3lib_div::intExplode(',',$GLOBALS['TSFE']->gr_list);
01011                 $orChecks=array();
01012                 $orChecks[]=$field.'=\'\'';     // If the field is empty, then OK
01013                 $orChecks[]=$field.' IS NULL';  // If the field is NULL, then OK
01014                 $orChecks[]=$field.'=\'0\'';    // If the field contsains zero, then OK
01015 
01016                 foreach($memberGroups as $value)        {
01017                         $orChecks[] = $GLOBALS['TYPO3_DB']->listQuery($field, $value, $table);
01018                 }
01019 
01020                 return ' AND ('.implode(' OR ',$orChecks).')';
01021         }
01022 
01023 
01024 
01025 
01026 
01027 
01028 
01029 
01030 
01031 
01032 
01033 
01034 
01035 
01036 
01037         /*********************************
01038          *
01039          * Versioning Preview
01040          *
01041          **********************************/
01042 
01055         function fixVersioningPid($table,&$rr)  {
01056                 global $TCA;
01057 
01058                 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!
01059 
01060                                 // Check values for t3ver_oid and t3ver_wsid:
01061                         if (isset($rr['t3ver_oid']) && isset($rr['t3ver_wsid']))        {       // If "t3ver_oid" is already a field, just set this:
01062                                 $oid = $rr['t3ver_oid'];
01063                                 $wsid = $rr['t3ver_wsid'];
01064                         } else {        // Otherwise we have to expect "uid" to be in the record and look up based on this:
01065                                 $newPidRec = $this->getRawRecord($table,$rr['uid'],'t3ver_oid,t3ver_wsid',TRUE);
01066                                 if (is_array($newPidRec))       {
01067                                         $oid = $newPidRec['t3ver_oid'];
01068                                         $wsid = $newPidRec['t3ver_wsid'];
01069                                 }
01070                         }
01071 
01072                         // If workspace ids matches and ID of current online version is found, look up the PID value of that:
01073                         if ($oid && (($this->versioningWorkspaceId == 0 && $this->checkWorkspaceAccess($wsid)) || !strcmp((int)$wsid,$this->versioningWorkspaceId)))    {
01074                                 $oidRec = $this->getRawRecord($table,$oid,'pid',TRUE);
01075 
01076                                 if (is_array($oidRec))  {
01077                                         # 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!
01078                                         $rr['_ORIG_pid'] = $rr['pid'];
01079                                         $rr['pid'] = $oidRec['pid'];
01080                                 }
01081                         }
01082                 }
01083                 
01084                         // changing PID in case of moving pointer:
01085                 if ($movePlhRec = $this->getMovePlaceholder($table,$rr['uid'],'pid'))   {
01086                         $rr['pid'] = $movePlhRec['pid'];
01087                 }
01088         }
01089 
01102         function versionOL($table,&$row,$unsetMovePointers=FALSE)       {
01103                 global $TCA;
01104                 
01105                 if ($this->versioningPreview && is_array($row)) {
01106                         $movePldSwap = $this->movePlhOL($table,$row);   // will overlay any movePlhOL found with the real record, which in turn will be overlaid with its workspace version if any. 
01107                         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()
01108                                 if (is_array($wsAlt))   {
01109 
01110                                                 // Always fix PID (like in fixVersioningPid() above). [This is usually not the important factor for versioning OL]
01111                                         $wsAlt['_ORIG_pid'] = $wsAlt['pid'];    // Keep the old (-1) - indicates it was a version...
01112                                         $wsAlt['pid'] = $row['pid'];            // Set in the online versions PID.
01113 
01114                                                 // "element" and "page" type versions:
01115                                                 // For versions of single elements or page+content, preserve online UID and PID (this will produce true "overlay" of element _content_, not any references)
01116                                                 // For page+content the "_ORIG_uid" should actually be used as PID for selection of tables with "versioning_followPages" enabled.
01117                                         if ($table!=='pages' || $wsAlt['t3ver_swapmode']<=0)    {
01118                                                 $wsAlt['_ORIG_uid'] = $wsAlt['uid'];
01119                                                 $wsAlt['uid'] = $row['uid'];
01120 
01121                                                         // Translate page alias as well so links are pointing to the _online_ page:
01122                                                 if ($table==='pages')   {
01123                                                         $wsAlt['alias'] = $row['alias'];
01124                                                 }
01125                                         } else {
01126                                                         // "branch" versions:
01127                                                         // Keeping overlay uid and pid so references are changed. This is only for page-versions with BRANCH below!
01128                                                 $wsAlt['_ONLINE_uid'] = $row['uid'];    // The UID of the versionized record is kept and the uid of the online version is stored
01129                                         }
01130 
01131                                                 // Changing input record to the workspace version alternative:
01132                                         $row = $wsAlt;
01133 
01134                                                 // Check if it is deleted/new
01135                                         if ((int)$row['t3ver_state']===1 || (int)$row['t3ver_state']===2)       {
01136                                                 $row = FALSE;   // Unset record if it turned out to be deleted in workspace
01137                                         }
01138 
01139                                                 // Check if move-pointer in workspace (unless if a move-placeholder is the reason why it appears!):
01140                                                 // You have to specifically set $unsetMovePointers in order to clear these because it is normally a display issue if it should be shown or not.
01141                                         if ((int)$row['t3ver_state']===4 && !$movePldSwap && $unsetMovePointers)        {
01142                                                 $row = FALSE;   // Unset record if it turned out to be deleted in workspace
01143                                         }
01144                                 } else {
01145                                                 // No version found, then check if t3ver_state =1 (online version is dummy-representation)
01146                                         if ($wsAlt==-1 || (int)$row['t3ver_state']>0)   {
01147                                                 $row = FALSE;   // Unset record if it turned out to be "hidden"
01148                                         }
01149                                 }
01150                         }
01151                 }
01152         }
01153         
01163         function movePlhOL($table,&$row)        {
01164                 global $TCA;
01165 
01166                 if (($table=='pages' || (int)$TCA[$table]['ctrl']['versioningWS']>=2) && (int)$row['t3ver_state']===3)  {       // Only for WS ver 2... (moving)
01167 
01168                                 // If t3ver_move_id is not found, then find it... (but we like best if it is here...)
01169                         if (!isset($row['t3ver_move_id']))      {
01170                                 $moveIDRec = $this->getRawRecord($table,$row['uid'],'t3ver_move_id',TRUE);
01171                                 $moveID = $moveIDRec['t3ver_move_id'];
01172                         } else {
01173                                 $moveID = $row['t3ver_move_id'];
01174                         }
01175                 
01176                                 // Find pointed-to record.
01177                         if ($moveID)    {
01178                                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(implode(',',array_keys($row)), $table, 'uid='.intval($moveID).$this->enableFields($table));
01179                                 if ($origRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))     {
01180                                         $row = $origRow;
01181                                         return TRUE;
01182                                 }
01183                         }
01184                 }
01185                 return FALSE;
01186         }
01187 
01197         function getMovePlaceholder($table,$uid,$fields='*')    {
01198                 global $TCA;
01199 
01200                 if ($this->versioningPreview)   {
01201                         $workspace = (int)$this->versioningWorkspaceId;
01202                         if (($table=='pages' || (int)$TCA[$table]['ctrl']['versioningWS']>=2) && $workspace!==0)        {
01203 
01204                                         // Select workspace version of record:
01205                                 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01206                                         $fields,
01207                                         $table,
01208                                         'pid!=-1 AND
01209                                          t3ver_state=3 AND
01210                                          t3ver_move_id='.intval($uid).' AND
01211                                          t3ver_wsid='.intval($workspace).
01212                                                 $this->deleteClause($table)
01213                                 );
01214 
01215                                 if (is_array($rows[0])) return $rows[0];
01216                         }
01217                 }
01218                 return FALSE;
01219         }
01220         
01231         function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields='*')     {
01232                 global $TCA;
01233 
01234                 if ($workspace!==0 && ($table=='pages' || $TCA[$table]['ctrl']['versioningWS']))        {       // Have to hardcode it for "pages" table since TCA is not loaded at this moment!
01235 
01236                                 // Setting up enableFields for version record:
01237                         if ($table=='pages')    {
01238                                 $enFields = $this->versioningPreview_where_hid_del;
01239                         } else {
01240                                 $enFields = $this->enableFields($table,-1,array(),TRUE);
01241                         }
01242 
01243                                 // Select workspace version of record, only testing for deleted.
01244                         list($newrow) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01245                                 $fields,
01246                                 $table,
01247                                 'pid=-1 AND
01248                                  t3ver_oid='.intval($uid).' AND
01249                                  t3ver_wsid='.intval($workspace).
01250                                         $this->deleteClause($table)
01251                         );
01252 
01253                                 // If version found, check if it could have been selected with enableFields on as well:
01254                         if (is_array($newrow))  {
01255                                 if ($GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01256                                         'uid',
01257                                         $table,
01258                                         'pid=-1 AND
01259                                                 t3ver_oid='.intval($uid).' AND
01260                                                 t3ver_wsid='.intval($workspace).
01261                                                 $enFields
01262                                 )) {
01263                                         return $newrow; // Return offline version, tested for its enableFields.
01264                                 } else {
01265                                         return -1;      // Return -1 because version was de-selected due to its enableFields.
01266                                 }
01267                         } else {
01268                                         // OK, so no workspace version was found. Then check if online version can be selected with full enable fields and if so, return 1:
01269                                 if ($GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01270                                         'uid',
01271                                         $table,
01272                                         'uid='.intval($uid).$enFields
01273                                 ))      {
01274                                         return 1;       // Means search was done, but no version found.
01275                                 } else {
01276                                         return -1;      // Return -1 because the current record was de-selected due to its enableFields.
01277                                 }
01278                         }
01279                 }
01280 
01281                 return FALSE;   // No look up in database because versioning not enabled / or workspace not offline
01282         }
01283 
01290         function checkWorkspaceAccess($wsid) {
01291                 if (!$GLOBALS['BE_USER']) {
01292                         return false;
01293                 }
01294                 if (isset($this->workspaceCache[$wsid])) {
01295                         $ws = $this->workspaceCache[$wsid];
01296                 }
01297                 else {
01298                         if ($wsid > 0) {
01299                                 $ws = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_workspace', 'uid='.intval($wsid).' AND deleted=0'); // No $TCA yet!
01300                                 if (count($ws)) {
01301                                         $ws = $ws[0];
01302                                 }
01303                                 else {
01304                                         return false;
01305                                 }
01306                         }
01307                         else {
01308                                 $ws = $wsid;
01309                         }
01310                         $ws = $GLOBALS['BE_USER']->checkWorkspace($ws);
01311                         $this->workspaceCache[$wsid] = $ws;
01312                 }
01313                 return ($ws['_ACCESS'] != '');
01314         }
01315 }
01316 
01317 
01318 
01319 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php'])      {
01320         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php']);
01321 }
01322 ?>

This documentation has been generated automatically from TYPO3 source code using Doxygen and is provided as is by Cast Iron Coding as a courtesy to other TYPO3 developers and users. Please consider Cast Iron Coding — a full-service web development agency in Portland, Oregon specializing in TYPO3 extension development — for all of your TYPO3 development and consulting needs!