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