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