[BUGFIX] Show correct record title
[Packages/TYPO3.CMS.git] / typo3 / class.db_list_extra.inc
1 <?php
2 /*************************************************************
3 *  Copyright notice
4 *
5 *  (c) 1999-2009 Kasper Skårhøj (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  * Include file extending recordList which extended t3lib_recordList
29  * Used specifically for the Web>List module (db_list.php)
30  *
31  * Revised for TYPO3 3.6 December/2003 by Kasper Skårhøj
32  * XHTML compliant
33  *
34  * @author      Kasper Skårhøj <kasperYYYY@typo3.com>
35  */
36 /**
37  * [CLASS/FUNCTION INDEX of SCRIPT]
38  *
39  *
40  *
41  *   91: class localRecordList extends recordList
42  *  123:     function writeTop($row)
43  *  304:     function getTable($table,$id,$rowlist)
44  *  559:     function renderListRow($table,$row,$cc,$titleCol,$thumbsCol,$indent=0)
45  *  648:     function renderListHeader($table,$currentIdList)
46  *
47  *              SECTION: Rendering of various elements
48  *  796:     function makeControl($table,$row)
49  *  986:     function makeClip($table,$row)
50  * 1057:     function makeRef($table,$uid)
51  * 1086:     function makeLocalizationPanel($table,$row)
52  * 1148:     function fieldSelectBox($table,$formFields=1)
53  *
54  *              SECTION: Helper functions
55  * 1231:     function linkClipboardHeaderIcon($string,$table,$cmd,$warning='')
56  * 1242:     function clipNumPane()
57  * 1256:     function addSortLink($code,$field,$table)
58  * 1281:     function recPath($pid)
59  * 1294:     function showNewRecLink($table)
60  * 1304:     function makeReturnUrl()
61  *
62  *              SECTION: CSV related functions
63  * 1329:     function initCSV()
64  * 1352:     function addToCSV($row,$table)
65  * 1376:     function setCsvRow($csvRow)
66  * 1387:     function outputCSV($prefix)
67  *
68  * TOTAL FUNCTIONS: 19
69  * (This index is automatically created/updated by the extension "extdeveval")
70  *
71  */
72
73
74
75
76
77
78
79
80
81
82 /**
83  * Class for rendering of Web>List module
84  *
85  * @author      Kasper Skårhøj <kasperYYYY@typo3.com>
86  * @package TYPO3
87  * @subpackage core
88  */
89 class localRecordList extends recordList {
90
91                 // External:
92         var $alternateBgColors=FALSE;                   // If TRUE, table rows in the list will alternate in background colors (and have background colors at all!)
93         var $allowedNewTables=array();                  // Used to indicate which tables (values in the array) that can have a create-new-record link. If the array is empty, all tables are allowed.
94         var $deniedNewTables=array();                   // Used to indicate which tables (values in the array) that cannot have a create-new-record link. If the array is empty, all tables are allowed.
95         var $newWizards=FALSE;                                  // If TRUE, the control panel will contain links to the create-new wizards for pages and tt_content elements (normally, the link goes to just creating a new element without the wizards!).
96
97         var $dontShowClipControlPanels=FALSE;   // If TRUE, will disable the rendering of clipboard + control panels.
98         var $showClipboard=FALSE;                               // If TRUE, will show the clipboard in the field list.
99         var $noControlPanels = FALSE;                   // If TRUE, will DISABLE all control panels in lists. (Takes precedence)
100         var $clickMenuEnabled = TRUE;                   // If TRUE, clickmenus will be rendered
101
102         var $totalRowCount;                                             // count of record rows in view
103
104         var $spaceIcon;                                                 // space icon used for alignment
105
106                 // Internal:
107         var $pageRow=array();                                   // Set to the page record (see writeTop())
108
109                 // Used to accumulate CSV lines for CSV export.
110         protected $csvLines = array();
111
112         var $csvOutput=FALSE;                                   // If set, the listing is returned as CSV instead.
113
114         /**
115          * Clipboard object
116          *
117          * @var t3lib_clipboard
118          */
119         var $clipObj;
120         var $CBnames=array();                                   // Tracking names of elements (for clipboard use)
121         var $duplicateStack=array();                    // Used to track which elements has duplicates and how many
122
123         /**
124          * references of the current record
125          *
126          * @var array
127          *
128          * @deprecated since 4.4: Use getReferenceCount instead
129          */
130         public $references;
131
132         /**
133          * [$tablename][$uid] = number of references to this record
134          *
135          * @var array
136          */
137         protected $referenceCount = array();
138
139         var $translations;                                              // Translations of the current record
140         var $selFieldList;                                              // select fields for the query which fetches the translations of the current record
141
142         public function __construct() {
143                 parent::__construct();
144         }
145
146         /**
147          * Create the panel of buttons for submitting the form or otherwise perform operations.
148          *
149          * @return      array   all available buttons as an assoc. array
150          */
151         public function getButtons()    {
152                 $buttons = array(
153                         'csh' => '',
154                         'view' => '',
155                         'edit' => '',
156                         'hide_unhide' => '',
157                         'move' => '',
158                         'new_record' => '',
159                         'paste' => '',
160                         'level_up' => '',
161                         'cache' => '',
162                         'reload' => '',
163                         'shortcut' => '',
164                         'back' => '',
165                         'csv' => '',
166                         'export' => ''
167                 );
168
169                         // Get users permissions for this page record:
170                 $localCalcPerms = $GLOBALS['BE_USER']->calcPerms($this->pageRow);
171
172                         // CSH
173                 if (!strlen($this->id)) {
174                         $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module_noId', $GLOBALS['BACK_PATH'], '', TRUE);
175                 } elseif(!$this->id) {
176                         $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module_root', $GLOBALS['BACK_PATH'], '', TRUE);
177                 } else {
178                         $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module', $GLOBALS['BACK_PATH'], '', TRUE);
179                 }
180
181                 if (isset($this->id)) {
182                                 // View  Exclude doktypes 254,255 Configuration: mod.web_list.noViewWithDokTypes = 254,255
183                         if (isset($GLOBALS['SOBE']->modTSconfig['properties']['noViewWithDokTypes'])) {
184                                 $noViewDokTypes = t3lib_div::trimExplode(',', $GLOBALS['SOBE']->modTSconfig['properties']['noViewWithDokTypes'], TRUE);
185                         } else {
186                                         //default exclusion: doktype 254 (folder), 255 (recycler)
187                                 $noViewDokTypes = array(t3lib_pageSelect::DOKTYPE_SYSFOLDER, t3lib_pageSelect::DOKTYPE_RECYCLER);
188                         }
189
190                         if (!in_array($this->pageRow['doktype'], $noViewDokTypes)) {
191                                 $buttons['view'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::viewOnClick($this->id, $this->backPath, t3lib_BEfunc::BEgetRootLine($this->id))) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showPage', TRUE) . '">' .
192                                                                 t3lib_iconWorks::getSpriteIcon('actions-document-view') .
193                                                         '</a>';
194                         }
195
196                                 // New record
197                         if (!$GLOBALS['SOBE']->modTSconfig['properties']['noCreateRecordsLink']) {
198                                 $buttons['new_record'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'db_new.php?id=' . $this->id . '\');') . '" title="' . $GLOBALS['LANG']->getLL('newRecordGeneral', TRUE) . '">' .
199                                                                         t3lib_iconWorks::getSpriteIcon('actions-document-new') .
200                                                                 '</a>';
201                         }
202
203                                 // If edit permissions are set (see class.t3lib_userauthgroup.php)
204                         if ($localCalcPerms&2 && !empty($this->id))     {
205
206                                         // Edit
207                                 $params = '&edit[pages][' . $this->pageRow['uid'] . ']=edit';
208                                 $buttons['edit'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath, -1)) . '" title="' . $GLOBALS['LANG']->getLL('editPage', TRUE) . '">' .
209                                                                         t3lib_iconWorks::getSpriteIcon('actions-page-open') .
210                                                                 '</a>';
211                                         // Unhide
212                                 if ($this->pageRow['hidden'])   {
213                                         $params = '&data[pages][' . $this->pageRow['uid'] . '][hidden]=0';
214                                         $buttons['hide_unhide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('unHidePage', TRUE) . '">' .
215                                                                                 t3lib_iconWorks::getSpriteIcon('actions-edit-unhide') .
216                                                                         '</a>';
217                                         // Hide
218                                 } else {
219                                         $params = '&data[pages][' . $this->pageRow['uid'] . '][hidden]=1';
220                                         $buttons['hide_unhide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('hidePage', TRUE) . '">'.
221                                                                                 t3lib_iconWorks::getSpriteIcon('actions-edit-hide') .
222                                                                         '</a>';
223                                 }
224
225                                         // Move
226                                 $buttons['move'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'move_el.php?table=pages&uid=' . $this->pageRow['uid'] . '\');') . '" title="' . $GLOBALS['LANG']->getLL('move_page', TRUE) . '">' .
227                                                                         (($this->table == 'tt_content') ? t3lib_iconWorks::getSpriteIcon('actions-document-move') : t3lib_iconWorks::getSpriteIcon('actions-page-move')) .
228                                                                 '</a>';
229
230                                         // Up one level
231                                 $buttons['level_up'] = '<a href="' . htmlspecialchars($this->listURL($this->pageRow['pid'], '-1', 'firstElementNumber')) . '" onclick="setHighlight(' . $this->pageRow['pid'] . ')" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.upOneLevel', TRUE) . '">' .
232                                                                 t3lib_iconWorks::getSpriteIcon('actions-view-go-up') .
233                                                         '</a>';
234
235                         }
236
237
238                                 // Paste
239                         if (($localCalcPerms&8) || ($localCalcPerms&16)) {
240                                 $elFromTable = $this->clipObj->elFromTable('');
241                                 if (count($elFromTable)) {
242                                         $buttons['paste'] = '<a href="' . htmlspecialchars($this->clipObj->pasteUrl('', $this->id)) . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg('pages', $this->pageRow, 'into', $elFromTable)) . '" title="' . $GLOBALS['LANG']->getLL('clip_paste', TRUE) . '">' .
243                                                                                 t3lib_iconWorks::getSpriteIcon('actions-document-paste-after') .
244                                                                         '</a>';
245                                 }
246                         }
247
248                                 // Cache
249                         $buttons['cache'] = '<a href="' . htmlspecialchars($this->listURL() . '&clear_cache=1') . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.clear_cache', TRUE) . '">' .
250                                                                 t3lib_iconWorks::getSpriteIcon('actions-system-cache-clear') .
251                                                         '</a>';
252
253                         if ($this->table) {
254
255                                         // CSV
256                                 $buttons['csv'] = '<a href="' . htmlspecialchars($this->listURL() . '&csv=1') . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.csv', TRUE) . '">' .
257                                                                         t3lib_iconWorks::getSpriteIcon('mimetypes-text-csv') .
258                                                                 '</a>';
259
260                                         // Export
261                                 if (t3lib_extMgm::isLoaded('impexp')) {
262                                         $url = $this->backPath . t3lib_extMgm::extRelPath('impexp') . 'app/index.php?tx_impexp[action]=export';
263                                         $buttons['export'] = '<a href="' . htmlspecialchars($url . '&tx_impexp[list][]=' . rawurlencode($this->table . ':' . $this->id)) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.export', TRUE) . '">' .
264                                                                 t3lib_iconWorks::getSpriteIcon('actions-document-export-t3d') .
265                                                         '</a>';
266                                 }
267
268                         }
269
270                                 // Reload
271                         $buttons['reload'] = '<a href="' . htmlspecialchars($this->listURL()) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.reload', TRUE) . '">' .
272                                                                 t3lib_iconWorks::getSpriteIcon('actions-system-refresh') .
273                                                         '</a>';
274
275                                 // Shortcut
276                         if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
277                                 $buttons['shortcut'] = $GLOBALS['TBE_TEMPLATE']->makeShortcutIcon('id, imagemode, pointer, table, search_field, search_levels, showLimit, sortField, sortRev', implode(',', array_keys($this->MOD_MENU)), 'web_list');
278                         }
279
280                                 // Back
281                         if ($this->returnUrl) {
282                                 $buttons['back'] = '<a href="' . htmlspecialchars(t3lib_div::linkThisUrl($this->returnUrl, array('id' => $this->id))) . '" class="typo3-goBack" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.goBack', TRUE) . '">' .
283                                                                         t3lib_iconWorks::getSpriteIcon('actions-view-go-back') .
284                                                                 '</a>';
285                         }
286                 }
287
288                 return $buttons;
289         }
290
291         /**
292          * Creates the listing of records from a single table
293          *
294          * @param       string          Table name
295          * @param       integer         Page id
296          * @param       string          List of fields to show in the listing. Pseudo fields will be added including the record header.
297          * @return      string          HTML table with the listing for the record.
298          */
299         function getTable($table,$id,$rowlist)  {
300                 global $TYPO3_CONF_VARS;
301
302                         // Loading all TCA details for this table:
303                 t3lib_div::loadTCA($table);
304
305                         // Init
306                 $addWhere = '';
307                 $titleCol = $GLOBALS['TCA'][$table]['ctrl']['label'];
308                 $thumbsCol = $GLOBALS['TCA'][$table]['ctrl']['thumbnail'];
309                 $l10nEnabled = $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
310                         && !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'];
311                 $tableCollapsed = (!$this->tablesCollapsed[$table]) ? FALSE : TRUE;
312
313                 // prepare space icon
314                 $this->spaceIcon = t3lib_iconWorks::getSpriteIcon('empty-empty', array('style' => 'background-position: 0 10px;'));
315
316                         // Cleaning rowlist for duplicates and place the $titleCol as the first column always!
317                 $this->fieldArray=array();
318                         // title Column
319                 $this->fieldArray[] = $titleCol;        // Add title column
320                         // Control-Panel
321                 if (!t3lib_div::inList($rowlist,'_CONTROL_'))   {
322                         $this->fieldArray[] = '_CONTROL_';
323                         $this->fieldArray[] = '_AFTERCONTROL_';
324                 }
325                         // Clipboard
326                 if ($this->showClipboard)       {
327                         $this->fieldArray[] = '_CLIPBOARD_';
328                 }
329                         // Ref
330                 if (!$this->dontShowClipControlPanels)  {
331                         $this->fieldArray[]='_REF_';
332                         $this->fieldArray[]='_AFTERREF_';
333                 }
334                         // Path
335                 if ($this->searchLevels)        {
336                         $this->fieldArray[]='_PATH_';
337                 }
338                         // Localization
339                 if ($this->localizationView && $l10nEnabled)    {
340                         $this->fieldArray[] = '_LOCALIZATION_';
341                         $this->fieldArray[] = '_LOCALIZATION_b';
342                         $addWhere.=' AND (
343                                 ' . $GLOBALS['TCA'][$table]['ctrl']['languageField'] . '<=0
344                                 OR
345                                 ' . $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] . ' = 0
346                         )';
347                 }
348                         // Cleaning up:
349                 $this->fieldArray=array_unique(array_merge($this->fieldArray,t3lib_div::trimExplode(',',$rowlist,1)));
350                 if ($this->noControlPanels)     {
351                         $tempArray = array_flip($this->fieldArray);
352                         unset($tempArray['_CONTROL_']);
353                         unset($tempArray['_CLIPBOARD_']);
354                         $this->fieldArray = array_keys($tempArray);
355                 }
356
357                         // Creating the list of fields to include in the SQL query:
358                 $selectFields = $this->fieldArray;
359                 $selectFields[] = 'uid';
360                 $selectFields[] = 'pid';
361                 if ($thumbsCol) $selectFields[] = $thumbsCol;   // adding column for thumbnails
362                 if ($table=='pages')    {
363                         if (t3lib_extMgm::isLoaded('cms'))      {
364                                 $selectFields[] = 'module';
365                                 $selectFields[] = 'extendToSubpages';
366                                 $selectFields[] = 'nav_hide';
367                         }
368                         $selectFields[] = 'doktype';
369                 }
370                 if (is_array($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
371                         $selectFields = array_merge($selectFields, $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']);
372                 }
373                 if ($GLOBALS['TCA'][$table]['ctrl']['type']) {
374                         $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['type'];
375                 }
376                 if ($GLOBALS['TCA'][$table]['ctrl']['typeicon_column']) {
377                         $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
378                 }
379                 if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
380                         $selectFields[] = 't3ver_id';
381                         $selectFields[] = 't3ver_state';
382                         $selectFields[] = 't3ver_wsid';
383                         $selectFields[] = 't3ver_swapmode';             // Filtered out when pages in makeFieldList()
384                 }
385                 if ($l10nEnabled)       {
386                         $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['languageField'];
387                         $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
388                 }
389                 if ($GLOBALS['TCA'][$table]['ctrl']['label_alt'])       {
390                         $selectFields = array_merge(
391                                 $selectFields,
392                                 t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['ctrl']['label_alt'], 1)
393                         );
394                 }
395                 $selectFields = array_unique($selectFields);            // Unique list!
396                 $selectFields = array_intersect($selectFields,$this->makeFieldList($table,1));          // Making sure that the fields in the field-list ARE in the field-list from TCA!
397                 $selFieldList = implode(',',$selectFields);             // implode it into a list of fields for the SQL-statement.
398                 $this->selFieldList = $selFieldList;
399
400                 /**
401                  * @hook                        DB-List getTable
402                  * @date                        2007-11-16
403                  * @request             Malte Jansen  <mail@maltejansen.de>
404                  */
405                 if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['getTable'])) {
406                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['getTable'] as $classData) {
407                                 $hookObject = t3lib_div::getUserObj($classData);
408
409                                 if(!($hookObject instanceof t3lib_localRecordListGetTableHook)) {
410                                         throw new UnexpectedValueException('$hookObject must implement interface t3lib_localRecordListGetTableHook', 1195114460);
411                                 }
412
413                                 $hookObject->getDBlistQuery($table, $id, $addWhere, $selFieldList, $this);
414                         }
415                 }
416
417                         // Create the SQL query for selecting the elements in the listing:
418                 if ($this->csvOutput) { // do not do paging when outputting as CSV
419                         $this->iLimit = 0;
420                 }
421
422                 if ($this->firstElementNumber > 2 && $this->iLimit > 0) {
423                                 // Get the two previous rows for sorting if displaying page > 1
424                         $this->firstElementNumber = $this->firstElementNumber - 2;
425                         $this->iLimit = $this->iLimit + 2;
426                         $queryParts = $this->makeQueryArray($table, $id,$addWhere,$selFieldList);       // (API function from class.db_list.inc)
427                         $this->firstElementNumber = $this->firstElementNumber + 2;
428                         $this->iLimit = $this->iLimit - 2;
429                 } else {
430                         $queryParts = $this->makeQueryArray($table, $id,$addWhere,$selFieldList);       // (API function from class.db_list.inc)
431                 }
432
433                 $this->setTotalItems($queryParts);              // Finding the total amount of records on the page (API function from class.db_list.inc)
434
435                         // Init:
436                 $dbCount = 0;
437                 $out = '';
438                 $listOnlyInSingleTableMode = $this->listOnlyInSingleTableMode && !$this->table;
439
440                         // If the count query returned any number of records, we perform the real query, selecting records.
441                 if ($this->totalItems)  {
442                         // Fetch records only if not in single table mode or if in multi table mode and not collapsed
443                         if ($listOnlyInSingleTableMode || (!$this->table && $tableCollapsed)) {
444                                 $dbCount = $this->totalItems;
445                         } else {
446                                         // set the showLimit to the number of records when outputting as CSV
447                                 if ($this->csvOutput) {
448                                         $this->showLimit = $this->totalItems;
449                                         $this->iLimit = $this->totalItems;
450                                 }
451                                 $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
452                                 $dbCount = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
453                         }
454                 }
455
456                         // If any records was selected, render the list:
457                 if ($dbCount)   {
458
459                                 // Half line is drawn between tables:
460                         if (!$listOnlyInSingleTableMode)        {
461                                 $theData = Array();
462                                 if (!$this->table && !$rowlist) {
463                                         $theData[$titleCol] = '<img src="clear.gif" width="'.($GLOBALS['SOBE']->MOD_SETTINGS['bigControlPanel']?'230':'350').'" height="1" alt="" />';
464                                         if (in_array('_CONTROL_',$this->fieldArray))    $theData['_CONTROL_']='';
465                                         if (in_array('_CLIPBOARD_',$this->fieldArray))  $theData['_CLIPBOARD_']='';
466                                 }
467                                 $out.=$this->addelement(0,'',$theData,'class="c-table-row-spacer"',$this->leftMargin);
468                         }
469
470                                 // Header line is drawn
471                         $theData = Array();
472                         if ($this->disableSingleTableView)      {
473                                 $theData[$titleCol] = '<span class="c-table">' . t3lib_BEfunc::wrapInHelp($table, '', $GLOBALS['LANG']->sL($GLOBALS['TCA'][$table]['ctrl']['title'], TRUE)) . '</span> ('.$this->totalItems.')';
474                         } else {
475                                 $theData[$titleCol] = $this->linkWrapTable($table, '<span class="c-table">' . $GLOBALS['LANG']->sL($GLOBALS['TCA'][$table]['ctrl']['title'], TRUE) . '</span> (' . $this->totalItems . ') ' .
476                                                 ($this->table ? t3lib_iconWorks::getSpriteIcon('actions-view-table-collapse', array('title' => $GLOBALS['LANG']->getLL('contractView', TRUE))) : t3lib_iconWorks::getSpriteIcon('actions-view-table-expand', array('title' => $GLOBALS['LANG']->getLL('expandView', TRUE))))
477                                         );
478                         }
479
480                         if ($listOnlyInSingleTableMode) {
481                                 $out.='
482                                         <tr>
483                                                 <td class="t3-row-header" style="width:95%;">' . t3lib_BEfunc::wrapInHelp($table, '', $theData[$titleCol]) . '</td>
484                                         </tr>';
485                         } else {
486                                 // Render collapse button if in multi table mode
487                                 $collapseIcon = '';
488                                 if (!$this->table) {
489                                         $collapseIcon = '<a href="' . htmlspecialchars($this->listURL() . '&collapse[' . $table . ']=' . ($tableCollapsed ? '0' : '1')) . '" title="' . ($tableCollapsed ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.expandTable', TRUE) : $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.collapseTable', TRUE)) . '">' .
490                                                         ($tableCollapsed ? t3lib_iconWorks::getSpriteIcon('actions-view-list-expand', array('class' => 'collapseIcon')) : t3lib_iconWorks::getSpriteIcon('actions-view-list-collapse', array('class' => 'collapseIcon'))) .
491                                                 '</a>';
492                                 }
493                                 $out .= $this->addElement(1, $collapseIcon, $theData, ' class="t3-row-header"', '');
494                         }
495
496                         // Render table rows only if in multi table view and not collapsed or if in single table view
497                         if (!$listOnlyInSingleTableMode && (!$tableCollapsed || $this->table)) {
498                                         // Fixing a order table for sortby tables
499                                 $this->currentTable = array();
500                                 $currentIdList = array();
501                                 $doSort = ($GLOBALS['TCA'][$table]['ctrl']['sortby'] && !$this->sortField);
502
503                                 $prevUid = 0;
504                                 $prevPrevUid = 0;
505
506                                         // Get first two rows and initialize prevPrevUid and prevUid if on page > 1
507                                 if ($this->firstElementNumber > 2 && $this->iLimit > 0) {
508                                         $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
509                                         $prevPrevUid = -(int) $row['uid'];
510                                         $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
511                                         $prevUid = $row['uid'];
512                                 }
513
514                                 $accRows = array();     // Accumulate rows here
515                                 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result))    {
516
517                                                 // In offline workspace, look for alternative record:
518                                         t3lib_BEfunc::workspaceOL($table, $row, $GLOBALS['BE_USER']->workspace, TRUE);
519
520                                         if (is_array($row))     {
521                                                 $accRows[] = $row;
522                                                 $currentIdList[] = $row['uid'];
523                                                 if ($doSort)    {
524                                                         if ($prevUid)   {
525                                                                 $this->currentTable['prev'][$row['uid']] = $prevPrevUid;
526                                                                 $this->currentTable['next'][$prevUid] = '-'.$row['uid'];
527                                                                 $this->currentTable['prevUid'][$row['uid']] = $prevUid;
528                                                         }
529                                                         $prevPrevUid = isset($this->currentTable['prev'][$row['uid']]) ? -$prevUid : $row['pid'];
530                                                         $prevUid=$row['uid'];
531                                                 }
532                                         }
533                                 }
534                                 $GLOBALS['TYPO3_DB']->sql_free_result($result);
535
536                                 $this->totalRowCount = count($accRows);
537
538                                         // CSV initiated
539                                 if ($this->csvOutput) $this->initCSV();
540
541                                         // Render items:
542                                 $this->CBnames=array();
543                                 $this->duplicateStack=array();
544                                 $this->eCounter=$this->firstElementNumber;
545
546                                 $iOut = '';
547                                 $cc = 0;
548
549                                 foreach($accRows as $row)       {
550                                         // Render item row if counter < limit
551                                         if ($cc < $this->iLimit) {
552                                                 $cc++;
553                                                 $this->translations = FALSE;
554                                                 $iOut.= $this->renderListRow($table,$row,$cc,$titleCol,$thumbsCol);
555
556                                                         // If localization view is enabled it means that the selected records are either default or All language and here we will not select translations which point to the main record:
557                                                 if ($this->localizationView && $l10nEnabled)    {
558                                                                 // For each available translation, render the record:
559                                                         if (is_array($this->translations)) {
560                                                                 foreach ($this->translations as $lRow) {
561                                                                                 // $lRow isn't always what we want - if record was moved we've to work with the placeholder records otherwise the list is messed up a bit
562                                                                         if ($row['_MOVE_PLH_uid'] && $row['_MOVE_PLH_pid']) {
563                                                                                 $tmpRow = t3lib_BEfunc::getRecordRaw($table, 't3ver_move_id="'.intval($lRow['uid']) . '" AND pid="' . $row['_MOVE_PLH_pid'] . '" AND t3ver_wsid=' . $row['t3ver_wsid'] . t3lib_beFunc::deleteClause($table), $selFieldList);
564                                                                                 $lRow = is_array($tmpRow)?$tmpRow:$lRow;
565                                                                         }
566                                                                                 // In offline workspace, look for alternative record:
567                                                                         t3lib_BEfunc::workspaceOL($table, $lRow, $GLOBALS['BE_USER']->workspace, TRUE);
568                                                                         if (is_array($lRow) && $GLOBALS['BE_USER']->checkLanguageAccess($lRow[$GLOBALS['TCA'][$table]['ctrl']['languageField']])) {
569                                                                                 $currentIdList[] = $lRow['uid'];
570                                                                                 $iOut.=$this->renderListRow($table,$lRow,$cc,$titleCol,$thumbsCol,18);
571                                                                         }
572                                                                 }
573                                                         }
574                                                 }
575                                         }
576
577                                                 // Counter of total rows incremented:
578                                         $this->eCounter++;
579                                 }
580
581                                         // Record navigation is added to the beginning and end of the table if in single table mode
582                                 if ($this->table) {
583                                         $iOut = $this->renderListNavigation('top') . $iOut . $this->renderListNavigation('bottom');
584                                 } else {
585                                                 // show that there are more records than shown
586                                         if ($this->totalItems > $this->itemsLimitPerTable) {
587                                                 $countOnFirstPage = $this->totalItems > $this->itemsLimitSingleTable ? $this->itemsLimitSingleTable : $this->totalItems;
588                                                 $hasMore = ($this->totalItems > $this->itemsLimitSingleTable);
589                                                 $iOut .= '<tr><td colspan="' . count($this->fieldArray) . '" style="padding:5px;">
590                                                                 <a href="'.htmlspecialchars($this->listURL() . '&table=' . rawurlencode($table)) . '">' .
591                                                                 '<img' . t3lib_iconWorks::skinImg($this->backPath,'gfx/pildown.gif', 'width="14" height="14"') .' alt="" />'.
592                                                                 ' <i>[1 - ' . $countOnFirstPage . ($hasMore ? '+' : '') . ']</i></a>
593                                                                 </td></tr>';
594                                                 }
595
596                                 }
597
598                                         // The header row for the table is now created:
599                                 $out .= $this->renderListHeader($table,$currentIdList);
600                         }
601
602                                 // The list of records is added after the header:
603                         $out .= $iOut;
604                         unset($iOut);
605
606                                 // ... and it is all wrapped in a table:
607                         $out='
608
609
610
611                         <!--
612                                 DB listing of elements: "'.htmlspecialchars($table).'"
613                         -->
614                                 <table border="0" cellpadding="0" cellspacing="0" class="typo3-dblist'.($listOnlyInSingleTableMode?' typo3-dblist-overview':'').'">
615                                         '.$out.'
616                                 </table>';
617
618                                 // Output csv if...
619                         if ($this->csvOutput)   $this->outputCSV($table);       // This ends the page with exit.
620                 }
621
622                         // Return content:
623                 return $out;
624         }
625
626         /**
627          * Rendering a single row for the list
628          *
629          * @param       string          Table name
630          * @param       array           Current record
631          * @param       integer         Counter, counting for each time an element is rendered (used for alternating colors)
632          * @param       string          Table field (column) where header value is found
633          * @param       string          Table field (column) where (possible) thumbnails can be found
634          * @param       integer         Indent from left.
635          * @return      string          Table row for the element
636          * @access private
637          * @see getTable()
638          */
639         function renderListRow($table,$row,$cc,$titleCol,$thumbsCol,$indent=0)  {
640                 $iOut = '';
641
642                 if (strlen($this->searchString))        {       // If in search mode, make sure the preview will show the correct page
643                         $id_orig = $this->id;
644                         $this->id = $row['pid'];
645                 }
646
647                 if (is_array($row))     {
648                                 // add special classes for first and last row
649                         $rowSpecial = '';
650                         if ($cc == 1 && $indent == 0) {
651                                 $rowSpecial .= ' firstcol';
652                         }
653                         if ($cc == $this->totalRowCount || $cc == $this->iLimit) {
654                                 $rowSpecial .= ' lastcol';
655                         }
656
657                                 // Background color, if any:
658                         if ($this->alternateBgColors) {
659                                 $row_bgColor = ($cc%2) ? ' class="db_list_normal'.$rowSpecial.'"' : ' class="db_list_alt'.$rowSpecial.'"';
660                         } else {
661                                 $row_bgColor = ' class="db_list_normal'.$rowSpecial.'"';
662                         }
663                                 // Overriding with versions background color if any:
664                         $row_bgColor = $row['_CSSCLASS'] ? ' class="'.$row['_CSSCLASS'].'"' : $row_bgColor;
665
666                                 // Incr. counter.
667                         $this->counter++;
668
669                                 // The icon with link
670                         $alttext = t3lib_BEfunc::getRecordIconAltText($row,$table);
671                         $iconImg = t3lib_iconWorks::getSpriteIconForRecord($table, $row, array('title' => htmlspecialchars($alttext), 'style' => ($indent ? ' margin-left: ' . $indent . 'px;' : '')));
672
673
674                         $theIcon = $this->clickMenuEnabled ? $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg,$table,$row['uid']) : $iconImg;
675
676                                 // Preparing and getting the data-array
677                         $theData = Array();
678                         foreach($this->fieldArray as $fCol)     {
679                                 if ($fCol==$titleCol)   {
680                                         $recTitle = t3lib_BEfunc::getRecordTitle($table,$row,FALSE,TRUE);
681                                                 // If the record is edit-locked by another user, we will show a little warning sign:
682                                         if (($lockInfo = t3lib_BEfunc::isRecordLocked($table, $row['uid']))) {
683                                                 $warning = '<a href="#" onclick="' . htmlspecialchars('alert(' . $GLOBALS['LANG']->JScharCode($lockInfo['msg']) . '); return false;') . '" title="' . htmlspecialchars($lockInfo['msg']) . '">' .
684                                                                 t3lib_iconWorks::getSpriteIcon('status-warning-in-use') .
685                                                         '</a>';
686                                         }
687                                         $theData[$fCol] = $warning . $this->linkWrapItems($table, $row['uid'], $recTitle, $row);
688
689                                                 // Render thumbsnails if a thumbnail column exists and there is content in it:
690                                         if ($this->thumbs && trim($row[$thumbsCol])) {
691                                                 $theData[$fCol] .= '<br />' . $this->thumbCode($row,$table,$thumbsCol);
692                                         }
693
694                                         $localizationMarkerClass = '';
695                                         if (isset($GLOBALS['TCA'][$table]['ctrl']['languageField'])
696                                         && $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] != 0
697                                         && $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0) {
698                                                         // it's a translated record with a language parent
699                                                 $localizationMarkerClass = ' localization';
700                                         }
701                                 } elseif ($fCol == 'pid') {
702                                         $theData[$fCol]=$row[$fCol];
703                                 } elseif ($fCol == '_PATH_') {
704                                         $theData[$fCol]=$this->recPath($row['pid']);
705                                 } elseif ($fCol == '_REF_') {
706                                         $theData[$fCol] = $this->createReferenceHtml($table, $row['uid']);
707                                 } elseif ($fCol == '_CONTROL_') {
708                                         $theData[$fCol]=$this->makeControl($table,$row);
709                                 } elseif ($fCol == '_AFTERCONTROL_' || $fCol == '_AFTERREF_') {
710                                         $theData[$fCol] = '&nbsp;';
711                                 } elseif ($fCol == '_CLIPBOARD_') {
712                                         $theData[$fCol]=$this->makeClip($table,$row);
713                                 } elseif ($fCol == '_LOCALIZATION_') {
714                                         list($lC1, $lC2) = $this->makeLocalizationPanel($table,$row);
715                                         $theData[$fCol] = $lC1;
716                                         $theData[$fCol.'b'] = $lC2;
717                                 } elseif ($fCol == '_LOCALIZATION_b') {
718                                         // Do nothing, has been done above.
719                                 } else {
720                                         $tmpProc = t3lib_BEfunc::getProcessedValueExtra($table, $fCol, $row[$fCol], 100, $row['uid']);
721                                         $theData[$fCol] = $this->linkUrlMail(htmlspecialchars($tmpProc), $row[$fCol]);
722                                         if ($this->csvOutput) {
723                                                 $row[$fCol] = t3lib_BEfunc::getProcessedValueExtra($table, $fCol, $row[$fCol], 0, $row['uid']);
724                                         }
725                                 }
726                         }
727
728                         if (strlen($this->searchString))        {       // Reset the ID if it was overwritten
729                                 $this->id = $id_orig;
730                         }
731
732                                 // Add row to CSV list:
733                         if ($this->csvOutput) {
734                                 $this->addToCSV($row,$table);
735                         }
736
737                         // Add classes to table cells
738                         $this->addElement_tdCssClass[$titleCol]         = 'col-title' . $localizationMarkerClass;
739                         if (!$this->dontShowClipControlPanels) {
740                                 $this->addElement_tdCssClass['_CONTROL_']       = 'col-control';
741                                 $this->addElement_tdCssClass['_AFTERCONTROL_']  = 'col-control-space';
742                                 $this->addElement_tdCssClass['_CLIPBOARD_']     = 'col-clipboard';
743                         }
744                         $this->addElement_tdCssClass['_PATH_']          = 'col-path';
745                         $this->addElement_tdCssClass['_LOCALIZATION_']  = 'col-localizationa';
746                         $this->addElement_tdCssClass['_LOCALIZATION_b'] = 'col-localizationb';
747
748                                 // Create element in table cells:
749                         $iOut.=$this->addelement(1,$theIcon,$theData,$row_bgColor);
750
751                                 // Finally, return table row element:
752                         return $iOut;
753                 }
754         }
755
756         /**
757          * Write sys_refindex entries for current record to $this->references
758          *
759          * @param       string          Table name
760          * @param       integer         Uid of current record
761          * @return      void
762          *
763          * @deprecated since 4.4, will be removed in TYPO3 4.6 - Use getReferenceCount instead
764          */
765         function setReferences($table, $uid) {
766                 t3lib_div::logDeprecatedFunction();
767
768                 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
769                         'tablename, recuid, field',
770                         'sys_refindex',
771                         'ref_table='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_refindex').
772                                 ' AND ref_uid='.intval($uid).
773                                 ' AND deleted=0'
774                 );
775                 $this->references = $rows;
776         }
777
778         /**
779          * Gets the number of records referencing the record with the UID $uid in
780          * the table $tableName.
781          *
782          * @param string $tableName
783          *        table name of the referenced record, must not be empty
784          * @param integer $uid
785          *        UID of the referenced record, must be > 0
786          *
787          * @return integer the number of references to record $uid in table
788          *                 $tableName, will be >= 0
789          */
790         protected function getReferenceCount($tableName, $uid) {
791                 if (!isset($this->referenceCount[$tableName][$uid])) {
792                         $numberOfReferences = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
793                                 '*',
794                                 'sys_refindex',
795                                 'ref_table = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
796                                         $tableName, 'sys_refindex'
797                                 ) .
798                                         ' AND ref_uid = ' . $uid .
799                                         ' AND deleted = 0'
800                         );
801
802                         $this->referenceCount[$tableName][$uid] = $numberOfReferences;
803                 }
804
805                 return $this->referenceCount[$tableName][$uid];
806         }
807
808         /**
809          * Rendering the header row for a table
810          *
811          * @param       string          Table name
812          * @param       array           Array of the currently displayed uids of the table
813          * @return      string          Header table row
814          * @access private
815          * @see getTable()
816          */
817         function renderListHeader($table, $currentIdList)       {
818                 global $TYPO3_CONF_VARS;
819
820                         // Init:
821                 $theData = Array();
822
823                         // Traverse the fields:
824                 foreach($this->fieldArray as $fCol)     {
825
826                                 // Calculate users permissions to edit records in the table:
827                         $permsEdit = $this->calcPerms & ($table=='pages'?2:16);
828
829                         switch((string)$fCol)   {
830                                 case '_PATH_':                  // Path
831                                         $theData[$fCol] = '<i>[' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels._PATH_', 1) . ']</i>';
832                                 break;
833                                 case '_REF_':                   // References
834                                         $theData[$fCol] = '<i>[' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_file_list.xml:c__REF_', 1) . ']</i>';
835                                 break;
836                                 case '_LOCALIZATION_':                  // Path
837                                         $theData[$fCol] = '<i>[' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels._LOCALIZATION_', 1) . ']</i>';
838                                 break;
839                                 case '_LOCALIZATION_b':                 // Path
840                                         $theData[$fCol] = $GLOBALS['LANG']->getLL('Localize', 1);
841                                 break;
842                                 case '_CLIPBOARD_':             // Clipboard:
843                                         $cells=array();
844
845                                                 // If there are elements on the clipboard for this table, then display the "paste into" icon:
846                                         $elFromTable = $this->clipObj->elFromTable($table);
847                                         if (count($elFromTable))        {
848                                                 $cells['pasteAfter'] = '<a href="' . htmlspecialchars($this->clipObj->pasteUrl($table, $this->id)) .
849                                                         '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg('pages', $this->pageRow, 'into' ,$elFromTable)) .
850                                                         '" title="' . $GLOBALS['LANG']->getLL('clip_paste', TRUE) . '">' .
851                                                         t3lib_iconWorks::getSpriteIcon('actions-document-paste-after') . '</a>';
852                                         }
853
854                                                 // If the numeric clipboard pads are enabled, display the control icons for that:
855                                         if ($this->clipObj->current!='normal')  {
856
857                                                         // The "select" link:
858                                                 $cells['copyMarked'] = $this->linkClipboardHeaderIcon(
859                                                         t3lib_iconWorks::getSpriteIcon(
860                                                                 'actions-edit-copy',
861                                                                 array('title' => $GLOBALS['LANG']->getLL('clip_selectMarked', TRUE))
862                                                         ),
863                                                         $table,
864                                                         'setCB');
865
866                                                         // The "edit marked" link:
867                                                 $editIdList = implode(',',$currentIdList);
868                                                 $editIdList = "'+editList('".$table."','".$editIdList."')+'";
869                                                 $params='&edit['.$table.']['.$editIdList.']=edit&disHelp=1';
870                                                 $cells['edit'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath, -1)) .
871                                                                 '" title="' . $GLOBALS['LANG']->getLL('clip_editMarked', TRUE) . '">' .
872                                                                 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
873                                                                 '</a>';
874
875                                                         // The "Delete marked" link:
876                                                 $cells['delete'] = $this->linkClipboardHeaderIcon(
877                                                         t3lib_iconWorks::getSpriteIcon(
878                                                                 'actions-edit-delete',
879                                                                 array('title' => $GLOBALS['LANG']->getLL('clip_deleteMarked', TRUE))
880                                                         ),
881                                                         $table,
882                                                         'delete',
883                                                         sprintf($GLOBALS['LANG']->getLL('clip_deleteMarkedWarning'), $GLOBALS['LANG']->sL($GLOBALS['TCA'][$table]['ctrl']['title']))
884                                                 );
885
886                                                         // The "Select all" link:
887                                                 $cells['markAll'] = '<a class="cbcCheckAll" rel="" href="#" onclick="' .
888                                                                 htmlspecialchars('checkOffCB(\'' . implode(',', $this->CBnames) . '\', this); return false;') .
889                                                                 '" title="' . $GLOBALS['LANG']->getLL('clip_markRecords', TRUE) . '">' .
890                                                                 t3lib_iconWorks::getSpriteIcon('actions-document-select') .
891                                                                 '</a>';
892                                         } else {
893                                                 $cells['empty']='';
894                                         }
895                                         /**
896                                          * @hook                        renderListHeaderActions: Allows to change the clipboard icons of the Web>List table headers
897                                          * @date                        2007-11-20
898                                          * @request             Bernhard Kraft  <krafbt@kraftb.at>
899                                          * @usage               Above each listed table in Web>List a header row is shown. This hook allows to modify the icons responsible for the clipboard functions (shown above the clipboard checkboxes when a clipboard other than "Normal" is selected), or other "Action" functions which perform operations on the listed records.
900                                          */
901                                         if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions']))        {
902                                                 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData)       {
903                                                         $hookObject = t3lib_div::getUserObj($classData);
904                                                         if(!($hookObject instanceof localRecordList_actionsHook))       {
905                                                                 throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567850);
906                                                         }
907                                                         $cells = $hookObject->renderListHeaderActions($table, $currentIdList, $cells, $this);
908                                                 }
909                                         }
910                                         $theData[$fCol]=implode('',$cells);
911                                 break;
912                                 case '_CONTROL_':               // Control panel:
913                                         if (!$GLOBALS['TCA'][$table]['ctrl']['readOnly']) {
914
915                                                         // If new records can be created on this page, add links:
916                                                 if ($this->calcPerms&($table=='pages'?8:16) && $this->showNewRecLink($table))   {
917                                                         if ($table=="tt_content" && $this->newWizards)  {
918                                                                         //  If mod.web_list.newContentWiz.overrideWithExtension is set, use that extension's create new content wizard instead:
919                                                                 $tmpTSc = t3lib_BEfunc::getModTSconfig($this->pageinfo['uid'],'mod.web_list');
920                                                                 $tmpTSc = $tmpTSc['properties']['newContentWiz.']['overrideWithExtension'];
921                                                                 $newContentWizScriptPath = $this->backPath.t3lib_extMgm::isLoaded($tmpTSc) ? (t3lib_extMgm::extRelPath($tmpTSc).'mod1/db_new_content_el.php') : 'sysext/cms/layout/db_new_content_el.php';
922
923                                                                 $icon = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $newContentWizScriptPath . '?id=' . $this->id . '\');') . '" title="' . $GLOBALS['LANG']->getLL('new', TRUE) . '">'.
924                                                                                                         ($table == 'pages' ? t3lib_iconWorks::getSpriteIcon('actions-page-new') : t3lib_iconWorks::getSpriteIcon('actions-document-new')) .
925                                                                                                 '</a>';
926                                                         } elseif ($table=='pages' && $this->newWizards) {
927                                                                 $icon = '<a href="' . htmlspecialchars($this->backPath . 'db_new.php?id=' . $this->id . '&pagesOnly=1&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))) . '" title="' . $GLOBALS['LANG']->getLL('new', TRUE) . '">'.
928                                                                                                         ($table=='pages' ? t3lib_iconWorks::getSpriteIcon('actions-page-new') : t3lib_iconWorks::getSpriteIcon('actions-document-new')) .
929                                                                                                 '</a>';
930
931                                                         } else {
932                                                                 $params = '&edit['.$table.']['.$this->id.']=new';
933                                                                 if ($table == 'pages_language_overlay') {
934                                                                         $params .= '&overrideVals[pages_language_overlay][doktype]=' . (int) $this->pageRow['doktype'];
935                                                                 }
936                                                                 $icon   = '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath, -1)) . '" title="' . $GLOBALS['LANG']->getLL('new', TRUE) . '">'.
937                                                                                                         ($table=='pages' ? t3lib_iconWorks::getSpriteIcon('actions-page-new') : t3lib_iconWorks::getSpriteIcon('actions-document-new')) .
938                                                                                                 '</a>';
939                                                         }
940                                                 }
941
942                                                         // If the table can be edited, add link for editing ALL SHOWN fields for all listed records:
943                                                 if ($permsEdit && $this->table && is_array($currentIdList))     {
944                                                         $editIdList = implode(',',$currentIdList);
945                                                         if ($this->clipNumPane()) $editIdList = "'+editList('".$table."','".$editIdList."')+'";
946                                                         $params = '&edit['.$table.']['.$editIdList.']=edit&columnsOnly='.implode(',',$this->fieldArray).'&disHelp=1';
947                                                         $icon  .= '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath, -1 )) . '" title="' . $GLOBALS['LANG']->getLL('editShownColumns', TRUE) . '">' .
948                                                                                                 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
949                                                                                         '</a>';
950                                                 }
951                                                         // add an empty entry, so column count fits again after moving this into $icon
952                                                 $theData[$fCol] = '&nbsp;';
953                                         }
954                                 break;
955                                 case '_AFTERCONTROL_':  // space column
956                                 case '_AFTERREF_':      // space column
957                                         $theData[$fCol] = '&nbsp;';
958                                 break;
959                                 default:                        // Regular fields header:
960                                         $theData[$fCol]='';
961                                         if ($this->table && is_array($currentIdList))   {
962
963                                                         // If the numeric clipboard pads are selected, show duplicate sorting link:
964                                                 if ($this->clipNumPane()) {
965                                                         $theData[$fCol] .= '<a href="' . htmlspecialchars($this->listURL('', -1) . '&duplicateField=' . $fCol) . '" title="' . $GLOBALS['LANG']->getLL('clip_duplicates', TRUE) . '">' .
966                                                                                                 t3lib_iconWorks::getSpriteIcon('actions-document-duplicates-select') .
967                                                                                         '</a>';
968                                                 }
969
970                                                         // If the table can be edited, add link for editing THIS field for all listed records:
971                                                 if (!$GLOBALS['TCA'][$table]['ctrl']['readOnly'] && $permsEdit && $GLOBALS['TCA'][$table]['columns'][$fCol]) {
972                                                         $editIdList = implode(',',$currentIdList);
973                                                         if ($this->clipNumPane()) $editIdList = "'+editList('".$table."','".$editIdList."')+'";
974                                                         $params='&edit['.$table.']['.$editIdList.']=edit&columnsOnly='.$fCol.'&disHelp=1';
975                                                         $iTitle = sprintf($GLOBALS['LANG']->getLL('editThisColumn'), rtrim(trim($GLOBALS['LANG']->sL(t3lib_BEfunc::getItemLabel($table, $fCol))), ':'));
976                                                         $theData[$fCol].='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'" title="'.htmlspecialchars($iTitle).'">'.
977                                                                                                 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
978                                                                                         '</a>';
979                                                 }
980                                         }
981                                         $theData[$fCol] .= $this->addSortLink($GLOBALS['LANG']->sL(t3lib_BEfunc::getItemLabel($table, $fCol, '<i>[|]</i>')), $fCol, $table);
982                                 break;
983                         }
984
985                 }
986
987                 /**
988                  * @hook                        renderListHeader: Allows to change the contents of columns/cells of the Web>List table headers
989                  * @date                        2007-11-20
990                  * @request             Bernhard Kraft  <krafbt@kraftb.at>
991                  * @usage               Above each listed table in Web>List a header row is shown. Containing the labels of all shown fields and additional icons to create new records for this table or perform special clipboard tasks like mark and copy all listed records to clipboard, etc.
992                  */
993                 if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions']))        {
994                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData)       {
995                                 $hookObject = t3lib_div::getUserObj($classData);
996                                 if(!($hookObject instanceof localRecordList_actionsHook))       {
997                                         throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567855);
998                                 }
999                                 $theData = $hookObject->renderListHeader($table, $currentIdList, $theData, $this);
1000                         }
1001                 }
1002
1003                         // Create and return header table row:
1004                 return $this->addelement(1, $icon, $theData, ' class="c-headLine"', '');
1005         }
1006
1007         /**
1008          * Creates a page browser for tables with many records
1009          *
1010          * @param       string          Distinguish between 'top' and 'bottom' part of the navigation (above or below the records)
1011          * @return      string  Navigation HTML
1012          *
1013          */
1014         protected function renderListNavigation($renderPart = 'top') {
1015                 $totalPages = ceil($this->totalItems / $this->iLimit);
1016
1017                 $content = '';
1018                 $returnContent = '';
1019
1020                         // Show page selector if not all records fit into one page
1021                 if ($totalPages > 1) {
1022                         $first = $previous = $next = $last = $reload = '';
1023                         $listURL = $this->listURL('', $this->table);
1024
1025                                 // 1 = first page
1026                         $currentPage = floor(($this->firstElementNumber + 1) / $this->iLimit) + 1;
1027
1028                                 // Compile first, previous, next, last and refresh buttons
1029                         if ($currentPage > 1) {
1030                                 $labelFirst = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:first');
1031
1032                                 $first = '<a href="' . $listURL . '&pointer=0">' .
1033                                         t3lib_iconWorks::getSpriteIcon('actions-view-paging-first', array('title'=> $labelFirst)) .
1034                                 '</a>';
1035                         } else {
1036                                 $first = t3lib_iconWorks::getSpriteIcon('actions-view-paging-first-disabled');
1037                         }
1038
1039                         if (($currentPage - 1) > 0) {
1040                                 $labelPrevious = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:previous');
1041
1042                                 $previous = '<a href="' . $listURL . '&pointer=' . (($currentPage - 2) * $this->iLimit) . '">' .
1043                                         t3lib_iconWorks::getSpriteIcon('actions-view-paging-previous', array('title' => $labelPrevious)) .
1044                                         '</a>';
1045                         } else {
1046                                 $previous = t3lib_iconWorks::getSpriteIcon('actions-view-paging-previous-disabled');
1047                         }
1048
1049                         if (($currentPage + 1) <= $totalPages) {
1050                                 $labelNext = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:next');
1051
1052                                 $next = '<a href="' . $listURL . '&pointer=' . (($currentPage) * $this->iLimit) . '">' .
1053                                         t3lib_iconWorks::getSpriteIcon('actions-view-paging-next', array('title' => $labelNext)) .
1054                                         '</a>';
1055                         } else {
1056                                 $next = t3lib_iconWorks::getSpriteIcon('actions-view-paging-next-disabled');
1057                         }
1058
1059                         if ($currentPage != $totalPages) {
1060                                 $labelLast = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:last');
1061
1062                                 $last = '<a href="' . $listURL . '&pointer=' . (($totalPages - 1) * $this->iLimit) . '">' .
1063                                         t3lib_iconWorks::getSpriteIcon('actions-view-paging-last', array('title' => $labelLast)) .
1064                                         '</a>';
1065                         } else {
1066                                 $last = t3lib_iconWorks::getSpriteIcon('actions-view-paging-last-disabled');
1067                         }
1068
1069                         $reload = '<a href="#" onclick="document.dblistForm.action=\''
1070                                 . $listURL . '&pointer=\'+calculatePointer(document.getElementById(\'jumpPage-' . $renderPart .'\').value); document.dblistForm.submit(); return true;" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:reload', TRUE) . '">' .
1071                                         t3lib_iconWorks::getSpriteIcon('actions-system-refresh') .
1072                                 '</a>';
1073
1074                         if ($renderPart === 'top') {
1075                                         // Add js to traverse a page select input to a pointer value
1076                                 $content = '
1077 <script type="text/JavaScript">
1078 /*<![CDATA[*/
1079
1080         function calculatePointer(page) {
1081                 if (page > ' . $totalPages . ') {
1082                         page = ' . $totalPages . ';
1083                 }
1084
1085                 if (page < 1) {
1086                         page = 1;
1087                 }
1088
1089                 pointer = (page - 1) * ' . $this->iLimit . ';
1090
1091                 return pointer;
1092         }
1093
1094 /*]]>*/
1095 </script>
1096 ';
1097                         }
1098                         $pageNumberInput = '<span>
1099                                 <input type="text" value="' . $currentPage
1100                                 . '" size="3" id="jumpPage-' . $renderPart . '" name="jumpPage-' . $renderPart . '" onkeyup="if (event.keyCode == Event.KEY_RETURN) { document.dblistForm.action=\'' . $listURL . '&pointer=\'+calculatePointer(this.value); document.dblistForm.submit(); } return true;" />
1101                                 </span>';
1102                         $pageIndicator = '<span class="pageIndicator">'
1103                                 . sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:pageIndicator'), $pageNumberInput, $totalPages)
1104                                 . '</span>';
1105
1106                         if ($this->totalItems > ($this->firstElementNumber + $this->iLimit)) {
1107                                 $lastElementNumber = $this->firstElementNumber + $this->iLimit;
1108                         } else {
1109                                 $lastElementNumber = $this->totalItems;
1110                         }
1111                         $rangeIndicator = '<span class="pageIndicator">'
1112                                 . sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:rangeIndicator'), $this->firstElementNumber + 1, $lastElementNumber)
1113                                 . '</span>';
1114
1115                         $content .= '<div id="typo3-dblist-pagination">'
1116                                 . $first . $previous
1117                                 . '<span class="bar">&nbsp;</span>'
1118                                 . $rangeIndicator . '<span class="bar">&nbsp;</span>'
1119                                 . $pageIndicator . '<span class="bar">&nbsp;</span>'
1120                                 . $next . $last . '<span class="bar">&nbsp;</span>'
1121                                 . $reload
1122                                 . '</div>';
1123
1124                         $data = Array();
1125                         $titleColumn = $this->fieldArray[0];
1126                         $data[$titleColumn] = $content;
1127
1128                         $returnContent = $this->addElement(1, '', $data);
1129                 } // end of if pages > 1
1130
1131                 return $returnContent;
1132         }
1133
1134
1135
1136
1137
1138
1139         /*********************************
1140          *
1141          * Rendering of various elements
1142          *
1143          *********************************/
1144
1145         /**
1146          * Creates the control panel for a single record in the listing.
1147          *
1148          * @param       string          The table
1149          * @param       array           The record for which to make the control panel.
1150          * @return      string          HTML table with the control panel (unless disabled)
1151          */
1152         function makeControl($table,$row)       {
1153                 global $SOBE, $TYPO3_CONF_VARS;
1154
1155                 if ($this->dontShowClipControlPanels)   return '';
1156
1157                         // Initialize:
1158                 t3lib_div::loadTCA($table);
1159                 $cells=array();
1160
1161                         // If the listed table is 'pages' we have to request the permission settings for each page:
1162                 if ($table=='pages')    {
1163                         $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$row['uid']));
1164                 }
1165
1166                         // This expresses the edit permissions for this particular element:
1167                 $permsEdit = ($table=='pages' && ($localCalcPerms&2)) || ($table!='pages' && ($this->calcPerms&16));
1168
1169                         // "Show" link (only pages and tt_content elements)
1170                 if ($table=='pages' || $table=='tt_content')    {
1171                         $params='&edit['.$table.']['.$row['uid'].']=edit';
1172                         $cells['view'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::viewOnClick(
1173                                         $table=='tt_content' ? $this->id . '#' . $row['uid'] : $row['uid'],
1174                                         $this->backPath)
1175                                 ) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showPage', TRUE) . '">' .
1176                                 t3lib_iconWorks::getSpriteIcon('actions-document-view') . '</a>';
1177                 } elseif(!$this->table) {
1178                         $cells['view'] = $this->spaceIcon;
1179                 }
1180
1181                         // "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id)
1182                 if ($permsEdit) {
1183                         $params='&edit['.$table.']['.$row['uid'].']=edit';
1184                         $cells['edit'] = '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath, -1)) .
1185                                 '" title="' . $GLOBALS['LANG']->getLL('edit', TRUE) . '">' .
1186                                 ( $GLOBALS['TCA'][$table]['ctrl']['readOnly'] ? t3lib_iconWorks::getSpriteIcon('actions-document-open-read-only') : t3lib_iconWorks::getSpriteIcon('actions-document-open')) .
1187                                 '</a>';
1188                 } elseif(!$this->table) {
1189                         $cells['edit'] = $this->spaceIcon;
1190                 }
1191
1192                         // "Move" wizard link for pages/tt_content elements:
1193                 if (($table=="tt_content" && $permsEdit) || ($table=='pages'))  {
1194                         $cells['move'] = '<a href="#" onclick="' .
1195                                 htmlspecialchars(
1196                                         'return jumpExt(\'' . $this->backPath . 'move_el.php?table=' . $table . '&uid='.$row['uid'] . '\');'
1197                                 ) .'" title="' . $GLOBALS['LANG']->getLL('move_' . ($table == 'tt_content' ? 'record' : 'page'), TRUE) . '">' .
1198                                                 ($table == 'tt_content' ? t3lib_iconWorks::getSpriteIcon('actions-document-move') : t3lib_iconWorks::getSpriteIcon('actions-page-move')) .
1199                                         '</a>';
1200                 } elseif(!$this->table) {
1201                         $cells['move'] = $this->spaceIcon;
1202                 }
1203
1204                         // If the extended control panel is enabled OR if we are seeing a single table:
1205                 if ($SOBE->MOD_SETTINGS['bigControlPanel'] || $this->table)     {
1206
1207                                 // "Info": (All records)
1208                         $cells['viewBig'] = '<a href="#" onclick="' . htmlspecialchars(
1209                                         'top.launchView(\'' . $table . '\', \''.$row['uid'] . '\'); return false;'
1210                                 ) . '" title="' . $GLOBALS['LANG']->getLL('showInfo', TRUE) . '">'.
1211                                 t3lib_iconWorks::getSpriteIcon('actions-document-info') .
1212                                 '</a>';
1213
1214                                 // If the table is NOT a read-only table, then show these links:
1215                         if (!$GLOBALS['TCA'][$table]['ctrl']['readOnly']) {
1216
1217                                         // "Revert" link (history/undo)
1218                                 $cells['history'] = '<a href="#" onclick="' . htmlspecialchars(
1219                                         'return jumpExt(\'' . $this->backPath . 'show_rechis.php?element=' . rawurlencode($table . ':' . $row['uid']) . '\',\'#latest\');') .
1220                                         '" title="' . $GLOBALS['LANG']->getLL('history', TRUE) . '">'.
1221                                         t3lib_iconWorks::getSpriteIcon('actions-document-history-open') .
1222                                         '</a>';
1223
1224                                         // Versioning:
1225                                 if (t3lib_extMgm::isLoaded('version'))  {
1226                                         $vers = t3lib_BEfunc::selectVersionsOfRecord($table, $row['uid'], 'uid', $GLOBALS['BE_USER']->workspace, FALSE, $row);
1227                                         if (is_array($vers))    {       // If table can be versionized.
1228                                                 $versionIcon = 'no-version';
1229                                                 if (count($vers) > 1) {
1230                                                         $versionIcon = count($vers) - 1;
1231                                                 }
1232
1233                                                 $cells['version'] = '<a href="' . htmlspecialchars($this->backPath . t3lib_extMgm::extRelPath('version') . 'cm1/index.php?table=' . rawurlencode($table) . '&uid=' . rawurlencode($row['uid'])) . '" title="' . $GLOBALS['LANG']->getLL('displayVersions', TRUE) . '">' .
1234                                                                 t3lib_iconWorks::getSpriteIcon('status-version-' . $versionIcon) .
1235                                                                 '</a>';
1236                                         } elseif(!$this->table) {
1237                                                 $cells['version'] = $this->spaceIcon;
1238                                         }
1239                                 }
1240
1241                                         // "Edit Perms" link:
1242                                 if ($table == 'pages' && $GLOBALS['BE_USER']->check('modules','web_perm') && t3lib_extMgm::isLoaded('perm'))    {
1243                                         $cells['perms'] =
1244                                                 '<a href="' .
1245                                                         htmlspecialchars(
1246                                                                 t3lib_extMgm::extRelPath('perm') . 'mod1/index.php' .
1247                                                                 '?id=' . $row['uid'] . '&return_id=' . $row['uid'] . '&edit=1'
1248                                                         ) .
1249                                                         '" title="' . $GLOBALS['LANG']->getLL('permissions', TRUE) .
1250                                                 '">'.
1251                                                         t3lib_iconWorks::getSpriteIcon('status-status-locked') .
1252                                                 '</a>';
1253                                 } elseif(!$this->table && $GLOBALS['BE_USER']->check('modules','web_perm')) {
1254                                         $cells['perms'] = $this->spaceIcon;
1255                                 }
1256
1257                                         // "New record after" link (ONLY if the records in the table are sorted by a "sortby"-row or if default values can depend on previous record):
1258                                 if ($GLOBALS['TCA'][$table]['ctrl']['sortby'] || $GLOBALS['TCA'][$table]['ctrl']['useColumnsForDefaultValues']) {
1259                                         if (
1260                                                 ($table!='pages' && ($this->calcPerms&16)) ||   // For NON-pages, must have permission to edit content on this parent page
1261                                                 ($table=='pages' && ($this->calcPerms&8))               // For pages, must have permission to create new pages here.
1262                                                 )       {
1263                                                 if ($this->showNewRecLink($table))      {
1264                                                         $params='&edit['.$table.']['.(-($row['_MOVE_PLH']?$row['_MOVE_PLH_uid']:$row['uid'])).']=new';
1265                                                         $cells['new'] = '<a href="#" onclick="' . htmlspecialchars(
1266                                                                 t3lib_BEfunc::editOnClick($params, $this->backPath, -1)) .
1267                                                                 '" title="' . $GLOBALS['LANG']->getLL('new' . ($table == 'pages '? 'Page' : 'Record'), TRUE) . '">' .
1268                                                                 ($table == 'pages' ? t3lib_iconWorks::getSpriteIcon('actions-page-new') : t3lib_iconWorks::getSpriteIcon('actions-document-new')) .
1269                                                                 '</a>';
1270                                                 }
1271                                         }
1272                                 } elseif(!$this->table) {
1273                                         $cells['new'] = $this->spaceIcon;
1274                                 }
1275
1276                                         // "Up/Down" links
1277                                 if ($permsEdit && $GLOBALS['TCA'][$table]['ctrl']['sortby']  && !$this->sortField && !$this->searchLevels) {
1278                                         if (isset($this->currentTable['prev'][$row['uid']]))    {       // Up
1279                                                 $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['prev'][$row['uid']];
1280                                                 $cells['moveUp'] = '<a href="#" onclick="' . htmlspecialchars(
1281                                                                         'return jumpToUrl(\'' . $SOBE->doc->issueCommand($params, -1) . '\');'
1282                                                                 ) .'" title="'.$GLOBALS['LANG']->getLL('moveUp', TRUE) . '">' .
1283                                                                 t3lib_iconWorks::getSpriteIcon('actions-move-up') .
1284                                                                 '</a>';
1285                                         } else {
1286                                                 $cells['moveUp'] = $this->spaceIcon;
1287                                         }
1288                                         if ($this->currentTable['next'][$row['uid']])   {       // Down
1289                                                 $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['next'][$row['uid']];
1290                                                 $cells['moveDown']='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'" title="'.$GLOBALS['LANG']->getLL('moveDown', TRUE) . '">' .
1291                                                                         t3lib_iconWorks::getSpriteIcon('actions-move-down') .
1292                                                                 '</a>';
1293                                         } else {
1294                                                 $cells['moveDown'] = $this->spaceIcon;
1295                                         }
1296                                 } elseif(!$this->table) {
1297                                         $cells['moveUp']  = $this->spaceIcon;
1298                                         $cells['moveDown'] = $this->spaceIcon;
1299                                 }
1300
1301                                         // "Hide/Unhide" links:
1302                                 $hiddenField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
1303                                 if ($permsEdit && $hiddenField && $GLOBALS['TCA'][$table]['columns'][$hiddenField] && (!$GLOBALS['TCA'][$table]['columns'][$hiddenField]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $table . ':' . $hiddenField))) {
1304                                         if ($row[$hiddenField]) {
1305                                                 $params='&data['.$table.']['.$row['uid'].']['.$hiddenField.']=0';
1306                                                 $cells['hide']='<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $SOBE->doc->issueCommand($params, -1) . '\');') . '" title="'.$GLOBALS['LANG']->getLL('unHide' . ($table == 'pages' ? 'Page' : ''), TRUE) . '">' .
1307                                                                         t3lib_iconWorks::getSpriteIcon('actions-edit-unhide') .
1308                                                                 '</a>';
1309                                         } else {
1310                                                 $params='&data['.$table.']['.$row['uid'].']['.$hiddenField.']=1';
1311                                                 $cells['hide']='<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $SOBE->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('hide' . ($table == 'pages' ? 'Page' : ''), TRUE) . '">' .
1312                                                                         t3lib_iconWorks::getSpriteIcon('actions-edit-hide') .
1313                                                                 '</a>';
1314                                         }
1315                                 } elseif(!$this->table) {
1316                                         $cells['hide'] = $this->spaceIcon;
1317                                 }
1318
1319                                         // "Delete" link:
1320                                 if (($table=='pages' && ($localCalcPerms&4)) || ($table!='pages' && ($this->calcPerms&16))) {
1321                                         $titleOrig = t3lib_BEfunc::getRecordTitle($table,$row,FALSE,TRUE);
1322                                         $title = t3lib_div::slashJS(t3lib_div::fixed_lgd_cs($titleOrig, $this->fixedL), 1);
1323                                         $params = '&cmd['.$table.']['.$row['uid'].'][delete]=1';
1324
1325                                         $refCountMsg = t3lib_BEfunc::referenceCount(
1326                                                 $table,
1327                                                 $row['uid'],
1328                                                 ' ' . $GLOBALS['LANG']->sL(
1329                                                         'LLL:EXT:lang/locallang_core.xml:labels.referencesToRecord'
1330                                                 ),
1331                                                 $this->getReferenceCount($table, $row['uid'])
1332                                         ) .
1333                                                 t3lib_BEfunc::translationCount($table, $row['uid'], ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.translationsOfRecord'));
1334                                         $cells['delete'] = '<a href="#" onclick="' . htmlspecialchars('if (confirm(' . $GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->getLL('deleteWarning') . ' "' .  $title . '" ' . $refCountMsg) . ')) {jumpToUrl(\'' . $SOBE->doc->issueCommand($params, -1) . '\');} return false;') . '" title="' . $GLOBALS['LANG']->getLL('delete', TRUE) . '">' .
1335                                                         t3lib_iconWorks::getSpriteIcon('actions-edit-delete') .
1336                                                         '</a>';
1337                                 } elseif(!$this->table) {
1338                                         $cells['delete'] = $this->spaceIcon;
1339                                 }
1340
1341                                         // "Levels" links: Moving pages into new levels...
1342                                 if ($permsEdit && $table=='pages' && !$this->searchLevels)      {
1343
1344                                                 // Up (Paste as the page right after the current parent page)
1345                                         if ($this->calcPerms&8) {
1346                                                 $params='&cmd['.$table.']['.$row['uid'].'][move]='.-$this->id;
1347                                                 $cells['moveLeft'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $SOBE->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('prevLevel', TRUE) . '">' .
1348                                                                         t3lib_iconWorks::getSpriteIcon('actions-move-left') .
1349                                                                 '</a>';
1350                                         }
1351                                                 // Down (Paste as subpage to the page right above)
1352                                         if ($this->currentTable['prevUid'][$row['uid']])        {
1353                                                 $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$this->currentTable['prevUid'][$row['uid']]));
1354                                                 if ($localCalcPerms&8)  {
1355                                                         $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['prevUid'][$row['uid']];
1356                                                         $cells['moveRight'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $SOBE->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('nextLevel', TRUE) . '">' .
1357                                                                                 t3lib_iconWorks::getSpriteIcon('actions-move-right') .
1358                                                                         '</a>';
1359                                                 } else {
1360                                                         $cells['moveRight'] = $this->spaceIcon;
1361                                                 }
1362                                         } else {
1363                                                 $cells['moveRight'] = $this->spaceIcon;
1364                                         }
1365                                 } elseif(!$this->table) {
1366                                         $cells['moveLeft'] = $this->spaceIcon;
1367                                         $cells['moveRight'] = $this->spaceIcon;
1368                                 }
1369                         }
1370                 }
1371
1372
1373                 /**
1374                  * @hook                        recStatInfoHooks: Allows to insert HTML before record icons on various places
1375                  * @date                        2007-09-22
1376                  * @request             Kasper Skårhøj  <kasper2007@typo3.com>
1377                  */
1378                 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['GLOBAL']['recStatInfoHooks']))     {
1379                         $stat='';
1380                         $_params = array($table,$row['uid']);
1381                         foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef)     {
1382                                 $stat.=t3lib_div::callUserFunction($_funcRef,$_params,$this);
1383                         }
1384                         $cells['stat'] = $stat;
1385                 }
1386                 /**
1387                  * @hook                        makeControl: Allows to change control icons of records in list-module
1388                  * @date                        2007-11-20
1389                  * @request             Bernhard Kraft  <krafbt@kraftb.at>
1390                  * @usage               This hook method gets passed the current $cells array as third parameter. This array contains values for the icons/actions generated for each record in Web>List. Each array entry is accessible by an index-key. The order of the icons is dependend on the order of those array entries.
1391                  */
1392                 if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) {
1393                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) {
1394                                 $hookObject = t3lib_div::getUserObj($classData);
1395                                 if(!($hookObject instanceof localRecordList_actionsHook))       {
1396                                         throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567840);
1397                                 }
1398                                 $cells = $hookObject->makeControl($table, $row, $cells, $this);
1399                         }
1400                 }
1401
1402                         // Compile items into a DIV-element:
1403                 return '
1404                                                                                         <!-- CONTROL PANEL: '.$table.':'.$row['uid'].' -->
1405                                                                                         <div class="typo3-DBctrl">'.implode('',$cells).'</div>';
1406         }
1407
1408         /**
1409          * Creates the clipboard panel for a single record in the listing.
1410          *
1411          * @param       string          The table
1412          * @param       array           The record for which to make the clipboard panel.
1413          * @return      string          HTML table with the clipboard panel (unless disabled)
1414          */
1415         function makeClip($table,$row)  {
1416                 global $TYPO3_CONF_VARS;
1417
1418                         // Return blank, if disabled:
1419                 if ($this->dontShowClipControlPanels)   return '';
1420                 $cells=array();
1421
1422                 $cells['pasteAfter'] = $cells['pasteInto'] = $this->spaceIcon;
1423                         //enables to hide the copy, cut and paste icons for localized records - doesn't make much sense to perform these options for them
1424                 $isL10nOverlay = $this->localizationView && $table != 'pages_language_overlay' && $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0;
1425                         // Return blank, if disabled:
1426                         // Whether a numeric clipboard pad is active or the normal pad we will see different content of the panel:
1427                 if ($this->clipObj->current=='normal')  {       // For the "Normal" pad:
1428
1429                                 // Show copy/cut icons:
1430                         $isSel = (string)$this->clipObj->isSelected($table,$row['uid']);
1431                         $cells['copy'] = $isL10nOverlay ? $this->spaceIcon : '<a href="#" onclick="' . htmlspecialchars('return jumpSelf(\'' . $this->clipObj->selUrlDB($table, $row['uid'], 1, ($isSel=='copy'), array('returnUrl'=>'')) . '\');') . '" title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.copy', TRUE) . '">' .
1432                                                 ((!$isSel=='copy') ? t3lib_iconWorks::getSpriteIcon('actions-edit-copy') : t3lib_iconWorks::getSpriteIcon('actions-edit-copy-release')) .
1433                                         '</a>';
1434                         $cells['cut'] = $isL10nOverlay ? $this->spaceIcon : '<a href="#" onclick="' . htmlspecialchars('return jumpSelf(\'' . $this->clipObj->selUrlDB($table, $row['uid'], 0, ($isSel == 'cut'), array('returnUrl'=>'')) . '\');') . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.cut', TRUE) . '">' .
1435                                                 ((!$isSel=='cut') ? t3lib_iconWorks::getSpriteIcon('actions-edit-cut') : t3lib_iconWorks::getSpriteIcon('actions-edit-cut-release')) .
1436                                         '</a>';
1437
1438                 } else {        // For the numeric clipboard pads (showing checkboxes where one can select elements on/off)
1439
1440                                 // Setting name of the element in ->CBnames array:
1441                         $n=$table.'|'.$row['uid'];
1442                         $this->CBnames[]=$n;
1443
1444                                 // Check if the current element is selected and if so, prepare to set the checkbox as selected:
1445                         $checked = ($this->clipObj->isSelected($table,$row['uid'])?' checked="checked"':'');
1446
1447                                 // If the "duplicateField" value is set then select all elements which are duplicates...
1448                         if ($this->duplicateField && isset($row[$this->duplicateField]))        {
1449                                 $checked='';
1450                                 if (in_array($row[$this->duplicateField], $this->duplicateStack))       {
1451                                         $checked=' checked="checked"';
1452                                 }
1453                                 $this->duplicateStack[] = $row[$this->duplicateField];
1454                         }
1455
1456                                 // Adding the checkbox to the panel:
1457                         $cells['select'] = $isL10nOverlay ? $this->spaceIcon : '<input type="hidden" name="CBH['.$n.']" value="0" /><input type="checkbox" name="CBC['.$n.']" value="1" class="smallCheckboxes"'.$checked.' />';
1458                 }
1459
1460                         // Now, looking for selected elements from the current table:
1461                 $elFromTable = $this->clipObj->elFromTable($table);
1462                 if (count($elFromTable) && $GLOBALS['TCA'][$table]['ctrl']['sortby']){
1463                                 // IF elements are found and they can be individually ordered, then add a "paste after" icon:
1464                         $cells['pasteAfter'] = $isL10nOverlay ? $this->spaceIcon : '<a href="' . htmlspecialchars($this->clipObj->pasteUrl($table, -$row['uid'])) . '" onclick="' . htmlspecialchars('return '. $this->clipObj->confirmMsg($table, $row, 'after', $elFromTable)) . '" title="' . $GLOBALS['LANG']->getLL('clip_pasteAfter', TRUE) . '">' .
1465                                                 t3lib_iconWorks::getSpriteIcon('actions-document-paste-after') .
1466                                         '</a>';
1467                 }
1468
1469                         // Now, looking for elements in general:
1470                 $elFromTable = $this->clipObj->elFromTable('');
1471                 if ($table=='pages' && count($elFromTable))     {
1472                         $cells['pasteInto'] = '<a href="' . htmlspecialchars($this->clipObj->pasteUrl('', $row['uid'])) . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg($table, $row, 'into', $elFromTable)) . '" title="' . $GLOBALS['LANG']->getLL('clip_pasteInto', TRUE) . '">' .
1473                                                 t3lib_iconWorks::getSpriteIcon('actions-document-paste-into') .
1474                                         '</a>';
1475                 }
1476
1477                 /*
1478                  * @hook                        makeClip: Allows to change clip-icons of records in list-module
1479                  * @date                        2007-11-20
1480                  * @request             Bernhard Kraft  <krafbt@kraftb.at>
1481                  * @usage               This hook method gets passed the current $cells array as third parameter. This array contains values for the clipboard icons generated for each record in Web>List. Each array entry is accessible by an index-key. The order of the icons is dependend on the order of those array entries.
1482                  */
1483                 if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) {
1484                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) {
1485                                 $hookObject = t3lib_div::getUserObj($classData);
1486                                 if(!($hookObject instanceof localRecordList_actionsHook))       {
1487                                         throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567845);
1488                                 }
1489                                 $cells = $hookObject->makeClip($table, $row, $cells, $this);
1490                         }
1491                 }
1492
1493                         // Compile items into a DIV-element:
1494                 return '                                                        <!-- CLIPBOARD PANEL: '.$table.':'.$row['uid'].' -->
1495                                                                                         <div class="typo3-clipCtrl">'.implode('',$cells).'</div>';
1496         }
1497
1498         /**
1499          * Make reference count
1500          *
1501          * @param       string          Table name
1502          * @param       integer         UID of record
1503          * @return      string          HTML-table
1504          *
1505          * @deprecated since 4.4, will be removed in TYPO3 4.6 - Use createReferenceHtml() instead
1506          */
1507         function makeRef($table,$uid)   {
1508                 t3lib_div::logDeprecatedFunction();
1509
1510                         // Compile information for title tag:
1511                 $infoData=array();
1512                 if (is_array($this->references)) {
1513                         foreach ($this->references as $row) {
1514                                 $infoData[]=$row['tablename'].':'.$row['recuid'].':'.$row['field'];
1515                         }
1516                 }
1517
1518                 return count($infoData) ? '<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$table.'\', \''.$uid.'\'); return false;').'" title="'.htmlspecialchars(t3lib_div::fixed_lgd_cs(implode(' / ',$infoData),100)).'">'.count($infoData).'</a>' : '';
1519         }
1520
1521         /**
1522          * Creates the HTML for a reference count for the record with the UID $uid
1523          * in the table $tableName.
1524          *
1525          * @param string $tableName
1526          *        table name of the referenced record, must not be empty
1527          * @param integer $uid
1528          *        UID of the referenced record, must be > 0
1529          *
1530          * @return string HTML of reference a link, will be empty if there are no
1531          *                references to the corresponding record
1532          */
1533         protected function createReferenceHtml($tableName, $uid) {
1534                 $referenceCount = $this->getReferenceCount($tableName, $uid);
1535                 if ($referenceCount == 0) {
1536                         return '';
1537                 }
1538
1539                 $queryResult = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1540                         'tablename, recuid, field',
1541                         'sys_refindex',
1542                         'ref_table = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
1543                                 $tableName, 'sys_refindex'
1544                         ) .
1545                                 ' AND ref_uid = ' . $uid .
1546                                 ' AND deleted = 0',
1547                         '',
1548                         '',
1549                         '0,20'
1550                 );
1551
1552                 $referenceTitles = array();
1553
1554                 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($queryResult)) {
1555                         $referenceTitles[] = $row['tablename'] . ':' . $row['recuid'] .
1556                                 ':' . $row['field'];
1557                         if (strlen(implode(' / ', $referenceTitles)) >= 100) {
1558                                 break;
1559                         }
1560                 }
1561                 $GLOBALS['TYPO3_DB']->sql_free_result($queryResult);
1562
1563                 return '<a href="#" ' .
1564                         'onclick="' . htmlspecialchars(
1565                                 'top.launchView(\'' . $tableName . '\', \'' . $uid .
1566                                 '\'); return false;'
1567                         ) . '" ' .
1568                         'title="' . htmlspecialchars(
1569                                 t3lib_div::fixed_lgd_cs(implode(' / ', $referenceTitles), 100)
1570                         ) . '">' . $referenceCount . '</a>';
1571         }
1572
1573         /**
1574          * Creates the localization panel
1575          *
1576          * @param       string          The table
1577          * @param       array           The record for which to make the localization panel.
1578          * @return      array           Array with key 0/1 with content for column 1 and 2
1579          */
1580         function makeLocalizationPanel($table,$row)     {
1581                 $out = array(
1582                         0 => '',
1583                         1 => '',
1584                 );
1585
1586                 $translations = $this->translateTools->translationInfo($table, $row['uid'], 0, $row, $this->selFieldList);
1587                 $this->translations = $translations['translations'];
1588
1589                         // Language title and icon:
1590                 $out[0] = $this->languageFlag($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']]);
1591
1592                 if (is_array($translations))    {
1593
1594                                 // Traverse page translations and add icon for each language that does NOT yet exist:
1595                         $lNew = '';
1596                         foreach($this->pageOverlays as $lUid_OnPage => $lsysRec)        {
1597                                 if (!isset($translations['translations'][$lUid_OnPage]) && $GLOBALS['BE_USER']->checkLanguageAccess($lUid_OnPage))      {
1598                                         $url = substr($this->listURL(), strlen($this->backPath));
1599                                         $href = $GLOBALS['SOBE']->doc->issueCommand(
1600                                                 '&cmd[' . $table . '][' . $row['uid'] . '][localize]=' . $lUid_OnPage,
1601                                                 $url . '&justLocalized=' . rawurlencode($table . ':' . $row['uid'] . ':' . $lUid_OnPage)
1602                                         );
1603                                         $language = t3lib_BEfunc::getRecord('sys_language', $lUid_OnPage, 'title');
1604                                         if ($this->languageIconTitles[$lUid_OnPage]['flagIcon']) {
1605                                                 $lC = t3lib_iconWorks::getSpriteIcon($this->languageIconTitles[$lUid_OnPage]['flagIcon']);
1606                                         } else {
1607                                                 $lC = $this->languageIconTitles[$lUid_OnPage]['title'];
1608                                         }
1609                                         $lC = '<a href="' . htmlspecialchars($href) . '" title="' . htmlspecialchars($language['title']) . '">' . $lC . '</a> ';
1610
1611                                         $lNew.=$lC;
1612                                 }
1613                         }
1614
1615                         if ($lNew)      $out[1].= $lNew;
1616                 } elseif ($row['l18n_parent']) {
1617                         $out[0] = '&nbsp;&nbsp;&nbsp;&nbsp;'.$out[0];
1618                 }
1619
1620
1621                 return $out;
1622         }
1623
1624         /**
1625          * Create the selector box for selecting fields to display from a table:
1626          *
1627          * @param       string          Table name
1628          * @param       boolean         If TRUE, form-fields will be wrapped around the table.
1629          * @return      string          HTML table with the selector box (name: displayFields['.$table.'][])
1630          */
1631         function fieldSelectBox($table,$formFields=1)   {
1632
1633                         // Init:
1634                 t3lib_div::loadTCA($table);
1635                 $formElements=array('','');
1636                 if ($formFields)        {
1637                         $formElements=array('<form action="'.htmlspecialchars($this->listURL()).'" method="post">','</form>');
1638                 }
1639
1640                         // Load already selected fields, if any:
1641                 $setFields=is_array($this->setFields[$table]) ? $this->setFields[$table] : array();
1642
1643                         // Request fields from table:
1644                 $fields = $this->makeFieldList($table, FALSE, TRUE);
1645
1646                         // Add pseudo "control" fields
1647                 $fields[]='_PATH_';
1648                 $fields[]='_REF_';
1649                 $fields[]='_LOCALIZATION_';
1650                 $fields[]='_CONTROL_';
1651                 $fields[]='_CLIPBOARD_';
1652
1653                         // Create an option for each field:
1654                 $opt=array();
1655                 $opt[] = '<option value=""></option>';
1656                 foreach($fields as $fN) {
1657                                 // Field label
1658                         $fL = (is_array($GLOBALS['TCA'][$table]['columns'][$fN])
1659                                 ? rtrim($GLOBALS['LANG']->sL($GLOBALS['TCA'][$table]['columns'][$fN]['label']), ':')
1660                                 : '[' . $fN . ']');
1661                         $opt[] = '
1662                                                                                         <option value="'.$fN.'"'.(in_array($fN,$setFields)?' selected="selected"':'').'>'.htmlspecialchars($fL).'</option>';
1663                 }
1664
1665                         // Compile the options into a multiple selector box:
1666                 $lMenu = '
1667                                                                                 <select size="'.t3lib_div::intInRange(count($fields)+1,3,20).'" multiple="multiple" name="displayFields['.$table.'][]">'.implode('',$opt).'
1668                                                                                 </select>
1669                                 ';
1670
1671                         // Table with the field selector::
1672                 $content.= '
1673                         '.$formElements[0].'
1674
1675                                 <!--
1676                                         Field selector for extended table view:
1677                                 -->
1678                                 <table border="0" cellpadding="0" cellspacing="0" id="typo3-dblist-fieldSelect">
1679                                         <tr>
1680                                                 <td>'.$lMenu.'</td>
1681                                                 <td><input type="submit" name="search" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.setFields', 1) . '" /></td>
1682                                         </tr>
1683                                 </table>
1684                         '.$formElements[1];
1685                 return $content;
1686         }
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698         /*********************************
1699          *
1700          * Helper functions
1701          *
1702          *********************************/
1703
1704         /**
1705          * Creates a link around $string. The link contains an onclick action which submits the script with some clipboard action.
1706          * Currently, this is used for setting elements / delete elements.
1707          *
1708          * @param       string          The HTML content to link (image/text)
1709          * @param       string          Table name
1710          * @param       string          Clipboard command (eg. "setCB" or "delete")
1711          * @param       string          Warning text, if any ("delete" uses this for confirmation)
1712          * @return      string          <a> tag wrapped link.
1713          */
1714         function linkClipboardHeaderIcon($string,$table,$cmd,$warning='')       {
1715                 $onClickEvent = 'document.dblistForm.cmd.value=\''.$cmd.'\';document.dblistForm.cmd_table.value=\''.$table.'\';document.dblistForm.submit();';
1716                 if ($warning)   $onClickEvent = 'if (confirm('.$GLOBALS['LANG']->JScharCode($warning).')){'.$onClickEvent.'}';
1717                 return '<a href="#" onclick="'.htmlspecialchars($onClickEvent.'return false;').'">'.$string.'</a>';
1718         }
1719
1720         /**
1721          * Returns TRUE if a numeric clipboard pad is selected/active
1722          *
1723          * @return      boolean
1724          */
1725         function clipNumPane()  {
1726                 return in_Array('_CLIPBOARD_',$this->fieldArray) && $this->clipObj->current!='normal';
1727         }
1728
1729         /**
1730          * Creates a sort-by link on the input string ($code).
1731          * It will automatically detect if sorting should be ascending or descending depending on $this->sortRev.
1732          * Also some fields will not be possible to sort (including if single-table-view is disabled).
1733          *
1734          * @param       string          The string to link (text)
1735          * @param       string          The fieldname represented by the title ($code)
1736          * @param       string          Table name
1737          * @return      string          Linked $code variable
1738          */
1739         function addSortLink($code,$field,$table)       {
1740
1741                         // Certain circumstances just return string right away (no links):
1742                 if ($field=='_CONTROL_' || $field=='_LOCALIZATION_' || $field=='_CLIPBOARD_' || $field=='_REF_' || $this->disableSingleTableView)       return $code;
1743
1744                         // If "_PATH_" (showing record path) is selected, force sorting by pid field (will at least group the records!)
1745                 if ($field=='_PATH_')   $field=pid;
1746
1747                         //       Create the sort link:
1748                 $sortUrl = $this->listURL('', -1, 'sortField,sortRev,table,firstElementNumber') . '&table=' . $table . '&sortField=' . $field . '&sortRev=' . ($this->sortRev || ($this->sortField != $field) ? 0 : 1);
1749                 $sortArrow = ($this->sortField==$field?'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/red'.($this->sortRev?'up':'down').'.gif','width="7" height="4"').' alt="" />':'');
1750
1751                         // Return linked field:
1752                 return '<a href="'.htmlspecialchars($sortUrl).'">'.$code.
1753                                 $sortArrow.
1754                                 '</a>';
1755         }
1756
1757         /**
1758          * Returns the path for a certain pid
1759          * The result is cached internally for the session, thus you can call this function as much as you like without performance problems.
1760          *
1761          * @param       integer         The page id for which to get the path
1762          * @return      string          The path.
1763          */
1764         function recPath($pid)  {
1765                 if (!isset($this->recPath_cache[$pid])) {
1766                         $this->recPath_cache[$pid] = t3lib_BEfunc::getRecordPath($pid,$this->perms_clause,20);
1767                 }
1768                 return $this->recPath_cache[$pid];
1769         }
1770
1771         /**
1772          * Returns TRUE if a link for creating new records should be displayed for $table
1773          *
1774          * @param       string          Table name
1775          * @return      boolean         Returns TRUE if a link for creating new records should be displayed for $table
1776          * @see         SC_db_new::showNewRecLink
1777          */
1778         function showNewRecLink($table) {
1779                         // No deny/allow tables are set:
1780                 if (!count($this->allowedNewTables) && !count($this->deniedNewTables)) {
1781                         return TRUE;
1782                         // If table is not denied (which takes precedence over allowed tables):
1783                 } elseif (!in_array($table, $this->deniedNewTables) && (!count($this->allowedNewTables) || in_array($table, $this->allowedNewTables))) {
1784                         return TRUE;
1785                         // If table is denied or allowed tables are set, but table is not part of:
1786                 } else {
1787                         return FALSE;
1788                 }
1789         }
1790
1791         /**
1792          * Creates the "&returnUrl" parameter for links - this is used when the script links to other scripts and passes its own URL with the link so other scripts can return to the listing again.
1793          * Uses REQUEST_URI as value.
1794          *
1795          * @return      string
1796          */
1797         function makeReturnUrl()        {
1798                 return '&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'));
1799         }
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811         /************************************
1812          *
1813          * CSV related functions
1814          *
1815          ************************************/
1816
1817         /**
1818          * Initializes internal csvLines array with the header of field names
1819          *
1820          * @return      void
1821          */
1822         protected function initCSV() {
1823                 $this->addHeaderRowToCSV();
1824         }
1825
1826         /**
1827          * Add header line with field names as CSV line
1828          *
1829          * @return void
1830          */
1831         protected function addHeaderRowToCSV() {
1832                         // Add header row, control fields will be reduced inside addToCSV()
1833                 $this->addToCSV(array_combine($this->fieldArray, $this->fieldArray));
1834         }
1835
1836         /**
1837          * Adds selected columns of one table row as CSV line.
1838          *
1839          * @param       array           Record array, from which the values of fields found in $this->fieldArray will be listed in the CSV output.
1840          * @param       string          Table name @deprecated since 4.4
1841          * @return      void
1842          */
1843         protected function addToCSV(array $row = array(), $table = '') {
1844                 $rowReducedByControlFields = self::removeControlFieldsFromFieldRow($row);
1845                 $rowReducedToSelectedColumns = array_intersect_key($rowReducedByControlFields, array_flip($this->fieldArray));
1846                 $this->setCsvRow($rowReducedToSelectedColumns);
1847         }
1848
1849         /**
1850          * Remove control fields from row for CSV export
1851          *
1852          * @param array fieldNames => fieldValues
1853          * @return array Input array reduces by control fields
1854          */
1855         protected static function removeControlFieldsFromFieldRow(array $row = array()) {
1856                         // Possible control fields in a list row
1857                 $controlFields = array(
1858                         '_PATH_',
1859                         '_REF_',
1860                         '_CONTROL_',
1861                         '_AFTERCONTROL_',
1862                         '_AFTERREF_',
1863                         '_CLIPBOARD_',
1864                         '_LOCALIZATION_',
1865                         '_LOCALIZATION_b',
1866                 );
1867                 return array_diff_key($row, array_flip($controlFields));
1868         }
1869
1870
1871         /**
1872          * Adds input row of values to the internal csvLines array as a CSV formatted line
1873          *
1874          * @param       array           Array with values to be listed.
1875          * @return      void
1876          */
1877         function setCsvRow($csvRow)     {
1878                 $this->csvLines[] = t3lib_div::csvValues($csvRow);
1879         }
1880
1881         /**
1882          * Compiles the internal csvLines array to a csv-string and outputs it to the browser.
1883          * This function exits!
1884          *
1885          * @param       string          Filename prefix:
1886          * @return      void            EXITS php execusion!
1887          */
1888         function outputCSV($prefix)     {
1889
1890                         // Setting filename:
1891                 $filename=$prefix.'_'.date('dmy-Hi').'.csv';
1892
1893                         // Creating output header:
1894                 $mimeType = 'application/octet-stream';
1895                 Header('Content-Type: '.$mimeType);
1896                 Header('Content-Disposition: attachment; filename='.$filename);
1897
1898                         // Printing the content of the CSV lines:
1899                 echo implode(chr(13).chr(10),$this->csvLines);
1900
1901                         // Exits:
1902                 exit;
1903         }
1904 }
1905
1906
1907
1908 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/class.db_list_extra.inc'])) {
1909         include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/class.db_list_extra.inc']);
1910 }
1911
1912 ?>