[ 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_loaddbgroup.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 class for loading database groups
  29   *
  30   * $Id: class.t3lib_loaddbgroup.php 1929 2007-01-23 20:11:23Z ingmars $
  31   * Revised for TYPO3 3.6 September/2003 by Kasper Skaarhoj
  32   *
  33   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
  34   */
  35  /**
  36   * [CLASS/FUNCTION INDEX of SCRIPT]
  37   *
  38   *
  39   *
  40   *   76: class t3lib_loadDBGroup
  41   *  111:     function start($itemlist, $tablelist, $MMtable='', $MMuid=0, $currentTable='', $conf=array())
  42   *  179:     function readList($itemlist)
  43   *  225:     function readMM($tableName,$uid)
  44   *  276:     function writeMM($tableName,$uid,$prependTableName=0)
  45   *  352:     function readForeignField($uid, $conf)
  46   *  435:     function writeForeignField($conf, $parentUid, $updateToUid=0)
  47   *  510:     function getValueArray($prependTableName='')
  48   *  538:     function convertPosNeg($valueArray,$fTable,$nfTable)
  49   *  560:     function getFromDB()
  50   *  595:     function readyForInterface()
  51   *  621:     function countItems($returnAsArray = true)
  52   *  636:     function updateRefIndex($table,$id)
  53   *
  54   * TOTAL FUNCTIONS: 12
  55   * (This index is automatically created/updated by the extension "extdeveval")
  56   *
  57   */
  58  
  59  
  60  
  61  
  62  
  63  
  64  
  65  
  66  
  67  
  68  /**
  69   * Load database groups (relations)
  70   * Used to process the relations created by the TCA element types "group" and "select" for database records. Manages MM-relations as well.
  71   *
  72   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
  73   * @package TYPO3
  74   * @subpackage t3lib
  75   */
  76  class t3lib_loadDBGroup    {
  77          // External, static:
  78      var $fromTC = 1;                    // Means that only uid and the label-field is returned
  79      var $registerNonTableValues=0;        // If set, values that are not ids in tables are normally discarded. By this options they will be preserved.
  80  
  81          // Internal, dynamic:
  82      var $tableArray=Array();            // Contains the table names as keys. The values are the id-values for each table. Should ONLY contain proper table names.
  83      var $itemArray=Array();                // Contains items in an numeric array (table/id for each). Tablenames here might be "_NO_TABLE"
  84      var $nonTableArray=array();            // Array for NON-table elements
  85      var $additionalWhere=array();
  86      var $checkIfDeleted = 1;            // deleted-column is added to additionalWhere... if this is set...
  87      var $dbPaths=Array();
  88      var $firstTable = '';                // Will contain the first table name in the $tablelist (for positive ids)
  89      var $secondTable = '';                // Will contain the second table name in the $tablelist (for negative ids)
  90          // private
  91      var $MM_is_foreign = 0;        // boolean - if 1, uid_local and uid_foreign are switched, and the current table is inserted as tablename - this means you display a foreign relation "from the opposite side"
  92      var $MM_oppositeField = '';    // field name at the "local" side of the MM relation
  93      var $MM_oppositeTable = ''; // only set if MM_is_foreign is set
  94      var $MM_oppositeFieldConf = ''; // only set if MM_is_foreign is set
  95      var $MM_isMultiTableRelationship = 0;    // is empty by default; if MM_is_foreign is set and there is more than one table allowed (on the "local" side), then it contains the first table (as a fallback)
  96      var $currentTable;    // current table => Only needed for reverse relations
  97      var $undeleteRecord;        // if a record should be undeleted (so do not use the $useDeleteClause on t3lib_BEfunc)
  98  
  99  
 100      var $MM_match_fields = array();    // array of fields value pairs that should match while SELECT and will be written into MM table if $MM_insert_fields is not set
 101      var $MM_insert_fields = array();    // array of fields and value pairs used for insert in MM table
 102      var $MM_table_where = ''; // extra MM table where
 103  
 104  
 105      /**
 106       * Initialization of the class.
 107       *
 108       * @param    string        List of group/select items
 109       * @param    string        Comma list of tables, first table takes priority if no table is set for an entry in the list.
 110       * @param    string        Name of a MM table.
 111       * @param    integer        Local UID for MM lookup
 112       * @param    string        current table name
 113       * @param    integer        TCA configuration for current field
 114       * @return    void
 115       */
 116  	function start($itemlist, $tablelist, $MMtable='', $MMuid=0, $currentTable='', $conf=array())    {
 117              // SECTION: MM reverse relations
 118          $this->MM_is_foreign = ($conf['MM_opposite_field']?1:0);
 119          $this->MM_oppositeField = $conf['MM_opposite_field'];
 120          $this->MM_table_where = $conf['MM_table_where'];
 121          $this->MM_match_fields = is_array($conf['MM_match_fields']) ? $conf['MM_match_fields'] : array();
 122          $this->MM_insert_fields = is_array($conf['MM_insert_fields']) ? $conf['MM_insert_fields'] : $this->MM_match_fields;
 123          
 124          $this->currentTable = $currentTable;
 125          if ($this->MM_is_foreign)    {
 126              $tmp = ($conf['type']==='group'?$conf['allowed']:$conf['foreign_table']);
 127                  // normally, $conf['allowed'] can contain a list of tables, but as we are looking at a MM relation from the foreign side, it only makes sense to allow one one table in $conf['allowed']
 128              $tmp = t3lib_div::trimExplode(',', $tmp);
 129              $this->MM_oppositeTable = $tmp[0];
 130              unset($tmp);
 131  
 132                  // only add the current table name if there is more than one allowed field
 133              $this->MM_oppositeFieldConf = $GLOBALS['TCA'][$this->MM_oppositeTable]['columns'][$this->MM_oppositeField]['config'];
 134  
 135              if ($this->MM_oppositeFieldConf['allowed'])    {
 136                  $oppositeFieldConf_allowed = explode(',', $this->MM_oppositeFieldConf['allowed']);
 137                  if (count($oppositeFieldConf_allowed) > 1)    {
 138                      $this->MM_isMultiTableRelationship = $oppositeFieldConf_allowed[0];
 139                  }
 140              }
 141          }
 142  
 143              // SECTION:    normal MM relations
 144  
 145              // If the table list is "*" then all tables are used in the list:
 146          if (!strcmp(trim($tablelist),'*'))    {
 147              $tablelist = implode(',',array_keys($GLOBALS['TCA']));
 148          }
 149  
 150              // The tables are traversed and internal arrays are initialized:
 151          $tempTableArray = t3lib_div::trimExplode(',',$tablelist,1);
 152          foreach($tempTableArray as $key => $val)    {
 153              $tName = trim($val);
 154              $this->tableArray[$tName] = Array();
 155              if ($this->checkIfDeleted && $GLOBALS['TCA'][$tName]['ctrl']['delete'])    {
 156                  $fieldN = $tName.'.'.$GLOBALS['TCA'][$tName]['ctrl']['delete'];
 157                  $this->additionalWhere[$tName].=' AND '.$fieldN.'=0';
 158              }
 159          }
 160  
 161          if (is_array($this->tableArray))    {
 162              reset($this->tableArray);
 163          } else {return 'No tables!';}
 164  
 165              // Set first and second tables:
 166          $this->firstTable = key($this->tableArray);        // Is the first table
 167          next($this->tableArray);
 168          $this->secondTable = key($this->tableArray);    // If the second table is set and the ID number is less than zero (later) then the record is regarded to come from the second table...
 169  
 170              // Now, populate the internal itemArray and tableArray arrays:
 171          if ($MMtable)    {    // If MM, then call this function to do that:
 172              $this->readMM($MMtable,$MMuid);
 173          } elseif ($MMuid && $conf['foreign_field']) {
 174                  // If not MM but foreign_field, the read the records by the foreign_field
 175              $this->readForeignField($MMuid, $conf);
 176          } else {
 177                  // If not MM, then explode the itemlist by "," and traverse the list:
 178              $this->readList($itemlist);
 179                  // do automatic default_sortby, if any
 180              if ($conf['foreign_default_sortby']) {
 181                  $this->sortList($conf['foreign_default_sortby']);
 182              }
 183          }
 184      }
 185  
 186      /**
 187       * Explodes the item list and stores the parts in the internal arrays itemArray and tableArray from MM records.
 188       *
 189       * @param    string        Item list
 190       * @return    void
 191       */
 192  	function readList($itemlist)    {
 193          if ((string)trim($itemlist)!='')    {
 194              $tempItemArray = t3lib_div::trimExplode(',', $itemlist);    // Changed to trimExplode 31/3 04; HMENU special type "list" didn't work if there were spaces in the list... I suppose this is better overall...
 195              foreach($tempItemArray as $key => $val)    {
 196                  $isSet = 0;    // Will be set to "1" if the entry was a real table/id:
 197  
 198                      // Extract table name and id. This is un the formular [tablename]_[id] where table name MIGHT contain "_", hence the reversion of the string!
 199                  $val = strrev($val);
 200                  $parts = explode('_',$val,2);
 201                  $theID = strrev($parts[0]);
 202  
 203                      // Check that the id IS an integer:
 204                  if (t3lib_div::testInt($theID))    {
 205                          // Get the table name: If a part of the exploded string, use that. Otherwise if the id number is LESS than zero, use the second table, otherwise the first table
 206                      $theTable = trim($parts[1]) ? strrev(trim($parts[1])) : ($this->secondTable && $theID<0 ? $this->secondTable : $this->firstTable);
 207                          // If the ID is not blank and the table name is among the names in the inputted tableList, then proceed:
 208                      if ((string)$theID!='' && $theID && $theTable && isset($this->tableArray[$theTable]))    {
 209                              // Get ID as the right value:
 210                          $theID = $this->secondTable ? abs(intval($theID)) : intval($theID);
 211                              // Register ID/table name in internal arrays:
 212                          $this->itemArray[$key]['id'] = $theID;
 213                          $this->itemArray[$key]['table'] = $theTable;
 214                          $this->tableArray[$theTable][] = $theID;
 215                              // Set update-flag:
 216                          $isSet=1;
 217                      }
 218                  }
 219  
 220                      // If it turns out that the value from the list was NOT a valid reference to a table-record, then we might still set it as a NO_TABLE value:
 221                  if (!$isSet && $this->registerNonTableValues)    {
 222                      $this->itemArray[$key]['id'] = $tempItemArray[$key];
 223                      $this->itemArray[$key]['table'] = '_NO_TABLE';
 224                      $this->nonTableArray[] = $tempItemArray[$key];
 225                  }
 226              }
 227          }
 228      }
 229  
 230      /**
 231       * Does a sorting on $this->itemArray depending on a default sortby field.
 232       * This is only used for automatic sorting of comma separated lists.
 233       * This function is only relevant for data that is stored in comma separated lists!
 234       * 
 235       * @param    string        $sortby: The default_sortby field/command (e.g. 'price DESC')
 236       * @return    void
 237       */
 238  	function sortList($sortby) {
 239              // sort directly without fetching addional data
 240          if ($sortby == 'uid') {
 241              usort($this->itemArray, create_function('$a,$b', 'return $a["id"] < $b["id"] ? -1 : 1;'));
 242              // only useful if working on the same table
 243          } elseif (count($this->tableArray) == 1) {
 244              reset($this->tableArray);
 245              $table = key($this->tableArray);
 246              $uidList = implode(',', current($this->tableArray));
 247  
 248              if ($uidList) {
 249                  $this->itemArray = array();
 250                  $this->tableArray = array();
 251                  
 252                  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'uid IN ('.$uidList.')', '', $sortby);
 253                  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
 254                      $this->itemArray[] = array('id' => $row['uid'], 'table' => $table);
 255                      $this->tableArray[$table][] = $row['uid'];
 256                  }
 257                  $GLOBALS['TYPO3_DB']->sql_free_result($res);
 258              }
 259          }
 260      }
 261  
 262      /**
 263       * Reads the record tablename/id into the internal arrays itemArray and tableArray from MM records.
 264       * You can call this function after start if you supply no list to start()
 265       *
 266       * @param    string        MM Tablename
 267       * @param    integer        Local UID
 268       * @return    void
 269       */
 270  	function readMM($tableName,$uid)    {
 271          $key=0;
 272          $additionalWhere = '';
 273          
 274          if ($this->MM_is_foreign)    {    // in case of a reverse relation
 275              $uidLocal_field = 'uid_foreign';
 276              $uidForeign_field = 'uid_local';
 277              $sorting_field = 'sorting_foreign';
 278  
 279              if ($this->MM_isMultiTableRelationship)    {
 280                  $additionalWhere .= ' AND ( tablenames="'.$this->currentTable.'"';
 281                  if ($this->currentTable == $this->MM_isMultiTableRelationship)    {    // be backwards compatible! When allowing more than one table after having previously allowed only one table, this case applies.
 282                      $additionalWhere .= ' OR tablenames=""';
 283                  }
 284                  $additionalWhere .= ' ) ';
 285              }
 286              $theTable = $this->MM_oppositeTable;
 287          } else {    // default
 288              $uidLocal_field = 'uid_local';
 289              $uidForeign_field = 'uid_foreign';
 290              $sorting_field = 'sorting';
 291          }
 292  
 293  
 294          if ($this->MM_table_where) {
 295              $additionalWhere.= "\n".str_replace('###THIS_UID###', intval($uid), $this->MM_table_where);
 296          }
 297          foreach ($this->MM_match_fields as $field => $value) {
 298              $additionalWhere.= ' AND '.$field.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($value, $tableName);
 299          }
 300          
 301              // Select all MM relations:
 302          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $tableName, $uidLocal_field.'='.intval($uid).$additionalWhere, '', $sorting_field);
 303          while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 304              if (!$this->MM_is_foreign) {    // default
 305                  $theTable = $row['tablenames'] ? $row['tablenames'] : $this->firstTable;        // If tablesnames columns exists and contain a name, then this value is the table, else it's the firstTable...
 306              }
 307              if (($row[$uidForeign_field] || $theTable=='pages') && $theTable && isset($this->tableArray[$theTable]))    {
 308  
 309                  $this->itemArray[$key]['id'] = $row[$uidForeign_field];
 310                  $this->itemArray[$key]['table'] = $theTable;
 311                  $this->tableArray[$theTable][]= $row[$uidForeign_field];
 312              } elseif ($this->registerNonTableValues)    {
 313                  $this->itemArray[$key]['id'] = $row[$uidForeign_field];
 314                  $this->itemArray[$key]['table'] = '_NO_TABLE';
 315                  $this->nonTableArray[] = $row[$uidForeign_field];
 316              }
 317              $key++;
 318          }
 319          $GLOBALS['TYPO3_DB']->sql_free_result($res);
 320      }
 321  
 322      /**
 323       * Writes the internal itemArray to MM table:
 324       *
 325       * @param    string        MM table name
 326       * @param    integer        Local UID
 327       * @param    boolean        If set, then table names will always be written.
 328       * @return    void
 329       */
 330  	function writeMM($tableName,$uid,$prependTableName=0)    {
 331  
 332          if ($this->MM_is_foreign)    {    // in case of a reverse relation
 333              $uidLocal_field = 'uid_foreign';
 334              $uidForeign_field = 'uid_local';
 335              $sorting_field = 'sorting_foreign';
 336          } else {    // default
 337              $uidLocal_field = 'uid_local';
 338              $uidForeign_field = 'uid_foreign';
 339              $sorting_field = 'sorting';
 340          }
 341  
 342              // If there are tables...
 343          $tableC = count($this->tableArray);
 344          if ($tableC)    {
 345              $prep = ($tableC>1||$prependTableName||$this->MM_isMultiTableRelationship) ? 1 : 0;    // boolean: does the field "tablename" need to be filled?
 346              $c=0;
 347  
 348              $additionalWhere_tablenames = '';
 349              if ($this->MM_is_foreign && $prep)    {
 350                  $additionalWhere_tablenames = ' AND tablenames="'.$this->currentTable.'"';
 351              }
 352  
 353              $additionalWhere = '';
 354                  // add WHERE clause if configured
 355              if ($this->MM_table_where) {
 356                  $additionalWhere.= "\n".str_replace('###THIS_UID###', intval($uid), $this->MM_table_where);
 357              }
 358                  // Select, update or delete only those relations that match the configured fields
 359              foreach ($this->MM_match_fields as $field => $value) {
 360                  $additionalWhere.= ' AND '.$field.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($value, $tableName);
 361              }
 362  
 363              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($uidForeign_field.($prep?', tablenames':''), $tableName, $uidLocal_field.'='.$uid.$additionalWhere_tablenames.$additionalWhere);
 364  
 365              $oldMMs = array();
 366              while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
 367                  if (!$this->MM_is_foreign && $prep)    {
 368                      $oldMMs[] = array($row['tablenames'], $row[$uidForeign_field]);
 369                  } else {
 370                      $oldMMs[] = $row[$uidForeign_field];
 371                  }
 372              }
 373  
 374                  // For each item, insert it:
 375              foreach($this->itemArray as $val)    {
 376                  $c++;
 377  
 378                  if ($prep || $val['table']=='_NO_TABLE')    {
 379                      if ($this->MM_is_foreign)    {    // insert current table if needed
 380                          $tablename = $this->currentTable;
 381                      } else {
 382                          $tablename = $val['table'];
 383                      }
 384                  } else {
 385                      $tablename = '';
 386                  }
 387  
 388                  if(!$this->MM_is_foreign && $prep) {
 389                      $item = array($val['table'], $val['id']);
 390                  } else {
 391                      $item = $val['id'];
 392                  }
 393  
 394                  if (in_array($item, $oldMMs))    {
 395                      unset($oldMMs[array_search($item, $oldMMs)]);    // remove the item from the $oldMMs array so after this foreach loop only the ones that need to be deleted are in there.
 396  
 397                      $whereClause = $uidLocal_field.'='.$uid.' AND '.$uidForeign_field.'='.$val['id'];
 398                      if ($tablename) {
 399                          $whereClause .= ' AND tablenames="'.$tablename.'"';
 400                      }
 401                      $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tableName, $whereClause.$additionalWhere, array($sorting_field => $c));
 402                  } else {
 403  
 404                      $insertFields = $this->MM_insert_fields;
 405                      $insertFields[$uidLocal_field] = $uid;
 406                      $insertFields[$uidForeign_field] = $val['id'];
 407                      $insertFields[$sorting_field] = $c;
 408                      if($tablename)    {
 409                          $insertFields['tablenames'] = $tablename;
 410                      }
 411  
 412                      $GLOBALS['TYPO3_DB']->exec_INSERTquery($tableName, $insertFields);
 413                  }
 414              }
 415  
 416                  // Delete all not-used relations:
 417              if(is_array($oldMMs) && count($oldMMs) > 0) {
 418                  $removeClauses = array();
 419                  foreach($oldMMs as $mmItem) {
 420                      if(is_array($mmItem)) {
 421                          $removeClauses[] = 'tablenames="'.$mmItem[0].'" AND '.$uidForeign_field.'='.$mmItem[1];
 422                      } else {
 423                          $removeClauses[] = $uidForeign_field.'='.$mmItem;
 424                      }
 425                  }
 426                  $deleteAddWhere = ' AND ('.implode(' OR ', $removeClauses).')';
 427                  $GLOBALS['TYPO3_DB']->exec_DELETEquery($tableName, $uidLocal_field.'='.intval($uid).$deleteAddWhere.$additionalWhere_tablenames.$additionalWhere);
 428              }
 429          }
 430      }
 431  
 432      /**
 433       * Reads items from a foreign_table, that has a foreign_field (uid of the parent record) and
 434       * stores the parts in the internal array itemArray and tableArray.
 435       *
 436       * @param    integer        $uid: The uid of the parent record (this value is also on the foreign_table in the foreign_field)
 437       * @param    array        $conf: TCA configuration for current field
 438       * @return    void
 439       */
 440  	function readForeignField($uid, $conf) {
 441          $key = 0;
 442          $uid = intval($uid);
 443          $whereClause = '';
 444          $foreign_table = $conf['foreign_table'];
 445          $foreign_table_field = $conf['foreign_table_field'];
 446          $useDeleteClause = $this->undeleteRecord ? false : true;
 447  
 448              // search for $uid in foreign_field, and if we have symmetric relations, do this also on symmetric_field
 449          if ($conf['symmetric_field']) {
 450              $whereClause = '('.$conf['foreign_field'].'='.$uid.' OR '.$conf['symmetric_field'].'='.$uid.')';
 451          } else {
 452              $whereClause = $conf['foreign_field'].'='.$uid;
 453          }
 454              // use the deleteClause (e.g. "deleted=0") on this table
 455          if ($useDeleteClause) {
 456              $whereClause .= t3lib_BEfunc::deleteClause($foreign_table);
 457          }
 458              // if it's requested to look for the parent uid AND the parent table,
 459              // add an additional SQL-WHERE clause
 460          if ($foreign_table_field && $this->currentTable) {
 461              $whereClause .= ' AND '.$foreign_table_field.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->currentTable, $foreign_table);
 462          }
 463          
 464              // get the correct sorting field
 465          if ($conf['foreign_sortby']) {                                            // specific manual sortby for data handled by this field
 466              if ($conf['symmetric_sortby'] && $conf['symmetric_field']) {
 467                      // sorting depends on, from which side of the relation we're looking at it
 468                  $sortby = '
 469                      CASE
 470                          WHEN '.$conf['foreign_field'].'='.$uid.'
 471                          THEN '.$conf['foreign_sortby'].'
 472                          ELSE '.$conf['symmetric_sortby'].'
 473                      END';
 474              } else {
 475                      // regular single-side behaviour
 476                  $sortby = $conf['foreign_sortby'];
 477              }
 478          } elseif ($conf['foreign_default_sortby']) {                            // specific default sortby for data handled by this field
 479              $sortby = $conf['foreign_default_sortby'];
 480          } elseif ($GLOBALS['TCA'][$foreign_table]['ctrl']['sortby']) {            // manual sortby for all table records
 481              $sortby = $GLOBALS['TCA'][$foreign_table]['ctrl']['sortby'];
 482          } elseif ($GLOBALS['TCA'][$foreign_table]['ctrl']['default_sortby']) {    // default sortby for all table records
 483              $sortby = $GLOBALS['TCA'][$foreign_table]['ctrl']['default_sortby'];
 484          }
 485  
 486              // strip a possible "ORDER BY" in front of the $sortby value
 487          $sortby = $GLOBALS['TYPO3_DB']->stripOrderBy($sortby);
 488              // get the rows from storage
 489          $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $foreign_table, $whereClause, '', $sortby);
 490  
 491          if (count($rows)) {
 492              foreach ($rows as $row) {
 493                  $this->itemArray[$key]['id'] = $row['uid'];
 494                  $this->itemArray[$key]['table'] = $foreign_table;
 495                  $this->tableArray[$foreign_table][]= $row['uid'];
 496                  $key++;
 497              }
 498          }
 499      }
 500  
 501      /**
 502       * Write the sorting values to a foreign_table, that has a foreign_field (uid of the parent record)
 503       *
 504       * @param    array        $conf: TCA configuration for current field
 505       * @param    integer        $parentUid: The uid of the parent record
 506       * @param    boolean        $updateForeignField: Whether to update the foreign field with the $parentUid (on Copy)
 507       * @param     boolean        $skipSorting: Do not update the sorting columns, this could happen for imported values
 508       * @return    void
 509       */
 510  	function writeForeignField($conf, $parentUid, $updateToUid=0, $skipSorting=false) {
 511          $c = 0;
 512          $foreign_table = $conf['foreign_table'];
 513          $foreign_field = $conf['foreign_field'];
 514          $symmetric_field = $conf['symmetric_field'];
 515          $foreign_table_field = $conf['foreign_table_field'];
 516  
 517              // if there are table items and we have a proper $parentUid
 518          if (t3lib_div::testInt($parentUid) && count($this->tableArray)) {
 519                  // if updateToUid is not a positive integer, set it to '0', so it will be ignored
 520              if (!(t3lib_div::testInt($updateToUid) && $updateToUid > 0)) $updateToUid = 0;
 521              $fields = 'uid,'.$foreign_field.($symmetric_field ? ','.$symmetric_field : '');
 522  
 523                  // update all items
 524              foreach ($this->itemArray as $val) {
 525                  $uid = $val['id'];
 526                  $table = $val['table'];
 527  
 528                      // fetch the current (not overwritten) relation record if we should handle symmetric relations
 529                  if ($conf['symmetric_field']) {
 530                      $row = t3lib_BEfunc::getRecord($table,$uid,$fields,'',false);
 531                      $isOnSymmetricSide = t3lib_loadDBGroup::isOnSymmetricSide($parentUid, $conf, $row);
 532                  }
 533  
 534                  $updateValues = array();
 535  
 536                      // no update to the uid is requested, so this is the normal behaviour
 537                      // just update the fields and care about sorting
 538                  if (!$updateToUid) {
 539                          // Always add the pointer to the parent uid
 540                      if ($isOnSymmetricSide) {
 541                          $updateValues[$symmetric_field] = $parentUid;
 542                      } else {
 543                          $updateValues[$foreign_field] = $parentUid;
 544                      }
 545                      
 546                          // if it is configured in TCA also to store the parent table in the child record, just do it
 547                      if ($foreign_table_field && $this->currentTable) {
 548                          $updateValues[$foreign_table_field] = $this->currentTable;
 549                      }
 550  
 551                          // update sorting columns if not to be skipped
 552                      if (!$skipSorting) {
 553                              // get the correct sorting field
 554                          if ($conf['foreign_sortby']) {                                    // specific manual sortby for data handled by this field 
 555                              $sortby = $conf['foreign_sortby'];
 556                          } elseif ($GLOBALS['TCA'][$foreign_table]['ctrl']['sortby']) {    // manual sortby for all table records
 557                              $sortby = $GLOBALS['TCA'][$foreign_table]['ctrl']['sortby'];
 558                          }
 559                              // strip a possible "ORDER BY" in front of the $sortby value
 560                          $sortby = $GLOBALS['TYPO3_DB']->stripOrderBy($sortby);
 561                          $symSortby = $conf['symmetric_sortby'];
 562      
 563                              // set the sorting on the right side, it depends on who created the relation, so what uid is in the symmetric_field
 564                          if ($isOnSymmetricSide && $symSortby) {
 565                              $updateValues[$symSortby] = ++$c;
 566                          } elseif ($sortby) {
 567                              $updateValues[$sortby] = ++$c;
 568                          }
 569                      }
 570  
 571                      // update to a foreign_field/symmetric_field pointer is requested, normally used on record copies
 572                      // only update the fields, if the old uid is found somewhere - for select fields, TCEmain is doing this already!
 573                  } else {
 574                      if ($isOnSymmetricSide) {
 575                          $updateValues[$symmetric_field] = $updateToUid;
 576                      } else {
 577                          $updateValues[$foreign_field] = $updateToUid;
 578                      }
 579                  }
 580  
 581                  if (count($updateValues)) {
 582                      $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, "uid='$uid'", $updateValues);
 583                      $this->updateRefIndex($table, $uid);
 584                  }
 585              }
 586          }
 587      }
 588  
 589      /**
 590       * After initialization you can extract an array of the elements from the object. Use this function for that.
 591       *
 592       * @param    boolean        If set, then table names will ALWAYS be prepended (unless its a _NO_TABLE value)
 593       * @return    array        A numeric array.
 594       */
 595  	function getValueArray($prependTableName='')    {
 596              // INIT:
 597          $valueArray=Array();
 598          $tableC = count($this->tableArray);
 599  
 600              // If there are tables in the table array:
 601          if ($tableC)    {
 602                  // If there are more than ONE table in the table array, then always prepend table names:
 603              $prep = ($tableC>1||$prependTableName) ? 1 : 0;
 604  
 605                  // Traverse the array of items:
 606              foreach($this->itemArray as $val)    {
 607                  $valueArray[]=(($prep && $val['table']!='_NO_TABLE') ? $val['table'].'_' : '').
 608                                      $val['id'];
 609              }
 610          }
 611              // Return the array
 612          return $valueArray;
 613      }
 614  
 615      /**
 616       * Converts id numbers from negative to positive.
 617       *
 618       * @param    array        Array of [table]_[id] pairs.
 619       * @param    string        Foreign table (the one used for positive numbers)
 620       * @param    string        NEGative foreign table
 621       * @return    array        The array with ID integer values, converted to positive for those where the table name was set but did NOT match the positive foreign table.
 622       */
 623  	function convertPosNeg($valueArray,$fTable,$nfTable)    {
 624          if (is_array($valueArray) && $fTable)    {
 625              foreach($valueArray as $key => $val)    {
 626                  $val = strrev($val);
 627                  $parts = explode('_',$val,2);
 628                  $theID = strrev($parts[0]);
 629                  $theTable = strrev($parts[1]);
 630  
 631                  if ( t3lib_div::testInt($theID) && (!$theTable || !strcmp($theTable,$fTable) || !strcmp($theTable,$nfTable)) )    {
 632                      $valueArray[$key]= $theTable && strcmp($theTable,$fTable) ? $theID*-1 : $theID;
 633                  }
 634              }
 635          }
 636          return $valueArray;
 637      }
 638  
 639      /**
 640       * Reads all records from internal tableArray into the internal ->results array where keys are table names and for each table, records are stored with uids as their keys.
 641       * If $this->fromTC is set you can save a little memory since only uid,pid and a few other fields are selected.
 642       *
 643       * @return    void
 644       */
 645  	function getFromDB()    {
 646              // Traverses the tables listed:
 647          foreach($this->tableArray as $key => $val)    {
 648              if (is_array($val))    {
 649                  $itemList = implode(',',$val);
 650                  if ($itemList)    {
 651                      $from = '*';
 652                      if ($this->fromTC)    {
 653                          $from = 'uid,pid';
 654                          if ($GLOBALS['TCA'][$key]['ctrl']['label'])    {
 655                              $from.= ','.$GLOBALS['TCA'][$key]['ctrl']['label'];    // Titel
 656                          }
 657                          if ($GLOBALS['TCA'][$key]['ctrl']['label_alt'])    {
 658                              $from.= ','.$GLOBALS['TCA'][$key]['ctrl']['label_alt']; // Alternative Title-Fields
 659                          }
 660                          if ($GLOBALS['TCA'][$key]['ctrl']['thumbnail'])    {
 661                              $from.= ','.$GLOBALS['TCA'][$key]['ctrl']['thumbnail'];    // Thumbnail
 662                          }
 663                      }
 664                      $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($from, $key, 'uid IN ('.$itemList.')'.$this->additionalWhere[$key]);
 665                      while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 666                          $this->results[$key][$row['uid']]=$row;
 667                      }
 668                  }
 669              }
 670          }
 671          return $this->results;
 672      }
 673  
 674      /**
 675       * Prepare items from itemArray to be transferred to the TCEforms interface (as a comma list)
 676       *
 677       * @return    string
 678       * @see t3lib_transferdata::renderRecord()
 679       */
 680  	function readyForInterface()    {
 681          global $TCA;
 682  
 683          if (!is_array($this->itemArray))    {return false;}
 684  
 685          $output=array();
 686          $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);        // For use when getting the paths....
 687          $titleLen=intval($GLOBALS['BE_USER']->uc['titleLen']);
 688  
 689          foreach($this->itemArray as $key => $val)    {
 690              $theRow = $this->results[$val['table']][$val['id']];
 691              if ($theRow && is_array($TCA[$val['table']]))    {
 692                  $label = t3lib_div::fixed_lgd_cs(strip_tags(t3lib_BEfunc::getRecordTitle($val['table'], $theRow)),$titleLen);
 693                  $label = ($label)?$label:'[...]';
 694                  $output[]=str_replace(',','',$val['table'].'_'.$val['id'].'|'.rawurlencode($label));
 695              }
 696          }
 697          return implode(',',$output);
 698      }
 699  
 700      /**
 701       * Counts the items in $this->itemArray and puts this value in an array by default.
 702       *
 703       * @param    boolean        Whether to put the count value in an array
 704       * @return    mixed        The plain count as integer or the same inside an array
 705       */
 706  	function countItems($returnAsArray = true) {
 707          $count = count($this->itemArray);
 708          if ($returnAsArray) $count = array($count);
 709          return $count;
 710      }
 711  
 712      /**
 713       * Update Reference Index (sys_refindex) for a record
 714       * Should be called any almost any update to a record which could affect references inside the record.
 715       * (copied from TCEmain)
 716       *
 717       * @param    string        Table name
 718       * @param    integer        Record UID
 719       * @return    void
 720       */
 721  	function updateRefIndex($table,$id)    {
 722          $refIndexObj = t3lib_div::makeInstance('t3lib_refindex');
 723          $result = $refIndexObj->updateRefIndexTable($table,$id);
 724      }
 725  
 726      /**
 727       * Checks, if we're looking from the "other" side, the symmetric side, to a symmetric relation.
 728       *
 729       * @param    string        $parentUid: The uid of the parent record
 730       * @param    array        $parentConf: The TCA configuration of the parent field embedding the child records
 731       * @param    array        $childRec: The record row of the child record
 732       * @return    boolean        Returns true if looking from the symmetric ("other") side to the relation.
 733       */
 734  	function isOnSymmetricSide($parentUid, $parentConf, $childRec) {
 735          return t3lib_div::testInt($childRec['uid']) && $parentConf['symmetric_field'] && $parentUid == $childRec[$parentConf['symmetric_field']]
 736              ? true
 737              : false;
 738      }
 739  }
 740  
 741  
 742  if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_loaddbgroup.php'])    {
 743      include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_loaddbgroup.php']);
 744  }
 745  ?>


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