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