| [ Index ] |
|
Code source de Typo3 4.1.3 |
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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Nov 25 17:13:16 2007 | par Balluche grâce à PHPXref 0.7 |
|