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