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