PageRenderTime 1543ms CodeModel.GetById 72ms RepoModel.GetById 11ms app.codeStats 0ms

/typo3/class.db_list_extra.inc

https://bitbucket.org/linxpinx/mercurial
PHP | 1878 lines | 1127 code | 263 blank | 488 comment | 264 complexity | eab6c910d7f7936dde0dd9ea1c52e184 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, Unlicense, LGPL-2.1, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  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: class.db_list_extra.inc 8289 2010-07-27 19:08:35Z psychomieze $
  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. * Class for rendering of Web>List module
  75. *
  76. * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
  77. * @package TYPO3
  78. * @subpackage core
  79. */
  80. class localRecordList extends recordList {
  81. // External:
  82. var $alternateBgColors=FALSE; // If true, table rows in the list will alternate in background colors (and have background colors at all!)
  83. 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.
  84. 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.
  85. 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!).
  86. var $dontShowClipControlPanels=FALSE; // If true, will disable the rendering of clipboard + control panels.
  87. var $showClipboard=FALSE; // If true, will show the clipboard in the field list.
  88. var $noControlPanels = FALSE; // If true, will DISABLE all control panels in lists. (Takes precedence)
  89. var $clickMenuEnabled = TRUE; // If true, clickmenus will be rendered
  90. var $totalRowCount; // count of record rows in view
  91. var $spaceIcon; // space icon used for alignment
  92. // Internal:
  93. var $pageRow=array(); // Set to the page record (see writeTop())
  94. // Used to accumulate CSV lines for CSV export.
  95. protected $csvLines = array();
  96. var $csvOutput=FALSE; // If set, the listing is returned as CSV instead.
  97. /**
  98. * Clipboard object
  99. *
  100. * @var t3lib_clipboard
  101. */
  102. var $clipObj;
  103. var $CBnames=array(); // Tracking names of elements (for clipboard use)
  104. var $duplicateStack=array(); // Used to track which elements has duplicates and how many
  105. /**
  106. * references of the current record
  107. *
  108. * @var array
  109. *
  110. * @deprecated since 4.4: Use getReferenceCount instead
  111. */
  112. public $references;
  113. /**
  114. * [$tablename][$uid] = number of references to this record
  115. *
  116. * @var array
  117. */
  118. protected $referenceCount = array();
  119. var $translations; // Translations of the current record
  120. var $selFieldList; // select fields for the query which fetches the translations of the current record
  121. public function __construct() {
  122. parent::__construct();
  123. }
  124. /**
  125. * Create the panel of buttons for submitting the form or otherwise perform operations.
  126. *
  127. * @return array all available buttons as an assoc. array
  128. */
  129. public function getButtons() {
  130. global $LANG;
  131. $buttons = array(
  132. 'csh' => '',
  133. 'view' => '',
  134. 'edit' => '',
  135. 'hide_unhide' => '',
  136. 'move' => '',
  137. 'new_record' => '',
  138. 'paste' => '',
  139. 'level_up' => '',
  140. 'cache' => '',
  141. 'reload' => '',
  142. 'shortcut' => '',
  143. 'back' => '',
  144. 'csv' => '',
  145. 'export' => ''
  146. );
  147. // Get users permissions for this page record:
  148. $localCalcPerms = $GLOBALS['BE_USER']->calcPerms($this->pageRow);
  149. // CSH
  150. if (!strlen($this->id)) {
  151. $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module_noId', $GLOBALS['BACK_PATH'], '', TRUE);
  152. } elseif(!$this->id) {
  153. $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module_root', $GLOBALS['BACK_PATH'], '', TRUE);
  154. } else {
  155. $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'list_module', $GLOBALS['BACK_PATH'], '', TRUE);
  156. }
  157. if (isset($this->id)) {
  158. // View Exclude doktypes 254,255 Configuration: mod.web_list.noViewWithDokTypes = 254,255
  159. if (isset($GLOBALS['SOBE']->modTSconfig['properties']['noViewWithDokTypes'])) {
  160. $noViewDokTypes = t3lib_div::trimExplode(',', $GLOBALS['SOBE']->modTSconfig['properties']['noViewWithDokTypes'], true);
  161. } else {
  162. //default exclusion: doktype 254, 255
  163. $noViewDokTypes = array('254', '255');
  164. }
  165. if (!in_array($this->pageRow['doktype'], $noViewDokTypes)) {
  166. $buttons['view'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::viewOnClick($this->id, $this->backPath, t3lib_BEfunc::BEgetRootLine($this->id))) . '" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showPage', TRUE) . '">' .
  167. t3lib_iconWorks::getSpriteIcon('actions-document-view') .
  168. '</a>';
  169. }
  170. // New record
  171. if (!$GLOBALS['SOBE']->modTSconfig['properties']['noCreateRecordsLink']) {
  172. $buttons['new_record'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'db_new.php?id=' . $this->id . '\');') . '" title="' . $LANG->getLL('newRecordGeneral', TRUE) . '">' .
  173. t3lib_iconWorks::getSpriteIcon('actions-document-new') .
  174. '</a>';
  175. }
  176. // If edit permissions are set (see class.t3lib_userauthgroup.php)
  177. if ($localCalcPerms&2 && !empty($this->id)) {
  178. // Edit
  179. $params = '&edit[pages][' . $this->pageRow['uid'] . ']=edit';
  180. $buttons['edit'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath, -1)) . '" title="' . $LANG->getLL('editPage', TRUE) . '">' .
  181. t3lib_iconWorks::getSpriteIcon('actions-page-open') .
  182. '</a>';
  183. // Unhide
  184. if ($this->pageRow['hidden']) {
  185. $params = '&data[pages][' . $this->pageRow['uid'] . '][hidden]=0';
  186. $buttons['hide_unhide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $LANG->getLL('unHidePage', TRUE) . '">' .
  187. t3lib_iconWorks::getSpriteIcon('actions-edit-unhide') .
  188. '</a>';
  189. // Hide
  190. } else {
  191. $params = '&data[pages][' . $this->pageRow['uid'] . '][hidden]=1';
  192. $buttons['hide_unhide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $LANG->getLL('hidePage', TRUE) . '">'.
  193. t3lib_iconWorks::getSpriteIcon('actions-edit-hide') .
  194. '</a>';
  195. }
  196. // Move
  197. $buttons['move'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'move_el.php?table=pages&uid=' . $this->pageRow['uid'] . '\');') . '" title="' . $LANG->getLL('move_page', TRUE) . '">' .
  198. (($this->table == 'tt_content') ? t3lib_iconWorks::getSpriteIcon('actions-document-move') : t3lib_iconWorks::getSpriteIcon('actions-page-move')) .
  199. '</a>';
  200. // Up one level
  201. $buttons['level_up'] = '<a href="' . htmlspecialchars($this->listURL($this->pageRow['pid'])) . '" onclick="setHighlight(' . $this->pageRow['pid'] . ')" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.upOneLevel', TRUE) . '">' .
  202. t3lib_iconWorks::getSpriteIcon('actions-view-go-up') .
  203. '</a>';
  204. }
  205. // Paste
  206. if (($localCalcPerms&8) || ($localCalcPerms&16)) {
  207. $elFromTable = $this->clipObj->elFromTable('');
  208. if (count($elFromTable)) {
  209. $buttons['paste'] = '<a href="' . htmlspecialchars($this->clipObj->pasteUrl('', $this->id)) . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg('pages', $this->pageRow, 'into', $elFromTable)) . '" title="' . $LANG->getLL('clip_paste', TRUE) . '">' .
  210. t3lib_iconWorks::getSpriteIcon('actions-document-paste-after') .
  211. '</a>';
  212. }
  213. }
  214. // Cache
  215. $buttons['cache'] = '<a href="' . htmlspecialchars($this->listURL() . '&clear_cache=1') . '" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.clear_cache', TRUE) . '">' .
  216. t3lib_iconWorks::getSpriteIcon('actions-system-cache-clear') .
  217. '</a>';
  218. if ($this->table) {
  219. // CSV
  220. $buttons['csv'] = '<a href="' . htmlspecialchars($this->listURL() . '&csv=1') . '" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.csv', TRUE) . '">' .
  221. t3lib_iconWorks::getSpriteIcon('mimetypes-text-csv') .
  222. '</a>';
  223. // Export
  224. if (t3lib_extMgm::isLoaded('impexp')) {
  225. $url = $this->backPath . t3lib_extMgm::extRelPath('impexp') . 'app/index.php?tx_impexp[action]=export';
  226. $buttons['export'] = '<a href="' . htmlspecialchars($url . '&tx_impexp[list][]=' . rawurlencode($this->table . ':' . $this->id)) . '" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:rm.export', TRUE) . '">' .
  227. t3lib_iconWorks::getSpriteIcon('actions-document-export-t3d') .
  228. '</a>';
  229. }
  230. }
  231. // Reload
  232. $buttons['reload'] = '<a href="' . htmlspecialchars($this->listURL()) . '" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.reload', TRUE) . '">' .
  233. t3lib_iconWorks::getSpriteIcon('actions-system-refresh') .
  234. '</a>';
  235. // Shortcut
  236. if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
  237. $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');
  238. }
  239. // Back
  240. if ($this->returnUrl) {
  241. $buttons['back'] = '<a href="' . htmlspecialchars(t3lib_div::linkThisUrl($this->returnUrl, array('id' => $this->id))) . '" class="typo3-goBack" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.goBack', TRUE) . '">' .
  242. t3lib_iconWorks::getSpriteIcon('actions-view-go-back') .
  243. '</a>';
  244. }
  245. }
  246. return $buttons;
  247. }
  248. /**
  249. * Creates the listing of records from a single table
  250. *
  251. * @param string Table name
  252. * @param integer Page id
  253. * @param string List of fields to show in the listing. Pseudo fields will be added including the record header.
  254. * @return string HTML table with the listing for the record.
  255. */
  256. function getTable($table,$id,$rowlist) {
  257. global $TCA, $TYPO3_CONF_VARS;
  258. // Loading all TCA details for this table:
  259. t3lib_div::loadTCA($table);
  260. // Init
  261. $addWhere = '';
  262. $titleCol = $TCA[$table]['ctrl']['label'];
  263. $thumbsCol = $TCA[$table]['ctrl']['thumbnail'];
  264. $l10nEnabled = $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField'] && !$TCA[$table]['ctrl']['transOrigPointerTable'];
  265. $tableCollapsed = (!$this->tablesCollapsed[$table]) ? false : true;
  266. // prepare space icon
  267. $this->spaceIcon = t3lib_iconWorks::getSpriteIcon('empty-empty', array('style' => 'background-position: 0 10px;'));
  268. // Cleaning rowlist for duplicates and place the $titleCol as the first column always!
  269. $this->fieldArray=array();
  270. // title Column
  271. $this->fieldArray[] = $titleCol; // Add title column
  272. // Control-Panel
  273. if (!t3lib_div::inList($rowlist,'_CONTROL_')) {
  274. $this->fieldArray[] = '_CONTROL_';
  275. $this->fieldArray[] = '_AFTERCONTROL_';
  276. }
  277. // Clipboard
  278. if ($this->showClipboard) {
  279. $this->fieldArray[] = '_CLIPBOARD_';
  280. }
  281. // Ref
  282. if (!$this->dontShowClipControlPanels) {
  283. $this->fieldArray[]='_REF_';
  284. $this->fieldArray[]='_AFTERREF_';
  285. }
  286. // Path
  287. if ($this->searchLevels) {
  288. $this->fieldArray[]='_PATH_';
  289. }
  290. // Localization
  291. if ($this->localizationView && $l10nEnabled) {
  292. $this->fieldArray[] = '_LOCALIZATION_';
  293. $this->fieldArray[] = '_LOCALIZATION_b';
  294. $addWhere.=' AND (
  295. '.$TCA[$table]['ctrl']['languageField'].'<=0
  296. OR
  297. '.$TCA[$table]['ctrl']['transOrigPointerField'].' = 0
  298. )';
  299. }
  300. // Cleaning up:
  301. $this->fieldArray=array_unique(array_merge($this->fieldArray,t3lib_div::trimExplode(',',$rowlist,1)));
  302. if ($this->noControlPanels) {
  303. $tempArray = array_flip($this->fieldArray);
  304. unset($tempArray['_CONTROL_']);
  305. unset($tempArray['_CLIPBOARD_']);
  306. $this->fieldArray = array_keys($tempArray);
  307. }
  308. // Creating the list of fields to include in the SQL query:
  309. $selectFields = $this->fieldArray;
  310. $selectFields[] = 'uid';
  311. $selectFields[] = 'pid';
  312. if ($thumbsCol) $selectFields[] = $thumbsCol; // adding column for thumbnails
  313. if ($table=='pages') {
  314. if (t3lib_extMgm::isLoaded('cms')) {
  315. $selectFields[] = 'module';
  316. $selectFields[] = 'extendToSubpages';
  317. $selectFields[] = 'nav_hide';
  318. }
  319. $selectFields[] = 'doktype';
  320. }
  321. if (is_array($TCA[$table]['ctrl']['enablecolumns'])) {
  322. $selectFields = array_merge($selectFields,$TCA[$table]['ctrl']['enablecolumns']);
  323. }
  324. if ($TCA[$table]['ctrl']['type']) {
  325. $selectFields[] = $TCA[$table]['ctrl']['type'];
  326. }
  327. if ($TCA[$table]['ctrl']['typeicon_column']) {
  328. $selectFields[] = $TCA[$table]['ctrl']['typeicon_column'];
  329. }
  330. if ($TCA[$table]['ctrl']['versioningWS']) {
  331. $selectFields[] = 't3ver_id';
  332. $selectFields[] = 't3ver_state';
  333. $selectFields[] = 't3ver_wsid';
  334. $selectFields[] = 't3ver_swapmode'; // Filtered out when pages in makeFieldList()
  335. }
  336. if ($l10nEnabled) {
  337. $selectFields[] = $TCA[$table]['ctrl']['languageField'];
  338. $selectFields[] = $TCA[$table]['ctrl']['transOrigPointerField'];
  339. }
  340. if ($TCA[$table]['ctrl']['label_alt']) {
  341. $selectFields = array_merge($selectFields,t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['label_alt'],1));
  342. }
  343. $selectFields = array_unique($selectFields); // Unique list!
  344. $selectFields = array_intersect($selectFields,$this->makeFieldList($table,1)); // Making sure that the fields in the field-list ARE in the field-list from TCA!
  345. $selFieldList = implode(',',$selectFields); // implode it into a list of fields for the SQL-statement.
  346. $this->selFieldList = $selFieldList;
  347. /**
  348. * @hook DB-List getTable
  349. * @date 2007-11-16
  350. * @request Malte Jansen <mail@maltejansen.de>
  351. */
  352. if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['getTable'])) {
  353. foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['getTable'] as $classData) {
  354. $hookObject = t3lib_div::getUserObj($classData);
  355. if(!($hookObject instanceof t3lib_localRecordListGetTableHook)) {
  356. throw new UnexpectedValueException('$hookObject must implement interface t3lib_localRecordListGetTableHook', 1195114460);
  357. }
  358. $hookObject->getDBlistQuery($table, $id, $addWhere, $selFieldList, $this);
  359. }
  360. }
  361. // Create the SQL query for selecting the elements in the listing:
  362. if ($this->csvOutput) { // do not do paging when outputting as CSV
  363. $this->iLimit = 0;
  364. }
  365. if ($this->firstElementNumber > 2 && $this->iLimit > 0) {
  366. // Get the two previous rows for sorting if displaying page > 1
  367. $this->firstElementNumber = $this->firstElementNumber - 2;
  368. $this->iLimit = $this->iLimit + 2;
  369. $queryParts = $this->makeQueryArray($table, $id,$addWhere,$selFieldList); // (API function from class.db_list.inc)
  370. $this->firstElementNumber = $this->firstElementNumber + 2;
  371. $this->iLimit = $this->iLimit - 2;
  372. } else {
  373. $queryParts = $this->makeQueryArray($table, $id,$addWhere,$selFieldList); // (API function from class.db_list.inc)
  374. }
  375. $this->setTotalItems($queryParts); // Finding the total amount of records on the page (API function from class.db_list.inc)
  376. // Init:
  377. $dbCount = 0;
  378. $out = '';
  379. $listOnlyInSingleTableMode = $this->listOnlyInSingleTableMode && !$this->table;
  380. // If the count query returned any number of records, we perform the real query, selecting records.
  381. if ($this->totalItems) {
  382. // Fetch records only if not in single table mode or if in multi table mode and not collapsed
  383. if ($listOnlyInSingleTableMode || (!$this->table && $tableCollapsed)) {
  384. $dbCount = $this->totalItems;
  385. } else {
  386. // set the showLimit to the number of records when outputting as CSV
  387. if ($this->csvOutput) {
  388. $this->showLimit = $this->totalItems;
  389. $this->iLimit = $this->totalItems;
  390. }
  391. $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
  392. $dbCount = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
  393. }
  394. }
  395. // If any records was selected, render the list:
  396. if ($dbCount) {
  397. // Half line is drawn between tables:
  398. if (!$listOnlyInSingleTableMode) {
  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,'class="c-table-row-spacer"',$this->leftMargin);
  406. }
  407. // Header line is drawn
  408. $theData = Array();
  409. if ($this->disableSingleTableView) {
  410. $theData[$titleCol] = '<span class="c-table">'.$GLOBALS['LANG']->sL($TCA[$table]['ctrl']['title'],1).'</span> ('.$this->totalItems.')';
  411. } else {
  412. $theData[$titleCol] = $this->linkWrapTable($table, '<span class="c-table">' . $GLOBALS['LANG']->sL($TCA[$table]['ctrl']['title'], TRUE) . '</span> (' . $this->totalItems . ') ' .
  413. ($this->table ? t3lib_iconWorks::getSpriteIcon('actions-view-table-collapse', array('title' => $GLOBALS['LANG']->getLL('contractView', TRUE))) : t3lib_iconWorks::getSpriteIcon('actions-view-table-expand', array('title' => $GLOBALS['LANG']->getLL('expandView', TRUE))))
  414. );
  415. }
  416. // CSH:
  417. $theData[$titleCol].= t3lib_BEfunc::cshItem($table,'',$this->backPath,'',FALSE,'margin-bottom:0px; white-space: normal;');
  418. if ($listOnlyInSingleTableMode) {
  419. $out.='
  420. <tr>
  421. <td class="t3-row-header" style="width:95%;">' . $theData[$titleCol] . '</td>
  422. </tr>';
  423. if ($GLOBALS['BE_USER']->uc["edit_showFieldHelp"]) {
  424. $GLOBALS['LANG']->loadSingleTableDescription($table);
  425. if (isset($GLOBALS['TCA_DESCR'][$table]['columns'][''])) {
  426. $onClick = 'vHWin=window.open(\'view_help.php?tfID='.$table.'.\',\'viewFieldHelp\',\'height=400,width=600,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;';
  427. $out.='
  428. <tr>
  429. <td class="c-tableDescription">'.t3lib_BEfunc::helpTextIcon($table,'',$this->backPath,TRUE).$GLOBALS['TCA_DESCR'][$table]['columns']['']['description'].'</td>
  430. </tr>';
  431. }
  432. }
  433. } else {
  434. // Render collapse button if in multi table mode
  435. $collapseIcon = '';
  436. if (!$this->table) {
  437. $collapseIcon = '<a href="' . htmlspecialchars($this->listURL() . '&collapse[' . $table . ']=' . ($tableCollapsed ? '0' : '1')) . '" title="' . ($tableCollapsed ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.expandTable', TRUE) : $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.collapseTable', TRUE)) . '">' .
  438. ($tableCollapsed ? t3lib_iconWorks::getSpriteIcon('actions-view-list-expand', array('class' => 'collapseIcon')) : t3lib_iconWorks::getSpriteIcon('actions-view-list-collapse', array('class' => 'collapseIcon'))) .
  439. '</a>';
  440. }
  441. $out .= $this->addElement(1, $collapseIcon, $theData, ' class="t3-row-header"', '');
  442. }
  443. // Render table rows only if in multi table view and not collapsed or if in single table view
  444. if (!$listOnlyInSingleTableMode && (!$tableCollapsed || $this->table)) {
  445. // Fixing a order table for sortby tables
  446. $this->currentTable = array();
  447. $currentIdList = array();
  448. $doSort = ($TCA[$table]['ctrl']['sortby'] && !$this->sortField);
  449. $prevUid = 0;
  450. $prevPrevUid = 0;
  451. // Get first two rows and initialize prevPrevUid and prevUid if on page > 1
  452. if ($this->firstElementNumber > 2 && $this->iLimit > 0) {
  453. $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
  454. $prevPrevUid = -(int) $row['uid'];
  455. $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
  456. $prevUid = $row['uid'];
  457. }
  458. $accRows = array(); // Accumulate rows here
  459. while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
  460. // In offline workspace, look for alternative record:
  461. t3lib_BEfunc::workspaceOL($table, $row, $GLOBALS['BE_USER']->workspace, TRUE);
  462. if (is_array($row)) {
  463. $accRows[] = $row;
  464. $currentIdList[] = $row['uid'];
  465. if ($doSort) {
  466. if ($prevUid) {
  467. $this->currentTable['prev'][$row['uid']] = $prevPrevUid;
  468. $this->currentTable['next'][$prevUid] = '-'.$row['uid'];
  469. $this->currentTable['prevUid'][$row['uid']] = $prevUid;
  470. }
  471. $prevPrevUid = isset($this->currentTable['prev'][$row['uid']]) ? -$prevUid : $row['pid'];
  472. $prevUid=$row['uid'];
  473. }
  474. }
  475. }
  476. $GLOBALS['TYPO3_DB']->sql_free_result($result);
  477. $this->totalRowCount = count($accRows);
  478. // CSV initiated
  479. if ($this->csvOutput) $this->initCSV();
  480. // Render items:
  481. $this->CBnames=array();
  482. $this->duplicateStack=array();
  483. $this->eCounter=$this->firstElementNumber;
  484. $iOut = '';
  485. $cc = 0;
  486. foreach($accRows as $row) {
  487. // Render item row if counter < limit
  488. if ($cc < $this->iLimit) {
  489. $cc++;
  490. $this->translations = FALSE;
  491. $iOut.= $this->renderListRow($table,$row,$cc,$titleCol,$thumbsCol);
  492. // 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:
  493. if ($this->localizationView && $l10nEnabled) {
  494. // For each available translation, render the record:
  495. if (is_array($this->translations)) {
  496. foreach ($this->translations as $lRow) {
  497. // $lRow isn't always what we want - if record was moved we've to work with the placeholder records otherwise the list is messed up a bit
  498. if ($row['_MOVE_PLH_uid'] && $row['_MOVE_PLH_pid']) {
  499. $tmpRow = t3lib_BEfunc::getRecordRaw($table, 't3ver_move_id="'.intval($lRow['uid']) . '" AND pid="' . $row['_MOVE_PLH_pid'] . '" AND t3ver_wsid=' . $row['t3ver_wsid'] . t3lib_beFunc::deleteClause($table), $selFieldList);
  500. $lRow = is_array($tmpRow)?$tmpRow:$lRow;
  501. }
  502. // In offline workspace, look for alternative record:
  503. t3lib_BEfunc::workspaceOL($table, $lRow, $GLOBALS['BE_USER']->workspace, true);
  504. if (is_array($lRow) && $GLOBALS['BE_USER']->checkLanguageAccess($lRow[$TCA[$table]['ctrl']['languageField']])) {
  505. $currentIdList[] = $lRow['uid'];
  506. $iOut.=$this->renderListRow($table,$lRow,$cc,$titleCol,$thumbsCol,18);
  507. }
  508. }
  509. }
  510. }
  511. }
  512. // Counter of total rows incremented:
  513. $this->eCounter++;
  514. }
  515. // Record navigation is added to the beginning and end of the table if in single table mode
  516. if ($this->table) {
  517. $pageNavigation = $this->renderListNavigation();
  518. $iOut = $pageNavigation . $iOut . $pageNavigation;
  519. } else {
  520. // show that there are more records than shown
  521. if ($this->totalItems > $this->itemsLimitPerTable) {
  522. $countOnFirstPage = $this->totalItems > $this->itemsLimitSingleTable ? $this->itemsLimitSingleTable : $this->totalItems;
  523. $hasMore = ($this->totalItems > $this->itemsLimitSingleTable);
  524. $iOut .= '<tr><td colspan="' . count($this->fieldArray) . '" style="padding:5px;">
  525. <a href="'.htmlspecialchars($this->listURL() . '&table=' . rawurlencode($table)) . '">' .
  526. '<img' . t3lib_iconWorks::skinImg($this->backPath,'gfx/pildown.gif', 'width="14" height="14"') .' alt="" />'.
  527. ' <i>[1 - ' . $countOnFirstPage . ($hasMore ? '+' : '') . ']</i></a>
  528. </td></tr>';
  529. }
  530. }
  531. // The header row for the table is now created:
  532. $out .= $this->renderListHeader($table,$currentIdList);
  533. }
  534. // The list of records is added after the header:
  535. $out .= $iOut;
  536. unset($iOut);
  537. // ... and it is all wrapped in a table:
  538. $out='
  539. <!--
  540. DB listing of elements: "'.htmlspecialchars($table).'"
  541. -->
  542. <table border="0" cellpadding="0" cellspacing="0" class="typo3-dblist'.($listOnlyInSingleTableMode?' typo3-dblist-overview':'').'">
  543. '.$out.'
  544. </table>';
  545. // Output csv if...
  546. if ($this->csvOutput) $this->outputCSV($table); // This ends the page with exit.
  547. }
  548. // Return content:
  549. return $out;
  550. }
  551. /**
  552. * Rendering a single row for the list
  553. *
  554. * @param string Table name
  555. * @param array Current record
  556. * @param integer Counter, counting for each time an element is rendered (used for alternating colors)
  557. * @param string Table field (column) where header value is found
  558. * @param string Table field (column) where (possible) thumbnails can be found
  559. * @param integer Indent from left.
  560. * @return string Table row for the element
  561. * @access private
  562. * @see getTable()
  563. */
  564. function renderListRow($table,$row,$cc,$titleCol,$thumbsCol,$indent=0) {
  565. $iOut = '';
  566. if (strlen($this->searchString)) { // If in search mode, make sure the preview will show the correct page
  567. $id_orig = $this->id;
  568. $this->id = $row['pid'];
  569. }
  570. if (is_array($row)) {
  571. // add special classes for first and last row
  572. $rowSpecial = '';
  573. if ($cc == 1 && $indent == 0) {
  574. $rowSpecial .= ' firstcol';
  575. }
  576. if ($cc == $this->totalRowCount || $cc == $this->iLimit) {
  577. $rowSpecial .= ' lastcol';
  578. }
  579. // Background color, if any:
  580. if ($this->alternateBgColors) {
  581. $row_bgColor = ($cc%2) ? ' class="db_list_normal'.$rowSpecial.'"' : ' class="db_list_alt'.$rowSpecial.'"';
  582. } else {
  583. $row_bgColor = ' class="db_list_normal'.$rowSpecial.'"';
  584. }
  585. // Overriding with versions background color if any:
  586. $row_bgColor = $row['_CSSCLASS'] ? ' class="'.$row['_CSSCLASS'].'"' : $row_bgColor;
  587. // Incr. counter.
  588. $this->counter++;
  589. // The icon with link
  590. $alttext = t3lib_BEfunc::getRecordIconAltText($row,$table);
  591. $iconImg = t3lib_iconWorks::getSpriteIconForRecord($table, $row, array('title' => htmlspecialchars($alttext), 'style' => ($indent ? ' margin-left: ' . $indent . 'px;' : '')));
  592. $theIcon = $this->clickMenuEnabled ? $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg,$table,$row['uid']) : $iconImg;
  593. // Preparing and getting the data-array
  594. $theData = Array();
  595. foreach($this->fieldArray as $fCol) {
  596. if ($fCol==$titleCol) {
  597. $recTitle = t3lib_BEfunc::getRecordTitle($table,$row,FALSE,TRUE);
  598. // If the record is edit-locked by another user, we will show a little warning sign:
  599. if (($lockInfo = t3lib_BEfunc::isRecordLocked($table, $row['uid']))) {
  600. $warning = '<a href="#" onclick="' . htmlspecialchars('alert(' . $GLOBALS['LANG']->JScharCode($lockInfo['msg']) . '); return false;') . '" title="' . htmlspecialchars($lockInfo['msg']) . '">' .
  601. t3lib_iconWorks::getSpriteIcon('status-warning-in-use') .
  602. '</a>';
  603. }
  604. $theData[$fCol] = $warning . $this->linkWrapItems($table, $row['uid'], $recTitle, $row);
  605. // Render thumbsnails if a thumbnail column exists and there is content in it:
  606. if ($this->thumbs && trim($row[$thumbsCol])) {
  607. $theData[$fCol] .= '<br />' . $this->thumbCode($row,$table,$thumbsCol);
  608. }
  609. $localizationMarkerClass = '';
  610. if (isset($GLOBALS['TCA'][$table]['ctrl']['languageField'])
  611. && $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] != 0) {
  612. // it's a translated record
  613. $localizationMarkerClass = ' localization';
  614. }
  615. } elseif ($fCol == 'pid') {
  616. $theData[$fCol]=$row[$fCol];
  617. } elseif ($fCol == '_PATH_') {
  618. $theData[$fCol]=$this->recPath($row['pid']);
  619. } elseif ($fCol == '_REF_') {
  620. $theData[$fCol] = $this->createReferenceHtml($table, $row['uid']);
  621. } elseif ($fCol == '_CONTROL_') {
  622. $theData[$fCol]=$this->makeControl($table,$row);
  623. } elseif ($fCol == '_AFTERCONTROL_' || $fCol == '_AFTERREF_') {
  624. $theData[$fCol] = '&nbsp;';
  625. } elseif ($fCol == '_CLIPBOARD_') {
  626. $theData[$fCol]=$this->makeClip($table,$row);
  627. } elseif ($fCol == '_LOCALIZATION_') {
  628. list($lC1, $lC2) = $this->makeLocalizationPanel($table,$row);
  629. $theData[$fCol] = $lC1;
  630. $theData[$fCol.'b'] = $lC2;
  631. } elseif ($fCol == '_LOCALIZATION_b') {
  632. // Do nothing, has been done above.
  633. } else {
  634. $tmpProc = t3lib_BEfunc::getProcessedValueExtra($table, $fCol, $row[$fCol], 100, $row['uid']);
  635. $theData[$fCol] = $this->linkUrlMail(htmlspecialchars($tmpProc), $row[$fCol]);
  636. $row[$fCol] = $tmpProc;
  637. }
  638. }
  639. if (strlen($this->searchString)) { // Reset the ID if it was overwritten
  640. $this->id = $id_orig;
  641. }
  642. // Add row to CSV list:
  643. if ($this->csvOutput) {
  644. $this->addToCSV($row,$table);
  645. }
  646. // Add classes to table cells
  647. $this->addElement_tdCssClass[$titleCol] = 'col-title' . $localizationMarkerClass;
  648. if (!$this->dontShowClipControlPanels) {
  649. $this->addElement_tdCssClass['_CONTROL_'] = 'col-control';
  650. $this->addElement_tdCssClass['_AFTERCONTROL_'] = 'col-control-space';
  651. $this->addElement_tdCssClass['_CLIPBOARD_'] = 'col-clipboard';
  652. }
  653. $this->addElement_tdCssClass['_PATH_'] = 'col-path';
  654. $this->addElement_tdCssClass['_LOCALIZATION_'] = 'col-localizationa';
  655. $this->addElement_tdCssClass['_LOCALIZATION_b'] = 'col-localizationb';
  656. // Create element in table cells:
  657. $iOut.=$this->addelement(1,$theIcon,$theData,$row_bgColor);
  658. // Finally, return table row element:
  659. return $iOut;
  660. }
  661. }
  662. /**
  663. * Write sys_refindex entries for current record to $this->references
  664. *
  665. * @param string Table name
  666. * @param integer Uid of current record
  667. * @return void
  668. *
  669. * @deprecated since 4.4: Use getReferenceCount instead
  670. */
  671. function setReferences($table, $uid) {
  672. t3lib_div::logDeprecatedFunction();
  673. $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
  674. 'tablename, recuid, field',
  675. 'sys_refindex',
  676. 'ref_table='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_refindex').
  677. ' AND ref_uid='.intval($uid).
  678. ' AND deleted=0'
  679. );
  680. $this->references = $rows;
  681. }
  682. /**
  683. * Gets the number of records referencing the record with the UID $uid in
  684. * the table $tableName.
  685. *
  686. * @param string $tableName
  687. * table name of the referenced record, must not be empty
  688. * @param integer $uid
  689. * UID of the referenced record, must be > 0
  690. *
  691. * @return integer the number of references to record $uid in table
  692. * $tableName, will be >= 0
  693. */
  694. protected function getReferenceCount($tableName, $uid) {
  695. if (!isset($this->referenceCount[$tableName][$uid])) {
  696. $numberOfReferences = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
  697. '*',
  698. 'sys_refindex',
  699. 'ref_table = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
  700. $tableName, 'sys_refindex'
  701. ) .
  702. ' AND ref_uid = ' . $uid .
  703. ' AND deleted = 0'
  704. );
  705. $this->referenceCount[$tableName][$uid] = $numberOfReferences;
  706. }
  707. return $this->referenceCount[$tableName][$uid];
  708. }
  709. /**
  710. * Rendering the header row for a table
  711. *
  712. * @param string Table name
  713. * @param array Array of the currently displayed uids of the table
  714. * @return string Header table row
  715. * @access private
  716. * @see getTable()
  717. */
  718. function renderListHeader($table, $currentIdList) {
  719. global $TCA, $LANG, $TYPO3_CONF_VARS;
  720. // Init:
  721. $theData = Array();
  722. // Traverse the fields:
  723. foreach($this->fieldArray as $fCol) {
  724. // Calculate users permissions to edit records in the table:
  725. $permsEdit = $this->calcPerms & ($table=='pages'?2:16);
  726. switch((string)$fCol) {
  727. case '_PATH_': // Path
  728. $theData[$fCol] = '<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._PATH_',1).']</i>';
  729. break;
  730. case '_REF_': // References
  731. $theData[$fCol] = '<i>['.$LANG->sL('LLL:EXT:lang/locallang_mod_file_list.xml:c__REF_',1).']</i>';
  732. break;
  733. case '_LOCALIZATION_': // Path
  734. $theData[$fCol] = '<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._LOCALIZATION_',1).']</i>';
  735. break;
  736. case '_LOCALIZATION_b': // Path
  737. $theData[$fCol] = $LANG->getLL('Localize',1);
  738. break;
  739. case '_CLIPBOARD_': // Clipboard:
  740. $cells=array();
  741. // If there are elements on the clipboard for this table, then display the "paste into" icon:
  742. $elFromTable = $this->clipObj->elFromTable($table);
  743. if (count($elFromTable)) {
  744. $cells['pasteAfter']='<a href="'.htmlspecialchars($this->clipObj->pasteUrl($table,$this->id)).'" onclick="'.htmlspecialchars('return '.$this->clipObj->confirmMsg('pages',$this->pageRow,'into',$elFromTable)).'" title="' . $LANG->getLL('clip_paste', TRUE) . '">' .
  745. t3lib_iconWorks::getSpriteIcon('actions-document-paste-after') .
  746. '</a>';
  747. }
  748. // If the numeric clipboard pads are enabled, display the control icons for that:
  749. if ($this->clipObj->current!='normal') {
  750. // The "select" link:
  751. $cells['copyMarked']=$this->linkClipboardHeaderIcon(t3lib_iconWorks::getSpriteIcon('actions-edit-copy', array('title' => $LANG->getLL('clip_selectMarked', TRUE))), $table, 'setCB');
  752. // The "edit marked" link:
  753. $editIdList = implode(',',$currentIdList);
  754. $editIdList = "'+editList('".$table."','".$editIdList."')+'";
  755. $params='&edit['.$table.']['.$editIdList.']=edit&disHelp=1';
  756. $cells['edit']='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'" title="' . $LANG->getLL('clip_editMarked', TRUE) . '">' .
  757. t3lib_iconWorks::getSpriteIcon('actions-document-open') .
  758. '</a>';
  759. // The "Delete marked" link:
  760. $cells['delete']=$this->linkClipboardHeaderIcon(t3lib_iconWorks::getSpriteIcon('actions-edit-delete', array('title' => $LANG->getLL('clip_deleteMarked', TRUE))), $table,'delete',sprintf($LANG->getLL('clip_deleteMarkedWarning'), $LANG->sL($TCA[$table]['ctrl']['title'])));
  761. // The "Select all" link:
  762. $cells['markAll'] = '<a class="cbcCheckAll" rel="" href="#" onclick="' . htmlspecialchars('checkOffCB(\'' . implode(',', $this->CBnames) . '\', this); return false;') . '" title="' . $LANG->getLL('clip_markRecords', TRUE) . '">' .
  763. t3lib_iconWorks::getSpriteIcon('actions-document-select') .
  764. '</a>';
  765. } else {
  766. $cells['empty']='';
  767. }
  768. /**
  769. * @hook renderListHeaderActions: Allows to change the clipboard icons of the Web>List table headers
  770. * @date 2007-11-20
  771. * @request Bernhard Kraft <krafbt@kraftb.at>
  772. * @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.
  773. */
  774. if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) {
  775. foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) {
  776. $hookObject = t3lib_div::getUserObj($classData);
  777. if(!($hookObject instanceof localRecordList_actionsHook)) {
  778. throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567850);
  779. }
  780. $cells = $hookObject->renderListHeaderActions($table, $currentIdList, $cells, $this);
  781. }
  782. }
  783. $theData[$fCol]=implode('',$cells);
  784. break;
  785. case '_CONTROL_': // Control panel:
  786. if (!$TCA[$table]['ctrl']['readOnly']) {
  787. // If new records can be created on this page, add links:
  788. if ($this->calcPerms&($table=='pages'?8:16) && $this->showNewRecLink($table)) {
  789. if ($table=="tt_content" && $this->newWizards) {
  790. // If mod.web_list.newContentWiz.overrideWithExtension is set, use that extension's create new content wizard instead:
  791. $tmpTSc = t3lib_BEfunc::getModTSconfig($this->pageinfo['uid'],'mod.web_list');
  792. $tmpTSc = $tmpTSc ['properties']['newContentWiz.']['overrideWithExtension'];
  793. $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';
  794. $icon = '<a href="#" onclick="'.htmlspecialchars('return jumpExt(\''.$newContentWizScriptPath.'?id='.$this->id.'\');').'" title="' . $LANG->getLL('new', TRUE) . '">'.
  795. ($table == 'pages' ? t3lib_iconWorks::getSpriteIcon('actions-page-new') : t3lib_iconWorks::getSpriteIcon('actions-document-new')) .
  796. '</a>';
  797. } elseif ($table=='pages' && $this->newWizards) {
  798. $icon = '<a href="'.htmlspecialchars($this->backPath.'db_new.php?id='.$this->id.'&pagesOnly=1&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'" title="'.$LANG->getLL('new', TRUE).'">'.
  799. ($table=='pages' ? t3lib_iconWorks::getSpriteIcon('actions-page-new') : t3lib_iconWorks::getSpriteIcon('actions-document-new')) .
  800. '</a>';
  801. } else {
  802. $params = '&edit['.$table.']['.$this->id.']=new';
  803. if ($table == 'pages_language_overlay') {
  804. $params .= '&overrideVals[pages_language_overlay][doktype]=' . (int) $this->pageRow['doktype'];
  805. }
  806. $icon = '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'" title="'.$LANG->getLL('new', TRUE).'">'.
  807. ($table=='pages' ? t3lib_iconWorks::getSpriteIcon('actions-page-new') : t3lib_iconWorks::getSpriteIcon('actions-document-new')) .
  808. '</a>';
  809. }
  810. }
  811. // If the table can be edited, add link for editing ALL SHOWN fields for all listed records:
  812. if ($permsEdit && $this->table && is_array($currentIdList)) {
  813. $editIdList = implode(',',$currentIdList);
  814. if ($this->clipNumPane()) $editIdList = "'+editList('".$table."','".$editIdList."')+'";
  815. $params = '&edit['.$table.']['.$editIdList.']=edit&columnsOnly='.implode(',',$this->fieldArray).'&disHelp=1';
  816. $icon .= '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'" title="'.$LANG->getLL('editShownColumns', TRUE) . '">'.
  817. t3lib_iconWorks::getSpriteIcon('actions-document-open') .
  818. '</a>';
  819. }
  820. // add an empty entry, so column count fits again after moving this into $icon
  821. $theData[$fCol] = '&nbsp;';
  822. }
  823. break;
  824. case '_AFTERCONTROL_': // space column
  825. case '_AFTERREF_': // space column
  826. $theData[$fCol] = '&nbsp;';
  827. break;
  828. default: // Regular fields header:
  829. $theData[$fCol]='';
  830. if ($this->table && is_array($currentIdList)) {
  831. // If the numeric clipboard pads are selected, show duplicate sorting link:
  832. if ($this->clipNumPane()) {
  833. $theData[$fCol].='<a href="'.htmlspecialchars($this->listURL('',-1).'&duplicateField='.$fCol).'" title="'.$LANG->getLL('clip_duplicates', TRUE) . '">'.
  834. t3lib_iconWorks::getSpriteIcon('actions-document-duplicates-select') .
  835. '</a>';
  836. }
  837. // If the table can be edited, add link for editing THIS field for all listed records:
  838. if (!$TCA[$table]['ctrl']['readOnly'] && $permsEdit && $TCA[$table]['columns'][$fCol]) {
  839. $editIdList = implode(',',$currentIdList);
  840. if ($this->clipNumPane()) $editIdList = "'+editList('".$table."','".$editIdList."')+'";
  841. $params='&edit['.$table.']['.$editIdList.']=edit&columnsOnly='.$fCol.'&disHelp=1';
  842. $iTitle = sprintf($LANG->getLL('editThisColumn'),rtrim(trim($LANG->sL(t3lib_BEfunc::getItemLabel($table,$fCol))),':'));
  843. $theData[$fCol].='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'" title="'.htmlspecialchars($iTitle).'">'.
  844. t3lib_iconWorks::getSpriteIcon('actions-document-open') .
  845. '</a>';
  846. }
  847. }
  848. $theData[$fCol].=$this->addSortLink($LANG->sL(t3lib_BEfunc::getItemLabel($table,$fCol,'<i>[|]</i>')),$fCol,$table);
  849. break;
  850. }
  851. }
  852. /**
  853. * @hook renderListHeader: Allows to change the contents of columns/cells of the Web>List table headers
  854. * @date 2007-11-20
  855. * @request Bernhard Kraft <krafbt@kraftb.at>
  856. * @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.
  857. */
  858. if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) {
  859. foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) {
  860. $hookObject = t3lib_div::getUserObj($classData);
  861. if(!($hookObject instanceof localRecordList_actionsHook)) {
  862. throw new UnexpectedValueException('$hookObject must implement interface localRecordList_actionsHook', 1195567855);
  863. }
  864. $theData = $hookObject->renderListHeader($table, $currentIdList, $theData, $this);
  865. }
  866. }
  867. // Create and return header table row:
  868. return $this->addelement(1, $icon, $theData, ' class="c-headLine"', '');
  869. }
  870. /**
  871. * Creates a page browser for tables with many records
  872. *
  873. * @return string Navigation HTML
  874. *
  875. */
  876. protected function renderListNavigation() {
  877. $totalPages = ceil($this->totalItems / $this->iLimit);
  878. $content = '';
  879. $returnContent = '';
  880. // Show page selector if not all records fit into one page
  881. if ($totalPages > 1) {
  882. $first = $previous = $next = $last = $reload = '';
  883. $listURL = $this->listURL('', $this->table);
  884. // 1 = first page
  885. $currentPage = floor(($this->firstElementNumber + 1) / $this->iLimit) + 1;
  886. // Compile first, previous, next, last and refresh buttons
  887. if ($currentPage > 1) {
  888. $labelFirst = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:first');
  889. $first = '<a href="' . $listURL . '&pointer=0">' .
  890. t3lib_iconWorks::getSpriteIcon('actions-view-paging-first', array('title'=> $labelFirst)) .
  891. '</a>';
  892. } else {
  893. $first = t3lib_iconWorks::getSpriteIcon('actions-view-paging-first-disabled');
  894. }
  895. if (($currentPage - 1) > 0) {
  896. $labelPrevious = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:previous');
  897. $previous = '<a href="' . $listURL . '&pointer=' . (($currentPage - 2) * $this->iLimit) . '">' .
  898. t3lib_iconWorks::getSpriteIcon('actions-view-paging-previous', array('title' => $labelPrevious)) .
  899. '</a>';
  900. } else {
  901. $previous = t3lib_iconWorks::getSpriteIcon('actions-view-paging-previous-disabled');
  902. }
  903. if (($currentPage + 1) <= $totalPages) {
  904. $labelNext = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:next');
  905. $next = '<a href="' . $listURL . '&pointer=' . (($currentPage) * $this->iLimit) . '">' .
  906. t3lib_iconWorks::getSpriteIcon('actions-view-paging-next', array('title' => $labelNext)) .
  907. '</a>';
  908. } else {
  909. $next = t3lib_iconWorks::getSpriteIcon('actions-view-paging-next-disabled');
  910. }
  911. if ($currentPage != $totalPages) {
  912. $labelLast = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:last');
  913. $last = '<a href="' . $listURL . '&pointer=' . (($totalPages - 1) * $this->iLimit) . '">' .
  914. t3lib_iconWorks::getSpriteIcon('actions-view-paging-last', array('title' => $labelLast)) .
  915. '</a>';
  916. } else {
  917. $last = t3lib_iconWorks::getSpriteIcon('actions-view-paging-last-disabled');
  918. }
  919. $reload = '<a href="#" onclick="document.dblistForm.action=\''
  920. . $listURL . '&pointer=\'+calculatePointer(); document.dblistForm.submit(); return true;" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:reload', TRUE) . '">' .
  921. t3lib_iconWorks::getSpriteIcon('actions-system-refresh') .
  922. '</a>';
  923. // Add js to traverse a page select input to a pointer value
  924. $content = '
  925. <script type="text/JavaScript">
  926. /*<![CDATA[*/
  927. function calculatePointer(){
  928. page = document.getElementById(\'jumpPage\').value;
  929. if (page > ' . $totalPages . ') {
  930. page = ' . $totalPages . ';
  931. }
  932. if (page < 1) {
  933. page = 1;
  934. }
  935. pointer = (page - 1) * ' . $this->iLimit . ';
  936. return pointer;
  937. }
  938. /*]]>*/
  939. </script>
  940. ';
  941. $pageNumberInput = '<span>
  942. <input type="text" value="' . $currentPage
  943. . '" size="3" id="jumpPage" name="jumpPage" onkeyup="if (event.keyCode == Event.KEY_RETURN) { document.dblistForm.action=\'' . $listURL . '&pointer=\'+calculatePointer(); document.dblistForm.submit(); } return true;" />
  944. </span>';
  945. $pageIndicator = '<span class="pageIndicator">'
  946. . sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:pageIndicator'), $pageNumberInput, $totalPages)
  947. . '</span>';
  948. if ($this->totalItems > ($this->firstElementNumber + $this->iLimit)) {
  949. $lastElementNumber = $this->firstElementNumber + $this->iLimit;
  950. } else {
  951. $lastElementNumber = $this->totalItems;
  952. }
  953. $rangeIndicator = '<span class="pageIndicator">'
  954. . sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_web_list.xml:rangeIndicator'), $this->firstElementNumber + 1, $lastElementNumber)
  955. . '</span>';
  956. $content .= '<div id="typo3-dblist-pagination">'
  957. . $first . $previous
  958. . '<span class="bar">&nbsp;</span>'
  959. . $rangeIndicator . '<span class="bar">&nbsp;</span>'
  960. . $pageIndicator . '<span class="bar">&nbsp;</span>'
  961. . $next . $last . '<span class="bar">&nbsp;</span>'
  962. . $reload
  963. . '</div>';
  964. $data = Array();
  965. $titleColumn = $this->fieldArray[0];
  966. $data[$titleColumn] = $content;
  967. $returnContent = $this->addElement(1, '', $data);
  968. } // end of if pages > 1
  969. return $returnContent;
  970. }
  971. /*********************************
  972. *
  973. * Rendering of various elements
  974. *
  975. *********************************/
  976. /**
  977. * Creates the control panel for a single record in the listing.
  978. *
  979. * @param string The table
  980. * @param array The record for which to make the control panel.
  981. * @return string HTML table with the control panel (unless disabled)
  982. */
  983. function makeControl($table,$row) {
  984. global $TCA, $LANG, $SOBE, $TYPO3_CONF_VARS;
  985. if ($this->dontShowClipControlPanels) return '';
  986. // Initialize:
  987. t3lib_div::loadTCA($table);
  988. $cells=array();
  989. // If the listed table is 'pages' we have to request the permission settings for each page:
  990. if ($table=='pages') {
  991. $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$row['uid']));
  992. }
  993. // This expresses the edit permissions for this particular element:
  994. $permsEdit = ($table=='pages' && ($localCalcPerms&2)) || ($table!='pages' && ($this->calcPerms&16));
  995. // "Show" link (only pages and tt_content elements)
  996. if ($table=='pages' || $table=='tt_content') {
  997. $params='&edit['.$table.']['.$row['uid'].']=edit';
  998. $cells['view']='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($table=='tt_content'?$this->id.'#'.$row['uid']:$row['uid'], $this->backPath)).'" title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showPage', TRUE).'">'.
  999. t3lib_iconWorks::getSpriteIcon('actions-document-view') .
  1000. '</a>';
  1001. } elseif(!$this->table) {
  1002. $cells['view'] = $this->spaceIcon;
  1003. }
  1004. // "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id)
  1005. if ($permsEdit) {
  1006. $params='&edit['.$table.']['.$row['uid'].']=edit';
  1007. $cells['edit']='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->backPath,-1)).'" title="'.$LANG->getLL('edit', TRUE).'">'.
  1008. ( $TCA[$table]['ctrl']['readOnly'] ? t3lib_iconWorks::getSpriteIcon('actions-document-open-read-only') : t3lib_iconWorks::getSpriteIcon('actions-document-open') ).
  1009. '</a>';
  1010. } elseif(!$this->table) {
  1011. $cells['edit'] = $this->spaceIcon;
  1012. }
  1013. // "Move" wizard link for pages/tt_content elements:
  1014. if (($table=="tt_content" && $permsEdit) || ($table=='pages')) {
  1015. $cells['move']='<a href="#" onclick="'.htmlspecialchars('return jumpExt(\''.$this->backPath.'move_el.php?table='.$table.'&uid='.$row['uid'].'\');').'" title="'.$LANG->getLL('move_…

Large files files are truncated, but you can click here to view the full file