[ Index ]
 

Code source de Typo3 4.1.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/t3lib/ -> class.t3lib_page.php (source)

   1  <?php
   2  /***************************************************************
   3  *  Copyright notice
   4  *
   5  *  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
   6  *  All rights reserved
   7  *
   8  *  This script is part of the TYPO3 project. The TYPO3 project is
   9  *  free software; you can redistribute it and/or modify
  10  *  it under the terms of the GNU General Public License as published by
  11  *  the Free Software Foundation; either version 2 of the License, or
  12  *  (at your option) any later version.
  13  *
  14  *  The GNU General Public License can be found at
  15  *  http://www.gnu.org/copyleft/gpl.html.
  16  *  A copy is found in the textfile GPL.txt and important notices to the license
  17  *  from the author is found in LICENSE.txt distributed with these scripts.
  18  *
  19  *
  20  *  This script is distributed in the hope that it will be useful,
  21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23  *  GNU General Public License for more details.
  24  *
  25  *  This copyright notice MUST APPEAR in all copies of the script!
  26  ***************************************************************/
  27  /**
  28   * Contains a class with "Page functions" mainly for the frontend
  29   *
  30   * $Id: class.t3lib_page.php 2262 2007-04-20 16:43:13Z liels_bugs $
  31   * Revised for TYPO3 3.6 2/2003 by Kasper Skaarhoj
  32   * XHTML-trans compliant
  33   *
  34   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
  35   */
  36  /**
  37   * [CLASS/FUNCTION INDEX of SCRIPT]
  38   *
  39   *
  40   *
  41   *  109: class t3lib_pageSelect
  42   *  134:     function init($show_hidden)
  43   *
  44   *              SECTION: Selecting page records
  45   *  184:     function getPage($uid, $disableGroupAccessCheck=FALSE)
  46   *  200:     function getPage_noCheck($uid)
  47   *  216:     function getFirstWebPage($uid)
  48   *  234:     function getPageIdFromAlias($alias)
  49   *  250:     function getPageOverlay($pageInput,$lUid=-1)
  50   *  314:     function getRecordOverlay($table,$row,$sys_language_content,$OLmode='')
  51   *
  52   *              SECTION: Page related: Menu, Domain record, Root line
  53   *  413:     function getMenu($uid,$fields='*',$sortField='sorting',$addWhere='',$checkShortcuts=1)
  54   *  471:     function getDomainStartPage($domain, $path='',$request_uri='')
  55   *  519:     function getRootLine($uid, $MP='', $ignoreMPerrors=FALSE)
  56   *  640:     function getPathFromRootline($rl,$len=20)
  57   *  661:     function getExtURL($pagerow,$disable=0)
  58   *  685:     function getMountPointInfo($pageId, $pageRec=FALSE, $prevMountPids=array(), $firstPageUid=0)
  59   *
  60   *              SECTION: Selecting records in general
  61   *  762:     function checkRecord($table,$uid,$checkPage=0)
  62   *  797:     function getRawRecord($table,$uid,$fields='*',$noWSOL=FALSE)
  63   *  823:     function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='')
  64   *
  65   *              SECTION: Caching and standard clauses
  66   *  875:     function getHash($hash,$expTime=0)
  67   *  898:     function storeHash($hash,$data,$ident)
  68   *  916:     function deleteClause($table)
  69   *  936:     function enableFields($table,$show_hidden=-1,$ignore_array=array(),$noVersionPreview=FALSE)
  70   * 1008:     function getMultipleGroupsWhereClause($field, $table)
  71   *
  72   *              SECTION: Versioning Preview
  73   * 1055:     function fixVersioningPid($table,&$rr)
  74   * 1096:     function versionOL($table,&$row)
  75   * 1151:     function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields='*')
  76   *
  77   * TOTAL FUNCTIONS: 24
  78   * (This index is automatically created/updated by the extension "extdeveval")
  79   *
  80   */
  81  
  82  
  83  
  84  
  85  
  86  
  87  
  88  
  89  
  90  
  91  
  92  
  93  
  94  
  95  
  96  
  97  
  98  
  99  /**
 100   * Page functions, a lot of sql/pages-related functions
 101   * Mainly used in the frontend but also in some cases in the backend.
 102   * It's important to set the right $where_hid_del in the object so that the functions operate properly
 103   *
 104   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
 105   * @package TYPO3
 106   * @subpackage t3lib
 107   * @see tslib_fe::fetch_the_id()
 108   */
 109  class t3lib_pageSelect {
 110      var $urltypes = Array('','http://','ftp://','mailto:','https://');
 111      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
 112      var $where_groupAccess = '';    // Clause for fe_group access
 113      var $sys_language_uid = 0;
 114  
 115          // Versioning preview related:
 116      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!!!
 117      var $versioningWorkspaceId = 0;        // Workspace ID for preview
 118      var    $workspaceCache = array();
 119  
 120  
 121          // Internal, dynamic:
 122      var $error_getRootLine = '';        // Error string set by getRootLine()
 123      var $error_getRootLine_failPid = 0;        // Error uid set by getRootLine()
 124  
 125  
 126      /**
 127       * init() MUST be run directly after creating a new template-object
 128       * This sets the internal variable $this->where_hid_del to the correct where clause for page records taking deleted/hidden/starttime/endtime/t3ver_state into account
 129       *
 130       * @param    boolean        If $show_hidden is true, the hidden-field is ignored!! Normally this should be false. Is used for previewing.
 131       * @return    void
 132       * @see tslib_fe::fetch_the_id(), tx_tstemplateanalyzer::initialize_editor()
 133       */
 134  	function init($show_hidden)    {
 135          $this->where_groupAccess = '';
 136          $this->where_hid_del = ' AND pages.deleted=0 ';
 137          if (!$show_hidden)    {
 138              $this->where_hid_del.= 'AND pages.hidden=0 ';
 139          }
 140          $this->where_hid_del.= 'AND (pages.starttime<='.$GLOBALS['SIM_EXEC_TIME'].') AND (pages.endtime=0 OR pages.endtime>'.$GLOBALS['SIM_EXEC_TIME'].') ';
 141  
 142              // Filter out new place-holder pages in case we are NOT in a versioning preview (that means we are online!)
 143          if (!$this->versioningPreview)    {
 144              $this->where_hid_del.= ' AND NOT(pages.t3ver_state=1)';
 145          } else {
 146                  // 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.
 147              $this->versioningPreview_where_hid_del = $this->where_hid_del;    // Copy where_hid_del to other variable (used in relation to versionOL())
 148              $this->where_hid_del = ' AND pages.deleted=0 ';    // Clear where_hid_del
 149          }
 150      }
 151  
 152  
 153  
 154  
 155  
 156  
 157  
 158  
 159  
 160  
 161  
 162  
 163  
 164  
 165  
 166  
 167  
 168      /*******************************************
 169       *
 170       * Selecting page records
 171       *
 172       ******************************************/
 173  
 174      /**
 175       * Returns the $row for the page with uid = $uid (observing ->where_hid_del)
 176       * Any pages_language_overlay will be applied before the result is returned.
 177       * If no page is found an empty array is returned.
 178       *
 179       * @param    integer        The page id to look up.
 180       * @param    boolean        If set, the check for group access is disabled. VERY rarely used
 181       * @return    array        The page row with overlayed localized fields. Empty it no page.
 182       * @see getPage_noCheck()
 183       */
 184  	function getPage($uid, $disableGroupAccessCheck=FALSE)    {
 185          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid='.intval($uid).$this->where_hid_del.($disableGroupAccessCheck ? '' : $this->where_groupAccess));
 186          if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 187              $this->versionOL('pages',$row);
 188              if (is_array($row))        return $this->getPageOverlay($row);
 189          }
 190          return Array();
 191      }
 192  
 193      /**
 194       * Return the $row for the page with uid = $uid WITHOUT checking for ->where_hid_del (start- and endtime or hidden). Only "deleted" is checked!
 195       *
 196       * @param    integer        The page id to look up
 197       * @return    array        The page row with overlayed localized fields. Empty it no page.
 198       * @see getPage()
 199       */
 200  	function getPage_noCheck($uid)    {
 201          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid='.intval($uid).$this->deleteClause('pages'));
 202          if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 203              $this->versionOL('pages',$row);
 204              if (is_array($row))        return $this->getPageOverlay($row);
 205          }
 206          return Array();
 207      }
 208  
 209      /**
 210       * Returns the $row of the first web-page in the tree (for the default menu...)
 211       *
 212       * @param    integer        The page id for which to fetch first subpages (PID)
 213       * @return    mixed        If found: The page record (with overlayed localized fields, if any). If NOT found: blank value (not array!)
 214       * @see tslib_fe::fetch_the_id()
 215       */
 216  	function getFirstWebPage($uid)    {
 217          $output = '';
 218          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'pid='.intval($uid).$this->where_hid_del.$this->where_groupAccess, '', 'sorting', '1');
 219          if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 220              $this->versionOL('pages',$row);
 221              if (is_array($row))        $output = $this->getPageOverlay($row);
 222          }
 223          $GLOBALS['TYPO3_DB']->sql_free_result($res);
 224          return $output;
 225      }
 226  
 227      /**
 228       * Returns a pagerow for the page with alias $alias
 229       *
 230       * @param    string        The alias to look up the page uid for.
 231       * @return    integer        Returns page uid (integer) if found, otherwise 0 (zero)
 232       * @see tslib_fe::checkAndSetAlias(), tslib_cObj::typoLink()
 233       */
 234  	function getPageIdFromAlias($alias)    {
 235          $alias = strtolower($alias);
 236          $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!)
 237          if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 238              return $row['uid'];
 239          }
 240          return 0;
 241      }
 242  
 243      /**
 244       * Returns the relevant page overlay record fields
 245       *
 246       * @param    mixed        If $pageInput is an integer, it's the pid of the pageOverlay record and thus the page overlay record is returned. If $pageInput is an array, it's a page-record and based on this page record the language record is found and OVERLAYED before the page record is returned.
 247       * @param    integer        Language UID if you want to set an alternative value to $this->sys_language_uid which is default. Should be >=0
 248       * @return    array        Page row which is overlayed with language_overlay record (or the overlay record alone)
 249       */
 250  	function getPageOverlay($pageInput,$lUid=-1)    {
 251  
 252              // Initialize:
 253          if ($lUid<0)    $lUid = $this->sys_language_uid;
 254          $row = NULL;
 255  
 256              // If language UID is different from zero, do overlay:
 257          if ($lUid)    {
 258              $fieldArr = explode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']);
 259              if (is_array($pageInput))    {
 260                  $page_id = $pageInput['uid'];    // Was the whole record
 261                  $fieldArr = array_intersect($fieldArr,array_keys($pageInput));        // Make sure that only fields which exist in the incoming record are overlaid!
 262              } else {
 263                  $page_id = $pageInput;    // Was the id
 264              }
 265  
 266              if (count($fieldArr))    {
 267                  /*
 268                      NOTE to enabledFields('pages_language_overlay'):
 269                      Currently the showHiddenRecords of TSFE set will allow pages_language_overlay records to be selected as they are child-records of a page.
 270                      However you may argue that the showHiddenField flag should determine this. But that's not how it's done right now.
 271                  */
 272  
 273                      // Selecting overlay record:
 274                  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
 275                              implode(',',$fieldArr),
 276                              'pages_language_overlay',
 277                              'pid='.intval($page_id).'
 278                                  AND sys_language_uid='.intval($lUid).
 279                                  $this->enableFields('pages_language_overlay'),
 280                              '',
 281                              '',
 282                              '1'
 283                          );
 284                  $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
 285                  $this->versionOL('pages_language_overlay',$row);
 286  
 287                  if (is_array($row))    {
 288                      $row['_PAGES_OVERLAY'] = TRUE;
 289  
 290                          // Unset vital fields that are NOT allowed to be overlaid:
 291                      unset($row['uid']);
 292                      unset($row['pid']);
 293                  }
 294              }
 295          }
 296  
 297              // Create output:
 298          if (is_array($pageInput))    {
 299              return is_array($row) ? array_merge($pageInput,$row) : $pageInput;    // If the input was an array, simply overlay the newfound array and return...
 300          } else {
 301              return is_array($row) ? $row : array();    // always an array in return
 302          }
 303      }
 304  
 305      /**
 306       * Creates language-overlay for records in general (where translation is found in records from the same table)
 307       *
 308       * @param    string        Table name
 309       * @param    array        Record to overlay. Must containt uid, pid and $table]['ctrl']['languageField']
 310       * @param    integer        Pointer to the sys_language uid for content on the site.
 311       * @param    string        Overlay mode. If "hideNonTranslated" then records without translation will not be returned un-translated but unset (and return value is false)
 312       * @return    mixed        Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return false if no translation is found.
 313       */
 314  	function getRecordOverlay($table,$row,$sys_language_content,$OLmode='')    {
 315          global $TCA;
 316  
 317          if ($row['uid']>0 && $row['pid']>0)    {
 318              if ($TCA[$table] && $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField'])    {
 319                  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....)
 320  
 321                          // Will try to overlay a record only if the sys_language_content value is larger than zero.
 322                      if ($sys_language_content>0)    {
 323  
 324                              // Must be default language or [All], otherwise no overlaying:
 325                          if ($row[$TCA[$table]['ctrl']['languageField']]<=0)    {
 326  
 327                                  // Select overlay record:
 328                              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
 329                                  '*',
 330                                  $table,
 331                                  'pid='.intval($row['pid']).
 332                                      ' AND '.$TCA[$table]['ctrl']['languageField'].'='.intval($sys_language_content).
 333                                      ' AND '.$TCA[$table]['ctrl']['transOrigPointerField'].'='.intval($row['uid']).
 334                                      $this->enableFields($table),
 335                                  '',
 336                                  '',
 337                                  '1'
 338                              );
 339                              $olrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
 340                              $this->versionOL($table,$olrow);
 341      #debug($row);
 342      #debug($olrow);
 343                                  // Merge record content by traversing all fields:
 344                              if (is_array($olrow))    {
 345                                  foreach($row as $fN => $fV)    {
 346                                      if ($fN!='uid' && $fN!='pid' && isset($olrow[$fN]))    {
 347  
 348                                          if ($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$fN]!='exclude'
 349                                                  && ($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$fN]!='mergeIfNotBlank' || strcmp(trim($olrow[$fN]),'')))    {
 350                                              $row[$fN] = $olrow[$fN];
 351                                          }
 352                                      } elseif ($fN=='uid')    {
 353                                          $row['_LOCALIZED_UID'] = $olrow['uid'];
 354                                      }
 355                                  }
 356                              } 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.
 357                                  unset($row);
 358                              }
 359  
 360                              // 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.
 361                          } elseif ($sys_language_content!=$row[$TCA[$table]['ctrl']['languageField']])    {
 362                              unset($row);
 363                          }
 364                      } else {
 365                              // When default language is displayed, we never want to return a record carrying another language!:
 366                          if ($row[$TCA[$table]['ctrl']['languageField']]>0)    {
 367                              unset($row);
 368                          }
 369                      }
 370                  }
 371              }
 372          }
 373  
 374          return $row;
 375      }
 376  
 377  
 378  
 379  
 380  
 381  
 382  
 383  
 384  
 385  
 386  
 387  
 388  
 389  
 390  
 391  
 392  
 393  
 394      /*******************************************
 395       *
 396       * Page related: Menu, Domain record, Root line
 397       *
 398       ******************************************/
 399  
 400      /**
 401       * Returns an array with pagerows for subpages with pid=$uid (which is pid here!). This is used for menus.
 402       * If there are mount points in overlay mode the _MP_PARAM field is set to the corret MPvar.
 403       * If the $uid being input does in itself require MPvars to define a correct rootline these must be handled externally to this function.
 404       *
 405       * @param    integer        The page id for which to fetch subpages (PID)
 406       * @param    string        List of fields to select. Default is "*" = all
 407       * @param    string        The field to sort by. Default is "sorting"
 408       * @param    string        Optional additional where clauses. Like "AND title like '%blabla%'" for instance.
 409       * @param    boolean        check if shortcuts exist, checks by default
 410       * @return    array        Array with key/value pairs; keys are page-uid numbers. values are the corresponding page records (with overlayed localized fields, if any)
 411       * @see tslib_fe::getPageShortcut(), tslib_menu::makeMenu(), tx_wizardcrpages_webfunc_2, tx_wizardsortpages_webfunc_2
 412       */
 413  	function getMenu($uid,$fields='*',$sortField='sorting',$addWhere='',$checkShortcuts=1)    {
 414  
 415          $output = Array();
 416          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, 'pages', 'pid='.intval($uid).$this->where_hid_del.$this->where_groupAccess.' '.$addWhere, '', $sortField);
 417          while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 418              $this->versionOL('pages',$row);
 419  
 420              if (is_array($row))    {
 421                      // Keep mount point:
 422                  $origUid = $row['uid'];
 423                  $mount_info = $this->getMountPointInfo($origUid, $row);    // $row MUST have "uid", "pid", "doktype", "mount_pid", "mount_pid_ol" fields in it
 424                  if (is_array($mount_info) && $mount_info['overlay'])    {    // There is a valid mount point.
 425                      $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!
 426                      if (count($mp_row))    {
 427                          $row = $mp_row;
 428                          $row['_MP_PARAM'] = $mount_info['MPvar'];
 429                      } 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!
 430                  }
 431  
 432                      // if shortcut, look up if the target exists and is currently visible
 433                  if ($row['doktype'] == 4 && ($row['shortcut'] || $row['shortcut_mode']) && $checkShortcuts)    {
 434                      if ($row['shortcut_mode'] == 0)    {
 435                          $searchField = 'uid';
 436                          $searchUid = intval($row['shortcut']);
 437                      } else { // check subpages - first subpage or random subpage
 438                          $searchField = 'pid';
 439                              // If a shortcut mode is set and no valid page is given to select subpags from use the actual page.
 440                          $searchUid = intval($row['shortcut'])?intval($row['shortcut']):$row['uid'];
 441                      }
 442                      $res2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', $searchField.'='.$searchUid.$this->where_hid_del.$this->where_groupAccess.' '.$addWhere, '', $sortField);
 443                      if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res2))    {
 444                          unset($row);
 445                      }
 446                      $GLOBALS['TYPO3_DB']->sql_free_result($res2);
 447                  } elseif ($row['doktype'] == 4 && $checkShortcuts)    {
 448                          // Neither shortcut target nor mode is set. Remove the page from the menu.
 449                      unset($row);
 450                  }
 451  
 452                      // Add to output array after overlaying language:
 453                  if (is_array($row))    {
 454                      $output[$origUid] = $this->getPageOverlay($row);
 455                  }
 456              }
 457          }
 458          return $output;
 459      }
 460  
 461      /**
 462       * Will find the page carrying the domain record matching the input domain.
 463       * Might exit after sending a redirect-header IF a found domain record instructs to do so.
 464       *
 465       * @param    string        Domain name to search for. Eg. "www.typo3.com". Typical the HTTP_HOST value.
 466       * @param    string        Path for the current script in domain. Eg. "/somedir/subdir". Typ. supplied by t3lib_div::getIndpEnv('SCRIPT_NAME')
 467       * @param    string        Request URI: Used to get parameters from if they should be appended. Typ. supplied by t3lib_div::getIndpEnv('REQUEST_URI')
 468       * @return    mixed        If found, returns integer with page UID where found. Otherwise blank. Might exit if location-header is sent, see description.
 469       * @see tslib_fe::findDomainRecord()
 470       */
 471  	function getDomainStartPage($domain, $path='',$request_uri='')    {
 472          $domain = explode(':',$domain);
 473          $domain = strtolower(ereg_replace('\.$','',$domain[0]));
 474              // Removing extra trailing slashes
 475          $path = trim(ereg_replace('\/[^\/]*$','',$path));
 476              // Appending to domain string
 477          $domain.= $path;
 478          $domain = ereg_replace('\/*$','',$domain);
 479  
 480          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
 481                      'pages.uid,sys_domain.redirectTo,sys_domain.prepend_params',
 482                      'pages,sys_domain',
 483                      'pages.uid=sys_domain.pid
 484                          AND sys_domain.hidden=0
 485                          AND (sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain, 'sys_domain').' OR sys_domain.domainName='.$GLOBALS['TYPO3_DB']->fullQuoteStr($domain.'/', 'sys_domain').') '.
 486                          $this->where_hid_del.$this->where_groupAccess,
 487                      '',
 488                      '',
 489                      1
 490                  );
 491          if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 492              if ($row['redirectTo'])    {
 493                  $rURL = $row['redirectTo'];
 494                  if ($row['prepend_params'])    {
 495                      $rURL = ereg_replace('\/$','',$rURL);
 496                      $prependStr = ereg_replace('^\/','',substr($request_uri,strlen($path)));
 497                      $rURL.= '/'.$prependStr;
 498                  }
 499                  Header('Location: '.t3lib_div::locationHeaderUrl($rURL));
 500                  exit;
 501              } else {
 502                  return $row['uid'];
 503              }
 504          }
 505      }
 506  
 507      /**
 508       * Returns array with fields of the pages from here ($uid) and back to the root
 509       * NOTICE: This function only takes deleted pages into account! So hidden, starttime and endtime restricted pages are included no matter what.
 510       * Further: If any "recycler" page is found (doktype=255) then it will also block for the rootline)
 511       * If you want more fields in the rootline records than default such can be added by listing them in $GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields']
 512       *
 513       * @param    integer        The page uid for which to seek back to the page tree root.
 514       * @param    string        Commalist of MountPoint parameters, eg. "1-2,3-4" etc. Normally this value comes from the GET var, MP
 515       * @param    boolean        If set, some errors related to Mount Points in root line are ignored.
 516       * @return    array        Array with page records from the root line as values. The array is ordered with the outer records first and root record in the bottom. The keys are numeric but in reverse order. So if you traverse/sort the array by the numeric keys order you will get the order from root and out. If an error is found (like eternal looping or invalid mountpoint) it will return an empty array.
 517       * @see tslib_fe::getPageAndRootline()
 518       */
 519  	function getRootLine($uid, $MP='', $ignoreMPerrors=FALSE)    {
 520  
 521              // Initialize:
 522          $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']);
 523          $this->error_getRootLine = '';
 524          $this->error_getRootLine_failPid = 0;
 525  
 526              // Splitting the $MP parameters if present
 527          $MPA = array();
 528          if ($MP)    {
 529              $MPA = explode(',',$MP);
 530              reset($MPA);
 531              while(list($MPAk) = each($MPA))    {
 532                  $MPA[$MPAk] = explode('-', $MPA[$MPAk]);
 533              }
 534          }
 535  
 536          $loopCheck = 0;
 537          $theRowArray = Array();
 538          $uid = intval($uid);
 539  
 540          while ($uid!=0 && $loopCheck<20)    {    // Max 20 levels in the page tree.
 541              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid='.intval($uid).' AND pages.deleted=0 AND pages.doktype!=255');
 542              if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 543                  $this->versionOL('pages',$row);
 544                  $this->fixVersioningPid('pages',$row);
 545  
 546                  if (is_array($row))    {
 547                          // 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:
 548                      if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'] && $row['doktype']==7 && !$ignoreMPerrors)    {
 549                          $mount_info = $this->getMountPointInfo($row['uid'], $row);
 550                          if ($loopCheck>0 || $mount_info['overlay'])    {
 551                              $this->error_getRootLine = 'Illegal Mount Point found in rootline';
 552                              return array();
 553                          }
 554                      }
 555  
 556                      $uid = $row['pid'];    // Next uid
 557  
 558                      if (count($MPA) && $GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'])    {
 559                          $curMP = end($MPA);
 560                          if (!strcmp($row['uid'],$curMP[0]))    {
 561  
 562                              array_pop($MPA);
 563                              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selFields, 'pages', 'uid='.intval($curMP[1]).' AND pages.deleted=0 AND pages.doktype!=255');
 564                              $mp_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
 565  
 566                              $this->versionOL('pages',$mp_row);
 567                              $this->fixVersioningPid('pages',$mp_row);
 568  
 569                              if (is_array($mp_row))    {
 570                                  $mount_info = $this->getMountPointInfo($mp_row['uid'], $mp_row);
 571                                  if (is_array($mount_info) && $mount_info['mount_pid']==$curMP[0])    {
 572                                      $uid = $mp_row['pid'];    // Setting next uid
 573  
 574                                      if ($mount_info['overlay'])    {    // Symlink style: Keep mount point (current row).
 575                                          $row['_MOUNT_OL'] = TRUE;    // Set overlay mode:
 576                                          $row['_MOUNT_PAGE'] = array(
 577                                              'uid' => $mp_row['uid'],
 578                                              'pid' => $mp_row['pid'],
 579                                              'title' =>  $mp_row['title'],
 580                                          );
 581                                      } else {    // Normal operation: Insert the mount page row in rootline instead mount point.
 582                                          if ($loopCheck>0)    {
 583                                              $row = $mp_row;
 584                                          } else {
 585                                              $this->error_getRootLine = 'Current Page Id is a mounted page of the overlay type and cannot be accessed directly!';
 586                                              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!)
 587                                          }
 588                                      }
 589  
 590                                      $row['_MOUNTED_FROM'] = $curMP[0];
 591                                      $row['_MP_PARAM'] = $mount_info['MPvar'];
 592                                  } else {
 593                                      $this->error_getRootLine = 'MP var was corrupted';
 594                                      return array();    // The MP variables did NOT connect proper mount points:
 595                                  }
 596                              } else {
 597                                  $this->error_getRootLine = 'No moint point record found according to PID in MP var';
 598                                  return array();    // The second PID in MP var was NOT a valid page.
 599                              }
 600                          }
 601                      }
 602                  }
 603                      // Add row to rootline with language overlaid:
 604                  $theRowArray[] = $this->getPageOverlay($row);
 605              } else {
 606                  $this->error_getRootLine = 'Broken rootline';
 607                  $this->error_getRootLine_failPid = $uid;
 608                  return array();    // broken rootline.
 609              }
 610  
 611              $loopCheck++;
 612          }
 613  
 614              // If the MPA array is NOT empty, we have to return an error; All MP elements were not resolved!
 615          if (count($MPA))    {
 616              $this->error_getRootLine = 'MP value remain!';
 617              return array();
 618          }
 619  
 620              // Create output array (with reversed order of numeric keys):
 621          $output = Array();
 622          $c = count($theRowArray);
 623          foreach($theRowArray as $key => $val)    {
 624              $c--;
 625              $output[$c] = $val;
 626          }
 627  
 628          return $output;
 629      }
 630  
 631      /**
 632       * Creates a "path" string for the input root line array titles.
 633       * Used for writing statistics.
 634       *
 635       * @param    array        A rootline array!
 636       * @param    integer        The max length of each title from the rootline.
 637       * @return    string        The path in the form "/page title/This is another pageti.../Another page"
 638       * @see tslib_fe::getConfigArray()
 639       */
 640  	function getPathFromRootline($rl,$len=20)    {
 641          if (is_array($rl))    {
 642              $c=count($rl);
 643              $path = '';
 644              for ($a=0;$a<$c;$a++)    {
 645                  if ($rl[$a]['uid'])    {
 646                      $path.='/'.t3lib_div::fixed_lgd_cs(strip_tags($rl[$a]['title']),$len);
 647                  }
 648              }
 649              return $path;
 650          }
 651      }
 652  
 653      /**
 654       * Returns the URL type for the input page row IF the doktype is 3 and not disabled.
 655       *
 656       * @param    array        The page row to return URL type for
 657       * @param    boolean        A flag to simply disable any output from here.
 658       * @return    string        The URL type from $this->urltypes array. False if not found or disabled.
 659       * @see tslib_fe::setExternalJumpUrl()
 660       */
 661  	function getExtURL($pagerow,$disable=0)    {
 662          if ($pagerow['doktype']==3 && !$disable)    {
 663              $redirectTo = $this->urltypes[$pagerow['urltype']].$pagerow['url'];
 664  
 665                  // If relative path, prefix Site URL:
 666              $uI = parse_url($redirectTo);
 667              if (!$uI['scheme'] && substr($redirectTo,0,1)!='/')    { // relative path assumed now...
 668                  $redirectTo = t3lib_div::getIndpEnv('TYPO3_SITE_URL').$redirectTo;
 669              }
 670              return $redirectTo;
 671          }
 672      }
 673  
 674      /**
 675       * Returns MountPoint id for page
 676       * Does a recursive search if the mounted page should be a mount page itself. It has a run-away break so it can't go into infinite loops.
 677       *
 678       * @param    integer        Page id for which to look for a mount pid. Will be returned only if mount pages are enabled, the correct doktype (7) is set for page and there IS a mount_pid (which has a valid record that is not deleted...)
 679       * @param    array        Optional page record for the page id. If not supplied it will be looked up by the system. Must contain at least uid,pid,doktype,mount_pid,mount_pid_ol
 680       * @param    array        Array accumulating formerly tested page ids for mount points. Used for recursivity brake.
 681       * @param    integer        The first page id.
 682       * @return    mixed        Returns FALSE if no mount point was found, "-1" if there should have been one, but no connection to it, otherwise an array with information about mount pid and modes.
 683       * @see tslib_menu
 684       */
 685  	function getMountPointInfo($pageId, $pageRec=FALSE, $prevMountPids=array(), $firstPageUid=0)    {
 686          if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'])    {
 687  
 688                  // Get pageRec if not supplied:
 689              if (!is_array($pageRec))    {
 690                  $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');
 691                  $pageRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
 692                  $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!
 693              }
 694  
 695                  // Set first Page uid:
 696              if (!$firstPageUid)    $firstPageUid = $pageRec['uid'];
 697  
 698                  // Look for mount pid value plus other required circumstances:
 699              $mount_pid = intval($pageRec['mount_pid']);
 700              if (is_array($pageRec) && $pageRec['doktype']==7 && $mount_pid>0 && !in_array($mount_pid, $prevMountPids))    {
 701  
 702                      // Get the mount point record (to verify its general existence):
 703                  $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');
 704                  $mount_rec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
 705                  $this->versionOL('pages',$mount_rec);
 706  
 707                  if (is_array($mount_rec))    {
 708                          // Look for recursive mount point:
 709                      $prevMountPids[] = $mount_pid;
 710                      $recursiveMountPid = $this->getMountPointInfo($mount_pid, $mount_rec, $prevMountPids, $firstPageUid);
 711  
 712                          // Return mount point information:
 713                      return $recursiveMountPid ?
 714                                  $recursiveMountPid :
 715                                  array(
 716                                      'mount_pid' => $mount_pid,
 717                                      'overlay' => $pageRec['mount_pid_ol'],
 718                                      'MPvar' => $mount_pid.'-'.$firstPageUid,
 719                                      'mount_point_rec' => $pageRec,
 720                                      'mount_pid_rec' => $mount_rec,
 721                                  );
 722                  } else {
 723                      return -1;    // Means, there SHOULD have been a mount point, but there was none!
 724                  }
 725              }
 726          }
 727  
 728          return FALSE;
 729      }
 730  
 731  
 732  
 733  
 734  
 735  
 736  
 737  
 738  
 739  
 740  
 741  
 742  
 743  
 744  
 745  
 746  
 747      /*********************************
 748       *
 749       * Selecting records in general
 750       *
 751       **********************************/
 752  
 753      /**
 754       * Checks if a record exists and is accessible.
 755       * The row is returned if everything's OK.
 756       *
 757       * @param    string        The table name to search
 758       * @param    integer        The uid to look up in $table
 759       * @param    boolean        If checkPage is set, it's also required that the page on which the record resides is accessible
 760       * @return    mixed        Returns array (the record) if OK, otherwise blank/0 (zero)
 761       */
 762  	function checkRecord($table,$uid,$checkPage=0)    {
 763          global $TCA;
 764          $uid = intval($uid);
 765          if (is_array($TCA[$table]))    {
 766              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($uid).$this->enableFields($table));
 767              if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 768                  $this->versionOL($table,$row);
 769                  $GLOBALS['TYPO3_DB']->sql_free_result($res);
 770  
 771                  if (is_array($row))    {
 772                      if ($checkPage)    {
 773                          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'uid='.intval($row['pid']).$this->enableFields('pages'));
 774                          if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))    {
 775                              return $row;
 776                          } else {
 777                              return 0;
 778                          }
 779                      } else {
 780                          return $row;
 781                      }
 782                  }
 783              }
 784          }
 785      }
 786  
 787      /**
 788       * Returns record no matter what - except if record is deleted
 789       *
 790       * @param    string        The table name to search
 791       * @param    integer        The uid to look up in $table
 792       * @param    string        The fields to select, default is "*"
 793       * @param    boolean        If set, no version overlay is applied
 794       * @return    mixed        Returns array (the record) if found, otherwise blank/0 (zero)
 795       * @see getPage_noCheck()
 796       */
 797  	function getRawRecord($table,$uid,$fields='*',$noWSOL=FALSE)    {
 798          global $TCA;
 799          $uid = intval($uid);
 800          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()...
 801              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, 'uid='.intval($uid).$this->deleteClause($table));
 802              $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
 803              $GLOBALS['TYPO3_DB']->sql_free_result($res);
 804              if ($row) {
 805                  if (!$noWSOL)    {
 806                      $this->versionOL($table,$row);
 807                  }
 808                  if (is_array($row))    return $row;
 809              }
 810          }
 811      }
 812  
 813      /**
 814       * Selects records based on matching a field (ei. other than UID) with a value
 815       *
 816       * @param    string        The table name to search, eg. "pages" or "tt_content"
 817       * @param    string        The fieldname to match, eg. "uid" or "alias"
 818       * @param    string        The value that fieldname must match, eg. "123" or "frontpage"
 819       * @param    string        Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
 820       * @param    string        Optional GROUP BY field(s), if none, supply blank string.
 821       * @param    string        Optional ORDER BY field(s), if none, supply blank string.
 822       * @param    string        Optional LIMIT value ([begin,]max), if none, supply blank string.
 823       * @return    mixed        Returns array (the record) if found, otherwise blank/0 (zero)
 824       */
 825  	function getRecordsByField($theTable,$theField,$theValue,$whereClause='',$groupBy='',$orderBy='',$limit='')    {
 826          global $TCA;
 827          if (is_array($TCA[$theTable])) {
 828              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
 829                          '*',
 830                          $theTable,
 831                          $theField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($theValue, $theTable).
 832                              $this->deleteClause($theTable).' '.
 833                                  $whereClause,    // whereClauseMightContainGroupOrderBy
 834                          $groupBy,
 835                          $orderBy,
 836                          $limit
 837                      );
 838              $rows = array();
 839              while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 840                  #$this->versionOL($theTable,$row);    // not used since records here are fetched based on other fields than uid!
 841                  if (is_array($row)) $rows[] = $row;
 842              }
 843              $GLOBALS['TYPO3_DB']->sql_free_result($res);
 844              if (count($rows))    return $rows;
 845          }
 846      }
 847  
 848  
 849  
 850  
 851  
 852  
 853  
 854  
 855  
 856  
 857  
 858  
 859  
 860  
 861      /*********************************
 862       *
 863       * Caching and standard clauses
 864       *
 865       **********************************/
 866  
 867      /**
 868       * Returns string value stored for the hash string in the table "cache_hash"
 869       * Can be used to retrieved a cached value
 870       * Can be used from your frontend plugins if you like. Is also used to store the parsed TypoScript template structures. You can call it directly like t3lib_pageSelect::getHash()
 871       *
 872       * @param    string        The hash-string which was used to store the data value
 873       * @param    integer        Allowed expiretime in seconds. Basically a record is selected only if it is not older than this value in seconds. If expTime is not set, the hashed value will never expire.
 874       * @return    string        The "content" field of the "cache_hash" table row.
 875       * @see tslib_TStemplate::start(), storeHash()
 876       */
 877  	function getHash($hash,$expTime=0)    {
 878              //
 879          $expTime = intval($expTime);
 880          if ($expTime)    {
 881              $whereAdd = ' AND tstamp > '.(time()-$expTime);
 882          }
 883          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash').$whereAdd);
 884          if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 885              $GLOBALS['TYPO3_DB']->sql_free_result($res);
 886              return $row['content'];
 887          }
 888      }
 889  
 890      /**
 891       * Stores a string value in the cache_hash table identified by $hash.
 892       * Can be used from your frontend plugins if you like. You can call it directly like t3lib_pageSelect::storeHash()
 893       *
 894       * @param    string        32 bit hash string (eg. a md5 hash of a serialized array identifying the data being stored)
 895       * @param    string        The data string. If you want to store an array, then just serialize it first.
 896       * @param    string        $ident is just a textual identification in order to inform about the content! May be 20 characters long.
 897       * @return    void
 898       * @see tslib_TStemplate::start(), getHash()
 899       */
 900  	function storeHash($hash,$data,$ident)    {
 901          $insertFields = array(
 902              'hash' => $hash,
 903              'content' => $data,
 904              'ident' => $ident,
 905              'tstamp' => time()
 906          );
 907          $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_hash', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_hash'));
 908          $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_hash', $insertFields);
 909      }
 910  
 911      /**
 912       * Returns the "AND NOT deleted" clause for the tablename given IF $TCA configuration points to such a field.
 913       *
 914       * @param    string        Tablename
 915       * @return    string
 916       * @see enableFields()
 917       */
 918  	function deleteClause($table)    {
 919          global $TCA;
 920          if (!strcmp($table,'pages'))    {    // Hardcode for pages because TCA might not be loaded yet (early frontend initialization)
 921              return ' AND pages.deleted=0';
 922          } else {
 923              return $TCA[$table]['ctrl']['delete'] ? ' AND '.$table.'.'.$TCA[$table]['ctrl']['delete'].'=0' : '';
 924          }
 925      }
 926  
 927      /**
 928       * Returns a part of a WHERE clause which will filter out records with start/end times or hidden/fe_groups fields set to values that should de-select them according to the current time, preview settings or user login. Definitely a frontend function.
 929       * Is using the $TCA arrays "ctrl" part where the key "enablefields" determines for each table which of these features applies to that table.
 930       *
 931       * @param    string        Table name found in the $TCA array
 932       * @param    integer        If $show_hidden is set (0/1), any hidden-fields in records are ignored. NOTICE: If you call this function, consider what to do with the show_hidden parameter. Maybe it should be set? See tslib_cObj->enableFields where it's implemented correctly.
 933       * @param    array        Array you can pass where keys can be "disabled", "starttime", "endtime", "fe_group" (keys from "enablefields" in TCA) and if set they will make sure that part of the clause is not added. Thus disables the specific part of the clause. For previewing etc.
 934       * @param    boolean        If set, enableFields will be applied regardless of any versioning preview settings which might otherwise disable enableFields
 935       * @return    string        The clause starting like " AND ...=... AND ...=..."
 936       * @see tslib_cObj::enableFields(), deleteClause()
 937       */
 938  	function enableFields($table,$show_hidden=-1,$ignore_array=array(),$noVersionPreview=FALSE)    {
 939          global $TYPO3_CONF_VARS;
 940  
 941          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
 942              $show_hidden = $table=='pages' ? $GLOBALS['TSFE']->showHiddenPage : $GLOBALS['TSFE']->showHiddenRecords;
 943          }
 944          if ($show_hidden==-1)    $show_hidden=0;    // If show_hidden was not changed during the previous evaluation, do it here.
 945  
 946          $ctrl = $GLOBALS['TCA'][$table]['ctrl'];
 947          $query='';
 948          if (is_array($ctrl))    {
 949  
 950                  // Delete field check:
 951              if ($ctrl['delete'])    {
 952                  $query.=' AND '.$table.'.'.$ctrl['delete'].'=0';
 953              }
 954  
 955                  // Filter out new place-holder records in case we are NOT in a versioning preview (that means we are online!)
 956              if ($ctrl['versioningWS'] && !$this->versioningPreview)    {
 957                  $query.=' AND '.$table.'.t3ver_state!=1';    // Shadow state for new items MUST be ignored!
 958              }
 959  
 960                  // Enable fields:
 961              if (is_array($ctrl['enablecolumns']))    {
 962                  if (!$this->versioningPreview || !$ctrl['versioningWS'] || $noVersionPreview) { // In case of versioning-preview, enableFields are ignored (checked in versionOL())
 963                      if ($ctrl['enablecolumns']['disabled'] && !$show_hidden && !$ignore_array['disabled']) {
 964                          $field = $table.'.'.$ctrl['enablecolumns']['disabled'];
 965                          $query.=' AND '.$field.'=0';
 966                      }
 967                      if ($ctrl['enablecolumns']['starttime'] && !$ignore_array['starttime']) {
 968                          $field = $table.'.'.$ctrl['enablecolumns']['starttime'];
 969                          $query.=' AND ('.$field.'<='.$GLOBALS['SIM_EXEC_TIME'].')';
 970                      }
 971                      if ($ctrl['enablecolumns']['endtime'] && !$ignore_array['endtime']) {
 972                          $field = $table.'.'.$ctrl['enablecolumns']['endtime'];
 973                          $query.=' AND ('.$field.'=0 OR '.$field.'>'.$GLOBALS['SIM_EXEC_TIME'].')';
 974                      }
 975                      if ($ctrl['enablecolumns']['fe_group'] && !$ignore_array['fe_group']) {
 976                          $field = $table.'.'.$ctrl['enablecolumns']['fe_group'];
 977                          $query.= $this->getMultipleGroupsWhereClause($field, $table);
 978                      }
 979  
 980                      // Call hook functions for additional enableColumns
 981                      // It is used by the extension ingmar_accessctrl which enables assigning more than one usergroup to content and page records
 982                      if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns']))    {
 983                          $_params = array(
 984                              'table' => $table,
 985                              'show_hidden' => $show_hidden,
 986                              'ignore_array' => $ignore_array,
 987                              'ctrl' => $ctrl
 988                          );
 989                          foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_page.php']['addEnableColumns'] as $_funcRef)    {
 990                              $query .= t3lib_div::callUserFunction($_funcRef,$_params,$this);
 991                          }
 992                      }
 993                  }
 994              }
 995          } else {
 996              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.');
 997          }
 998  
 999          return $query;
1000      }
1001  
1002      /**
1003       * Creating where-clause for checking group access to elements in enableFields function
1004       *
1005       * @param    string        Field with group list
1006       * @param    string        Table name
1007       * @return    string        AND sql-clause
1008       * @see enableFields()
1009       */
1010  	function getMultipleGroupsWhereClause($field, $table)    {
1011          $memberGroups = t3lib_div::intExplode(',',$GLOBALS['TSFE']->gr_list);
1012          $orChecks=array();
1013          $orChecks[]=$field.'=\'\'';    // If the field is empty, then OK
1014          $orChecks[]=$field.' IS NULL';    // If the field is NULL, then OK
1015          $orChecks[]=$field.'=\'0\'';    // If the field contsains zero, then OK
1016  
1017          foreach($memberGroups as $value)    {
1018              $orChecks[] = $GLOBALS['TYPO3_DB']->listQuery($field, $value, $table);
1019          }
1020  
1021          return ' AND ('.implode(' OR ',$orChecks).')';
1022      }
1023  
1024  
1025  
1026  
1027  
1028  
1029  
1030  
1031  
1032  
1033  
1034  
1035  
1036  
1037  
1038      /*********************************
1039       *
1040       * Versioning Preview
1041       *
1042       **********************************/
1043  
1044      /**
1045       * Finding online PID for offline version record
1046       * ONLY active when backend user is previewing records. MUST NEVER affect a site served which is not previewed by backend users!!!
1047       * Will look if the "pid" value of the input record is -1 (it is an offline version) and if the table supports versioning; if so, it will translate the -1 PID into the PID of the original record
1048       * Used whenever you are tracking something back, like making the root line.
1049       * Principle; Record offline! => Find online?
1050       *
1051       * @param    string        Table name
1052       * @param    array        Record array passed by reference. As minimum, "pid" and "uid" fields must exist! "t3ver_oid" and "t3ver_wsid" is nice and will save you a DB query.
1053       * @return    void        (Passed by ref).
1054       * @see t3lib_BEfunc::fixVersioningPid(), versionOL(), getRootLine()
1055       */
1056  	function fixVersioningPid($table,&$rr)    {
1057          global $TCA;
1058  
1059          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!
1060  
1061                  // Check values for t3ver_oid and t3ver_wsid:
1062              if (isset($rr['t3ver_oid']) && isset($rr['t3ver_wsid']))    {    // If "t3ver_oid" is already a field, just set this:
1063                  $oid = $rr['t3ver_oid'];
1064                  $wsid = $rr['t3ver_wsid'];
1065              } else {    // Otherwise we have to expect "uid" to be in the record and look up based on this:
1066                  $newPidRec = $this->getRawRecord($table,$rr['uid'],'t3ver_oid,t3ver_wsid',TRUE);
1067                  if (is_array($newPidRec))    {
1068                      $oid = $newPidRec['t3ver_oid'];
1069                      $wsid = $newPidRec['t3ver_wsid'];
1070                  }
1071              }
1072  
1073              // If workspace ids matches and ID of current online version is found, look up the PID value of that:
1074              if ($oid && (($this->versioningWorkspaceId == 0 && $this->checkWorkspaceAccess($wsid)) || !strcmp((int)$wsid,$this->versioningWorkspaceId)))    {
1075                  $oidRec = $this->getRawRecord($table,$oid,'pid',TRUE);
1076  
1077                  if (is_array($oidRec))    {
1078                      # 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!
1079                      $rr['_ORIG_pid'] = $rr['pid'];
1080                      $rr['pid'] = $oidRec['pid'];
1081                  }
1082              }
1083          }
1084      }
1085  
1086      /**
1087       * Versioning Preview Overlay
1088       * ONLY active when backend user is previewing records. MUST NEVER affect a site served which is not previewed by backend users!!!
1089       * Generally ALWAYS used when records are selected based on uid or pid. If records are selected on other fields than uid or pid (eg. "email = ....") then usage might produce undesired results and that should be evaluated on individual basis.
1090       * Principle; Record online! => Find offline?
1091       *
1092       * @param    string        Table name
1093       * @param    array        Record array passed by reference. As minimum, the "uid", "pid" and "t3ver_state" fields must exist! The record MAY be set to FALSE in which case the calling function should act as if the record is forbidden to access!
1094       * @return    void        (Passed by ref).
1095       * @see fixVersioningPid(), t3lib_BEfunc::workspaceOL()
1096       */
1097  	function versionOL($table,&$row)    {
1098          global $TCA;
1099  
1100          if ($this->versioningPreview && is_array($row))    {
1101              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()
1102                  if (is_array($wsAlt))    {
1103  
1104                          // Always fix PID (like in fixVersioningPid() above). [This is usually not the important factor for versioning OL]
1105                      $wsAlt['_ORIG_pid'] = $wsAlt['pid'];    // Keep the old (-1) - indicates it was a version...
1106                      $wsAlt['pid'] = $row['pid'];        // Set in the online versions PID.
1107  
1108                          // "element" and "page" type versions:
1109                          // For versions of single elements or page+content, preserve online UID and PID (this will produce true "overlay" of element _content_, not any references)
1110                          // For page+content the "_ORIG_uid" should actually be used as PID for selection of tables with "versioning_followPages" enabled.
1111                      if ($table!=='pages' || $wsAlt['t3ver_swapmode']<=0)    {
1112                          $wsAlt['_ORIG_uid'] = $wsAlt['uid'];
1113                          $wsAlt['uid'] = $row['uid'];
1114  
1115                              // Translate page alias as well so links are pointing to the _online_ page:
1116                          if ($table==='pages')    {
1117                              $wsAlt['alias'] = $row['alias'];
1118                          }
1119                      } else {
1120                              // "branch" versions:
1121                              // Keeping overlay uid and pid so references are changed. This is only for page-versions with BRANCH below!
1122                          $wsAlt['_ONLINE_uid'] = $row['uid'];    // The UID of the versionized record is kept and the uid of the online version is stored
1123                      }
1124  
1125                          // Changing input record to the workspace version alternative:
1126                      $row = $wsAlt;
1127  
1128                          // Check if it is deleted in workspace:
1129                      if ((int)$row['t3ver_state']===2)    {
1130                          $row = FALSE;    // Unset record if it turned out to be deleted in workspace
1131                      }
1132                  } else {
1133                          // No version found, then check if t3ver_state =1 (online version is dummy-representation)
1134                      if ($wsAlt==-1 || (int)$row['t3ver_state']===1)    {
1135                          $row = FALSE;    // Unset record if it turned out to be "hidden"
1136                      }
1137                  }
1138              }
1139          }
1140      }
1141  
1142      /**
1143       * Select the version of a record for a workspace
1144       *
1145       * @param    integer        Workspace ID
1146       * @param    string        Table name to select from
1147       * @param    integer        Record uid for which to find workspace version.
1148       * @param    string        Field list to select
1149       * @return    array        If found, return record, otherwise false. Returns 1 if version was sought for but not found, returns -1 if record existed but had enableFields that would disable it.
1150       * @see t3lib_befunc::getWorkspaceVersionOfRecord()
1151       */
1152  	function getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields='*')    {
1153          global $TCA;
1154  
1155          if ($workspace!==0 && ($table=='pages' || $TCA[$table]['ctrl']['versioningWS']))    {    // Have to hardcode it for "pages" table since TCA is not loaded at this moment!
1156  
1157                  // Setting up enableFields for version record:
1158              if ($table=='pages')    {
1159                  $enFields = $this->versioningPreview_where_hid_del;
1160              } else {
1161                  $enFields = $this->enableFields($table,-1,array(),TRUE);
1162              }
1163  
1164                  // Select workspace version of record, only testing for deleted.
1165              list($newrow) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1166                  $fields,
1167                  $table,
1168                  'pid=-1 AND
1169                   t3ver_oid='.intval($uid).' AND
1170                   t3ver_wsid='.intval($workspace).
1171                      $this->deleteClause($table)
1172              );
1173  
1174                  // If version found, check if it could have been selected with enableFields on as well:
1175              if (is_array($newrow))    {
1176                  if ($GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1177                      'uid',
1178                      $table,
1179                      'pid=-1 AND
1180                          t3ver_oid='.intval($uid).' AND
1181                          t3ver_wsid='.intval($workspace).
1182                          $enFields
1183                  )) {
1184                      return $newrow;    // Return offline version, tested for its enableFields.
1185                  } else {
1186                      return -1;    // Return -1 because version was de-selected due to its enableFields.
1187                  }
1188              } else {
1189                      // OK, so no workspace version was found. Then check if online version can be selected with full enable fields and if so, return 1:
1190                  if ($GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1191                      'uid',
1192                      $table,
1193                      'uid='.intval($uid).$enFields
1194                  ))    {
1195                      return 1;    // Means search was done, but no version found.
1196                  } else {
1197                      return -1;    // Return -1 because the current record was de-selected due to its enableFields.
1198                  }
1199              }
1200          }
1201  
1202          return FALSE;    // No look up in database because versioning not enabled / or workspace not offline
1203      }
1204  
1205      /**
1206       * Checks if user has access to workspace.
1207       * 
1208       * @param    int    $wsid    Workspace ID
1209       * @return    boolean    <code>true</code> if has access
1210       */
1211  	function checkWorkspaceAccess($wsid) {
1212          if (!$GLOBALS['BE_USER']) {
1213              return false;
1214          }
1215          if (isset($this->workspaceCache[$wsid])) {
1216              $ws = $this->workspaceCache[$wsid];
1217          }
1218          else {
1219              if ($wsid > 0) {
1220                  $ws = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_workspace', 'uid='.intval($wsid).' AND deleted=0'); // No $TCA yet!
1221                  if (count($ws)) {
1222                      $ws = $ws[0];
1223                  }
1224                  else {
1225                      return false;
1226                  }
1227              }
1228              else {
1229                  $ws = $wsid;
1230              }
1231              $ws = $GLOBALS['BE_USER']->checkWorkspace($ws);
1232              $this->workspaceCache[$wsid] = $ws;
1233          }
1234          return ($ws['_ACCESS'] != '');
1235      }
1236  }
1237  
1238  
1239  
1240  if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php'])    {
1241      include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php']);
1242  }
1243  ?>


Généré le : Sun Nov 25 17:13:16 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics