Implemented versioning API, phase 1 (tcemain). See changelog
[Packages/TYPO3.CMS.git] / typo3 / class.db_list_extra.inc
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2004 Kasper Skaarhoj (kasper@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 <kasper@typo3.com>
36 */
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 *
41 *
42 * 89: class localRecordList extends recordList
43 * 121: function writeTop($row,$path)
44 * 295: function getTable($table,$id,$rowlist)
45 * 476: function renderListRow($table,$row,$cc,$titleCol,$thumbsCol)
46 * 539: function renderListHeader($table,$currentIdList)
47 *
48 * SECTION: Rendering of various elements
49 * 678: function makeControl($table,$row)
50 * 852: function makeClip($table,$row)
51 * 921: function fieldSelectBox($table,$formFields=1)
52 *
53 * SECTION: Helper functions
54 * 1000: function linkClipboardHeaderIcon($string,$table,$cmd,$warning='')
55 * 1011: function clipNumPane()
56 * 1025: function addSortLink($code,$field,$table)
57 * 1050: function recPath($pid)
58 * 1063: function showNewRecLink($table)
59 * 1073: function makeReturnUrl()
60 *
61 * SECTION: CSV related functions
62 * 1097: function initCSV()
63 * 1119: function addToCSV($row)
64 * 1141: function setCsvRow($csvRow)
65 * 1152: function outputCSV($prefix)
66 *
67 * TOTAL FUNCTIONS: 17
68 * (This index is automatically created/updated by the extension "extdeveval")
69 *
70 */
71
72
73
74
75
76
77
78
79
80
81
82 /**
83 * Class for rendering of Web>List module
84 *
85 * @author Kasper Skaarhoj <kasper@typo3.com>
86 * @package TYPO3
87 * @subpackage core
88 */
89 class localRecordList extends recordList {
90
91 // External:
92 var $alternateBgColors=FALSE; // If true, table rows in the list will alternate in background colors (and have background colors at all!)
93 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.
94 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!).
95
96 var $dontShowClipControlPanels=FALSE; // If true, will disable the rendering of clipboard + control panels.
97 var $showClipboard=FALSE; // If true, will show the clipboard in the field list.
98 var $noControlPanels = FALSE; // If true, will DISABLE all control panels in lists. (Takes precedence)
99
100
101
102
103 // Internal:
104 var $pageRow=array(); // Set to the page record (see writeTop())
105
106 var $csvLines=array(); // Used to accumulate CSV lines in for CSV export.
107 var $csvOutput=FALSE; // If set, the listing is returned as CSV instead.
108
109 var $clipObj; // Clipboard object
110 var $CBnames=array(); // Tracking names of elements (for clipboard use)
111 var $duplicateStack=array(); // Used to track which elements has duplicates and how many
112
113
114 /**
115 * Writes the top of the full listing
116 *
117 * @param array Current page record
118 * @return void (Adds content to internal variable, $this->HTMLcode)
119 */
120 function writeTop($row) {
121 global $LANG;
122
123 // Makes the code for the pageicon in the top
124 $this->pageRow = $row;
125 $this->counter++;
126 $alttext = t3lib_BEfunc::getRecordIconAltText($row,'pages');
127 $iconImg = t3lib_iconWorks::getIconImage('pages',$row,$this->backPath,'title="'.htmlspecialchars($alttext).'"');
128 $titleCol = 'test'; // pseudo title column name
129 $this->fieldArray = Array($titleCol,'up'); // Setting the fields to display in the list (this is of course "pseudo fields" since this is the top!)
130
131
132 // Filling in the pseudo data array:
133 $theData = Array();
134 $theData[$titleCol] = $this->widthGif;
135
136 // Get users permissions for this row:
137 $localCalcPerms = $GLOBALS['BE_USER']->calcPerms($row);
138
139 $theData['up']=array();
140
141 // Initialize control panel for currect page ($this->id):
142 // Some of the controls are added only if $this->id is set - since they make sense only on a real page, not root level.
143 $theCtrlPanel =array();
144
145 // "View page" icon is added:
146 $theCtrlPanel[]='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($this->id,'',t3lib_BEfunc::BEgetRootLine($this->id))).'">'.
147 '<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="" />'.
148 '</a>';
149
150 // If edit permissions are set (see class.t3lib_userauthgroup.php)
151 if ($localCalcPerms&2) {
152
153 // Adding "Edit page" icon:
154 if ($this->id) {
155 $params='&edit[pages]['.$row['uid'].']=edit';
156 $theCtrlPanel[]='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,'',-1)).'">'.
157 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('editPage',1).'" alt="" />'.
158 '</a>';
159 }
160
161 // Adding "New record" icon:
162 if (!$GLOBALS['SOBE']->modTSconfig['properties']['noCreateRecordsLink']) {
163 $theCtrlPanel[]='<a href="#" onclick="'.htmlspecialchars('return jumpExt(\'db_new.php?id='.$this->id.'\');').'">'.
164 '<img'.t3lib_iconWorks::skinImg('','gfx/new_el.gif','width="11" height="12"').' title="'.$LANG->getLL('newRecordGeneral',1).'" alt="" />'.
165 '</a>';
166 }
167
168 // Adding "Hide/Unhide" icon:
169 if ($this->id) {
170 if ($row['hidden']) {
171 $params='&data[pages]['.$row['uid'].'][hidden]=0';
172 $theCtrlPanel[]='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$GLOBALS['SOBE']->doc->issueCommand($params,-1).'\');').'">'.
173 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_unhide.gif','width="11" height="10"').' title="'.$LANG->getLL('unHidePage',1).'" alt="" />'.
174 '</a>';
175 } else {
176 $params='&data[pages]['.$row['uid'].'][hidden]=1';
177 $theCtrlPanel[]='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$GLOBALS['SOBE']->doc->issueCommand($params,-1).'\');').'">'.
178 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_hide.gif','width="11" height="10"').' title="'.$LANG->getLL('hidePage',1).'" alt="" />'.
179 '</a>';
180 }
181 }
182
183 // Adding "move page" button:
184 if ($this->id) {
185 $theCtrlPanel[]='<a href="#" onclick="'.htmlspecialchars('return jumpExt(\'move_el.php?table=pages&uid='.$row['uid'].'\');').'">'.
186 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/move_'.($table=='tt_content'?'record':'page').'.gif','width="11" height="12"').' title="'.$LANG->getLL('move_page',1).'" alt="" />'.
187 '</a>';
188 }
189 }
190
191 // "Paste into page" link:
192 if (($localCalcPerms&8) || ($localCalcPerms&16)) {
193 $elFromTable = $this->clipObj->elFromTable('');
194 if (count($elFromTable)) {
195 $theCtrlPanel[]='<a href="'.htmlspecialchars($this->clipObj->pasteUrl('',$this->id)).'" onclick="'.htmlspecialchars('return '.$this->clipObj->confirmMsg('pages',$this->pageRow,'into',$elFromTable)).'">'.
196 '<img'.t3lib_iconWorks::skinImg('','gfx/clip_pasteafter.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_paste',1).'" alt="" />'.
197 '</a>';
198 }
199 }
200
201 // Finally, compile all elements of the control panel into table cells:
202 if (count($theCtrlPanel)) {
203 $theData['up'][]='
204
205 <!--
206 Control panel for page
207 -->
208 <table border="0" cellpadding="0" cellspacing="0" class="bgColor4" id="typo3-dblist-ctrltop">
209 <tr>
210 <td>'.implode('</td>
211 <td>',$theCtrlPanel).'</td>
212 </tr>
213 </table>';
214 }
215
216
217 // Add "clear-cache" link:
218 $theData['up'][]='<a href="'.htmlspecialchars($this->listURL().'&clear_cache=1').'">'.
219 '<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="" />'.
220 '</a>';
221
222 // Add "CSV" link, if a specific table is shown:
223 if ($this->table) {
224 $theData['up'][]='<a href="'.htmlspecialchars($this->listURL().'&csv=1').'">'.
225 '<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="" />'.
226 '</a>';
227 }
228
229 // Add "refresh" link:
230 $theData['up'][]='<a href="'.htmlspecialchars($this->listURL()).'">'.
231 '<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="" />'.
232 '</a>';
233
234
235 // Add icon with clickmenu, etc:
236 if ($this->id) { // If there IS a real page...:
237
238 // Setting title of page + the "Go up" link:
239 $theData[$titleCol].='<br /><span title="'.htmlspecialchars($row['_thePathFull']).'">'.htmlspecialchars(t3lib_div::fixed_lgd_cs($row['_thePath'],-$this->fixedL)).'</span>';
240 $theData['up'][]='<a href="'.htmlspecialchars($this->listURL($row['pid'])).'">'.
241 '<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="" />'.
242 '</a>';
243
244 // Make Icon:
245 $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg,'pages',$this->id);
246 } else { // On root-level of page tree:
247
248 // Setting title of root (sitename):
249 $theData[$titleCol].='<br />'.htmlspecialchars(t3lib_div::fixed_lgd_cs($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],-$this->fixedL));
250
251 // Make Icon:
252 $theIcon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/i/_icon_website.gif','width="18" height="16"').' alt="" />';
253 }
254
255 // If there is a returnUrl given, add a back-link:
256 if ($this->returnUrl) {
257 $theData['up'][]='<a href="'.htmlspecialchars(t3lib_div::linkThisUrl($this->returnUrl,array('id'=>$this->id))).'" class="typo3-goBack">'.
258 '<img'.t3lib_iconWorks::skinImg($GLOBALS["BACK_PATH"],'gfx/goback.gif','width="14" height="14"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.goBack',1).'" alt="" />'.
259 '</a>';
260 }
261
262 // Finally, the "up" pseudo field is compiled into a table - has been accumulated in an array:
263 $theData['up']='
264 <table border="0" cellpadding="0" cellspacing="0">
265 <tr>
266 <td>'.implode('</td>
267 <td>',$theData['up']).'</td>
268 </tr>
269 </table>';
270
271 // ... and the element row is created:
272 $out.=$this->addelement(1,'',$theData,'',$this->leftMargin, $theIcon);
273
274 // ... and wrapped into a table and added to the internal ->HTMLcode variable:
275 $this->HTMLcode.='
276
277
278 <!--
279 Page header for db_list:
280 -->
281 <table border="0" cellpadding="0" cellspacing="0" id="typo3-dblist-top">
282 '.$out.'
283 </table>';
284 }
285
286 /**
287 * Creates the listing of records from a single table
288 *
289 * @param string Table name
290 * @param integer Page id
291 * @param string List of fields to show in the listing. Pseudo fields will be added including the record header.
292 * @return string HTML table with the listing for the record.
293 */
294 function getTable($table,$id,$rowlist) {
295 global $TCA;
296
297 // Loading all TCA details for this table:
298 t3lib_div::loadTCA($table);
299
300 // Init
301 $titleCol = $TCA[$table]['ctrl']['label'];
302 $thumbsCol = $TCA[$table]['ctrl']['thumbnail'];
303
304 // Cleaning rowlist for duplicates and place the $titleCol as the first column always!
305 $this->fieldArray=array();
306 $this->fieldArray[] = $titleCol; // Add title column
307 if (!t3lib_div::inList($rowlist,'_CONTROL_')) {
308 $this->fieldArray[] = '_CONTROL_';
309 }
310 if ($this->showClipboard) {
311 $this->fieldArray[] = '_CLIPBOARD_';
312 }
313 if ($this->searchLevels) {
314 $this->fieldArray[]='_PATH_';
315 }
316 // Cleaning up:
317 $this->fieldArray=array_unique(array_merge($this->fieldArray,t3lib_div::trimExplode(',',$rowlist,1)));
318 if ($this->noControlPanels) {
319 $tempArray = array_flip($this->fieldArray);
320 unset($tempArray['_CONTROL_']);
321 unset($tempArray['_CLIPBOARD_']);
322 $this->fieldArray = array_keys($tempArray);
323 }
324
325 // Creating the list of fields to include in the SQL query:
326 $selectFields = $this->fieldArray;
327 $selectFields[] = 'uid';
328 $selectFields[] = 'pid';
329 if ($thumbsCol) $selectFields[] = $thumbsCol; // adding column for thumbnails
330 if ($table=='pages') {
331 if (t3lib_extMgm::isLoaded('cms')) {
332 $selectFields[] = 'module';
333 $selectFields[] = 'extendToSubpages';
334 }
335 $selectFields[] = 'doktype';
336 }
337 if (is_array($TCA[$table]['ctrl']['enablecolumns'])) {
338 $selectFields = array_merge($selectFields,$TCA[$table]['ctrl']['enablecolumns']);
339 }
340 if ($TCA[$table]['ctrl']['type']) {
341 $selectFields[] = $TCA[$table]['ctrl']['type'];
342 }
343 if ($TCA[$table]['ctrl']['typeicon_column']) {
344 $selectFields[] = $TCA[$table]['ctrl']['typeicon_column'];
345 }
346 if ($TCA[$table]['ctrl']['versioning']) {
347 $selectFields[] = 't3ver_id';
348 }
349 if ($TCA[$table]['ctrl']['label_alt']) {
350 $selectFields = array_merge($selectFields,t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['label_alt'],1));
351 }
352 $selectFields = array_unique($selectFields); // Unique list!
353 $selectFields = array_intersect($selectFields,$this->makeFieldList($table,1)); // Making sure that the fields in the field-list ARE in the field-list from TCA!
354 $selFieldList = implode(',',$selectFields); // implode it into a list of fields for the SQL-statement.
355
356 // Create the SQL query for selecting the elements in the listing:
357 $queryParts = $this->makeQueryArray($table, $id,'',$selFieldList); // (API function from class.db_list.inc)
358 $this->setTotalItems($queryParts); // Finding the total amount of records on the page (API function from class.db_list.inc)
359
360 // Init:
361 $dbCount = 0;
362 $out = '';
363
364 // If the count query returned any number of records, we perform the real query, selecting records.
365 if ($this->totalItems) {
366 $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
367 $dbCount = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
368 }
369
370 $LOISmode = $this->listOnlyInSingleTableMode && !$this->table;
371
372 // If any records was selected, render the list:
373 if ($dbCount) {
374
375 // Half line is drawn between tables:
376 if (!$LOISmode) {
377 $theData = Array();
378 if (!$this->table && !$rowlist) {
379 $theData[$titleCol] = '<img src="clear.gif" width="'.($GLOBALS['SOBE']->MOD_SETTINGS['bigControlPanel']?'230':'350').'" height="1" alt="" />';
380 if (in_array('_CONTROL_',$this->fieldArray)) $theData['_CONTROL_']='';
381 if (in_array('_CLIPBOARD_',$this->fieldArray)) $theData['_CLIPBOARD_']='';
382 }
383 $out.=$this->addelement(0,'',$theData,'',$this->leftMargin);
384 }
385
386 // Header line is drawn
387 $theData = Array();
388 if ($this->disableSingleTableView) {
389 $theData[$titleCol] = '<span class="c-table">'.$GLOBALS['LANG']->sL($TCA[$table]['ctrl']['title'],1).'</span> ('.$this->totalItems.')';
390 } else {
391 $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="" />');
392 }
393
394 // CSH:
395 $theData[$titleCol].= t3lib_BEfunc::cshItem($table,'',$this->backPath,'',FALSE,'margin-bottom:0px; white-space: normal;');
396
397 if ($LOISmode) {
398 $out.='
399 <tr>
400 <td class="c-headLineTable" style="width:95%;">'.$theData[$titleCol].'</td>
401 </tr>';
402
403 if ($GLOBALS['BE_USER']->uc["edit_showFieldHelp"]) {
404 $GLOBALS['LANG']->loadSingleTableDescription($table);
405 if (isset($GLOBALS['TCA_DESCR'][$table]['columns'][''])) {
406 $onClick = 'vHWin=window.open(\'view_help.php?tfID='.$table.'.\',\'viewFieldHelp\',\'height=400,width=600,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;';
407 $out.='
408 <tr>
409 <td class="c-tableDescription">'.t3lib_BEfunc::helpTextIcon($table,'',$this->backPath,TRUE).$GLOBALS['TCA_DESCR'][$table]['columns']['']['description'].'</td>
410 </tr>';
411 }
412 }
413 } else {
414 $theUpIcon = ($table=='pages'&&$this->id&&isset($this->pageRow['pid'])) ? '<a href="'.htmlspecialchars($this->listURL($this->pageRow['pid'])).'"><img'.t3lib_iconWorks::skinImg('','gfx/i/pages_up.gif','width="18" height="16"').' title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.upOneLevel',1).'" alt="" /></a>':'';
415 $out.=$this->addelement(1,$theUpIcon,$theData,' class="c-headLineTable"','');
416 }
417
418 If (!$LOISmode) {
419 // Fixing a order table for sortby tables
420 $this->currentTable = array();
421 $currentIdList = array();
422 $doSort = ($TCA[$table]['ctrl']['sortby'] && !$this->sortField);
423
424 $prevUid = 0;
425 $prevPrevUid = 0;
426 $accRows = array(); // Accumulate rows here
427 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
428 $accRows[] = $row;
429 $currentIdList[] = $row['uid'];
430 if ($doSort) {
431 if ($prevUid) {
432 $this->currentTable['prev'][$row['uid']] = $prevPrevUid;
433 $this->currentTable['next'][$prevUid] = '-'.$row['uid'];
434 $this->currentTable['prevUid'][$row['uid']] = $prevUid;
435 }
436 $prevPrevUid = isset($this->currentTable['prev'][$row['uid']]) ? -$prevUid : $row['pid'];
437 $prevUid=$row['uid'];
438 }
439 }
440 $GLOBALS['TYPO3_DB']->sql_free_result($result);
441
442 // CSV initiated
443 if ($this->csvOutput) $this->initCSV();
444
445 // Render items:
446 $this->CBnames=array();
447 $this->duplicateStack=array();
448 $this->eCounter=$this->firstElementNumber;
449
450 $iOut = '';
451 $cc = 0;
452 foreach($accRows as $row) {
453
454 // Forward/Backwards navigation links:
455 list($flag,$code) = $this->fwd_rwd_nav($table);
456 $iOut.=$code;
457
458 // If render item, increment counter and call function
459 if ($flag) {
460 $cc++;
461 $iOut.=$this->renderListRow($table,$row,$cc,$titleCol,$thumbsCol);
462 }
463
464 // Counter of total rows incremented:
465 $this->eCounter++;
466 }
467
468 // The header row for the table is now created:
469 $out.=$this->renderListHeader($table,$currentIdList);
470 }
471
472 // The list of records is added after the header:
473 $out.=$iOut;
474
475 // ... and it is all wrapped in a table:
476 $out='
477
478
479
480 <!--
481 DB listing of elements: "'.htmlspecialchars($table).'"
482 -->
483 <table border="0" cellpadding="0" cellspacing="0" class="typo3-dblist'.($LOISmode?' typo3-dblist-overview':'').'">
484 '.$out.'
485 </table>';
486
487 // Output csv if...
488 if ($this->csvOutput) $this->outputCSV($table); // This ends the page with exit.
489 }
490
491 // Return content:
492 return $out;
493 }
494
495 /**
496 * Rendering a single row for the list
497 *
498 * @param string Table name
499 * @param array Current record
500 * @param integer Counter, counting for each time an element is rendered (used for alternating colors)
501 * @param string Table field (column) where header value is found
502 * @param string Table field (column) where (possible) thumbnails can be found
503 * @return string Table row for the element
504 * @access private
505 * @see getTable()
506 */
507 function renderListRow($table,$row,$cc,$titleCol,$thumbsCol) {
508 $iOut = '';
509
510 // Background color, if any:
511 $row_bgColor=
512 $this->alternateBgColors ?
513 (($cc%2)?'' :' bgcolor="'.t3lib_div::modifyHTMLColor($GLOBALS['SOBE']->doc->bgColor4,+10,+10,+10).'"') :
514 '';
515
516 // Initialization
517 $alttext = t3lib_BEfunc::getRecordIconAltText($row,$table);
518 $recTitle = t3lib_BEfunc::getRecordTitle($table,$row);
519
520 // Incr. counter.
521 $this->counter++;
522
523 // The icon with link
524 $iconImg = t3lib_iconWorks::getIconImage($table,$row,$this->backPath,'title="'.htmlspecialchars($alttext).'"');
525 $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg,$table,$row['uid']);
526
527 // Preparing and getting the data-array
528 $theData = Array();
529 foreach($this->fieldArray as $fCol) {
530 if ($fCol==$titleCol) {
531 $theData[$fCol] = $this->linkWrapItems($table,$row['uid'],$recTitle,$row);
532 } elseif ($fCol=='pid') {
533 $theData[$fCol]=$row[$fCol];
534 } elseif ($fCol=='_PATH_') {
535 $theData[$fCol]=$this->recPath($row['pid']);
536 } elseif ($fCol=='_CONTROL_') {
537 $theData[$fCol]=$this->makeControl($table,$row);
538 } elseif ($fCol=='_CLIPBOARD_') {
539 $theData[$fCol]=$this->makeClip($table,$row);
540 } else {
541 $theData[$fCol]=htmlspecialchars(t3lib_BEfunc::getProcessedValueExtra($table,$fCol,$row[$fCol],100));
542 }
543 }
544
545 // Add row to CSV list:
546 if ($this->csvOutput) $this->addToCSV($row);
547
548 // Create element in table cells:
549 $iOut.=$this->addelement(1,$theIcon,$theData,$row_bgColor);
550
551 // Render thumbsnails if a thumbnail column exists and there is content in it:
552 if ($this->thumbs && trim($row[$thumbsCol])) {
553 $iOut.=$this->addelement(4,'', Array($titleCol=>$this->thumbCode($row,$table,$thumbsCol)),$row_bgColor);
554 }
555
556 // Finally, return table row element:
557 return $iOut;
558 }
559
560 /**
561 * Rendering the header row for a table
562 *
563 * @param string Table name
564 * @param array Array of the currectly displayed uids of the table
565 * @return string Header table row
566 * @access private
567 * @see getTable()
568 */
569 function renderListHeader($table,$currentIdList) {
570 global $TCA, $LANG;
571
572 // Init:
573 $theData = Array();
574
575 // Traverse the fields:
576 foreach($this->fieldArray as $fCol) {
577
578 // Calculate users permissions to edit records in the table:
579 $permsEdit = $this->calcPerms & ($table=='pages'?2:16);
580
581 switch((string)$fCol) {
582 case '_PATH_': // Path
583 $theData[$fCol]='<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._PATH_',1).']</i>';
584 break;
585 case '_CLIPBOARD_': // Clipboard:
586 $cells=array();
587
588 // If there are elements on the clipboard for this table, then display the "paste into" icon:
589 $elFromTable = $this->clipObj->elFromTable($table);
590 if (count($elFromTable)) {
591 $cells[]='<a href="'.htmlspecialchars($this->clipObj->pasteUrl($table,$this->id)).'" onclick="'.htmlspecialchars('return '.$this->clipObj->confirmMsg('pages',$this->pageRow,'into',$elFromTable)).'">'.
592 '<img'.t3lib_iconWorks::skinImg('','gfx/clip_pasteafter.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_paste',1).'" alt="" />'.
593 '</a>';
594 }
595
596 // If the numeric clipboard pads are enabled, display the control icons for that:
597 if ($this->clipObj->current!='normal') {
598
599 // The "select" link:
600 $cells[]=$this->linkClipboardHeaderIcon('<img'.t3lib_iconWorks::skinImg('','gfx/clip_copy.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_selectMarked',1).'" alt="" />',$table,'setCB');
601
602 // The "edit marked" link:
603 $editIdList = implode(',',$currentIdList);
604 $editIdList = "'+editList('".$table."','".$editIdList."')+'";
605 $params='&edit['.$table.']['.$editIdList.']=edit&disHelp=1';
606 $cells[]='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,'',-1)).'">'.
607 '<img'.t3lib_iconWorks::skinImg('','gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('clip_editMarked',1).'" alt="" />'.
608 '</a>';
609
610 // The "Delete marked" link:
611 $cells[]=$this->linkClipboardHeaderIcon('<img'.t3lib_iconWorks::skinImg('','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'])));
612
613 // The "Select all" link:
614 $cells[]='<a href="#" onclick="'.htmlspecialchars('checkOffCB(\''.implode(',',$this->CBnames).'\'); return false;').'">'.
615 '<img'.t3lib_iconWorks::skinImg('','gfx/clip_select.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_markRecords',1).'" alt="" />'.
616 '</a>';
617 } else {
618 $cells[]='';
619 }
620 $theData[$fCol]=implode('',$cells);
621 break;
622 case '_CONTROL_': // Control panel:
623 if (!$TCA[$table]['ctrl']['readOnly']) {
624
625 // If new records can be created on this page, add links:
626 if ($this->calcPerms&($table=='pages'?8:16) && $this->showNewRecLink($table)) {
627 if ($table=="tt_content" && $this->newWizards) {
628 // If mod.web_list.newContentWiz.overrideWithExtension is set, use that extension's create new content wizard instead:
629 $tmpTSc = t3lib_BEfunc::getModTSconfig($this->pageinfo['uid'],'mod.web_list');
630 $tmpTSc = $tmpTSc ['properties']['newContentWiz.']['overrideWithExtension'];
631 $newContentWizScriptPath = t3lib_extMgm::isLoaded($tmpTSc) ? (t3lib_extMgm::extRelPath($tmpTSc).'mod1/db_new_content_el.php') : 'sysext/cms/layout/db_new_content_el.php';
632
633 $theData[$fCol]='<a href="#" onclick="'.htmlspecialchars('return jumpExt(\''.$newContentWizScriptPath.'?id='.$this->id.'\');').'">'.
634 '<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="" />'.
635 '</a>';
636 } elseif ($table=='pages' && $this->newWizards) {
637 $theData[$fCol]='<a href="'.htmlspecialchars('db_new.php?id='.$this->id.'&pagesOnly=1returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'">'.
638 '<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="" />'.
639 '</a>';
640 } else {
641 $params='&edit['.$table.']['.$this->id.']=new';
642 $theData[$fCol]='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,'',-1)).'">'.
643 '<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="" />'.
644 '</a>';
645 }
646 }
647
648 // If the table can be edited, add link for editing ALL SHOWN fields for all listed records:
649 if ($permsEdit && $this->table && is_array($currentIdList)) {
650 $editIdList = implode(',',$currentIdList);
651 if ($this->clipNumPane()) $editIdList = "'+editList('".$table."','".$editIdList."')+'";
652 $params='&edit['.$table.']['.$editIdList.']=edit&columnsOnly='.implode(',',$this->fieldArray).'&disHelp=1';
653 $theData[$fCol].='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,'',-1)).'">'.
654 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('editShownColumns',1).'" alt="" />'.
655 '</a>';
656 }
657 }
658 break;
659 default: // Regular fields header:
660 $theData[$fCol]='';
661 if ($this->table && is_array($currentIdList)) {
662
663 // If the numeric clipboard pads are selected, show duplicate sorting link:
664 if ($this->clipNumPane()) {
665 $theData[$fCol].='<a href="'.htmlspecialchars($this->listURL('',-1).'&duplicateField='.$fCol).'">'.
666 '<img'.t3lib_iconWorks::skinImg('','gfx/select_duplicates.gif','width="11" height="11"').' title="'.$LANG->getLL('clip_duplicates',1).'" alt="" />'.
667 '</a>';
668 }
669
670 // If the table can be edited, add link for editing THIS field for all listed records:
671 if (!$TCA[$table]['ctrl']['readOnly'] && $permsEdit && $TCA[$table]['columns'][$fCol]) {
672 $editIdList = implode(',',$currentIdList);
673 if ($this->clipNumPane()) $editIdList = "'+editList('".$table."','".$editIdList."')+'";
674 $params='&edit['.$table.']['.$editIdList.']=edit&columnsOnly='.$fCol.'&disHelp=1';
675 $iTitle = sprintf($LANG->getLL('editThisColumn'),ereg_replace(':$','',trim($LANG->sL(t3lib_BEfunc::getItemLabel($table,$fCol)))));
676 $theData[$fCol].='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,'',-1)).'">'.
677 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2.gif','width="11" height="12"').' title="'.htmlspecialchars($iTitle).'" alt="" />'.
678 '</a>';
679 }
680 }
681 $theData[$fCol].=$this->addSortLink($LANG->sL(t3lib_BEfunc::getItemLabel($table,$fCol,'<i>[|]</i>')),$fCol,$table);
682 break;
683 }
684 }
685
686 // Create and return header table row:
687 return $this->addelement(1,'',$theData,' class="c-headLine"','');
688 }
689
690
691
692
693
694
695 /*********************************
696 *
697 * Rendering of various elements
698 *
699 *********************************/
700
701 /**
702 * Creates the control panel for a single record in the listing.
703 *
704 * @param string The table
705 * @param array The record for which to make the control panel.
706 * @return string HTML table with the control panel (unless disabled)
707 */
708 function makeControl($table,$row) {
709 global $TCA, $LANG, $SOBE;
710
711 // Return blank, if disabled:
712 if ($this->dontShowClipControlPanels) return '';
713
714 // Initialize:
715 t3lib_div::loadTCA($table);
716 $cells=array();
717
718 // If the listed table is 'pages' we have to request the permission settings for each page:
719 if ($table=='pages') {
720 $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$row['uid']));
721 }
722
723 // This expresses the edit permissions for this particular element:
724 $permsEdit = ($table=='pages' && ($localCalcPerms&2)) || ($table!='pages' && ($this->calcPerms&16));
725
726 // "Show" link (only pages and tt_content elements)
727 if ($table=='pages' || $table=='tt_content') {
728 $params='&edit['.$table.']['.$row['uid'].']=edit';
729 $cells[]='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($table=='tt_content'?$this->id.'#'.$row['uid']:$row['uid'])).'">'.
730 '<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="" />'.
731 '</a>';
732 }
733
734 // "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id)
735 if ($permsEdit) {
736 $params='&edit['.$table.']['.$row['uid'].']=edit';
737 $cells[]='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,'',-1)).'">'.
738 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/edit2'.(!$TCA[$table]['ctrl']['readOnly']?'':'_d').'.gif','width="11" height="12"').' title="'.$LANG->getLL('edit',1).'" alt="" />'.
739 '</a>';
740 }
741
742 // "Move" wizard link for pages/tt_content elements:
743 if (($table=="tt_content" && $permsEdit) || ($table=='pages')) {
744 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpExt(\'move_el.php?table='.$table.'&uid='.$row['uid'].'\');').'">'.
745 '<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="" />'.
746 '</a>';
747 }
748
749 // If the extended control panel is enabled OR if we are seeing a single table:
750 if ($SOBE->MOD_SETTINGS['bigControlPanel'] || $this->table) {
751
752 // "Info": (All records)
753 $cells[]='<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$table.'\', \''.$row['uid'].'\'); return false;').'">'.
754 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/zoom2.gif','width="12" height="12"').' title="'.$LANG->getLL('showInfo',1).'" alt="" />'.
755 '</a>';
756
757 // If the table is NOT a read-only table, then show these links:
758 if (!$TCA[$table]['ctrl']['readOnly']) {
759
760 // "Revert" link (history/undo)
761 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpExt(\'show_rechis.php?element='.rawurlencode($table.':'.$row['uid']).'\',\'#latest\');').'">'.
762 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/history2.gif','width="13" height="12"').' title="'.$LANG->getLL('history',1).'" alt="" />'.
763 '</a>';
764
765 // "Edit Perms" link:
766 if ($table=='pages' && $GLOBALS['BE_USER']->check('modules','web_perm')) {
767 $cells[]='<a href="'.htmlspecialchars('mod/web/perm/index.php?id='.$row['uid'].'&return_id='.$row['uid'].'&edit=1').'">'.
768 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/perm.gif','width="7" height="12"').' title="'.$LANG->getLL('permissions',1).'" alt="" />'.
769 '</a>';
770 }
771
772 // "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):
773 if ($TCA[$table]['ctrl']['sortby'] || $TCA[$table]['ctrl']['useColumnsForDefaultValues']) {
774 if (
775 ($table!='pages' && ($this->calcPerms&16)) || // For NON-pages, must have permission to edit content on this parent page
776 ($table=='pages' && ($this->calcPerms&8)) // For pages, must have permission to create new pages here.
777 ) {
778 if ($this->showNewRecLink($table)) {
779 $params='&edit['.$table.']['.(-$row['uid']).']=new';
780 $cells[]='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,'',-1)).'">'.
781 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/new_'.($table=='pages'?'page':'el').'.gif','width="'.($table=='pages'?13:11).'" height="12"').' title="'.$LANG->getLL('new'.($table=='pages'?'Page':'Record'),1).'" alt="" />'.
782 '</a>';
783 }
784 }
785 }
786
787 // "Up/Down" links
788 if ($permsEdit && $TCA[$table]['ctrl']['sortby'] && !$this->sortField && !$this->searchLevels) {
789 if (isset($this->currentTable['prev'][$row['uid']])) { // Up
790 $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['prev'][$row['uid']];
791 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
792 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_up.gif','width="11" height="10"').' title="'.$LANG->getLL('moveUp',1).'" alt="" />'.
793 '</a>';
794 } else {
795 $cells[]='<img src="clear.gif" '.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_up.gif','width="11" height="10"',2).' alt="" />';
796 }
797 if ($this->currentTable['next'][$row['uid']]) { // Down
798 $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['next'][$row['uid']];
799 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
800 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_down.gif','width="11" height="10"').' title="'.$LANG->getLL('moveDown',1).'" alt="" />'.
801 '</a>';
802 } else {
803 $cells[]='<img src="clear.gif" '.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_down.gif','width="11" height="10"',2).' alt="" />';
804 }
805 }
806
807 // "Hide/Unhide" links:
808 $hiddenField = $TCA[$table]['ctrl']['enablecolumns']['disabled'];
809 if ($permsEdit && $hiddenField && $TCA[$table]['columns'][$hiddenField] && (!$TCA[$table]['columns'][$hiddenField]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields',$table.':'.$hiddenField))) {
810 if ($row[$hiddenField]) {
811 $params='&data['.$table.']['.$row['uid'].']['.$hiddenField.']=0';
812 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
813 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_unhide.gif','width="11" height="10"').' title="'.$LANG->getLL('unHide'.($table=='pages'?'Page':''),1).'" alt="" />'.
814 '</a>';
815 } else {
816 $params='&data['.$table.']['.$row['uid'].']['.$hiddenField.']=1';
817 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
818 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_hide.gif','width="11" height="10"').' title="'.$LANG->getLL('hide'.($table=='pages'?'Page':''),1).'" alt="" />'.
819 '</a>';
820 }
821 }
822
823 // "Delete" link:
824 if (
825 ($table=='pages' && ($localCalcPerms&4)) || ($table!='pages' && ($this->calcPerms&16))
826 ) {
827 $params='&cmd['.$table.']['.$row['uid'].'][delete]=1';
828 $cells[]='<a href="#" onclick="'.htmlspecialchars('if (confirm('.$LANG->JScharCode($LANG->getLL('deleteWarning')).')) {jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');} return false;').'">'.
829 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/garbage.gif','width="11" height="12"').' title="'.$LANG->getLL('delete',1).'" alt="" />'.
830 '</a>';
831 }
832
833 // "Levels" links: Moving pages into new levels...
834 if ($permsEdit && $table=='pages' && !$this->searchLevels) {
835
836 // Up (Paste as the page right after the current parent page)
837 if ($this->calcPerms&8) {
838 $params='&cmd['.$table.']['.$row['uid'].'][move]='.-$this->id;
839 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
840 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_left.gif','width="11" height="10"').' title="'.$LANG->getLL('prevLevel',1).'" alt="" />'.
841 '</a>';
842 }
843 // Down (Paste as subpage to the page right above)
844 if ($this->currentTable['prevUid'][$row['uid']]) {
845 $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$this->currentTable['prevUid'][$row['uid']]));
846 if ($localCalcPerms&8) {
847 $params='&cmd['.$table.']['.$row['uid'].'][move]='.$this->currentTable['prevUid'][$row['uid']];
848 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');').'">'.
849 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_right.gif','width="11" height="10"').' title="'.$LANG->getLL('nextLevel',1).'" alt="" />'.
850 '</a>';
851 } else {
852 $cells[]='<img src="clear.gif" '.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_right.gif','width="11" height="10"',2).' alt="" />';
853 }
854 } else {
855 $cells[]='<img src="clear.gif" '.t3lib_iconWorks::skinImg($this->backPath,'gfx/button_right.gif','width="11" height="10"',2).' alt="" />';
856 }
857 }
858 }
859 }
860
861 // If the record is edit-locked by another user, we will show a little warning sign:
862 if ($lockInfo=t3lib_BEfunc::isRecordLocked($table,$row['uid'])) {
863 $cells[]='<a href="#" onclick="'.htmlspecialchars('alert('.$LANG->JScharCode($lockInfo['msg']).');return false;').'">'.
864 '<img'.t3lib_iconWorks::skinImg('','gfx/recordlock_warning3.gif','width="17" height="12"').' title="'.htmlspecialchars($lockInfo['msg']).'" alt="" />'.
865 '</a>';
866 }
867
868
869 // Compile items into a DIV-element:
870 return '
871 <!-- CONTROL PANEL: '.$table.':'.$row['uid'].' -->
872 <div class="typo3-DBctrl">'.implode('',$cells).'</div>';
873 }
874
875 /**
876 * Creates the clipboard panel for a single record in the listing.
877 *
878 * @param string The table
879 * @param array The record for which to make the clipboard panel.
880 * @return string HTML table with the clipboard panel (unless disabled)
881 */
882 function makeClip($table,$row) {
883 global $TCA, $LANG;
884
885 // Return blank, if disabled:
886 if ($this->dontShowClipControlPanels) return '';
887 $cells=array();
888
889 // Whether a numeric clipboard pad is active or the normal pad we will see different content of the panel:
890 if ($this->clipObj->current=='normal') { // For the "Normal" pad:
891
892 // Show copy/cut icons:
893 $isSel = (string)$this->clipObj->isSelected($table,$row['uid']);
894 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpSelf(\''.$this->clipObj->selUrlDB($table,$row['uid'],1,($isSel=='copy'),array('returnUrl'=>'')).'\');').'">'.
895 '<img'.t3lib_iconWorks::skinImg('','gfx/clip_copy'.($isSel=='copy'?'_h':'').'.gif','width="12" height="12"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:cm.copy',1).'" alt="" />'.
896 '</a>';
897 $cells[]='<a href="#" onclick="'.htmlspecialchars('return jumpSelf(\''.$this->clipObj->selUrlDB($table,$row['uid'],0,($isSel=='cut'),array('returnUrl'=>'')).'\');').'">'.
898 '<img'.t3lib_iconWorks::skinImg('','gfx/clip_cut'.($isSel=='cut'?'_h':'').'.gif','width="12" height="12"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:cm.cut',1).'" alt="" />'.
899 '</a>';
900
901 } else { // For the numeric clipboard pads (showing checkboxes where one can select elements on/off)
902
903 // Setting name of the element in ->CBnames array:
904 $n=$table.'|'.$row['uid'];
905 $this->CBnames[]=$n;
906
907 // Check if the current element is selected and if so, prepare to set the checkbox as selected:
908 $checked = ($this->clipObj->isSelected($table,$row['uid'])?' checked="checked"':'');
909
910 // If the "duplicateField" value is set then select all elements which are duplicates...
911 if ($this->duplicateField && isset($row[$this->duplicateField])) {
912 $checked='';
913 if (in_array($row[$this->duplicateField], $this->duplicateStack)) {
914 $checked=' checked="checked"';
915 }
916 $this->duplicateStack[] = $row[$this->duplicateField];
917 }
918
919 // Adding the checkbox to the panel:
920 $cells[]='<input type="hidden" name="CBH['.$n.']" value="0" /><input type="checkbox" name="CBC['.$n.']" value="1" class="smallCheckboxes"'.$checked.' />';
921 }
922
923 // Now, looking for selected elements from the current table:
924 $elFromTable = $this->clipObj->elFromTable($table);
925 if (count($elFromTable) && $TCA[$table]['ctrl']['sortby']) { // IF elements are found and they can be individually ordered, then add a "paste after" icon:
926 $cells[]='<a href="'.htmlspecialchars($this->clipObj->pasteUrl($table,-$row['uid'])).'" onclick="'.htmlspecialchars('return '.$this->clipObj->confirmMsg($table,$row,'after',$elFromTable)).'">'.
927 '<img'.t3lib_iconWorks::skinImg('','gfx/clip_pasteafter.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_pasteAfter',1).'" alt="" />'.
928 '</a>';
929 }
930
931 // Now, looking for elements in general:
932 $elFromTable = $this->clipObj->elFromTable('');
933 if ($table=='pages' && count($elFromTable)) {
934 $cells[]='<a href="'.htmlspecialchars($this->clipObj->pasteUrl('',$row['uid'])).'" onclick="'.htmlspecialchars('return '.$this->clipObj->confirmMsg($table,$row,'into',$elFromTable)).'">'.
935 '<img'.t3lib_iconWorks::skinImg('','gfx/clip_pasteinto.gif','width="12" height="12"').' title="'.$LANG->getLL('clip_pasteInto',1).'" alt="" />'.
936 '</a>';
937 }
938
939 // Compile items into a DIV-element:
940 return ' <!-- CLIPBOARD PANEL: '.$table.':'.$row['uid'].' -->
941 <div class="typo3-clipCtrl">'.implode('',$cells).'</div>';
942 }
943
944 /**
945 * Create the selector box for selecting fields to display from a table:
946 *
947 * @param string Table name
948 * @param boolean If true, form-fields will be wrapped around the table.
949 * @return string HTML table with the selector box (name: displayFields['.$table.'][])
950 */
951 function fieldSelectBox($table,$formFields=1) {
952 global $TCA, $LANG;
953
954 // Init:
955 t3lib_div::loadTCA($table);
956 $formElements=array('','');
957 if ($formFields) {
958 $formElements=array('<form action="'.htmlspecialchars($this->listURL()).'" method="post">','</form>');
959 }
960
961 // Load already selected fields, if any:
962 $setFields=is_array($this->setFields[$table]) ? $this->setFields[$table] : array();
963
964 // Request fields from table:
965 $fields = $this->makeFieldList($table);
966
967 // Add pseudo "control" fields
968 $fields[]='_PATH_';
969 $fields[]='_CONTROL_';
970 $fields[]='_CLIPBOARD_';
971
972 // Create an option for each field:
973 $opt=array();
974 $opt[] = '<option value=""></option>';
975 foreach($fields as $fN) {
976 $fL = is_array($TCA[$table]['columns'][$fN]) ? ereg_replace(':$','',$LANG->sL($TCA[$table]['columns'][$fN]['label'])) : '['.$fN.']'; // Field label
977 $opt[] = '
978 <option value="'.$fN.'"'.(in_array($fN,$setFields)?' selected="selected"':'').'>'.htmlspecialchars($fL).'</option>';
979 }
980
981 // Compile the options into a multiple selector box:
982 $lMenu = '
983 <select size="'.t3lib_div::intInRange(count($fields)+1,3,20).'" multiple="multiple" name="displayFields['.$table.'][]">'.implode('',$opt).'
984 </select>
985 ';
986
987 // Table with the field selector::
988 $content.= '
989 '.$formElements[0].'
990
991 <!--
992 Field selector for extended table view:
993 -->
994 <table border="0" cellpadding="0" cellspacing="0" class="bgColor4" id="typo3-dblist-fieldSelect">
995 <tr>
996 <td>'.$lMenu.'</td>
997 <td><input type="submit" name="search" value="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.setFields',1).'" /></td>
998 </tr>
999 </table>
1000 '.$formElements[1];
1001 return $content;
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014 /*********************************
1015 *
1016 * Helper functions
1017 *
1018 *********************************/
1019
1020 /**
1021 * Creates a link around $string. The link contains an onclick action which submits the script with some clipboard action.
1022 * Currently, this is used for setting elements / delete elements.
1023 *
1024 * @param string The HTML content to link (image/text)
1025 * @param string Table name
1026 * @param string Clipboard command (eg. "setCB" or "delete")
1027 * @param string Warning text, if any ("delete" uses this for confirmation)
1028 * @return string <a> tag wrapped link.
1029 */
1030 function linkClipboardHeaderIcon($string,$table,$cmd,$warning='') {
1031 $onClickEvent = 'document.dblistForm.cmd.value=\''.$cmd.'\';document.dblistForm.cmd_table.value=\''.$table.'\';document.dblistForm.submit();';
1032 if ($warning) $onClickEvent = 'if (confirm('.$GLOBALS['LANG']->JScharCode($warning).')){'.$onClickEvent.'}';
1033 return '<a href="#" onclick="'.htmlspecialchars($onClickEvent.'return false;').'">'.$string.'</a>';
1034 }
1035
1036 /**
1037 * Returns true if a numeric clipboard pad is selected/active
1038 *
1039 * @return boolean
1040 */
1041 function clipNumPane() {
1042 return in_Array('_CLIPBOARD_',$this->fieldArray) && $this->clipObj->current!='normal';
1043 }
1044
1045 /**
1046 * Creates a sort-by link on the input string ($code).
1047 * It will automatically detect if sorting should be ascending or descending depending on $this->sortRev.
1048 * Also some fields will not be possible to sort (including if single-table-view is disabled).
1049 *
1050 * @param string The string to link (text)
1051 * @param string The fieldname represented by the title ($code)
1052 * @param string Table name
1053 * @return string Linked $code variable
1054 */
1055 function addSortLink($code,$field,$table) {
1056
1057 // Certain circumstances just return string right away (no links):
1058 if ($field=='_CONTROL_' || $field=='_CLIPBOARD_' || $this->disableSingleTableView) return $code;
1059
1060 // If "_PATH_" (showing record path) is selected, force sorting by pid field (will at least group the records!)
1061 if ($field=='_PATH_') $field=pid;
1062
1063 // Create the sort link:
1064 $sortUrl = $this->listURL('',-1,'sortField,sortRev,table').'&table='.$table.'&sortField='.$field.'&sortRev='.($this->sortRev || ($this->sortField!=$field)?0:1);
1065 $sortArrow = ($this->sortField==$field?'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/red'.($this->sortRev?'up':'down').'.gif','width="7" height="4"').' alt="" />':'');
1066
1067 // Return linked field:
1068 return '<a href="'.htmlspecialchars($sortUrl).'">'.$code.
1069 $sortArrow.
1070 '</a>';
1071 }
1072
1073 /**
1074 * Returns the path for a certain pid
1075 * The result is cached internally for the session, thus you can call this function as much as you like without performance problems.
1076 *
1077 * @param integer The page id for which to get the path
1078 * @return string The path.
1079 */
1080 function recPath($pid) {
1081 if (!isset($this->recPath_cache[$pid])) {
1082 $this->recPath_cache[$pid] = t3lib_BEfunc::getRecordPath($pid,$this->perms_clause,20);
1083 }
1084 return $this->recPath_cache[$pid];
1085 }
1086
1087 /**
1088 * Returns true if a link for creating new records should be displayed for $table
1089 *
1090 * @param string Table name
1091 * @return boolean
1092 */
1093 function showNewRecLink($table) {
1094 return !count($this->allowedNewTables) || in_array($table,$this->allowedNewTables);
1095 }
1096
1097 /**
1098 * 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.
1099 * Uses REQUEST_URI as value.
1100 *
1101 * @return string
1102 */
1103 function makeReturnUrl() {
1104 return '&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'));
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 /************************************
1117 *
1118 * CSV related functions
1119 *
1120 ************************************/
1121
1122 /**
1123 * Initializes internal csvLines array with the header of field names
1124 *
1125 * @return void
1126 */
1127 function initCSV() {
1128
1129 // Reset:
1130 $this->csvLines=array();
1131
1132 // Getting header line with field names:
1133 $csvRow=array();
1134 foreach($this->fieldArray as $fN) {
1135 $csvRow[]=$fN;
1136 }
1137
1138 // Set the header + an empty row:
1139 $this->setCsvRow($csvRow);
1140 $this->csvLines[]='';
1141 }
1142
1143 /**
1144 * Adds the content of input array $row to the CSV list:
1145 *
1146 * @param array Record array, from which the values of fields found in $this->fieldArray will be listed in the CSV output.
1147 * @return void
1148 */
1149 function addToCSV($row) {
1150
1151 // Traversing fields, adding values from $row:
1152 $csvRow=array();
1153 foreach($this->fieldArray as $fN) {
1154 if ($fN=='_PATH_') {
1155 $csvRow[]=$this->recPath($row['pid']);
1156 } else {
1157 $csvRow[]=$row[$fN];
1158 }
1159 }
1160
1161 // Set the values in the CSV list
1162 $this->setCsvRow($csvRow);
1163 }
1164
1165 /**
1166 * Adds input row of values to the internal csvLines array as a CSV formatted line
1167 *
1168 * @param array Array with values to be listed.
1169 * @return void
1170 */
1171 function setCsvRow($csvRow) {
1172 $this->csvLines[] = t3lib_div::csvValues($csvRow);
1173 }
1174
1175 /**
1176 * Compiles the internal csvLines array to a csv-string and outputs it to the browser.
1177 * This function exits!
1178 *
1179 * @param string Filename prefix:
1180 * @return void EXITS php execusion!
1181 */
1182 function outputCSV($prefix) {
1183
1184 // Setting filename:
1185 $filename=$prefix.'_'.date('dmy-Hi').'.csv';
1186
1187 // Creating output header:
1188 $mimeType = 'application/octet-stream';
1189 Header('Content-Type: '.$mimeType);
1190 Header('Content-Disposition: attachment; filename='.$filename);
1191
1192 // Printing the content of the CSV lines:
1193 echo implode(chr(13).chr(10),$this->csvLines);
1194
1195 // Exits:
1196 exit;
1197 }
1198 }
1199
1200
1201
1202 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/class.db_list_extra.inc']) {
1203 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/class.db_list_extra.inc']);
1204 }
1205 ?>