Follow up to #7986: in some cases columns were not aligned, credits Steffen Kamper
[Packages/TYPO3.CMS.git] / typo3 / class.db_list_extra.inc
1 <?php
2 /*************************************************************
3 *  Copyright notice
4 *
5 *  (c) 1999-2008 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         /**
123          * Create the panel of buttons for submitting the form or otherwise perform operations.
124          *
125          * @return      array   all available buttons as an assoc. array
126          */
127         public function getButtons()    {
128                 global $LANG;
129
130                 $buttons = array(
131                         'csh' => '',
132                         'view' => '',
133                         'edit' => '',
134                         'hide_unhide' => '',
135                         'move' => '',
136                         'new_record' => '',
137                         'paste' => '',
138                         'level_up' => '',
139                         'cache' => '',
140                         'reload' => '',
141                         'shortcut' => '',
142                         'back' => '',
143                         'csv' => '',
144                         'export' => ''
145                 );
146
147                         // Get users permissions for this page record:
148                 $localCalcPerms = $GLOBALS['BE_USER']->calcPerms($this->pageRow);
149
150                         // CSH
151                 if (!strlen($this->id)) {
152                         $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module_noId', $GLOBALS['BACK_PATH']);
153                 } elseif(!$this->id) {
154                         $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module_root', $GLOBALS['BACK_PATH']);
155                 } else {
156                         $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module', $GLOBALS['BACK_PATH']);
157                 }
158
159                 if (isset($this->id)) {
160                                 // View
161                         $buttons['view'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::viewOnClick($this->id, $this->backPath, t3lib_BEfunc::BEgetRootLine($this->id))) . '">' .
162                                                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/zoom.gif') . ' title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showPage', 1) . '" alt="" />' .
163                                                         '</a>';
164
165                                 // New record
166                         if (!$GLOBALS['SOBE']->modTSconfig['properties']['noCreateRecordsLink']) {
167                                 $buttons['new_record'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'db_new.php?id=' . $this->id . '\');') . '">' .
168                                                                 '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/new_el.gif') . ' title="' . $LANG->getLL('newRecordGeneral', 1) . '" alt="" />' .
169                                                                 '</a>';
170                         }
171
172                                 // If edit permissions are set (see class.t3lib_userauthgroup.php)
173                         if ($localCalcPerms&2 && !empty($this->id))     {
174
175                                         // Edit
176                                 $params = '&edit[pages][' . $this->pageRow['uid'] . ']=edit';
177                                 $buttons['edit'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath, -1)) . '">' .
178                                                                 '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/edit2.gif') . ' title="' . $LANG->getLL('editPage', 1) . '" alt="" />' .
179                                                                 '</a>';
180                                         // Unhide
181                                 if ($this->pageRow['hidden'])   {
182                                         $params = '&data[pages][' . $this->pageRow['uid'] . '][hidden]=0';
183                                         $buttons['hide_unhide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '">' .
184                                                                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/button_unhide.gif') . ' title="' . $LANG->getLL('unHidePage', 1) . '" alt="" />' .
185                                                                         '</a>';
186                                         // Hide
187                                 } else {
188                                         $params = '&data[pages][' . $this->pageRow['uid'] . '][hidden]=1';
189                                         $buttons['hide_unhide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '">'.
190                                                                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/button_hide.gif') . ' title="' . $LANG->getLL('hidePage', 1) . '" alt="" />' .
191                                                                         '</a>';
192                                 }
193
194                                         // Move
195                                 $buttons['move'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'move_el.php?table=pages&uid=' . $this->pageRow['uid'] . '\');') . '">' .
196                                                                 '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/move_' . ($this->table == 'tt_content' ? 'record' : 'page') . '.gif') . ' title="' . $LANG->getLL('move_page', 1) . '" alt="" />' .
197                                                                 '</a>';
198
199                                         // Up one level
200                                 $buttons['level_up'] = '<a href="' . htmlspecialchars($this->listURL($this->pageRow['pid'])) . '" onclick="setHighlight(' . $this->pageRow['pid'] . ')">' .
201                                                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/i/pages_up.gif') . ' title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.upOneLevel', 1) . '" alt="" />' .
202                                                         '</a>';
203
204                         }
205
206
207                                 // Paste
208                         if (($localCalcPerms&8) || ($localCalcPerms&16)) {
209                                 $elFromTable = $this->clipObj->elFromTable('');
210                                 if (count($elFromTable)) {
211                                         $buttons['paste'] = '<a href="' . htmlspecialchars($this->clipObj->pasteUrl('', $this->id)) . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg('pages', $this->pageRow, 'into', $elFromTable)) . '">' .
212                                                                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/clip_pasteafter.gif') . ' title="' . $LANG->getLL('clip_paste', 1) . '" alt="" />' .
213                                                                         '</a>';
214                                 }
215                         }
216
217                                 // Cache
218                         $buttons['cache'] = '<a href="' . htmlspecialchars($this->listURL() . '&clear_cache=1') . '">' .
219                                                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/clear_cache.gif') . ' title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.clear_cache', 1) . '" alt="" />' .
220                                                         '</a>';
221
222                         if ($this->table) {
223
224                                         // CSV
225                                 $buttons['csv'] = '<a href="' . htmlspecialchars($this->listURL() . '&csv=1') . '">' .
226                                                                 '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/csv.gif') . ' title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.csv', 1) . '" alt="" />' .
227                                                                 '</a>';
228
229                                         // Export
230                                 if (t3lib_extMgm::isLoaded('impexp')) {
231                                         $buttons['export'] = '<a href="' . htmlspecialchars($this->backPath. 'mod.php?M=xMOD_tximpexp&tx_impexp[action]=export&tx_impexp[list][]=' . rawurlencode($this->table . ':' . $this->id)) . '">' .
232                                                                         '<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="" />' .
233                                                                         '</a>';
234                                 }
235
236                         }
237
238                                 // Reload
239                         $buttons['reload'] = '<a href="' . htmlspecialchars($this->listURL()) . '">' .
240                                                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/refresh_n.gif') . ' title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.reload', 1) . '" alt="" />' .
241                                                         '</a>';
242
243                                 // Shortcut
244                         if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
245                                 $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');
246                         }
247
248                                 // Back
249                         if ($this->returnUrl) {
250                                 $buttons['back'] = '<a href="' . htmlspecialchars(t3lib_div::linkThisUrl($this->returnUrl, array('id' => $this->id))) . '" class="typo3-goBack">' .
251                                                                 '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/goback.gif') . ' title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.goBack', 1) . '" alt="" />' .
252                                                                 '</a>';
253                         }
254                 }
255
256                 return $buttons;
257         }
258
259         /**
260          * Creates the listing of records from a single table
261          *
262          * @param       string          Table name
263          * @param       integer         Page id
264          * @param       string          List of fields to show in the listing. Pseudo fields will be added including the record header.
265          * @return      string          HTML table with the listing for the record.
266          */
267         function getTable($table,$id,$rowlist)  {
268                 global $TCA, $TYPO3_CONF_VARS;
269
270                         // Loading all TCA details for this table:
271                 t3lib_div::loadTCA($table);
272
273                         // Init
274                 $addWhere = '';
275                 $titleCol = $TCA[$table]['ctrl']['label'];
276                 $thumbsCol = $TCA[$table]['ctrl']['thumbnail'];
277                 $l10nEnabled = $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField'] && !$TCA[$table]['ctrl']['transOrigPointerTable'];
278
279                         // prepare space icon
280                 $iconWidth  = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['iconSizeWidth']  ? $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['iconSizeWidth']  : 12;
281                 $iconHeight = $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['iconSizeHeight'] ? $GLOBALS['TBE_STYLES']['skinImgAutoCfg']['iconSizeHeight'] : 12;
282                 $this->spaceIcon = '<img src="' . $this->backPath . 'clear.gif" width="' . $iconWidth . '" height="' . $iconHeight . '" title="" alt="" />';
283
284                         // Cleaning rowlist for duplicates and place the $titleCol as the first column always!
285                 $this->fieldArray=array();
286                         // title Column
287                 $this->fieldArray[] = $titleCol;        // Add title column
288                         // Control-Panel
289                 if (!t3lib_div::inList($rowlist,'_CONTROL_'))   {
290                         $this->fieldArray[] = '_CONTROL_';
291                         $this->fieldArray[] = '_AFTERCONTROL_';
292                 }
293                         // Clipboard
294                 if ($this->showClipboard)       {
295                         $this->fieldArray[] = '_CLIPBOARD_';
296                 }
297                         // Ref
298                 if (!$this->dontShowClipControlPanels)  {
299                         $this->fieldArray[]='_REF_';
300                         $this->fieldArray[]='_AFTERREF_';
301                 }
302                         // Path
303                 if ($this->searchLevels)        {
304                         $this->fieldArray[]='_PATH_';
305                 }
306                         // Localization
307                 if ($this->localizationView && $l10nEnabled)    {
308                         $this->fieldArray[] = '_LOCALIZATION_';
309                         $this->fieldArray[] = '_LOCALIZATION_b';
310                         $addWhere.=' AND (
311                                 '.$TCA[$table]['ctrl']['languageField'].'<=0
312                                 OR
313                                 '.$TCA[$table]['ctrl']['transOrigPointerField'].' = 0
314                         )';
315                 }
316                         // Cleaning up:
317                 $this->fieldArray=array_unique(array_merge($this->fieldArray,t3lib_div::trimExplode(',',$rowlist,1)));
318                 if ($this->noControlPanels)     {
319                         $tempArray = array_flip($this->fieldArray);
320                         unset($tempArray['_CONTROL_']);
321                         unset($tempArray['_CLIPBOARD_']);
322                         $this->fieldArray = array_keys($tempArray);
323                 }
324
325                         // Creating the list of fields to include in the SQL query:
326                 $selectFields = $this->fieldArray;
327                 $selectFields[] = 'uid';
328                 $selectFields[] = 'pid';
329                 if ($thumbsCol) $selectFields[] = $thumbsCol;   // adding column for thumbnails
330                 if ($table=='pages')    {
331                         if (t3lib_extMgm::isLoaded('cms'))      {
332                                 $selectFields[] = 'module';
333                                 $selectFields[] = 'extendToSubpages';
334                                 $selectFields[] = 'nav_hide';
335                         }
336                         $selectFields[] = 'doktype';
337                 }
338                 if (is_array($TCA[$table]['ctrl']['enablecolumns']))    {
339                         $selectFields = array_merge($selectFields,$TCA[$table]['ctrl']['enablecolumns']);
340                 }
341                 if ($TCA[$table]['ctrl']['type'])       {
342                         $selectFields[] = $TCA[$table]['ctrl']['type'];
343                 }
344                 if ($TCA[$table]['ctrl']['typeicon_column'])    {
345                         $selectFields[] = $TCA[$table]['ctrl']['typeicon_column'];
346                 }
347                 if ($TCA[$table]['ctrl']['versioningWS'])       {
348                         $selectFields[] = 't3ver_id';
349                         $selectFields[] = 't3ver_state';
350                         $selectFields[] = 't3ver_wsid';
351                         $selectFields[] = 't3ver_swapmode';             // Filtered out when pages in makeFieldList()
352                 }
353                 if ($l10nEnabled)       {
354                         $selectFields[] = $TCA[$table]['ctrl']['languageField'];
355                         $selectFields[] = $TCA[$table]['ctrl']['transOrigPointerField'];
356                 }
357                 if ($TCA[$table]['ctrl']['label_alt'])  {
358                         $selectFields = array_merge($selectFields,t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['label_alt'],1));
359                 }
360                 $selectFields = array_unique($selectFields);            // Unique list!
361                 $selectFields = array_intersect($selectFields,$this->makeFieldList($table,1));          // Making sure that the fields in the field-list ARE in the field-list from TCA!
362                 $selFieldList = implode(',',$selectFields);             // implode it into a list of fields for the SQL-statement.
363
364                 /**
365                  * @hook                        DB-List getTable
366                  * @date                        2007-11-16
367                  * @request             Malte Jansen  <mail@maltejansen.de>
368                  */
369                 if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['getTable'])) {
370                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['getTable'] as $classData) {
371                                 $hookObject = &t3lib_div::getUserObj($classData);
372
373                                 if(!($hookObject instanceof t3lib_localRecordListGetTableHook)) {
374                                         throw new UnexpectedValueException('$hookObject must implement interface t3lib_localRecordListGetTableHook', 1195114460);
375                                 }
376
377                                 $hookObject->getDBlistQuery($table, $id, $addWhere, $selFieldList, $this);
378                         }
379                 }
380
381                         // Create the SQL query for selecting the elements in the listing:
382                 if ($this->csvOutput) { // do not do paging when outputting as CSV
383                         $this->iLimit = 0;
384                 }
385
386                 $queryParts = $this->makeQueryArray($table, $id,$addWhere,$selFieldList);       // (API function from class.db_list.inc)
387                 $this->setTotalItems($queryParts);              // Finding the total amount of records on the page (API function from class.db_list.inc)
388
389                         // Init:
390                 $dbCount = 0;
391                 $out = '';
392
393                         // If the count query returned any number of records, we perform the real query, selecting records.
394                 if ($this->totalItems)  {
395                                 // set the showLimit to the number of records when outputting as CSV
396                         if ($this->csvOutput) {
397                                 $this->showLimit = $this->totalItems;
398                                 $this->iLimit = $this->totalItems;
399                         }
400                         $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
401                         $dbCount = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
402                 }
403
404                 $LOISmode = $this->listOnlyInSingleTableMode && !$this->table;
405
406                         // If any records was selected, render the list:
407                 if ($dbCount)   {
408
409                                 // Half line is drawn between tables:
410                         if (!$LOISmode) {
411                                 $theData = Array();
412                                 if (!$this->table && !$rowlist) {
413                                         $theData[$titleCol] = '<img src="clear.gif" width="'.($GLOBALS['SOBE']->MOD_SETTINGS['bigControlPanel']?'230':'350').'" height="1" alt="" />';
414                                         if (in_array('_CONTROL_',$this->fieldArray))    $theData['_CONTROL_']='';
415                                         if (in_array('_CLIPBOARD_',$this->fieldArray))  $theData['_CLIPBOARD_']='';
416                                 }
417                                 $out.=$this->addelement(0,'',$theData,'class="c-table-row-spacer"',$this->leftMargin);
418                         }
419
420                                 // Header line is drawn
421                         $theData = Array();
422                         if ($this->disableSingleTableView)      {
423                                 $theData[$titleCol] = '<span class="c-table">'.$GLOBALS['LANG']->sL($TCA[$table]['ctrl']['title'],1).'</span> ('.$this->totalItems.')';
424                         } else {
425                                 $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="" />');
426                         }
427
428                                 // CSH:
429                         $theData[$titleCol].= t3lib_BEfunc::cshItem($table,'',$this->backPath,'',FALSE,'margin-bottom:0px; white-space: normal;');
430
431                         if ($LOISmode)  {
432                                 $out.='
433                                         <tr>
434                                                 <td class="c-headLineTable" style="width:95%;">'.$theData[$titleCol].'</td>
435                                         </tr>';
436
437                                 if ($GLOBALS['BE_USER']->uc["edit_showFieldHelp"])      {
438                                         $GLOBALS['LANG']->loadSingleTableDescription($table);
439                                         if (isset($GLOBALS['TCA_DESCR'][$table]['columns']['']))        {
440                                                 $onClick = 'vHWin=window.open(\'view_help.php?tfID='.$table.'.\',\'viewFieldHelp\',\'height=400,width=600,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;';
441                                                 $out.='
442                                         <tr>
443                                                 <td class="c-tableDescription">'.t3lib_BEfunc::helpTextIcon($table,'',$this->backPath,TRUE).$GLOBALS['TCA_DESCR'][$table]['columns']['']['description'].'</td>
444                                         </tr>';
445                                         }
446                                 }
447                         } else {
448                                 $theUpIcon = ($table=='pages'&&$this->id&&isset($this->pageRow['pid'])) ? '<a href="'.htmlspecialchars($this->listURL($this->pageRow['pid'])).'" onclick="setHighlight('.$this->pageRow['pid'].')"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/i/pages_up.gif','width="18" height="16"').' title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.upOneLevel',1).'" alt="" /></a>':'';
449                                 $out.=$this->addelement(1,$theUpIcon,$theData,' class="c-headLineTable"','');
450                         }
451
452                         If (!$LOISmode) {
453                                         // Fixing a order table for sortby tables
454                                 $this->currentTable = array();
455                                 $currentIdList = array();
456                                 $doSort = ($TCA[$table]['ctrl']['sortby'] && !$this->sortField);
457
458                                 $prevUid = 0;
459                                 $prevPrevUid = 0;
460                                 $accRows = array();     // Accumulate rows here
461                                 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result))    {
462
463                                                 // In offline workspace, look for alternative record:
464                                         t3lib_BEfunc::workspaceOL($table, $row, $GLOBALS['BE_USER']->workspace, TRUE);
465
466                                         if (is_array($row))     {
467                                                 $accRows[] = $row;
468                                                 $currentIdList[] = $row['uid'];
469                                                 if ($doSort)    {
470                                                         if ($prevUid)   {
471                                                                 $this->currentTable['prev'][$row['uid']] = $prevPrevUid;
472                                                                 $this->currentTable['next'][$prevUid] = '-'.$row['uid'];
473                                                                 $this->currentTable['prevUid'][$row['uid']] = $prevUid;
474                                                         }
475                                                         $prevPrevUid = isset($this->currentTable['prev'][$row['uid']]) ? -$prevUid : $row['pid'];
476                                                         $prevUid=$row['uid'];
477                                                 }
478                                         }
479                                 }
480                                 $GLOBALS['TYPO3_DB']->sql_free_result($result);
481
482                                 $this->totalRowCount = count($accRows);
483
484                                         // CSV initiated
485                                 if ($this->csvOutput) $this->initCSV();
486
487                                         // Render items:
488                                 $this->CBnames=array();
489                                 $this->duplicateStack=array();
490                                 $this->eCounter=$this->firstElementNumber;
491
492                                 $iOut = '';
493                                 $cc = 0;
494                                 foreach($accRows as $row)       {
495
496                                                 // Forward/Backwards navigation links:
497                                         list($flag,$code) = $this->fwd_rwd_nav($table);
498                                         $iOut.=$code;
499
500                                                 // If render item, increment counter and call function
501                                         if ($flag)      {
502                                                 $cc++;
503                                                 $iOut.= $this->renderListRow($table,$row,$cc,$titleCol,$thumbsCol);
504
505                                                         // 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:
506                                                 if ($this->localizationView && $l10nEnabled)    {
507
508                                                                 // Look for translations of this record:
509                                                         $translations = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
510                                                                 $selFieldList,
511                                                                 $table,
512                                                                 'pid='.$row['pid'].
513                                                                         ' AND '.$TCA[$table]['ctrl']['languageField'].'>0'.
514                                                                         ' AND '.$TCA[$table]['ctrl']['transOrigPointerField'].'='.intval($row['uid']).
515                                                                         t3lib_BEfunc::deleteClause($table).
516                                                                         t3lib_BEfunc::versioningPlaceholderClause($table)
517                                                         );
518
519                                                                 // For each available translation, render the record:
520                                                         if (is_array($translations)) {
521                                                                 foreach($translations as $lRow) {
522                                                                                 // In offline workspace, look for alternative record:
523                                                                         t3lib_BEfunc::workspaceOL($table, $lRow, $GLOBALS['BE_USER']->workspace);
524
525                                                                         if (is_array($lRow) && $GLOBALS['BE_USER']->checkLanguageAccess($lRow[$TCA[$table]['ctrl']['languageField']]))  {
526                                                                                 $currentIdList[] = $lRow['uid'];
527                                                                                 $iOut.=$this->renderListRow($table,$lRow,$cc,$titleCol,$thumbsCol,18);
528                                                                         }
529                                                                 }
530                                                         }
531                                                 }
532                                         }
533
534                                                 // Counter of total rows incremented:
535                                         $this->eCounter++;
536                                 }
537
538                                         // The header row for the table is now created:
539                                 $out.=$this->renderListHeader($table,$currentIdList);
540                         }
541
542                                 // The list of records is added after the header:
543                         $out.=$iOut;
544
545                                 // ... and it is all wrapped in a table:
546                         $out='
547
548
549
550                         <!--
551                                 DB listing of elements: "'.htmlspecialchars($table).'"
552                         -->
553                                 <table border="0" cellpadding="0" cellspacing="0" class="typo3-dblist'.($LOISmode?' typo3-dblist-overview':'').'">
554                                         '.$out.'
555                                 </table>';
556
557                                 // Output csv if...
558                         if ($this->csvOutput)   $this->outputCSV($table);       // This ends the page with exit.
559                 }
560
561                         // Return content:
562                 return $out;
563         }
564
565         /**
566          * Rendering a single row for the list
567          *
568          * @param       string          Table name
569          * @param       array           Current record
570          * @param       integer         Counter, counting for each time an element is rendered (used for alternating colors)
571          * @param       string          Table field (column) where header value is found
572          * @param       string          Table field (column) where (possible) thumbnails can be found
573          * @param       integer         Indent from left.
574          * @return      string          Table row for the element
575          * @access private
576          * @see getTable()
577          */
578         function renderListRow($table,$row,$cc,$titleCol,$thumbsCol,$indent=0)  {
579                 $iOut = '';
580
581                 if (strlen($this->searchString))        {       // If in search mode, make sure the preview will show the correct page
582                         $id_orig = $this->id;
583                         $this->id = $row['pid'];
584                 }
585
586                 if (is_array($row))     {
587
588                                 // add special classes for first and last row
589                         $rowSpecial = '';
590                         if ($cc == 1 && $indent == 0) {
591                                 $rowSpecial .= ' firstcol';
592                         }
593                         if ($cc == $this->totalRowCount || $cc == $this->iLimit) {
594                                 $rowSpecial .= ' lastcol';
595                         }
596
597                                 // Background color, if any:
598                         if ($this->alternateBgColors) {
599                                 $row_bgColor = ($cc%2) ? ' class="db_list_normal'.$rowSpecial.'"' : ' class="db_list_alt'.$rowSpecial.'"';
600                         } else {
601                                 $row_bgColor = ' class="db_list_normal'.$rowSpecial.'"';
602                         }
603                                 // Overriding with versions background color if any:
604                         $row_bgColor = $row['_CSSCLASS'] ? ' class="'.$row['_CSSCLASS'].'"' : $row_bgColor;
605
606                                 // Incr. counter.
607                         $this->counter++;
608
609                                 // The icon with link
610                         $alttext = t3lib_BEfunc::getRecordIconAltText($row,$table);
611                         $iconImg = t3lib_iconWorks::getIconImage($table,$row,$this->backPath,'title="'.htmlspecialchars($alttext).'"'.($indent ? ' style="margin-left: '.$indent.'px;"' : ''));
612                         $theIcon = $this->clickMenuEnabled ? $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg,$table,$row['uid']) : $iconImg;
613
614                                 // Preparing and getting the data-array
615                         $theData = Array();
616                         foreach($this->fieldArray as $fCol)     {
617                                 if ($fCol==$titleCol)   {
618                                         $recTitle = t3lib_BEfunc::getRecordTitle($table,$row,FALSE,TRUE);
619                                         $theData[$fCol] = $this->linkWrapItems($table,$row['uid'],$recTitle,$row);
620                                 } elseif ($fCol == 'pid') {
621                                         $theData[$fCol]=$row[$fCol];
622                                 } elseif ($fCol == '_PATH_') {
623                                         $theData[$fCol]=$this->recPath($row['pid']);
624                                 } elseif ($fCol == '_REF_') {
625                                         $theData[$fCol]=$this->makeRef($table,$row['uid']);
626                                 } elseif ($fCol == '_CONTROL_') {
627                                         $theData[$fCol]=$this->makeControl($table,$row);
628                                 } elseif ($fCol == '_AFTERCONTROL_' || $fCol == '_AFTERREF_') {
629                                         $theData[$fCol] = '&nbsp;';
630                                 } elseif ($fCol == '_CLIPBOARD_') {
631                                         $theData[$fCol]=$this->makeClip($table,$row);
632                                 } elseif ($fCol == '_LOCALIZATION_') {
633                                         list($lC1, $lC2) = $this->makeLocalizationPanel($table,$row);
634                                         $theData[$fCol] = $lC1;
635                                         $theData[$fCol.'b'] = $lC2;
636                                 } elseif ($fCol == '_LOCALIZATION_b') {
637                                         // Do nothing, has been done above.
638                                 } else {
639                                         $tmpProc = t3lib_BEfunc::getProcessedValueExtra($table, $fCol, $row[$fCol], 100, $row['uid']);
640                                         $theData[$fCol] = $this->linkUrlMail(htmlspecialchars($tmpProc), $row[$fCol]);
641                                         $row[$fCol] = $tmpProc;
642                                 }
643                         }
644
645                         if (strlen($this->searchString))        {       // Reset the ID if it was overwritten
646                                 $this->id = $id_orig;
647                         }
648
649                                 // Add row to CSV list:
650                         if ($this->csvOutput) {
651                                 $this->addToCSV($row,$table);
652                         }
653
654                         // Add classes to table cells
655                         $this->addElement_tdCssClass[$titleCol]         = 'col-title';
656                         if (!$this->dontShowClipControlPanels) {
657                                 $this->addElement_tdCssClass['_CONTROL_']       = 'col-control';
658                                 $this->addElement_tdCssClass['_AFTERCONTROL_']  = 'col-control-space';
659                                 $this->addElement_tdCssClass['_CLIPBOARD_']     = 'col-clipboard';
660                         }
661                         $this->addElement_tdCssClass['_PATH_']          = 'col-path';
662                         $this->addElement_tdCssClass['_LOCALIZATION_']  = 'col-localizationa';
663                         $this->addElement_tdCssClass['_LOCALIZATION_b'] = 'col-localizationb';
664
665
666                                 // Create element in table cells:
667                         $iOut.=$this->addelement(1,$theIcon,$theData,$row_bgColor);
668
669                                 // Render thumbsnails if a thumbnail column exists and there is content in it:
670                         if ($this->thumbs && trim($row[$thumbsCol]))    {
671                                 $iOut.=$this->addelement(4,'', Array($titleCol=>$this->thumbCode($row,$table,$thumbsCol)),$row_bgColor);
672                         }
673
674                                 // Finally, return table row element:
675                         return $iOut;
676                 }
677         }
678
679         /**
680          * Rendering the header row for a table
681          *
682          * @param       string          Table name
683          * @param       array           Array of the currently displayed uids of the table
684          * @return      string          Header table row
685          * @access private
686          * @see getTable()
687          */
688         function renderListHeader($table, $currentIdList)       {
689                 global $TCA, $LANG, $TYPO3_CONF_VARS;
690
691                         // Init:
692                 $theData = Array();
693
694                         // Traverse the fields:
695                 foreach($this->fieldArray as $fCol)     {
696
697                                 // Calculate users permissions to edit records in the table:
698                         $permsEdit = $this->calcPerms & ($table=='pages'?2:16);
699
700                         switch((string)$fCol)   {
701                                 case '_PATH_':                  // Path
702                                         $theData[$fCol] = '<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._PATH_',1).']</i>';
703                                 break;
704                                 case '_REF_':                   // References
705                                         $theData[$fCol] = '<i>['.$LANG->sL('LLL:EXT:lang/locallang_mod_file_list.xml:c__REF_',1).']</i>';
706                                 break;
707                                 case '_LOCALIZATION_':                  // Path
708                                         $theData[$fCol] = '<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._LOCALIZATION_',1).']</i>';
709                                 break;
710                                 case '_LOCALIZATION_b':                 // Path
711                                         $theData[$fCol] = $LANG->getLL('Localize',1);
712                                 break;
713                                 case '_CLIPBOARD_':             // Clipboard:
714                                         $cells=array();
715
716                                                 // If there are elements on the clipboard for this table, then display the "paste into" icon:
717                                         $elFromTable = $this->clipObj->elFromTable($table);
718                                         if (count($elFromTable))        {
719                                                 $cells['pasteAfter']='<a href="'.htmlspecialchars($this->clipObj->pasteUrl($table,$this->id)).'" onclick="'.htmlspecialchars('return '.$this->clipObj->confirmMsg('pages',$this->pageRow,'into',$elFromTable)).'">'.
720                                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/clip_pasteafter.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_paste',1).'" alt="" />'.
721                                                                 '</a>';
722                                         }
723
724                                                 // If the numeric clipboard pads are enabled, display the control icons for that:
725                                         if ($this->clipObj->current!='normal')  {
726
727                                                         // The "select" link:
728                                                 $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');
729
730                                                         // The "edit marked" link:
731                                                 $editIdList = implode(',',$currentIdList);
732                                                 $editIdList = "'+editList('".$table."','".$editIdList."')+'";
733                                                 $params='&edit['.$table.']['.$editIdList.']=edit&disHelp=1';
734                                                 $cells['edit']='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'">'.
735                                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('clip_editMarked',1).'" alt="" />'.
736                                                                 '</a>';
737
738                                                         // The "Delete marked" link:
739                                                 $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'])));
740
741                                                         // The "Select all" link:
742                                                 $cells['markAll']='<a href="#" onclick="'.htmlspecialchars('checkOffCB(\''.implode(',',$this->CBnames).'\'); return false;').'">'.
743                                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/clip_select.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_markRecords',1).'" alt="" />'.
744                                                                 '</a>';
745                                         } else {
746                                                 $cells['empty']='';
747                                         }
748                                         /**
749                                          * @hook                        renderListHeaderActions: Allows to change the clipboard icons of the Web>List table headers
750                                          * @date                        2007-11-20
751                                          * @request             Bernhard Kraft  <krafbt@kraftb.at>
752                                          * @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.
753                                          */
754                                         if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions']))        {
755                                                 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData)       {
756                                                         $hookObject = &t3lib_div::getUserObj($classData);
757                                                         if(!($hookObject instanceof localRecordList_actionsHook))       {
758                                                                 throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567850);
759                                                         }
760                                                         $cells = $hookObject->renderListHeaderActions($table, $currentIdList, $cells, $this);
761                                                 }
762                                         }
763                                         $theData[$fCol]=implode('',$cells);
764                                 break;
765                                 case '_CONTROL_':               // Control panel:
766                                         if (!$TCA[$table]['ctrl']['readOnly'])  {
767
768                                                         // If new records can be created on this page, add links:
769                                                 if ($this->calcPerms&($table=='pages'?8:16) && $this->showNewRecLink($table))   {
770                                                         if ($table=="tt_content" && $this->newWizards)  {
771                                                                         //  If mod.web_list.newContentWiz.overrideWithExtension is set, use that extension's create new content wizard instead:
772                                                                 $tmpTSc = t3lib_BEfunc::getModTSconfig($this->pageinfo['uid'],'mod.web_list');
773                                                                 $tmpTSc = $tmpTSc ['properties']['newContentWiz.']['overrideWithExtension'];
774                                                                 $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';
775
776                                                                 $icon = '<a href="#" onclick="'.htmlspecialchars('return jumpExt(\''.$newContentWizScriptPath.'?id='.$this->id.'\');').'">'.
777                                                                                                 '<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="" />'.
778                                                                                                 '</a>';
779                                                         } elseif ($table=='pages' && $this->newWizards) {
780                                                                 $icon = '<a href="'.htmlspecialchars($this->backPath.'db_new.php?id='.$this->id.'&pagesOnly=1&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'">'.
781                                                                                                 '<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="" />'.
782                                                                                                 '</a>';
783
784                                                         } else {
785                                                                 $params = '&edit['.$table.']['.$this->id.']=new';
786                                                                 $icon   = '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'">'.
787                                                                                                 '<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="" />'.
788                                                                                                 '</a>';
789                                                         }
790                                                 }
791
792                                                         // If the table can be edited, add link for editing ALL SHOWN fields for all listed records:
793                                                 if ($permsEdit && $this->table && is_array($currentIdList))     {
794                                                         $editIdList = implode(',',$currentIdList);
795                                                         if ($this->clipNumPane()) $editIdList = "'+editList('".$table."','".$editIdList."')+'";
796                                                         $params = '&edit['.$table.']['.$editIdList.']=edit&columnsOnly='.implode(',',$this->fieldArray).'&disHelp=1';
797                                                         $icon  .= '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'">'.
798                                                                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('editShownColumns',1).'" alt="" />'.
799                                                                                         '</a>';
800                                                 }
801                                                         // add an empty entry, so column count fits again after moving this into $icon
802                                                 $theData[$fCol] = '&nbsp;';
803                                         }
804                                 break;
805                                 case '_AFTERCONTROL_':  // space column
806                                 case '_AFTERREF_':      // space column
807                                         $theData[$fCol] = '&nbsp;';
808                                 break;
809                                 default:                        // Regular fields header:
810                                         $theData[$fCol]='';
811                                         if ($this->table && is_array($currentIdList))   {
812
813                                                         // If the numeric clipboard pads are selected, show duplicate sorting link:
814                                                 if ($this->clipNumPane()) {
815                                                         $theData[$fCol].='<a href="'.htmlspecialchars($this->listURL('',-1).'&duplicateField='.$fCol).'">'.
816                                                                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/select_duplicates.gif','width="11" height="11"').' title="'.$LANG->getLL('clip_duplicates',1).'" alt="" />'.
817                                                                                         '</a>';
818                                                 }
819
820                                                         // If the table can be edited, add link for editing THIS field for all listed records:
821                                                 if (!$TCA[$table]['ctrl']['readOnly'] && $permsEdit && $TCA[$table]['columns'][$fCol])  {
822                                                         $editIdList = implode(',',$currentIdList);
823                                                         if ($this->clipNumPane()) $editIdList = "'+editList('".$table."','".$editIdList."')+'";
824                                                         $params='&edit['.$table.']['.$editIdList.']=edit&columnsOnly='.$fCol.'&disHelp=1';
825                                                         $iTitle = sprintf($LANG->getLL('editThisColumn'),ereg_replace(':$','',trim($LANG->sL(t3lib_BEfunc::getItemLabel($table,$fCol)))));
826                                                         $theData[$fCol].='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'">'.
827                                                                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2.gif','width="11" height="12"').' title="'.htmlspecialchars($iTitle).'" alt="" />'.
828                                                                                         '</a>';
829                                                 }
830                                         }
831                                         $theData[$fCol].=$this->addSortLink($LANG->sL(t3lib_BEfunc::getItemLabel($table,$fCol,'<i>[|]</i>')),$fCol,$table);
832                                 break;
833                         }
834
835                 }
836
837                 /**
838                  * @hook                        renderListHeader: Allows to change the contents of columns/cells of the Web>List table headers
839                  * @date                        2007-11-20
840                  * @request             Bernhard Kraft  <krafbt@kraftb.at>
841                  * @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.
842                  */
843                 if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions']))        {
844                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData)       {
845                                 $hookObject = &t3lib_div::getUserObj($classData);
846                                 if(!($hookObject instanceof localRecordList_actionsHook))       {
847                                         throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567855);
848                                 }
849                                 $theData = $hookObject->renderListHeader($table, $currentIdList, $theData, $this);
850                         }
851                 }
852
853                         // Create and return header table row:
854                 return $this->addelement(1, $icon, $theData, ' class="c-headLine"', '');
855         }
856
857
858
859
860
861
862         /*********************************
863          *
864          * Rendering of various elements
865          *
866          *********************************/
867
868         /**
869          * Creates the control panel for a single record in the listing.
870          *
871          * @param       string          The table
872          * @param       array           The record for which to make the control panel.
873          * @return      string          HTML table with the control panel (unless disabled)
874          */
875         function makeControl($table,$row)       {
876                 global $TCA, $LANG, $SOBE, $TYPO3_CONF_VARS;
877
878                 if ($this->dontShowClipControlPanels)   return '';
879
880                         // Initialize:
881                 t3lib_div::loadTCA($table);
882                 $cells=array();
883
884                         // If the listed table is 'pages' we have to request the permission settings for each page:
885                 if ($table=='pages')    {
886                         $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$row['uid']));
887                 }
888
889                         // This expresses the edit permissions for this particular element:
890                 $permsEdit = ($table=='pages' && ($localCalcPerms&2)) || ($table!='pages' && ($this->calcPerms&16));
891
892                         // "Show" link (only pages and tt_content elements)
893                 if ($table=='pages' || $table=='tt_content')    {
894                         $params='&edit['.$table.']['.$row['uid'].']=edit';
895                         $cells['view']='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($table=='tt_content'?$this->id.'#'.$row['uid']:$row['uid'], $this->backPath)).'">'.
896                                         '<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="" />'.
897                                         '</a>';
898                 } elseif(!$this->table) {
899                         $cells['view'] = $this->spaceIcon;
900                 }
901
902                         // "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id)
903                 if ($permsEdit) {
904                         $params='&edit['.$table.']['.$row['uid'].']=edit';
905                         $cells['edit']='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'">'.
906                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2'.(!$TCA[$table]['ctrl']['readOnly']?'':'_d').'.gif','width="11" height="12"').' title="'.$LANG->getLL('edit',1).'" alt="" />'.
907                                         '</a>';
908                 } elseif(!$this->table) {
909                         $cells['edit'] = $this->spaceIcon;
910                 }
911
912                         // "Move" wizard link for pages/tt_content elements:
913                 if (($table=="tt_content" && $permsEdit) || ($table=='pages'))  {
914                         $cells['move']='<a href="#" onclick="'.htmlspecialchars('return jumpExt(\''.$this->backPath.'move_el.php?table='.$table.'&uid='.$row['uid'].'\');').'">'.
915                                         '<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="" />'.
916                                         '</a>';
917                 } elseif(!$this->table) {
918                         $cells['move'] = $this->spaceIcon;
919                 }
920
921                         // If the extended control panel is enabled OR if we are seeing a single table:
922                 if ($SOBE->MOD_SETTINGS['bigControlPanel'] || $this->table)     {
923
924                                 // "Info": (All records)
925                         $cells['viewBig']='<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$table.'\', \''.$row['uid'].'\'); return false;').'">'.
926                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/zoom2.gif','width="12" height="12"').' title="'.$LANG->getLL('showInfo',1).'" alt="" />'.
927                                         '</a>';
928
929                                 // If the table is NOT a read-only table, then show these links:
930                         if (!$TCA[$table]['ctrl']['readOnly'])  {
931
932                                         // "Revert" link (history/undo)
933                                 $cells['history']='<a href="#" onclick="'.htmlspecialchars('return jumpExt(\''.$this->backPath.'show_rechis.php?element='.rawurlencode($table.':'.$row['uid']).'\',\'#latest\');').'">'.
934                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/history2.gif','width="13" height="12"').' title="'.$LANG->getLL('history',1).'" alt="" />'.
935                                                 '</a>';
936
937                                         // Versioning:
938                                 if (t3lib_extMgm::isLoaded('version'))  {
939                                         $vers = t3lib_BEfunc::selectVersionsOfRecord($table, $row['uid'], 'uid', $GLOBALS['BE_USER']->workspace);
940                                         if (is_array($vers))    {       // If table can be versionized.
941                                                 if (count($vers)>1)     {
942                                                         $st = 'background-color: #FFFF00; font-weight: bold;';
943                                                         $lab = count($vers)-1;
944                                                 } else {
945                                                         $st = 'background-color: #9999cc; font-weight: bold;';
946                                                         $lab = 'V';
947                                                 }
948
949                                                 $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" style="'.htmlspecialchars($st).'">'.
950                                                                 $lab.
951                                                                 '</a>';
952                                         } elseif(!$this->table) {
953                                                 $cells['version'] = '<span class="typo3-ctrl-versioning" style="font-weight: bold; visibility: hidden;">V</span>';
954                                         }
955                                 }
956
957                                         // "Edit Perms" link:
958                                 if ($table=='pages' && $GLOBALS['BE_USER']->check('modules','web_perm'))        {
959                                         $cells['perms']='<a href="'.htmlspecialchars('mod/web/perm/index.php?id='.$row['uid'].'&return_id='.$row['uid'].'&edit=1').'">'.
960                                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/perm.gif','width="7" height="12"').' title="'.$LANG->getLL('permissions',1).'" alt="" />'.
961                                                         '</a>';
962                                 } elseif(!$this->table && $GLOBALS['BE_USER']->check('modules','web_perm')) {
963                                         $cells['perms'] = $this->spaceIcon;
964                                 }
965
966                                         // "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):
967                                 if ($TCA[$table]['ctrl']['sortby'] || $TCA[$table]['ctrl']['useColumnsForDefaultValues'])       {
968                                         if (
969                                                 ($table!='pages' && ($this->calcPerms&16)) ||   // For NON-pages, must have permission to edit content on this parent page
970                                                 ($table=='pages' && ($this->calcPerms&8))               // For pages, must have permission to create new pages here.
971                                                 )       {
972                                                 if ($this->showNewRecLink($table))      {
973                                                         $params='&edit['.$table.']['.(-($row['_MOVE_PLH']?$row['_MOVE_PLH_uid']:$row['uid'])).']=new';
974                                                         $cells['new']='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'">'.
975                                                                         '<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="" />'.
976                                                                         '</a>';
977                                                 }
978                                         }
979                                 } elseif(!$this->table) {
980                                         $cells['new'] = $this->spaceIcon;
981                                 }
982
983                                         // "Up/Down" links
984                                 if ($permsEdit && $TCA[$table]['ctrl']['sortby']  && !$this->sortField && !$this->searchLevels) {
985                                         if (isset($this->currentTable['prev'][$row['uid']]))    {       // Up
986                                                 $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['prev'][$row['uid']];
987                                                 $cells['moveUp']='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
988                                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_up.gif','width="11" height="10"').' title="'.$LANG->getLL('moveUp',1).'" alt="" />'.
989                                                                 '</a>';
990                                         } else {
991                                                 $cells['moveUp'] = $this->spaceIcon;
992                                         }
993                                         if ($this->currentTable['next'][$row['uid']])   {       // Down
994                                                 $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['next'][$row['uid']];
995                                                 $cells['moveDown']='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
996                                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_down.gif','width="11" height="10"').' title="'.$LANG->getLL('moveDown',1).'" alt="" />'.
997                                                                 '</a>';
998                                         } else {
999                                                 $cells['moveDown'] = $this->spaceIcon;
1000                                         }
1001                                 } elseif(!$this->table) {
1002                                         $cells['moveUp']  = $this->spaceIcon;
1003                                         $cells['moveDow'] = $this->spaceIcon;
1004                                 }
1005
1006                                         // "Hide/Unhide" links:
1007                                 $hiddenField = $TCA[$table]['ctrl']['enablecolumns']['disabled'];
1008                                 if ($permsEdit && $hiddenField && $TCA[$table]['columns'][$hiddenField] && (!$TCA[$table]['columns'][$hiddenField]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields',$table.':'.$hiddenField)))     {
1009                                         if ($row[$hiddenField]) {
1010                                                 $params='&data['.$table.']['.$row['uid'].']['.$hiddenField.']=0';
1011                                                 $cells['hide']='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
1012                                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_unhide.gif','width="11" height="10"').' title="'.$LANG->getLL('unHide'.($table=='pages'?'Page':''),1).'" alt="" />'.
1013                                                                 '</a>';
1014                                         } else {
1015                                                 $params='&data['.$table.']['.$row['uid'].']['.$hiddenField.']=1';
1016                                                 $cells['hide']='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
1017                                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_hide.gif','width="11" height="10"').' title="'.$LANG->getLL('hide'.($table=='pages'?'Page':''),1).'" alt="" />'.
1018                                                                 '</a>';
1019                                         }
1020                                 } elseif(!$this->table) {
1021                                         $cells['hide'] = $this->spaceIcon;
1022                                 }
1023
1024                                         // "Delete" link:
1025                                 if (
1026                                         ($table=='pages' && ($localCalcPerms&4)) || ($table!='pages' && ($this->calcPerms&16))
1027                                         )       {
1028                                         $params='&cmd['.$table.']['.$row['uid'].'][delete]=1';
1029                                         $cells['delete']='<a href="#" onclick="'.htmlspecialchars('if (confirm('.$LANG->JScharCode($LANG->getLL('deleteWarning').t3lib_BEfunc::referenceCount($table,$row['uid'],' (There are %s reference(s) to this record!)')).')) {jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');} return false;').'">'.
1030                                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/garbage.gif','width="11" height="12"').' title="'.$LANG->getLL('delete',1).'" alt="" />'.
1031                                                         '</a>';
1032                                 } elseif(!$this->table) {
1033                                         $cells['delete'] = $this->spaceIcon;
1034                                 }
1035
1036                                         // "Levels" links: Moving pages into new levels...
1037                                 if ($permsEdit && $table=='pages' && !$this->searchLevels)      {
1038
1039                                                 // Up (Paste as the page right after the current parent page)
1040                                         if ($this->calcPerms&8) {
1041                                                 $params='&cmd['.$table.']['.$row['uid'].'][move]='.-$this->id;
1042                                                 $cells['moveLeft']='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
1043                                                                 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_left.gif','width="11" height="10"').' title="'.$LANG->getLL('prevLevel',1).'" alt="" />'.
1044                                                                 '</a>';
1045                                         }
1046                                                 // Down (Paste as subpage to the page right above)
1047                                         if ($this->currentTable['prevUid'][$row['uid']])        {
1048                                                 $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$this->currentTable['prevUid'][$row['uid']]));
1049                                                 if ($localCalcPerms&8)  {
1050                                                         $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['prevUid'][$row['uid']];
1051                                                         $cells['moveRight']='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
1052                                                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_right.gif','width="11" height="10"').' title="'.$LANG->getLL('nextLevel',1).'" alt="" />'.
1053                                                                         '</a>';
1054                                                 } else {
1055                                                         $cells['moveRight'] = $this->spaceIcon;
1056                                                 }
1057                                         } else {
1058                                                 $cells['moveRight'] = $this->spaceIcon;
1059                                         }
1060                                 } elseif(!$this->table) {
1061                                         $cells['moveLeft'] = $this->spaceIcon;
1062                                         $cells['moveRight'] = $this->spaceIcon;
1063                                 }
1064                         }
1065                 }
1066
1067                         // If the record is edit-locked by another user, we will show a little warning sign:
1068                 if ($lockInfo=t3lib_BEfunc::isRecordLocked($table,$row['uid'])) {
1069                         $cells['locked'] = '<a href="#" onclick="'.htmlspecialchars('alert('.$LANG->JScharCode($lockInfo['msg']).');return false;').'">'.
1070                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/recordlock_warning3.gif','width="17" height="12"').' title="'.htmlspecialchars($lockInfo['msg']).'" alt="" />'.
1071                                         '</a>';
1072                 }
1073
1074                 /**
1075                  * @hook                        recStatInfoHooks: Allows to insert HTML before record icons on various places
1076                  * @date                        2007-09-22
1077                  * @request             Kasper Skaarhoj  <kasper2007@typo3.com>
1078                  */
1079                 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['GLOBAL']['recStatInfoHooks']))     {
1080                         $stat='';
1081                         $_params = array($table,$row['uid']);
1082                         foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef)     {
1083                                 $stat.=t3lib_div::callUserFunction($_funcRef,$_params,$this);
1084                         }
1085                         $cells['stat'] = $stat;
1086                 }
1087                 /**
1088                  * @hook                        makeControl: Allows to change control icons of records in list-module
1089                  * @date                        2007-11-20
1090                  * @request             Bernhard Kraft  <krafbt@kraftb.at>
1091                  * @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 accesible by an index-key. The order of the icons is dependend on the order of those array entries.
1092                  */
1093                 if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) {
1094                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) {
1095                                 $hookObject = &t3lib_div::getUserObj($classData);
1096                                 if(!($hookObject instanceof localRecordList_actionsHook))       {
1097                                         throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567840);
1098                                 }
1099                                 $cells = $hookObject->makeControl($table, $row, $cells, $this);
1100                         }
1101                 }
1102
1103                         // Compile items into a DIV-element:
1104                 return '
1105                                                                                         <!-- CONTROL PANEL: '.$table.':'.$row['uid'].' -->
1106                                                                                         <div class="typo3-DBctrl">'.implode('',$cells).'</div>';
1107         }
1108
1109         /**
1110          * Creates the clipboard panel for a single record in the listing.
1111          *
1112          * @param       string          The table
1113          * @param       array           The record for which to make the clipboard panel.
1114          * @return      string          HTML table with the clipboard panel (unless disabled)
1115          */
1116         function makeClip($table,$row)  {
1117                 global $TCA, $LANG, $TYPO3_CONF_VARS;
1118
1119                         // Return blank, if disabled:
1120                 if ($this->dontShowClipControlPanels)   return '';
1121                 $cells=array();
1122
1123                 $cells['pasteAfter'] = $cells['pasteInto'] = $this->spaceIcon;
1124
1125                         // Return blank, if disabled:
1126                         // Whether a numeric clipboard pad is active or the normal pad we will see different content of the panel:
1127                 if ($this->clipObj->current=='normal')  {       // For the "Normal" pad:
1128
1129                                 // Show copy/cut icons:
1130                         $isSel = (string)$this->clipObj->isSelected($table,$row['uid']);
1131                         $cells['copy']='<a href="#" onclick="'.htmlspecialchars('return jumpSelf(\''.$this->clipObj->selUrlDB($table,$row['uid'],1,($isSel=='copy'),array('returnUrl'=>'')).'\');').'">'.
1132                                         '<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="" />'.
1133                                         '</a>';
1134                         $cells['cut']='<a href="#" onclick="'.htmlspecialchars('return jumpSelf(\''.$this->clipObj->selUrlDB($table,$row['uid'],0,($isSel=='cut'),array('returnUrl'=>'')).'\');').'">'.
1135                                         '<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="" />'.
1136                                         '</a>';
1137
1138                 } else {        // For the numeric clipboard pads (showing checkboxes where one can select elements on/off)
1139
1140                                 // Setting name of the element in ->CBnames array:
1141                         $n=$table.'|'.$row['uid'];
1142                         $this->CBnames[]=$n;
1143
1144                                 // Check if the current element is selected and if so, prepare to set the checkbox as selected:
1145                         $checked = ($this->clipObj->isSelected($table,$row['uid'])?' checked="checked"':'');
1146
1147                                 // If the "duplicateField" value is set then select all elements which are duplicates...
1148                         if ($this->duplicateField && isset($row[$this->duplicateField]))        {
1149                                 $checked='';
1150                                 if (in_array($row[$this->duplicateField], $this->duplicateStack))       {
1151                                         $checked=' checked="checked"';
1152                                 }
1153                                 $this->duplicateStack[] = $row[$this->duplicateField];
1154                         }
1155
1156                                 // Adding the checkbox to the panel:
1157                         $cells['select']='<input type="hidden" name="CBH['.$n.']" value="0" /><input type="checkbox" name="CBC['.$n.']" value="1" class="smallCheckboxes"'.$checked.' />';
1158                 }
1159
1160                         // Now, looking for selected elements from the current table:
1161                 $elFromTable = $this->clipObj->elFromTable($table);
1162                 if (count($elFromTable) && $TCA[$table]['ctrl']['sortby'])      {       // IF elements are found and they can be individually ordered, then add a "paste after" icon:
1163                         $cells['pasteAfter']='<a href="'.htmlspecialchars($this->clipObj->pasteUrl($table,-$row['uid'])).'" onclick="'.htmlspecialchars('return '.$this->clipObj->confirmMsg($table,$row,'after',$elFromTable)).'">'.
1164                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/clip_pasteafter.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_pasteAfter',1).'" alt="" />'.
1165                                         '</a>';
1166                 }
1167
1168                         // Now, looking for elements in general:
1169                 $elFromTable = $this->clipObj->elFromTable('');
1170                 if ($table=='pages' && count($elFromTable))     {
1171                         $cells['pasteInto']='<a href="'.htmlspecialchars($this->clipObj->pasteUrl('',$row['uid'])).'" onclick="'.htmlspecialchars('return '.$this->clipObj->confirmMsg($table,$row,'into',$elFromTable)).'">'.
1172                                         '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/clip_pasteinto.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_pasteInto',1).'" alt="" />'.
1173                                         '</a>';
1174                 }
1175
1176                 /*
1177                  * @hook                        makeClip: Allows to change clip-icons of records in list-module
1178                  * @date                        2007-11-20
1179                  * @request             Bernhard Kraft  <krafbt@kraftb.at>
1180                  * @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 accesible by an index-key. The order of the icons is dependend on the order of those array entries.
1181                  */
1182                 if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) {
1183                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) {
1184                                 $hookObject = &t3lib_div::getUserObj($classData);
1185                                 if(!($hookObject instanceof localRecordList_actionsHook))       {
1186                                         throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567845);
1187                                 }
1188                                 $cells = $hookObject->makeClip($table, $row, $cells, $this);
1189                         }
1190                 }
1191
1192                         // Compile items into a DIV-element:
1193                 return '                                                        <!-- CLIPBOARD PANEL: '.$table.':'.$row['uid'].' -->
1194                                                                                         <div class="typo3-clipCtrl">'.implode('',$cells).'</div>';
1195         }
1196
1197         /**
1198          * Make reference count
1199          *
1200          * @param       string          Table name
1201          * @param       integer         UID of record
1202          * @return      string          HTML-table
1203          */
1204         function makeRef($table,$uid)   {
1205
1206                         // Look up the path:
1207                 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1208                         '*',
1209                         'sys_refindex',
1210                         'ref_table='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_refindex').
1211                                 ' AND ref_uid='.intval($uid).
1212                                 ' AND deleted=0'
1213                 );
1214
1215                         // Compile information for title tag:
1216                 $infoData=array();
1217                 if (is_array($rows)) {
1218                         foreach($rows as $row)  {
1219                                 $infoData[]=$row['tablename'].':'.$row['recuid'].':'.$row['field'];
1220                         }
1221                 }
1222
1223                 return count($infoData) ? '<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$table.'\', \''.$uid.'\'); return false;').'" title="'.htmlspecialchars(t3lib_div::fixed_lgd(implode(' / ',$infoData),100)).'">'.count($infoData).'</a>' : '';
1224         }
1225
1226         /**
1227          * Creates the localization panel
1228          *
1229          * @param       string          The table
1230          * @param       array           The record for which to make the localization panel.
1231          * @return      array           Array with key 0/1 with content for column 1 and 2
1232          */
1233         function makeLocalizationPanel($table,$row)     {
1234                 global $TCA,$LANG;
1235
1236                 $out = array(
1237                         0 => '',
1238                         1 => '',
1239                 );
1240
1241                 $t8Tools = t3lib_div::makeInstance('t3lib_transl8tools');
1242                 $translations = $t8Tools->translationInfo($table,$row['uid']);
1243
1244                         // Language title and icon:
1245                 $out[0] = $this->languageFlag($row[$TCA[$table]['ctrl']['languageField']]);
1246
1247                 if (is_array($translations))    {
1248
1249                                 // Traverse page translations and add icon for each language that does NOT yet exist:
1250                         $lNew = '';
1251                         foreach($this->pageOverlays as $lUid_OnPage => $lsysRec)        {
1252                                 if (!isset($translations['translations'][$lUid_OnPage]) && $GLOBALS['BE_USER']->checkLanguageAccess($lUid_OnPage))      {
1253                                         $href = $GLOBALS['TBE_TEMPLATE']->issueCommand(
1254                                                 '&cmd['.$table.']['.$row['uid'].'][localize]='.$lUid_OnPage,
1255                                                 $this->listURL().'&justLocalized='.rawurlencode($table.':'.$row['uid'].':'.$lUid_OnPage)
1256                                         );
1257
1258                                         $lC = ($this->languageIconTitles[$lUid_OnPage]['flagIcon'] ? '<img src="'.$this->languageIconTitles[$lUid_OnPage]['flagIcon'].'" class="absmiddle" alt="" />' : $this->languageIconTitles[$lUid_OnPage]['title']);
1259                                         $lC = '<a href="'.htmlspecialchars($href).'">'.$lC.'</a> ';
1260
1261                                         $lNew.=$lC;
1262                                 }
1263                         }
1264
1265                         if ($lNew)      $out[1].= $lNew;
1266                 } else {
1267                         $out[0] = '&nbsp;&nbsp;&nbsp;&nbsp;'.$out[0];
1268                 }
1269
1270
1271                 return $out;
1272         }
1273
1274         /**
1275          * Create the selector box for selecting fields to display from a table:
1276          *
1277          * @param       string          Table name
1278          * @param       boolean         If true, form-fields will be wrapped around the table.
1279          * @return      string          HTML table with the selector box (name: displayFields['.$table.'][])
1280          */
1281         function fieldSelectBox($table,$formFields=1)   {
1282                 global $TCA, $LANG;
1283
1284                         // Init:
1285                 t3lib_div::loadTCA($table);
1286                 $formElements=array('','');
1287                 if ($formFields)        {
1288                         $formElements=array('<form action="'.htmlspecialchars($this->listURL()).'" method="post">','</form>');
1289                 }
1290
1291                         // Load already selected fields, if any:
1292                 $setFields=is_array($this->setFields[$table]) ? $this->setFields[$table] : array();
1293
1294                         // Request fields from table:
1295                 $fields = $this->makeFieldList($table);
1296
1297                         // Add pseudo "control" fields
1298                 $fields[]='tstamp';
1299                 $fields[]='crdate';
1300                 $fields[]='_PATH_';
1301                 $fields[]='_REF_';
1302                 $fields[]='_LOCALIZATION_';
1303                 $fields[]='_CONTROL_';
1304                 $fields[]='_CLIPBOARD_';
1305
1306                         // Create an option for each field:
1307                 $opt=array();
1308                 $opt[] = '<option value=""></option>';
1309                 foreach($fields as $fN) {
1310                         $fL = is_array($TCA[$table]['columns'][$fN]) ? ereg_replace(':$','',$LANG->sL($TCA[$table]['columns'][$fN]['label'])) : '['.$fN.']';    // Field label
1311                         $opt[] = '
1312                                                                                         <option value="'.$fN.'"'.(in_array($fN,$setFields)?' selected="selected"':'').'>'.htmlspecialchars($fL).'</option>';
1313                 }
1314
1315                         // Compile the options into a multiple selector box:
1316                 $lMenu = '
1317                                                                                 <select size="'.t3lib_div::intInRange(count($fields)+1,3,20).'" multiple="multiple" name="displayFields['.$table.'][]">'.implode('',$opt).'
1318                                                                                 </select>
1319                                 ';
1320
1321                         // Table with the field selector::
1322                 $content.= '
1323                         '.$formElements[0].'
1324
1325                                 <!--
1326                                         Field selector for extended table view:
1327                                 -->
1328                                 <table border="0" cellpadding="0" cellspacing="0" class="bgColor4" id="typo3-dblist-fieldSelect">
1329                                         <tr>
1330                                                 <td>'.$lMenu.'</td>
1331                                                 <td><input type="submit" name="search" value="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.setFields',1).'" /></td>
1332                                         </tr>
1333                                 </table>
1334                         '.$formElements[1];
1335                 return $content;
1336         }
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348         /*********************************
1349          *
1350          * Helper functions
1351          *
1352          *********************************/
1353
1354         /**
1355          * Creates a link around $string. The link contains an onclick action which submits the script with some clipboard action.
1356          * Currently, this is used for setting elements / delete elements.
1357          *
1358          * @param       string          The HTML content to link (image/text)
1359          * @param       string          Table name
1360          * @param       string          Clipboard command (eg. "setCB" or "delete")
1361          * @param       string          Warning text, if any ("delete" uses this for confirmation)
1362          * @return      string          <a> tag wrapped link.
1363          */
1364         function linkClipboardHeaderIcon($string,$table,$cmd,$warning='')       {
1365                 $onClickEvent = 'document.dblistForm.cmd.value=\''.$cmd.'\';document.dblistForm.cmd_table.value=\''.$table.'\';document.dblistForm.submit();';
1366                 if ($warning)   $onClickEvent = 'if (confirm('.$GLOBALS['LANG']->JScharCode($warning).')){'.$onClickEvent.'}';
1367                 return '<a href="#" onclick="'.htmlspecialchars($onClickEvent.'return false;').'">'.$string.'</a>';
1368         }
1369
1370         /**
1371          * Returns true if a numeric clipboard pad is selected/active
1372          *
1373          * @return      boolean
1374          */
1375         function clipNumPane()  {
1376                 return in_Array('_CLIPBOARD_',$this->fieldArray) && $this->clipObj->current!='normal';
1377         }
1378
1379         /**
1380          * Creates a sort-by link on the input string ($code).
1381          * It will automatically detect if sorting should be ascending or descending depending on $this->sortRev.
1382          * Also some fields will not be possible to sort (including if single-table-view is disabled).
1383          *
1384          * @param       string          The string to link (text)
1385          * @param       string          The fieldname represented by the title ($code)
1386          * @param       string          Table name
1387          * @return      string          Linked $code variable
1388          */
1389         function addSortLink($code,$field,$table)       {
1390
1391                         // Certain circumstances just return string right away (no links):
1392                 if ($field=='_CONTROL_' || $field=='_LOCALIZATION_' || $field=='_CLIPBOARD_' || $field=='_REF_' || $this->disableSingleTableView)       return $code;
1393
1394                         // If "_PATH_" (showing record path) is selected, force sorting by pid field (will at least group the records!)
1395                 if ($field=='_PATH_')   $field=pid;
1396
1397                         //       Create the sort link:
1398                 $sortUrl = $this->listURL('',-1,'sortField,sortRev,table').'&table='.$table.'&sortField='.$field.'&sortRev='.($this->sortRev || ($this->sortField!=$field)?0:1);
1399                 $sortArrow = ($this->sortField==$field?'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/red'.($this->sortRev?'up':'down').'.gif','width="7" height="4"').' alt="" />':'');
1400
1401                         // Return linked field:
1402                 return '<a href="'.htmlspecialchars($sortUrl).'">'.$code.
1403                                 $sortArrow.
1404                                 '</a>';
1405         }
1406
1407         /**
1408          * Returns the path for a certain pid
1409          * The result is cached internally for the session, thus you can call this function as much as you like without performance problems.
1410          *
1411          * @param       integer         The page id for which to get the path
1412          * @return      string          The path.
1413          */
1414         function recPath($pid)  {
1415                 if (!isset($this->recPath_cache[$pid])) {
1416                         $this->recPath_cache[$pid] = t3lib_BEfunc::getRecordPath($pid,$this->perms_clause,20);
1417                 }
1418                 return $this->recPath_cache[$pid];
1419         }
1420
1421         /**
1422          * Returns true if a link for creating new records should be displayed for $table
1423          *
1424          * @param       string          Table name
1425          * @return      boolean         Returns true if a link for creating new records should be displayed for $table
1426          * @see         SC_db_new::showNewRecLink
1427          */
1428         function showNewRecLink($table) {
1429                         // No deny/allow tables are set:
1430                 if (!count($this->allowedNewTables) && !count($this->deniedNewTables)) {
1431                         return true;
1432                         // If table is not denied (which takes precedence over allowed tables):
1433                 } elseif (!in_array($table, $this->deniedNewTables) && (!count($this->allowedNewTables) || in_array($table, $this->allowedNewTables))) {
1434                         return true;
1435                         // If table is denied or allowed tables are set, but table is not part of:
1436                 } else {
1437                         return false;
1438                 }
1439         }
1440
1441         /**
1442          * 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.
1443          * Uses REQUEST_URI as value.
1444          *
1445          * @return      string
1446          */
1447         function makeReturnUrl()        {
1448                 return '&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'));
1449         }
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461         /************************************
1462          *
1463          * CSV related functions
1464          *
1465          ************************************/
1466
1467         /**
1468          * Initializes internal csvLines array with the header of field names
1469          *
1470          * @return      void
1471          */
1472         function initCSV()      {
1473
1474                         // Reset:
1475                 $this->csvLines=array();
1476
1477                         // Getting header line with field names:
1478                 $csvRow = array();
1479                 foreach ($this->fieldArray as $fN) {
1480                         if ($fN == '_CONTROL_' || $fn == '_CLIPBOARD_') {
1481                                         continue;
1482                         }
1483                         $csvRow[] = $fN;
1484                 }
1485
1486                         // Set the header + an empty row:
1487                 $this->setCsvRow($csvRow);
1488                 $this->csvLines[] = '';
1489         }
1490
1491
1492         /**
1493          * Adds the content of input array $row to the CSV list:
1494          *
1495          * @param       array           Record array, from which the values of fields found in $this->fieldArray will be listed in the CSV output.
1496          * @param       string          Table name
1497          * @return      void
1498          */
1499         function addToCSV($row,$table)  {
1500
1501                         // Traversing fields, adding values from $row:
1502                 $csvRow = array();
1503                 foreach ($this->fieldArray as $fN) {
1504                         switch ($fN) {
1505                                 case '_PATH':
1506                                         $csvRow[] = $this->recPath($row['pid']);
1507                                         break;
1508
1509                                 case '_REF_':
1510                                         $csvRow[] = $this->makeRef($table, $row['uid']);
1511                                         break;
1512
1513                                         // remove these columns from the CSV view
1514                                 case '_CONTROL_':
1515                                 case '_CLIPBOARD_':
1516                                         continue;
1517                                         break;
1518
1519                                 default:
1520                                         $csvRow[] = $row[$fN];
1521                         }
1522                 }
1523
1524                         // Set the values in the CSV list
1525                 $this->setCsvRow($csvRow);
1526         }
1527
1528
1529         /**
1530          * Adds input row of values to the internal csvLines array as a CSV formatted line
1531          *
1532          * @param       array           Array with values to be listed.
1533          * @return      void
1534          */
1535         function setCsvRow($csvRow)     {
1536                 $this->csvLines[] = t3lib_div::csvValues($csvRow);
1537         }
1538
1539         /**
1540          * Compiles the internal csvLines array to a csv-string and outputs it to the browser.
1541          * This function exits!
1542          *
1543          * @param       string          Filename prefix:
1544          * @return      void            EXITS php execusion!
1545          */
1546         function outputCSV($prefix)     {
1547
1548                         // Setting filename:
1549                 $filename=$prefix.'_'.date('dmy-Hi').'.csv';
1550
1551                         // Creating output header:
1552                 $mimeType = 'application/octet-stream';
1553                 Header('Content-Type: '.$mimeType);
1554                 Header('Content-Disposition: attachment; filename='.$filename);
1555
1556                         // Printing the content of the CSV lines:
1557                 echo implode(chr(13).chr(10),$this->csvLines);
1558
1559                         // Exits:
1560                 exit;
1561         }
1562 }
1563
1564
1565
1566 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/class.db_list_extra.inc'])   {
1567         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/class.db_list_extra.inc']);
1568 }
1569
1570 ?>