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