Cleanup: Updated copyright comments
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / layout / class.tx_cms_layout.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2011 Kasper Skårhøj (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 db_list.inc for use with the web_layout module
29 *
30 * $Id$
31 * Revised for TYPO3 3.6 November/2003 by Kasper Skårhøj
32 * XHTML compliant
33 *
34 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
35 */
36
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 *
41 *
42 * 115: class tx_cms_layout extends recordList
43 *
44 * SECTION: Renderings
45 * 180: function getTable($table,$id)
46 * 240: function getTable_pages($id)
47 * 378: function getTable_tt_content($id)
48 * 754: function getTable_fe_users($id)
49 * 780: function getTable_sys_note($id)
50 * 873: function getTable_tt_board($id)
51 * 955: function getTable_tt_address($id)
52 * 985: function getTable_tt_links($id)
53 * 1011: function getTable_tt_guest($id)
54 * 1026: function getTable_tt_news($id)
55 * 1047: function getTable_tt_calender($id)
56 * 1097: function getTable_tt_products($id)
57 *
58 * SECTION: Generic listing of items
59 * 1143: function makeOrdinaryList($table, $id, $fList, $icon=0, $addWhere='')
60 * 1224: function dataFields($fieldArr,$table,$row,$out=array())
61 * 1275: function headerFields($fieldArr,$table,$out=array())
62 *
63 * SECTION: Additional functions; Pages
64 * 1317: function pages_getTree($theRows,$pid,$qWhere,$treeIcons,$depth)
65 * 1350: function pages_drawItem($row,$fieldArr)
66 *
67 * SECTION: Additional functions; Content Elements
68 * 1461: function tt_content_drawColHeader($colName,$editParams,$newParams)
69 * 1513: function tt_content_drawHeader($row,$space=0,$disableMoveAndNewButtons=FALSE,$langMode=FALSE)
70 * 1643: function tt_content_drawItem($row, $isRTE=FALSE)
71 * 1806: function getNonTranslatedTTcontentUids($defLanguageCount,$id,$lP)
72 * 1836: function newLanguageButton($defLanguageCount,$lP)
73 * 1857: function infoGif($infoArr)
74 * 1873: function newContentElementOnClick($id,$colPos,$sys_language)
75 * 1891: function linkEditContent($str,$row)
76 * 1909: function linkRTEbutton($row)
77 * 1930: function languageSelector($id)
78 * 1967: function getResult($result)
79 *
80 * SECTION: Additional functions; Message board items (tt_board)
81 * 2036: function tt_board_getTree($theRows,$parent,$pid,$qWhere,$treeIcons)
82 * 2071: function tt_board_drawItem($table,$row,$re)
83 *
84 * SECTION: Various helper functions
85 * 2118: function numberOfRecords($table,$pid)
86 * 2137: function renderText($input)
87 * 2151: function getIcon($table,$row)
88 * 2174: function getProcessedValue($table,$fieldList,$row,&$info)
89 * 2194: function isDisabled($table,$row)
90 * 2212: function wordWrapper($content,$max=50,$char=' -')
91 * 2229: function noEditIcon($label='noEditItems')
92 * 2238: function cleanTableNames()
93 * 2274: function isRTEforField($table,$row,$field)
94 * 2304: function getSpecConfForField($table,$row,$field)
95 *
96 * SECTION: External renderings
97 * 2341: function getPageInfoBox($rec,$edit=0)
98 * 2510: function getTableMenu($id)
99 * 2575: function strip_tags($content, $fillEmptyContent=false)
100 *
101 * TOTAL FUNCTIONS: 43
102 * (This index is automatically created/updated by the extension "extdeveval")
103 *
104 */
105
106
107 /**
108 * Child class for the Web > Page module
109 *
110 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
111 * @package TYPO3
112 * @subpackage core
113 */
114 class tx_cms_layout extends recordList {
115
116 // External, static: For page statistics:
117 var $stat_select_field = 'page_id'; // fieldname from sys_stat to select on.
118 var $stat_codes = array(); // eg. "HITS_days:-1"
119
120 // External, static: Flags of various kinds:
121 var $pI_showUser = 0; // If true, users/groups are shown in the page info box.
122 var $pI_showStat = 1; // If true, hit statistics are shown in the page info box.
123 var $nextThree = 3; // The number of successive records to edit when showing content elements.
124 var $pages_noEditColumns = 0; // If true, disables the edit-column icon for tt_content elements
125 var $option_showBigButtons = 1; // If true, shows big buttons for editing page properties, moving, creating elements etc. in the columns view.
126 var $option_newWizard = 1; // If true, new-wizards are linked to rather than the regular new-element list.
127 var $ext_function = 0; // If set to "1", will link a big button to content element wizard.
128 var $doEdit = 1; // If true, elements will have edit icons (probably this is whethere the user has permission to edit the page content). Set externally.
129 var $agePrefixes = ' min| hrs| days| yrs'; // Age prefixes for displaying times. May be set externally to localized values.
130 var $externalTables = array(); // Array of tables to be listed by the Web > Page module in addition to the default tables.
131 var $descrTable; // "Pseudo" Description -table name
132 var $defLangBinding = FALSE; // If set true, the language mode of tt_content elements will be rendered with hard binding between default language content elements and their translations!
133
134 // External, static: Configuration of tt_content element display:
135 var $tt_contentConfig = Array(
136 'showInfo' => 1, // Boolean: Display info-marks or not
137 'showCommands' => 1, // Boolean: Display up/down arrows and edit icons for tt_content records
138 'single' => 1, // Boolean: If set, the content of column(s) $this->tt_contentConfig['showSingleCol'] is shown in the total width of the page
139 'showAsGrid' => 0, // Boolean: If set, the content of columns is shown in grid
140 'showSingleCol' => 0, // The column(s) to show if single mode (under each other)
141 'languageCols' => 0,
142 'languageMode' => 0,
143 'languageColsPointer' => 0,
144 'showHidden' => 1, // Displays hidden records as well
145 'sys_language_uid' => 0, // Which language
146 'cols' => '1,0,2,3' // The order of the rows: Default is left(1), Normal(0), right(2), margin(3)
147 );
148
149 // Internal, dynamic:
150 var $allowedTableNames = array(); // Will contain a list of tables which can be listed by the user.
151 var $activeTables = array(); // Contains icon/title of pages which are listed in the tables menu (see getTableMenu() function )
152 var $tt_contentData = Array(
153 'nextThree' => Array(),
154 'prev' => Array(),
155 'next' => Array()
156 );
157 var $CType_labels = array(); // Used to store labels for CTypes for tt_content elements
158 var $itemLabels = array(); // Used to store labels for the various fields in tt_content elements
159
160
161 /*****************************************
162 *
163 * Renderings
164 *
165 *****************************************/
166
167 /**
168 * Adds the code of a single table
169 *
170 * @param string Table name
171 * @param integer Current page id
172 * @return string HTML for listing.
173 */
174 function getTable($table, $id) {
175
176 // Load full table definition:
177 t3lib_div::loadTCA($table);
178
179 if (isset($this->externalTables[$table])) {
180 return $this->getExternalTables($id, $table);
181 } else {
182 // Branch out based on table name:
183 // Notice: Most of these tables belongs to other extensions than 'cms'. Each of these tables can be rendered only if the extensions they belong to is loaded.
184 switch ($table) {
185 case 'pages':
186 return $this->getTable_pages($id);
187 break;
188 case 'tt_content':
189 return $this->getTable_tt_content($id);
190 break;
191 case 'fe_users':
192 return $this->getTable_fe_users($id);
193 break;
194 case 'sys_note':
195 return $this->getTable_sys_note($id);
196 break;
197 case 'tt_board':
198 return $this->getTable_tt_board($id);
199 break;
200 case 'tt_address':
201 return $this->getTable_tt_address($id);
202 break;
203 case 'tt_links':
204 return $this->getTable_tt_links($id);
205 break;
206 case 'tt_guest':
207 return $this->getTable_tt_guest($id);
208 break;
209 case 'tt_news':
210 return $this->getTable_tt_news($id);
211 break;
212 case 'tt_calender':
213 return $this->getTable_tt_calender($id);
214 break;
215 case 'tt_products':
216 return $this->getTable_tt_products($id);
217 break;
218 }
219 }
220 }
221
222
223 /**
224 * Renders an external table from page id
225 *
226 * @param integer Page id
227 * @param string name of the table
228 * @return string HTML for the listing
229 */
230 function getExternalTables($id, $table) {
231
232 $type = $GLOBALS['SOBE']->MOD_SETTINGS[$table];
233 if (!isset($type)) {
234 $type = 0;
235 }
236
237 $fList = $this->externalTables[$table][$type]['fList']; // eg. "name;title;email;company,image"
238 // The columns are separeted by comma ','.
239 // Values separated by semicolon ';' are shown in the same column.
240 $icon = $this->externalTables[$table][$type]['icon'];
241 $addWhere = $this->externalTables[$table][$type]['addWhere'];
242
243 // Create listing
244 $out = $this->makeOrdinaryList($table, $id, $fList, $icon, $addWhere);
245 return $out;
246 }
247
248
249 /**
250 * Renders records from the pages table from page id
251 * (Used to get information about the page tree content by "Web>Info"!)
252 *
253 * @param integer Page id
254 * @return string HTML for the listing
255 */
256 function getTable_pages($id) {
257 global $TCA;
258
259 // Initializing:
260 $out = '';
261 $delClause = t3lib_BEfunc::deleteClause('pages') . ' AND ' . $GLOBALS['BE_USER']->getPagePermsClause(1); // Select clause for pages:
262
263 // Select current page:
264 if (!$id) {
265 $row = $GLOBALS['SOBE']->pageinfo; // The root has a pseudo record in pageinfo...
266 } else {
267 $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid=' . intval($id) . $delClause);
268 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
269 t3lib_BEfunc::workspaceOL('pages', $row);
270 }
271
272 // If there was found a page:
273 if (is_array($row)) {
274
275 // Select which fields to show:
276 $pKey = $GLOBALS['SOBE']->MOD_SETTINGS['function'] == 'tx_cms_webinfo_hits' ? 'hits' : $GLOBALS['SOBE']->MOD_SETTINGS['pages'];
277 switch ($pKey) {
278 case 'hits':
279 $this->fieldArray = explode(',', 'title,' . implode(',', $this->stat_codes));
280 break;
281 case 1:
282 $this->cleanTableNames();
283 $tableNames = $this->allowedTableNames;
284 $this->fieldArray = explode(',', 'title,uid,' . implode(',', array_keys($tableNames)));
285 break;
286 case 2:
287 $this->fieldArray = explode(',', 'title,uid,lastUpdated,newUntil,no_cache,cache_timeout,php_tree_stop,TSconfig,storage_pid,is_siteroot,fe_login_mode');
288 break;
289 default:
290 $this->fieldArray = explode(',', 'title,uid,alias,starttime,endtime,fe_group,target,url,shortcut,shortcut_mode');
291 break;
292 }
293
294 // Getting select-depth:
295 $depth = intval($GLOBALS['SOBE']->MOD_SETTINGS['pages_levels']);
296
297 // Half line is drawn
298 $theData = Array();
299 $theData['subject'] = $this->widthGif;
300 $out .= $this->addelement(0, '', $theData);
301
302 // Overriding a few things:
303 $this->no_noWrap = 0;
304 $this->oddColumnsCssClass = 'bgColor3-20';
305
306 // Items
307 $this->eCounter = $this->firstElementNumber;
308
309 // Creating elements:
310 list($flag, $code) = $this->fwd_rwd_nav();
311 $out .= $code;
312 $editUids = array();
313 if ($flag) {
314
315 // Getting children:
316 $theRows = Array();
317 $theRows = $this->pages_getTree($theRows, $row['uid'], $delClause . t3lib_BEfunc::versioningPlaceholderClause('pages'), '', $depth);
318 if ($GLOBALS['BE_USER']->doesUserHaveAccess($row, 2)) {
319 $editUids[] = $row['uid'];
320 }
321 $out .= $this->pages_drawItem($row, $this->fieldArray);
322
323 // Traverse all pages selected:
324 foreach ($theRows as $n => $sRow) {
325 if ($GLOBALS['BE_USER']->doesUserHaveAccess($sRow, 2)) {
326 $editUids[] = $sRow['uid'];
327 }
328 $out .= $this->pages_drawItem($sRow, $this->fieldArray);
329 }
330 $this->eCounter++;
331 }
332
333 // Header line is drawn
334 $theData = Array();
335 $editIdList = implode(',', $editUids);
336
337 // Traverse fields (as set above) in order to create header values:
338 foreach ($this->fieldArray as $field) {
339 if ($editIdList && isset($TCA['pages']['columns'][$field]) && $field != 'uid' && !$this->pages_noEditColumns) {
340 $params = '&edit[pages][' . $editIdList . ']=edit&columnsOnly=' . $field . '&disHelp=1';
341 $iTitle = sprintf($GLOBALS['LANG']->getLL('editThisColumn'), rtrim(trim($GLOBALS['LANG']->sL(t3lib_BEfunc::getItemLabel('pages', $field))), ':'));
342 $eI = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath, '')) . '" title="' . htmlspecialchars($iTitle) . '">' .
343 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
344 '</a>';
345 } else {
346 $eI = '';
347 }
348 switch ($field) {
349 case 'title':
350 $theData[$field] = '&nbsp;<strong>' . $GLOBALS['LANG']->sL($TCA['pages']['columns'][$field]['label']) . '</strong>' . $eI;
351 break;
352 case 'uid':
353 $theData[$field] = '&nbsp;<strong>ID:</strong>';
354 break;
355 default:
356 if (substr($field, 0, 6) == 'table_') {
357 $f2 = substr($field, 6);
358 if ($TCA[$f2]) {
359 $theData[$field] = '&nbsp;' . t3lib_iconWorks::getSpriteIconForRecord($f2, array(), array('title' => $GLOBALS['LANG']->sL($TCA[$f2]['ctrl']['title'], 1)));
360 }
361 } elseif (substr($field, 0, 5) == 'HITS_') {
362 $fParts = explode(':', substr($field, 5));
363 switch ($fParts[0]) {
364 case 'days':
365 $timespan = mktime(0, 0, 0) + intval($fParts[1]) * 3600 * 24;
366 $theData[$field] = '&nbsp;' . date('d', $timespan);
367 break;
368 default:
369 $theData[$field] = '';
370 break;
371 }
372 } else {
373 $theData[$field] = '&nbsp;&nbsp;<strong>' . $GLOBALS['LANG']->sL($TCA['pages']['columns'][$field]['label'], 1) . '</strong>' . $eI;
374 }
375 break;
376 }
377 }
378
379 // Start table:
380 $this->oddColumnsCssClass = '';
381
382 // CSH:
383 $out = t3lib_BEfunc::cshItem($this->descrTable, 'func_' . $pKey, $GLOBALS['BACK_PATH']) .
384 '
385 <table border="0" cellpadding="0" cellspacing="0" class="typo3-page-pages">
386 ' . $this->addelement(1, '', $theData, ' class="t3-row-header"', 20) .
387 $out . '
388 </table>';
389 }
390 $this->oddColumnsCssClass = '';
391 return $out;
392 }
393
394 /**
395 * Returns the backend layout which should be used for this page.
396 *
397 * @param integer $id: Uid of the current page
398 * @return mixed Uid of the backend layout record or NULL if no layout should be used
399 */
400 function getSelectedBackendLayoutUid($id) {
401 $page = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('be_layout', 'pages', 'uid=' . $id);
402 $backendLayoutUid = intval($page['be_layout']);
403 if ($backendLayoutUid == -1) {
404 // if it is set to "none" - don't use any
405 $backendLayoutUid = NULL;
406 } else if ($backendLayoutUid == 0) {
407 // if it not set check the rootline for a layout on next level and use this
408 $rootline = t3lib_BEfunc::BEgetRootLine($id);
409 for ($i = count($rootline) - 2; $i > 0; $i--) {
410 $backendLayoutUid = intval($rootline[$i]['be_layout_next_level']);
411 if ($backendLayoutUid > 0) {
412 // stop searching if a layout for "next level" is set
413 break;
414 } else if ($backendLayoutUid == -1){
415 // if layout for "next level" is set to "none" - don't use any and stop searching
416 $backendLayoutUid = NULL;
417 break;
418 }
419 }
420 }
421 // if it is set to a positive value use this
422 return $backendLayoutUid;
423 }
424
425 /**
426 * Renders Content Elements from the tt_content table from page id
427 *
428 * @param integer Page id
429 * @return string HTML for the listing
430 */
431 function getTable_tt_content($id) {
432 global $TCA;
433
434 $this->initializeLanguages();
435
436 // Initialize:
437 $RTE = $GLOBALS['BE_USER']->isRTE();
438 $lMarg = 1;
439 $showHidden = $this->tt_contentConfig['showHidden'] ? '' : t3lib_BEfunc::BEenableFields('tt_content');
440 $pageTitleParamForAltDoc = '&recTitle=' . rawurlencode(t3lib_BEfunc::getRecordTitle('pages', t3lib_BEfunc::getRecordWSOL('pages', $id), TRUE));
441 $GLOBALS['SOBE']->doc->getPageRenderer()->loadExtJs();
442 $GLOBALS['SOBE']->doc->getPageRenderer()->addJsFile($GLOBALS['BACK_PATH'] . 'sysext/cms/layout/js/typo3pageModule.js');
443
444 // Get labels for CTypes and tt_content element fields in general:
445 $this->CType_labels = array();
446 foreach ($TCA['tt_content']['columns']['CType']['config']['items'] as $val) {
447 $this->CType_labels[$val[1]] = $GLOBALS['LANG']->sL($val[0]);
448 }
449 $this->itemLabels = array();
450 foreach ($TCA['tt_content']['columns'] as $name => $val) {
451 $this->itemLabels[$name] = $GLOBALS['LANG']->sL($val['label']);
452 }
453
454 // Select display mode:
455 if (!$this->tt_contentConfig['single']) { // MULTIPLE column display mode, side by side:
456
457 // Setting language list:
458 $langList = $this->tt_contentConfig['sys_language_uid'];
459 if ($this->tt_contentConfig['languageMode']) {
460 if ($this->tt_contentConfig['languageColsPointer']) {
461 $langList = '0,' . $this->tt_contentConfig['languageColsPointer'];
462 } else {
463 $langList = implode(',', array_keys($this->tt_contentConfig['languageCols']));
464 }
465 $languageColumn = array();
466 }
467 $langListArr = explode(',', $langList);
468 $defLanguageCount = array();
469 $defLangBinding = array();
470
471 // For EACH languages... :
472 foreach ($langListArr as $lP) { // If NOT languageMode, then we'll only be through this once.
473 $showLanguage = $this->defLangBinding && $lP == 0 ? ' AND sys_language_uid IN (0,-1)' : ' AND sys_language_uid=' . $lP;
474 $cList = explode(',', $this->tt_contentConfig['cols']);
475 $content = array();
476 $head = array();
477
478 // For EACH column, render the content into a variable:
479 foreach ($cList as $key) {
480 if (!$lP) {
481 $defLanguageCount[$key] = array();
482 }
483
484 // Select content elements from this column/language:
485 $queryParts = $this->makeQueryArray('tt_content', $id, 'AND colPos=' . intval($key) . $showHidden . $showLanguage);
486 $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
487
488 // If it turns out that there are not content elements in the column, then display a big button which links directly to the wizard script:
489 if ($this->doEdit && $this->option_showBigButtons && !intval($key) && !$GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
490 $onClick = "window.location.href='db_new_content_el.php?id=" . $id . '&colPos=' . intval($key) . '&sys_language_uid=' . $lP . '&uid_pid=' . $id . '&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . "';";
491 $theNewButton = $GLOBALS['SOBE']->doc->t3Button($onClick, $GLOBALS['LANG']->getLL('newPageContent'));
492 $content[$key] .= '<img src="clear.gif" width="1" height="5" alt="" /><br />' . $theNewButton;
493 }
494
495 // Traverse any selected elements and render their display code:
496 $rowArr = $this->getResult($result);
497
498 foreach ($rowArr as $rKey => $row) {
499
500 if (is_array($row) && (int) $row['t3ver_state'] != 2) {
501 $singleElementHTML = '';
502 if (!$lP) {
503 $defLanguageCount[$key][] = $row['uid'];
504 }
505
506 $editUidList .= $row['uid'] . ',';
507 $singleElementHTML .= $this->tt_content_drawHeader($row, $this->tt_contentConfig['showInfo'] ? 15 : 5, $this->defLangBinding && $lP > 0, TRUE);
508
509 $isRTE = $RTE && $this->isRTEforField('tt_content', $row, 'bodytext');
510 $singleElementHTML .= '<div ' . ($row['_ORIG_uid'] ? ' class="ver-element"' : '') . '>' . $this->tt_content_drawItem($row, $isRTE) . '</div>';
511
512 // NOTE: this is the end tag for <div class="t3-page-ce-body">
513 // because of bad (historic) conception, starting tag has to be placed inside tt_content_drawHeader()
514 $singleElementHTML .= '</div>';
515
516
517 $statusHidden = ($this->isDisabled('tt_content', $row) ? ' t3-page-ce-hidden' : '');
518 $singleElementHTML = '<div class="t3-page-ce' . $statusHidden . '">' . $singleElementHTML . '</div>';
519
520 if ($this->defLangBinding && $this->tt_contentConfig['languageMode']) {
521 $defLangBinding[$key][$lP][$row[($lP ? 'l18n_parent' : 'uid')]] = $singleElementHTML;
522 } else {
523 $content[$key] .= $singleElementHTML;
524 }
525 } else {
526 unset($rowArr[$rKey]);
527 }
528 }
529
530 // Add new-icon link, header:
531 $newP = $this->newContentElementOnClick($id, $key, $lP);
532 $colTitle = t3lib_BEfunc::getProcessedValue('tt_content', 'colPos', $key);
533
534 $tcaItems = t3lib_div::callUserFunction('EXT:cms/classes/class.tx_cms_backendlayout.php:tx_cms_BackendLayout->getColPosListItemsParsed', $id, $this);
535 foreach ($tcaItems as $item) {
536 if ($item[1] == $key) {
537 $colTitle = $GLOBALS['LANG']->sL($item[0]);
538 }
539 }
540 $head[$key] .= $this->tt_content_drawColHeader($colTitle, ($this->doEdit && count($rowArr) ? '&edit[tt_content][' . $editUidList . ']=edit' . $pageTitleParamForAltDoc : ''), $newP);
541 $editUidList = '';
542 }
543
544 // For EACH column, fit the rendered content into a table cell:
545 $out = '';
546
547 $backendLayoutUid = $this->getSelectedBackendLayoutUid($id);
548 $backendLayoutRecord = t3lib_BEfunc::getRecord('be_layouts', intval($backendLayoutUid));
549 $this->tt_contentConfig['showAsGrid'] = !empty($backendLayoutRecord['config']) && !$this->tt_contentConfig['languageMode'];
550
551 if (!$this->tt_contentConfig['showAsGrid']) {
552 foreach ($cList as $k => $key) {
553
554 if (!$k) {
555 $out .= '
556 <td><img src="clear.gif" width="' . $lMarg . '" height="1" alt="" /></td>';
557 } else {
558 $out .= '
559 <td><img src="clear.gif" width="4" height="1" alt="" /></td>
560 <td bgcolor="#cfcfcf"><img src="clear.gif" width="1" height="1" alt="" /></td>
561 <td><img src="clear.gif" width="4" height="1" alt="" /></td>';
562 }
563 $out .= '
564 <td class="t3-page-column t3-page-column-' . $key . '">' . $head[$key] . $content[$key] . '</td>';
565
566 // Storing content for use if languageMode is set:
567 if ($this->tt_contentConfig['languageMode']) {
568 $languageColumn[$key][$lP] = $head[$key] . $content[$key];
569 if (!$this->defLangBinding) {
570 $languageColumn[$key][$lP] .= '<br /><br />' . $this->newLanguageButton($this->getNonTranslatedTTcontentUids($defLanguageCount[$key], $id, $lP), $lP);
571 }
572 }
573 }
574
575 // Wrap the cells into a table row:
576 $out = '
577 <table border="0" cellpadding="0" cellspacing="0" class="t3-page-columns">
578 <tr>' . $out . '
579 </tr>
580 </table>';
581
582 } else {
583 // GRID VIEW:
584
585 // initialize TS parser to parse config to array
586 $parser = t3lib_div::makeInstance('t3lib_TSparser');
587 $parser->parse($backendLayoutRecord['config']);
588
589 $grid .= '<div class="t3-gridContainer"><table border="0" cellspacing="1" cellpadding="4" width="80%" height="100%" class="t3-page-columns t3-gridTable">';
590
591 // add colgroups
592 $colCount = intval($parser->setup['be_layout.']['colCount']);
593 $rowCount = intval($parser->setup['be_layout.']['rowCount']);
594
595 $grid .= '<colgroup>';
596 for ($i = 0; $i < $colCount; $i++) {
597 $grid .= '<col style="width:' . (100 / $colCount) . '%"></col>';
598 }
599 $grid .= '</colgroup>';
600
601 // cycle through rows
602 for ($row = 1; $row <= $rowCount; $row++) {
603 $rowConfig = $parser->setup['be_layout.']['rows.'][$row . '.'];
604 if (!isset($rowConfig)) {
605 continue;
606 }
607
608 $grid .= '<tr>';
609
610 for ($col = 1; $col <= $colCount; $col++) {
611 $columnConfig = $rowConfig['columns.'][$col . '.'];
612
613 if (!isset($columnConfig)) {
614 continue;
615 }
616
617 // which tt_content colPos should be displayed inside this cell
618 $columnKey = intval($columnConfig['colPos']);
619
620 // render the grid cell
621 $grid .= '<td valign="top"' .
622 (isset($columnConfig['colspan']) ? ' colspan="' . $columnConfig['colspan'] . '"' : '') .
623 (isset($columnConfig['rowspan']) ? ' rowspan="' . $columnConfig['rowspan'] . '"' : '') .
624 ' class="t3-gridCell t3-page-column t3-page-column-' . $columnKey .
625 (!isset($columnConfig['colPos']) ? ' t3-gridCell-unassigned' : '') .
626 ((isset($columnConfig['colPos']) && ! $head[$columnKey]) ? ' t3-gridCell-restricted' : '') .
627 (isset($columnConfig['colspan']) ? ' t3-gridCell-width' . $columnConfig['colspan'] : '') .
628 (isset($columnConfig['rowspan']) ? ' t3-gridCell-height' . $columnConfig['rowspan'] : '') . '">';
629
630 // Draw the pre-generated header with edit and new buttons if a colPos is assigned.
631 // If not, a new header without any buttons will be generated.
632 if (isset($columnConfig['colPos']) && $head[$columnKey]) {
633 $grid .= $head[$columnKey] . $content[$columnKey];
634 } else if ($head[$columnKey]) {
635 $grid .= $this->tt_content_drawColHeader($GLOBALS['LANG']->getLL('notAssigned'), '', '');
636 } else {
637 $grid .= $this->tt_content_drawColHeader($GLOBALS['LANG']->getLL('noAccess'), '', '');
638 }
639
640 $grid .= '</td>';
641 }
642 $grid .= '</tr>';
643 }
644 $out .= $grid . '</table></div>';
645 }
646
647 // CSH:
648 $out .= t3lib_BEfunc::cshItem($this->descrTable, 'columns_multi', $GLOBALS['BACK_PATH']);
649 }
650
651 // If language mode, then make another presentation:
652 // Notice that THIS presentation will override the value of $out! But it needs the code above to execute since $languageColumn is filled with content we need!
653 if ($this->tt_contentConfig['languageMode']) {
654
655 // Get language selector:
656 $languageSelector = $this->languageSelector($id);
657
658 // Reset out - we will make new content here:
659 $out = '';
660 // Separator between language columns (black thin line)
661 $midSep = '
662 <td><img src="clear.gif" width="4" height="1" alt="" /></td>
663 <td bgcolor="black"><img src="clear.gif" width="1" height="1" alt="" /></td>
664 <td><img src="clear.gif" width="4" height="1" alt="" /></td>';
665
666 // Traverse languages found on the page and build up the table displaying them side by side:
667 $cCont = array();
668 $sCont = array();
669 foreach ($langListArr as $lP) {
670
671 // Header:
672 $cCont[$lP] = '
673 <td valign="top" align="center" class="bgColor6"><strong>' . htmlspecialchars($this->tt_contentConfig['languageCols'][$lP]) . '</strong></td>';
674
675 // "View page" icon is added:
676 $viewLink = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::viewOnClick($this->id, $this->backPath, t3lib_BEfunc::BEgetRootLine($this->id), '', '', '&L=' . $lP)) . '">' .
677 t3lib_iconWorks::getSpriteIcon('actions-document-view') .
678 '</a>';
679
680 // Language overlay page header:
681 if ($lP) {
682
683 list($lpRecord) = t3lib_BEfunc::getRecordsByField('pages_language_overlay', 'pid', $id, 'AND sys_language_uid=' . intval($lP));
684 t3lib_BEfunc::workspaceOL('pages_language_overlay', $lpRecord);
685 $params = '&edit[pages_language_overlay][' . $lpRecord['uid'] . ']=edit&overrideVals[pages_language_overlay][sys_language_uid]=' . $lP;
686 $lPLabel = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon(t3lib_iconWorks::getSpriteIconForRecord('pages_language_overlay', $lpRecord), $lpRecord['uid']) .
687 $viewLink .
688 ($GLOBALS['BE_USER']->check('tables_modify', 'pages_language_overlay') ? '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath)) . '" title="' . $GLOBALS['LANG']->getLL('edit', TRUE) . '">' .
689 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
690 '</a>' : '') .
691 htmlspecialchars(t3lib_div::fixed_lgd_cs($lpRecord['title'], 20));
692 } else {
693 $lPLabel = $viewLink;
694 }
695 $sCont[$lP] = '
696 <td nowrap="nowrap">' . $lPLabel . '</td>';
697 }
698 // Add headers:
699 $out .= '
700 <tr class="bgColor5">' . implode($midSep, $cCont) . '
701 </tr>';
702 $out .= '
703 <tr class="bgColor5">' . implode($midSep, $sCont) . '
704 </tr>';
705
706 // Traverse previously built content for the columns:
707 foreach ($languageColumn as $cKey => $cCont) {
708 $out .= '
709 <tr>
710 <td valign="top">' . implode('</td>' . $midSep . '
711 <td valign="top">', $cCont) . '</td>
712 </tr>';
713
714 if ($this->defLangBinding) {
715 // "defLangBinding" mode
716 foreach ($defLanguageCount[$cKey] as $defUid) {
717 $cCont = array();
718 foreach ($langListArr as $lP) {
719 $cCont[] = $defLangBinding[$cKey][$lP][$defUid] .
720 '<br/>' . $this->newLanguageButton($this->getNonTranslatedTTcontentUids(array($defUid), $id, $lP), $lP);
721 }
722 $out .= '
723 <tr>
724 <td valign="top">' . implode('</td>' . $midSep . '
725 <td valign="top">', $cCont) . '</td>
726 </tr>';
727 }
728
729 // Create spacer:
730 $cCont = array();
731 foreach ($langListArr as $lP) {
732 $cCont[] = '&nbsp;';
733 }
734 $out .= '
735 <tr>
736 <td valign="top">' . implode('</td>' . $midSep . '
737 <td valign="top">', $cCont) . '</td>
738 </tr>';
739 }
740 }
741
742 // Finally, wrap it all in a table and add the language selector on top of it:
743 $out = $languageSelector . '
744 <table border="0" cellpadding="0" cellspacing="0" width="480" class="typo3-page-langMode">
745 ' . $out . '
746 </table>';
747
748 // CSH:
749 $out .= t3lib_BEfunc::cshItem($this->descrTable, 'language_list', $GLOBALS['BACK_PATH']);
750 }
751 } else { // SINGLE column mode (columns shown beneath each other):
752 #debug('single column');
753 if ($this->tt_contentConfig['sys_language_uid'] == 0 || !$this->defLangBinding) {
754
755 // Initialize:
756 if ($this->defLangBinding && $this->tt_contentConfig['sys_language_uid'] == 0) {
757 $showLanguage = ' AND sys_language_uid IN (0,-1)';
758 $lP = 0;
759 } else {
760 $showLanguage = ' AND sys_language_uid=' . $this->tt_contentConfig['sys_language_uid'];
761 $lP = $this->tt_contentConfig['sys_language_uid'];
762 }
763
764 $cList = explode(',', $this->tt_contentConfig['showSingleCol']);
765 $content = array();
766 $out = '';
767
768 // Expand the table to some preset dimensions:
769 $out .= '
770 <tr>
771 <td><img src="clear.gif" width="' . $lMarg . '" height="1" alt="" /></td>
772 <td valign="top"><img src="clear.gif" width="150" height="1" alt="" /></td>
773 <td><img src="clear.gif" width="10" height="1" alt="" /></td>
774 <td valign="top"><img src="clear.gif" width="300" height="1" alt="" /></td>
775 </tr>';
776
777 // Traverse columns to display top-on-top
778 foreach ($cList as $counter => $key) {
779
780 // Select content elements:
781 $queryParts = $this->makeQueryArray('tt_content', $id, 'AND colPos=' . intval($key) . $showHidden . $showLanguage);
782 $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
783 $c = 0;
784 $rowArr = $this->getResult($result);
785 $rowOut = '';
786
787 // If it turns out that there are not content elements in the column, then display a big button which links directly to the wizard script:
788 if ($this->doEdit && $this->option_showBigButtons && !intval($key) && !$GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
789 $onClick = "window.location.href='db_new_content_el.php?id=" . $id . '&colPos=' . intval($key) . '&sys_language_uid=' . $lP . '&uid_pid=' . $id . '&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . "';";
790 $theNewButton = $GLOBALS['SOBE']->doc->t3Button($onClick, $GLOBALS['LANG']->getLL('newPageContent'));
791 $theNewButton = '<img src="clear.gif" width="1" height="5" alt="" /><br />' . $theNewButton;
792 } else {
793 $theNewButton = '';
794 }
795
796 // Traverse any selected elements:
797 foreach ($rowArr as $rKey => $row) {
798
799 if (is_array($row) && (int) $row['t3ver_state'] != 2) {
800
801 $c++;
802 $editUidList .= $row['uid'] . ',';
803 $isRTE = $RTE && $this->isRTEforField('tt_content', $row, 'bodytext');
804
805 // Create row output:
806 $rowOut .= '
807 <tr>
808 <td></td>
809 <td valign="top">' . $this->tt_content_drawHeader($row) . '</td>
810 <td>&nbsp;</td>
811 <td' . ($row['_ORIG_uid'] ? ' class="ver-element"' : '') . ' valign="top">' . $this->tt_content_drawItem($row, $isRTE) . '</td>
812 </tr>';
813
814 // If the element was not the last element, add a divider line:
815 if ($c != $GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
816 $rowOut .= '
817 <tr>
818 <td></td>
819 <td colspan="3"><img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/stiblet_medium2.gif', 'width="468" height="1"') . ' class="c-divider" alt="" /></td>
820 </tr>';
821 }
822 } else {
823 unset($rowArr[$rKey]);
824 }
825 }
826
827 // Add spacer between sections in the vertical list
828 if ($counter) {
829 $out .= '
830 <tr>
831 <td></td>
832 <td colspan="3"><br /><br /><br /><br /></td>
833 </tr>';
834 }
835
836 // Add section header:
837 $newP = $this->newContentElementOnClick($id, $key, $this->tt_contentConfig['sys_language_uid']);
838 $out .= '
839
840 <!-- Column header: -->
841 <tr>
842 <td></td>
843 <td valign="top" colspan="3">' .
844 $this->tt_content_drawColHeader(t3lib_BEfunc::getProcessedValue('tt_content', 'colPos', $key), ($this->doEdit && count($rowArr) ? '&edit[tt_content][' . $editUidList . ']=edit' . $pageTitleParamForAltDoc : ''), $newP) .
845 $theNewButton .
846 '<br /></td>
847 </tr>';
848
849 // Finally, add the content from the records in this column:
850 $out .= $rowOut;
851 }
852
853 // Finally, wrap all table rows in one, big table:
854 $out = '
855 <table border="0" cellpadding="0" cellspacing="0" width="400" class="typo3-page-columnsMode">
856 ' . $out . '
857 </table>';
858
859 // CSH:
860 $out .= t3lib_BEfunc::cshItem($this->descrTable, 'columns_single', $GLOBALS['BACK_PATH']);
861 } else {
862 $out = '<br/><br/>' . $GLOBALS['SOBE']->doc->icons(1) . 'Sorry, you cannot view a single language in this localization mode (Default Language Binding is enabled)<br/><br/>';
863 }
864 }
865
866
867 // Add the big buttons to page:
868 if ($this->option_showBigButtons) {
869 $bArray = array();
870
871 if (!$GLOBALS['SOBE']->current_sys_language) {
872 if ($this->ext_CALC_PERMS & 2) {
873 $bArray[0] = $GLOBALS['SOBE']->doc->t3Button(t3lib_BEfunc::editOnClick('&edit[pages][' . $id . "]=edit", $this->backPath, ''), $GLOBALS['LANG']->getLL('editPageProperties'));
874 }
875 } else {
876 if ($this->doEdit && $GLOBALS['BE_USER']->check('tables_modify', 'pages_language_overlay')) {
877 list($languageOverlayRecord) = t3lib_BEfunc::getRecordsByField('pages_language_overlay', 'pid', $id, 'AND sys_language_uid=' . intval($GLOBALS['SOBE']->current_sys_language));
878 $bArray[0] = $GLOBALS['SOBE']->doc->t3Button(t3lib_BEfunc::editOnClick('&edit[pages_language_overlay][' . $languageOverlayRecord['uid'] . "]=edit", $this->backPath, ''), $GLOBALS['LANG']->getLL('editPageProperties_curLang'));
879 }
880 }
881 if ($this->ext_CALC_PERMS & 4 || $this->ext_CALC_PERMS & 2) {
882 $bArray[1] = $GLOBALS['SOBE']->doc->t3Button("window.location.href='" . $this->backPath . "move_el.php?table=pages&uid=" . $id . '&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . "';", $GLOBALS['LANG']->getLL('move_page'));
883 }
884 if ($this->ext_CALC_PERMS & 8) {
885 $bArray[2] = $GLOBALS['SOBE']->doc->t3Button("window.location.href='" . $this->backPath . "db_new.php?id=" . $id . '&pagesOnly=1&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . "';", $GLOBALS['LANG']->getLL('newPage2'));
886 }
887 if ($this->doEdit && $this->ext_function == 1) {
888 $bArray[3] = $GLOBALS['SOBE']->doc->t3Button("window.location.href='db_new_content_el.php?id=" . $id . '&sys_language_uid=' . $GLOBALS['SOBE']->current_sys_language . '&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . "';", $GLOBALS['LANG']->getLL('newPageContent2'));
889 }
890 $out = '
891 <table border="0" cellpadding="4" cellspacing="0" class="typo3-page-buttons">
892 <tr>
893 <td>' . implode('</td>
894 <td>', $bArray) . '</td>
895 <td>' . t3lib_BEfunc::cshItem($this->descrTable, 'button_panel', $GLOBALS['BACK_PATH']) . '</td>
896 </tr>
897 </table>
898 <br />
899 ' . $out;
900 }
901
902 // Return content:
903 return $out;
904 }
905
906 /**
907 * Renders Frontend Users from the fe_users table from page id
908 *
909 * @param integer Page id
910 * @return string HTML for the listing
911 */
912 function getTable_fe_users($id) {
913
914 $this->addElement_tdParams = array(
915 'username' => ' nowrap="nowrap"',
916 'usergroup' => ' nowrap="nowrap"',
917 'name' => ' nowrap="nowrap"',
918 'address' => ' nowrap="nowrap"',
919 'zip' => ' nowrap="nowrap"',
920 'city' => ' nowrap="nowrap"',
921 'email' => ' nowrap="nowrap"',
922 'telephone' => ' nowrap="nowrap"'
923 );
924 $fList = 'username,usergroup,name,email,telephone,address,zip,city';
925 $out = $this->makeOrdinaryList('fe_users', $id, $fList, 1);
926 $this->addElement_tdParams = array();
927 return $out;
928 }
929
930 /**
931 * Renders records from the sys_notes table from page id
932 * NOTICE: Requires the sys_note extension to be loaded.
933 *
934 * @param integer Page id
935 * @return string HTML for the listing
936 */
937 function getTable_sys_note($id) {
938 global $TCA;
939
940 if (!t3lib_extMgm::isLoaded('sys_note')) {
941 return '';
942 }
943
944 // INIT:
945 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
946 $tree = $this->getTreeObject($id, intval($GLOBALS['SOBE']->MOD_SETTINGS['pages_levels']), $perms_clause);
947
948 $this->itemLabels = array();
949 foreach ($TCA['sys_note']['columns'] as $name => $val) {
950 $this->itemLabels[$name] = $GLOBALS['LANG']->sL($val['label']);
951 }
952
953 // If page ids were found, select all sys_notes from the page ids:
954 $out = '';
955 if (count($tree->ids)) {
956 $delClause = t3lib_BEfunc::deleteClause('sys_note') . t3lib_BEfunc::versioningPlaceholderClause('sys_note');
957 $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_note', 'pid IN (' . implode(',', $tree->ids) . ') AND (personal=0 OR cruser=' . intval($GLOBALS['BE_USER']->user['uid']) . ')' . $delClause);
958 $dbCount = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
959
960 // If sys_notes were found, render them:
961 if ($dbCount) {
962 $this->fieldArray = explode(',', '__cmds__,info,note');
963
964 // header line is drawn
965 $theData = Array();
966 $theData['__cmds__'] = '';
967 $theData['info'] = '<strong>Info</strong><br /><img src="clear.gif" height="1" width="220" alt="" />';
968 $theData['note'] = '<strong>Note</strong>';
969 $out .= $this->addelement(1, '', $theData, ' class="t3-row-header"', 20);
970
971 // half line is drawn
972 $theData = Array();
973 $theData['info'] = $this->widthGif;
974 $out .= $this->addelement(0, '', $theData);
975
976 $this->no_noWrap = 1;
977
978 // Items
979 $this->eCounter = $this->firstElementNumber;
980 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
981 t3lib_BEfunc::workspaceOL('sys_note', $row);
982
983 if (is_array($row)) {
984 list($flag, $code) = $this->fwd_rwd_nav();
985 $out .= $code;
986 if ($flag) {
987 $color = Array(
988 0 => '', // No category
989 1 => ' class="bgColor4"', // Instructions
990 2 => ' class="bgColor2"', // Template
991 3 => '', // Notes
992 4 => ' class="bgColor5"' // To-do
993 );
994 $tdparams = $color[$row['category']];
995 $info = Array();
996 ;
997 $theData = Array();
998 $this->getProcessedValue('sys_note', 'subject,category,author,email,personal', $row, $info);
999 $cont = implode('<br />', $info);
1000 $head = '<strong>Page:</strong> ' . t3lib_BEfunc::getRecordPath($row['pid'], $perms_clause, 10) . '<br />';
1001
1002 $theData['__cmds__'] = $this->getIcon('sys_note', $row);
1003 $theData['info'] = $head . $cont;
1004 $theData['note'] = nl2br($row['message']);
1005
1006 $out .= $this->addelement(1, '', $theData, $tdparams, 20);
1007
1008
1009 // half line is drawn
1010 $theData = Array();
1011 $theData['info'] = $this->widthGif;
1012 $out .= $this->addelement(0, '', $theData);
1013 }
1014 $this->eCounter++;
1015 }
1016 }
1017
1018 // Wrap it all in a table:
1019 $out = '
1020 <table border="0" cellpadding="1" cellspacing="2" width="480" class="typo3-page-sysnote">
1021 ' . $out . '
1022 </table>';
1023 }
1024 }
1025 return $out;
1026 }
1027
1028 /**
1029 * Renders records from the tt_board table from page id
1030 * NOTICE: Requires the tt_board extension to be loaded.
1031 *
1032 * @param integer Page id
1033 * @return string HTML for the listing
1034 */
1035 function getTable_tt_board($id) {
1036
1037 // Initialize:
1038 $delClause = t3lib_BEfunc::deleteClause('tt_board') . t3lib_BEfunc::versioningPlaceholderClause('tt_board');
1039 $queryParts = $this->makeQueryArray('tt_board', $id, 'AND parent=0');
1040 $this->setTotalItems($queryParts);
1041 $dbCount = 0;
1042
1043 // If items were selected, make query:
1044 if ($this->totalItems) {
1045 $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
1046 $dbCount = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
1047 }
1048
1049 // If results came out of that, render the list:
1050 $out = '';
1051 if ($dbCount) {
1052
1053 // Setting fields to display first:
1054 if ($GLOBALS['SOBE']->MOD_SETTINGS['tt_board'] == 'expand') {
1055 $this->fieldArray = explode(',', 'subject,author,date,age');
1056 } else {
1057 $this->fieldArray = explode(',', 'subject,author,date,age,replys');
1058 }
1059
1060 // Header line is drawn
1061 $theData = Array();
1062 $theData['subject'] = '<strong>' . $GLOBALS['LANG']->getLL('tt_board_subject', 1) . '</strong>';
1063 $theData['author'] = '<strong>' . $GLOBALS['LANG']->getLL('tt_board_author', 1) . '</strong>';
1064 $theData['date'] = '<strong>' . $GLOBALS['LANG']->getLL('tt_board_date', 1) . '</strong>';
1065 $theData['age'] = '<strong>' . $GLOBALS['LANG']->getLL('tt_board_age', 1) . '</strong>';
1066 if ($GLOBALS['SOBE']->MOD_SETTINGS['tt_board'] != 'expand') {
1067 $theData['replys'] = '<strong>' . $GLOBALS['LANG']->getLL('tt_board_RE', 1) . '</strong>';
1068 }
1069 $out .= $this->addelement(1, '', $theData, ' class="t3-row-header"', 20);
1070
1071 // half line is drawn
1072 $theData = Array();
1073 $theData['subject'] = $this->widthGif;
1074 $out .= $this->addelement(0, '', $theData);
1075
1076 // Items
1077 $this->eCounter = $this->firstElementNumber;
1078 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
1079 t3lib_BEfunc::workspaceOL('tt_board', $row);
1080
1081 if (is_array($row)) {
1082 list($flag, $code) = $this->fwd_rwd_nav();
1083 $out .= $code;
1084
1085 if ($flag) {
1086
1087 $theRows = Array();
1088 $theRows = $this->tt_board_getTree($theRows, $row['uid'], $id, $delClause, '');
1089 $out .= $this->tt_board_drawItem('tt_board', $row, count($theRows));
1090
1091 if ($GLOBALS['SOBE']->MOD_SETTINGS['tt_board'] == 'expand') {
1092 foreach ($theRows as $n => $sRow) {
1093 $out .= $this->tt_board_drawItem('tt_board', $sRow, 0);
1094 }
1095 }
1096 }
1097 $this->eCounter++;
1098 }
1099 }
1100
1101 // Wrap it all in a table:
1102 $out = '
1103 <table border="0" cellpadding="0" cellspacing="0" class="typo3-page-listTTboard">
1104 ' . $out . '
1105 </table>';
1106 }
1107
1108 return $out;
1109 }
1110
1111 /**
1112 * Renders address records from the tt_address table from page id
1113 * NOTICE: Requires the tt_address extension to be loaded.
1114 *
1115 * @param integer Page id
1116 * @return string HTML for the listing
1117 */
1118 function getTable_tt_address($id) {
1119
1120 // Define fieldlist to show:
1121 switch ($GLOBALS['SOBE']->MOD_SETTINGS['tt_address']) {
1122 case 1:
1123 $icon = 0;
1124 $fList = 'name,address,zip,city,country';
1125 break;
1126 case 2:
1127 $icon = 1;
1128 $fList = 'name;title;email;company,image';
1129 break;
1130 default:
1131 $icon = 0;
1132 $fList = 'name,email,www,phone,fax,mobile';
1133 break;
1134 }
1135
1136 // Create listing
1137 $out = $this->makeOrdinaryList('tt_address', $id, $fList, $icon);
1138 return $out;
1139 }
1140
1141 /**
1142 * Renders link records from the tt_links table from page id
1143 * NOTICE: Requires the tt_links extension to be loaded.
1144 *
1145 * @param integer Page id
1146 * @return string HTML for the listing
1147 */
1148 function getTable_tt_links($id) {
1149
1150 // Define fieldlist to show:
1151 switch ($GLOBALS['SOBE']->MOD_SETTINGS['tt_links']) {
1152 case 1:
1153 $fList = 'title,hidden,url';
1154 break;
1155 case 2:
1156 $fList = 'title;url,note2';
1157 break;
1158 default:
1159 $fList = 'title;url,note';
1160 break;
1161 }
1162
1163 $out = $this->makeOrdinaryList('tt_links', $id, $fList, 1);
1164 return $out;
1165 }
1166
1167 /**
1168 * Renders link records from the tt_links table from page id
1169 * NOTICE: Requires the tt_links extension to be loaded.
1170 *
1171 * @param integer Page id
1172 * @return string HTML for the listing
1173 */
1174 function getTable_tt_guest($id) {
1175
1176 // Define fieldlist to show:
1177 $fList = 'title;cr_name;cr_email,note';
1178 $out = $this->makeOrdinaryList('tt_guest', $id, $fList, 1);
1179 return $out;
1180 }
1181
1182 /**
1183 * Renders news items from the tt_news table from page id
1184 * NOTICE: Requires the tt_news extension to be loaded.
1185 *
1186 * @param integer Page id
1187 * @return string HTML for the listing
1188 */
1189 function getTable_tt_news($id) {
1190
1191 $this->addElement_tdParams = array(
1192 'title' => ' nowrap="nowrap"',
1193 'datetime' => ' nowrap="nowrap"',
1194 'starttime' => ' nowrap="nowrap"',
1195 'author' => ' nowrap="nowrap"'
1196 );
1197 $fList = 'title,author,author_email,datetime,starttime,category,image';
1198 $out = $this->makeOrdinaryList('tt_news', $id, $fList, 1);
1199 $this->addElement_tdParams = array();
1200 return $out;
1201 }
1202
1203 /**
1204 * Renders calender elements link records from the tt_calender table from page id
1205 * NOTICE: Requires the tt_calender extension to be loaded.
1206 *
1207 * @param integer Page id
1208 * @return string HTML for the listing
1209 */
1210 function getTable_tt_calender($id) {
1211
1212 $type = $GLOBALS['SOBE']->MOD_SETTINGS['tt_calender'];
1213 switch ($type) {
1214 case 'date':
1215 // Date default
1216 $fList = 'date,title';
1217 $icon = 0;
1218 $out = $this->makeOrdinaryList('tt_calender', $id, $fList, $icon, ' AND type=0');
1219 return $out;
1220 break;
1221 case 'date_ext':
1222 // Date extended
1223 $fList = 'title;date;time;datetext;link,note';
1224 $icon = 1;
1225 $out = $this->makeOrdinaryList('tt_calender', $id, $fList, $icon, ' AND type=0');
1226 return $out;
1227 break;
1228 case 'todo':
1229 // Todo default
1230 $fList = 'title,complete,priority,date';
1231 $icon = 0;
1232 $out = $this->makeOrdinaryList('tt_calender', $id, $fList, $icon, ' AND type=1');
1233 return $out;
1234 break;
1235 case 'todo_ext':
1236 // Todo extended
1237 $fList = 'title;complete;priority;date;workgroup;responsible;category,note';
1238 $icon = 1;
1239 $out = $this->makeOrdinaryList('tt_calender', $id, $fList, $icon, ' AND type=1');
1240 return $out;
1241 break;
1242 default:
1243 // Overview, both todo and calender
1244 $fList = 'title,date,time,week';
1245 $icon = 1;
1246 $out = $this->makeOrdinaryList('tt_calender', $id, $fList, $icon, ' AND type=0');
1247 $out .= $this->makeOrdinaryList('tt_calender', $id, $fList, $icon, ' AND type=1');
1248 return $out;
1249 break;
1250 }
1251 }
1252
1253 /**
1254 * Renders shopping elements from the tt_products table from page id
1255 * NOTICE: Requires the tt_products extension to be loaded.
1256 *
1257 * @param integer Page id
1258 * @return string HTML for the listing
1259 */
1260 function getTable_tt_products($id) {
1261
1262 $type = $GLOBALS['SOBE']->MOD_SETTINGS['tt_products'];
1263 switch ($type) {
1264 case 'ext':
1265 $fList = 'title;itemnumber;price;price2;inStock;category,image,note';
1266 $icon = 1;
1267 $out = $this->makeOrdinaryList('tt_products', $id, $fList, $icon);
1268 break;
1269 default:
1270 $fList = 'title,itemnumber,price,category,image';
1271 $icon = 1;
1272 $out = $this->makeOrdinaryList('tt_products', $id, $fList, $icon);
1273 break;
1274 }
1275
1276 return $out;
1277 }
1278
1279
1280 /**********************************
1281 *
1282 * Generic listing of items
1283 *
1284 **********************************/
1285
1286 /**
1287 * Creates a standard list of elements from a table.
1288 *
1289 * @param string Table name
1290 * @param integer Page id.
1291 * @param string Comma list of fields to display
1292 * @param boolean If true, icon is shown
1293 * @param string Additional WHERE-clauses.
1294 * @return string HTML table
1295 */
1296 function makeOrdinaryList($table, $id, $fList, $icon = 0, $addWhere = '') {
1297 global $TCA;
1298
1299 // Initialize:
1300 $out = '';
1301 $queryParts = $this->makeQueryArray($table, $id, $addWhere);
1302 $this->setTotalItems($queryParts);
1303 $dbCount = 0;
1304
1305 // Make query for records if there were any records found in the count operation:
1306 if ($this->totalItems) {
1307 $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
1308 $dbCount = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
1309 }
1310
1311 // If records were found, render the list:
1312 $out = '';
1313 if ($dbCount) {
1314
1315 // Set fields
1316 $this->fieldArray = t3lib_div::trimExplode(',', '__cmds__,' . $fList, TRUE);
1317
1318 // Header line is drawn
1319 $theData = array();
1320 $theData = $this->headerFields($this->fieldArray, $table, $theData);
1321 if ($this->doEdit) {
1322 $theData['__cmds__'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick('&edit[' . $table . '][' . $this->id . ']=new', $this->backPath)) . '" title="' . $GLOBALS['LANG']->getLL('new', TRUE) . '">' .
1323 t3lib_iconWorks::getSpriteIcon('actions-document-new') .
1324 '</a>';
1325 }
1326 $out .= $this->addelement(1, '', $theData, ' class="c-headLine"', 15);
1327
1328 // Render Items
1329 $this->eCounter = $this->firstElementNumber;
1330 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
1331 t3lib_BEfunc::workspaceOL($table, $row);
1332
1333 if (is_array($row)) {
1334 list($flag, $code) = $this->fwd_rwd_nav();
1335 $out .= $code;
1336 if ($flag) {
1337 $params = '&edit[' . $table . '][' . $row['uid'] . ']=edit';
1338 $Nrow = array();
1339
1340 // Setting icons/edit links:
1341 if ($icon) {
1342 $Nrow['__cmds__'] = $this->getIcon($table, $row);
1343 }
1344 if ($this->doEdit) {
1345 $Nrow['__cmds__'] .= '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath)) . '" title="' . $GLOBALS['LANG']->getLL('edit', TRUE) . '">' .
1346 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
1347 '</a>';
1348 } else {
1349 $Nrow['__cmds__'] .= $this->noEditIcon();
1350 }
1351
1352 // Get values:
1353 $Nrow = $this->dataFields($this->fieldArray, $table, $row, $Nrow);
1354 $tdparams = $this->eCounter % 2 ? ' class="bgColor4"' : ' class="bgColor4-20"';
1355 $out .= $this->addelement(1, '', $Nrow, $tdparams);
1356 }
1357 $this->eCounter++;
1358 }
1359 }
1360
1361 // Wrap it all in a table:
1362 $out = '
1363
1364 <!--
1365 STANDARD LIST OF "' . $table . '"
1366 -->
1367 <table border="0" cellpadding="1" cellspacing="2" width="480" class="typo3-page-stdlist">
1368 ' . $out . '
1369 </table>';
1370 }
1371 return $out;
1372 }
1373
1374 /**
1375 * Adds content to all data fields in $out array
1376 *
1377 * @param array Array of fields to display. Each field name has a special feature which is that the field name can be specified as more field names. Eg. "field1,field2;field3". Field 2 and 3 will be shown in the same cell of the table separated by <br /> while field1 will have its own cell.
1378 * @param string Table name
1379 * @param array Record array
1380 * @param array Array to which the data is added
1381 * @return array $out array returned after processing.
1382 * @see makeOrdinaryList()
1383 */
1384 function dataFields($fieldArr, $table, $row, $out = array()) {
1385 global $TCA;
1386
1387 // Check table validity:
1388 if ($TCA[$table]) {
1389 t3lib_div::loadTCA($table);
1390 $thumbsCol = $TCA[$table]['ctrl']['thumbnail'];
1391
1392 // Traverse fields:
1393 foreach ($fieldArr as $fieldName) {
1394
1395 if ($TCA[$table]['columns'][$fieldName]) { // Each field has its own cell (if configured in TCA)
1396 if ($fieldName == $thumbsCol) { // If the column is a thumbnail column:
1397 $out[$fieldName] = $this->thumbCode($row, $table, $fieldName);
1398 } else { // ... otherwise just render the output:
1399 $out[$fieldName] = nl2br(htmlspecialchars(trim(t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getProcessedValue($table, $fieldName, $row[$fieldName], 0, 0, 0, $row['uid']), 250))));
1400 }
1401 } else { // Each field is separated by <br /> and shown in the same cell (If not a TCA field, then explode the field name with ";" and check each value there as a TCA configured field)
1402 $theFields = explode(';', $fieldName);
1403
1404 // Traverse fields, separated by ";" (displayed in a single cell).
1405 foreach ($theFields as $fName2) {
1406 if ($TCA[$table]['columns'][$fName2]) {
1407 $out[$fieldName] .= '<strong>' . $GLOBALS['LANG']->sL($TCA[$table]['columns'][$fName2]['label'], 1) . '</strong>' .
1408 '&nbsp;&nbsp;' .
1409 htmlspecialchars(t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getProcessedValue($table, $fName2, $row[$fName2], 0, 0, 0, $row['uid']), 25)) .
1410 '<br />';
1411 }
1412 }
1413 }
1414 // If no value, add a nbsp.
1415 if (!$out[$fieldName]) {
1416 $out[$fieldName] = '&nbsp;';
1417 }
1418
1419 // Wrap in dimmed-span tags if record is "disabled"
1420 if ($this->isDisabled($table, $row)) {
1421 $out[$fieldName] = $GLOBALS['TBE_TEMPLATE']->dfw($out[$fieldName]);
1422 }
1423 }
1424 }
1425 return $out;
1426 }
1427
1428 /**
1429 * Header fields made for the listing of records
1430 *
1431 * @param array Field names
1432 * @param string The table name
1433 * @param array Array to which the headers are added.
1434 * @return array $out returned after addition of the header fields.
1435 * @see makeOrdinaryList()
1436 */
1437 function headerFields($fieldArr, $table, $out = array()) {
1438 global $TCA;
1439
1440 t3lib_div::loadTCA($table);
1441
1442 foreach ($fieldArr as $fieldName) {
1443 $ll = $GLOBALS['LANG']->sL($TCA[$table]['columns'][$fieldName]['label'], 1);
1444 $out[$fieldName] = '<strong>' . ($ll ? $ll : '&nbsp;') . '</strong>';
1445 }
1446 return $out;
1447 }
1448
1449
1450 /**********************************
1451 *
1452 * Additional functions; Pages
1453 *
1454 **********************************/
1455
1456 /**
1457 * Adds pages-rows to an array, selecting recursively in the page tree.
1458 *
1459 * @param array Array which will accumulate page rows
1460 * @param integer Pid to select from
1461 * @param string Query-where clause
1462 * @param string Prefixed icon code.
1463 * @param integer Depth (decreasing)
1464 * @return array $theRows, but with added rows.
1465 */
1466 function pages_getTree($theRows, $pid, $qWhere, $treeIcons, $depth) {
1467 $depth--;
1468 if ($depth >= 0) {
1469 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'pid=' . intval($pid) . $qWhere, '', 'sorting');
1470 $c = 0;
1471 $rc = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
1472 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1473 t3lib_BEfunc::workspaceOL('pages', $row);
1474 if (is_array($row)) {
1475 $c++;
1476 $row['treeIcons'] = $treeIcons . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/join' . ($rc == $c ? 'bottom' : '') . '.gif', 'width="18" height="16"') . ' alt="" />';
1477 $theRows[] = $row;
1478
1479 // Get the branch
1480 $spaceOutIcons = '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . ($rc == $c ? 'blank.gif' : 'line.gif'), 'width="18" height="16"') . ' alt="" />';
1481 $theRows = $this->pages_getTree($theRows, $row['uid'], $qWhere, $treeIcons . $spaceOutIcons, $row['php_tree_stop'] ? 0 : $depth);
1482 }
1483 }
1484 } else {
1485 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', 'pages', 'pid=' . intval($pid) . $qWhere);
1486 if ($count) {
1487 $this->plusPages[$pid] = $count;
1488 }
1489 }
1490 return $theRows;
1491 }
1492
1493 /**
1494 * Adds a list item for the pages-rendering
1495 *
1496 * @param array Record array
1497 * @param array Field list
1498 * @return string HTML for the item
1499 */
1500 function pages_drawItem($row, $fieldArr) {
1501 global $TCA;
1502
1503 // Initialization
1504 $theIcon = $this->getIcon('pages', $row);
1505
1506 // Preparing and getting the data-array
1507 $theData = Array();
1508 foreach ($fieldArr as $field) {
1509 switch ($field) {
1510 case 'title':
1511 $red = $this->plusPages[$row['uid']] ? '<font color="red"><strong>+&nbsp;</strong></font>' : '';
1512 $pTitle = htmlspecialchars(t3lib_BEfunc::getProcessedValue('pages', $field, $row[$field], 20));
1513 if ($red) {
1514 $pTitle = '<a href="' . htmlspecialchars($this->script . '?id=' . $row['uid']) . '">' . $pTitle . '</a>';
1515 }
1516 $theData[$field] = $row['treeIcons'] . $theIcon . $red . $pTitle . '&nbsp;&nbsp;';
1517 break;
1518 case 'php_tree_stop':
1519 case 'TSconfig':
1520 $theData[$field] = $row[$field] ? '&nbsp;<strong>x</strong>' : '&nbsp;';
1521 break;
1522 case 'uid':
1523 if ($GLOBALS['BE_USER']->doesUserHaveAccess($row, 2)) {
1524 $params = '&edit[pages][' . $row['uid'] . ']=edit';
1525 $eI = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath, '')) . '" title="' . $GLOBALS['LANG']->getLL('editThisPage', TRUE) . '">' .
1526 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
1527 '</a>';
1528 } else {
1529 $eI = '';
1530 }
1531 $theData[$field] = '<span align="right">' . $row['uid'] . $eI . '</span>';
1532 break;
1533 default:
1534 if (substr($field, 0, 6) == 'table_') {
1535 $f2 = substr($field, 6);
1536 if ($TCA[$f2]) {
1537 $c = $this->numberOfRecords($f2, $row['uid']);
1538 $theData[$field] = '&nbsp;&nbsp;' . ($c ? $c : '');
1539 }
1540 } elseif (substr($field, 0, 5) == 'HITS_') {
1541 if (t3lib_extMgm::isLoaded('sys_stat')) {
1542 $fParts = explode(':', substr($field, 5));
1543 switch ($fParts[0]) {
1544 case 'days':
1545 $timespan = mktime(0, 0, 0) + intval($fParts[1]) * 3600 * 24;
1546 // Page hits
1547 $number = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
1548 '*',
1549 'sys_stat',
1550 $this->stat_select_field . '=' . intval($row['uid']) .
1551 ' AND tstamp >=' . intval($timespan) .
1552 ' AND tstamp <' . intval($timespan + 3600 * 24)
1553 );
1554 if ($number) {
1555 // Sessions
1556 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1557 'count(*)',
1558 'sys_stat',
1559 $this->stat_select_field . '=' . intval($row['uid']) . '
1560 AND tstamp>=' . intval($timespan) . '
1561 AND tstamp<' . intval($timespan + 3600 * 24) . '
1562 AND surecookie!=""',
1563 'surecookie'
1564 );
1565 $scnumber = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
1566
1567 $number .= '/' . $scnumber;
1568 } else {
1569 $number = '';
1570 }
1571 break;
1572 }
1573 $theData[$field] = '&nbsp;' . $number;
1574 } else {
1575 $theData[$field] = '&nbsp;';
1576 }
1577 } else {
1578 $theData[$field] = '&nbsp;&nbsp;' . htmlspecialchars(t3lib_BEfunc::getProcessedValue('pages', $field, $row[$field]));
1579 }
1580 break;
1581 }
1582 }
1583 $this->addElement_tdParams['title'] = ($row['_CSSCLASS'] ? ' class="' . $row['_CSSCLASS'] . '"' : '');
1584 return $this->addelement(1, '', $theData);
1585 }
1586
1587
1588 /**********************************
1589 *
1590 * Additional functions; Content Elements
1591 *
1592 **********************************/
1593
1594 /**
1595 * Draw header for a content element column:
1596 *
1597 * @param string Column name
1598 * @param string Edit params (Syntax: &edit[...] for alt_doc.php)
1599 * @param string New element params (Syntax: &edit[...] for alt_doc.php)
1600 * @return string HTML table
1601 */
1602 function tt_content_drawColHeader($colName, $editParams, $newParams) {
1603
1604 $icons = '';
1605 // Create command links:
1606 if ($this->tt_contentConfig['showCommands']) {
1607 // New record:
1608 if ($newParams) {
1609 $icons .= '<a href="#" onclick="' . htmlspecialchars($newParams) . '" title="' . $GLOBALS['LANG']->getLL('newInColumn', TRUE) . '">' .
1610 t3lib_iconWorks::getSpriteIcon('actions-document-new') .
1611 '</a>';
1612 }
1613 // Edit whole of column:
1614 if ($editParams) {
1615 $icons .= '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($editParams, $this->backPath)) . '" title="' . $GLOBALS['LANG']->getLL('editColumn', TRUE) . '">' .
1616 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
1617 '</a>';
1618 }
1619 }
1620 if (strlen($icons)) {
1621 $icons = '<div class="t3-page-colHeader-icons">' . $icons . '</div>';
1622 }
1623
1624 // Create header row:
1625 $out = '<div class="t3-page-colHeader t3-row-header">
1626 ' . $icons . '
1627 <div class="t3-page-colHeader-label">' . htmlspecialchars($colName) . '</div>
1628 </div>';
1629 return $out;
1630 }
1631
1632 /**
1633 * Draw the header for a single tt_content element
1634 *
1635 * @param array Record array
1636 * @param integer Amount of pixel space above the header.
1637 * @param boolean If set the buttons for creating new elements and moving up and down are not shown.
1638 * @param boolean If set, we are in language mode and flags will be shown for languages
1639 * @return string HTML table with the record header.
1640 */
1641 function tt_content_drawHeader($row, $space = 0, $disableMoveAndNewButtons = FALSE, $langMode = FALSE) {
1642 global $TCA;
1643
1644 // Load full table description:
1645 t3lib_div::loadTCA('tt_content');
1646
1647 // Get record locking status:
1648 if ($lockInfo = t3lib_BEfunc::isRecordLocked('tt_content', $row['uid'])) {
1649 $lockIcon = '<a href="#" onclick="' . htmlspecialchars('alert(' . $GLOBALS['LANG']->JScharCode($lockInfo['msg']) . ');return false;') . '" title="' . htmlspecialchars($lockInfo['msg']) . '">' .
1650 t3lib_iconWorks::getSpriteIcon('status-warning-in-use') .
1651 '</a>';
1652 } else {
1653 $lockIcon = '';
1654 }
1655
1656 // Call stats information hook
1657 $stat = '';
1658 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) {
1659 $_params = array('tt_content', $row['uid'], &$row);
1660 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) {
1661 $stat .= t3lib_div::callUserFunction($_funcRef, $_params, $this);
1662 }
1663 }
1664
1665 // Create line with type of content element and icon/lock-icon/title:
1666 $ceType = $this->getIcon('tt_content', $row) . ' ' .
1667 $lockIcon . ' ' .
1668 $stat . ' ' .
1669 ($langMode ? $this->languageFlag($row['sys_language_uid']) : '') . ' ' .
1670 '&nbsp;<strong>' . htmlspecialchars($this->CType_labels[$row['CType']]) . '</strong>';
1671
1672 // If show info is set...;
1673 if ($this->tt_contentConfig['showInfo']) {
1674
1675 // Get processed values:
1676 $info = Array();
1677 $this->getProcessedValue('tt_content', 'hidden,starttime,endtime,fe_group,spaceBefore,spaceAfter', $row, $info);
1678
1679 // Render control panel for the element:
1680 if ($this->tt_contentConfig['showCommands'] && $this->doEdit) {
1681
1682 if (!$disableMoveAndNewButtons) {
1683 // New content element:
1684 if ($this->option_newWizard) {
1685 $onClick = "window.location.href='db_new_content_el.php?id=" . $row['pid'] . '&sys_language_uid=' . $row['sys_language_uid'] . '&colPos=' . $row['colPos'] . '&uid_pid=' . (-$row['uid']) . '&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . "';";
1686 } else {
1687 $params = '&edit[tt_content][' . (-$row['uid']) . ']=new';
1688 $onClick = t3lib_BEfunc::editOnClick($params, $this->backPath);
1689 }
1690 $out .= '<a href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $GLOBALS['LANG']->getLL('newAfter', 1) . '">' .
1691 t3lib_iconWorks::getSpriteIcon('actions-document-new') .
1692 '</a>';
1693 }
1694
1695 // Edit content element:
1696 $params = '&edit[tt_content][' . $this->tt_contentData['nextThree'][$row['uid']] . ']=edit';
1697 $out .= '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath)) . '" title="' .
1698 htmlspecialchars($this->nextThree > 1 ? sprintf($GLOBALS['LANG']->getLL('nextThree'), $this->nextThree) : $GLOBALS['LANG']->getLL('edit')) . '">' .
1699 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
1700 '</a>';
1701
1702 // Hide element:
1703 $hiddenField = $TCA['tt_content']['ctrl']['enablecolumns']['disabled'];
1704 if ($hiddenField && $TCA['tt_content']['columns'][$hiddenField] && (!$TCA['tt_content']['columns'][$hiddenField]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', 'tt_content:' . $hiddenField))) {
1705 if ($row[$hiddenField]) {
1706 $params = '&data[tt_content][' . ($row['_ORIG_uid'] ? $row['_ORIG_uid'] : $row['uid']) . '][' . $hiddenField . ']=0';
1707 $out .= '<a href="' . htmlspecialchars($GLOBALS['SOBE']->doc->issueCommand($params)) . '" title="' . $GLOBALS['LANG']->getLL('unHide', TRUE) . '">' .
1708 t3lib_iconWorks::getSpriteIcon('actions-edit-unhide') .
1709 '</a>';
1710 } else {
1711 $params = '&data[tt_content][' . ($row['_ORIG_uid'] ? $row['_ORIG_uid'] : $row['uid']) . '][' . $hiddenField . ']=1';
1712 $out .= '<a href="' . htmlspecialchars($GLOBALS['SOBE']->doc->issueCommand($params)) . '" title="' . $GLOBALS['LANG']->getLL('hide', TRUE) . '">' .
1713 t3lib_iconWorks::getSpriteIcon('actions-edit-hide') .
1714 '</a>';
1715 }
1716 }
1717
1718 // Delete
1719 $params = '&cmd[tt_content][' . $row['uid'] . '][delete]=1';
1720 $confirm = $GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->getLL('deleteWarning') .
1721 t3lib_BEfunc::translationCount('tt_content', $row['uid'], ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.translationsOfRecord')));
1722 $out .= '<a href="' . htmlspecialchars($GLOBALS['SOBE']->doc->issueCommand($params)) . '" onclick="' . htmlspecialchars('return confirm(' . $confirm . ');') . '" title="' . $GLOBALS['LANG']->getLL('deleteItem', TRUE) . '">' .
1723 t3lib_iconWorks::getSpriteIcon('actions-edit-delete') .
1724 '</a>';
1725
1726 if (!$disableMoveAndNewButtons) {
1727 $out .= '<span class="t3-page-ce-icons-move">';
1728 // Move element up:
1729 if ($this->tt_contentData['prev'][$row['uid']]) {
1730 $params = '&cmd[tt_content][' . $row['uid'] . '][move]=' . $this->tt_contentData['prev'][$row['uid']];
1731 $out .= '<a href="' . htmlspecialchars($GLOBALS['SOBE']->doc->issueCommand($params)) . '" title="' . $GLOBALS['LANG']->getLL('moveUp', TRUE) . '">' .
1732 t3lib_iconWorks::getSpriteIcon('actions-move-up') .
1733 '</a>';
1734 } else {
1735 $out .= t3lib_iconWorks::getSpriteIcon('empty-empty');
1736 }
1737 // Move element down:
1738 if ($this->tt_contentData['next'][$row['uid']]) {
1739 $params = '&cmd[tt_content][' . $row['uid'] . '][move]= ' . $this->tt_contentData['next'][$row['uid']];
1740 $out .= '<a href="' . htmlspecialchars($GLOBALS['SOBE']->doc->issueCommand($params)) . '" title="' . $GLOBALS['LANG']->getLL('moveDown', TRUE) . '">' .
1741 t3lib_iconWorks::getSpriteIcon('actions-move-down') .
1742 '</a>';
1743 } else {
1744 $out .= t3lib_iconWorks::getSpriteIcon('empty-empty');
1745 }
1746 $out .= '</span>';
1747 }
1748 }
1749
1750 // Display info from records fields:
1751 $infoOutput = '';
1752 if (count($info)) {
1753 $infoOutput = '<div class="t3-page-ce-info">
1754 ' . implode('<br />', $info) . '
1755 </div>';
1756 }
1757 }
1758 // Wrap the whole header
1759 // NOTE: end-tag for <div class="t3-page-ce-body"> is in getTable_tt_content()
1760 return '<h4 class="t3-page-ce-header">
1761 <div class="t3-row-header">
1762 ' . $out . '
1763 </div>
1764 </h4>
1765 <div class="t3-page-ce-body">
1766 <div class="t3-page-ce-type">
1767 ' . $ceType . '
1768 </div>
1769 ' . $infoOutput;
1770 }
1771
1772 /**
1773 * Draws the preview content for a content element
1774 *
1775 * @param string Content element
1776 * @param boolean Set if the RTE link can be created.
1777 * @return string HTML
1778 */
1779 function tt_content_drawItem($row, $isRTE = FALSE) {
1780 global $TCA;
1781
1782 $out = '';
1783 $outHeader = '';
1784
1785 // Make header:
1786 if ($row['header']) {
1787 $infoArr = Array();
1788 $this->getProcessedValue('tt_content', 'header_position,header_layout,header_link', $row, $infoArr);
1789
1790 // If header layout is set to 'hidden', display an accordant note:
1791 if ($row['header_layout'] == 100) {
1792 $hiddenHeaderNote = ' <em>[' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.hidden', true) . ']</em>';
1793 }
1794 $outHeader = ($row['date'] ? htmlspecialchars($this->itemLabels['date'] . ' ' . t3lib_BEfunc::date($row['date'])) . '<br />' : '') .
1795 '<strong>' . $this->linkEditContent($this->renderText($row['header']), $row) . $hiddenHeaderNote . '</strong><br />';
1796 }
1797
1798 // Make content:
1799 $infoArr = array();
1800 $drawItem = true;
1801
1802 // Hook: Render an own preview of a record
1803 $drawItemHooks =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem'];
1804
1805 if (is_array($drawItemHooks)) {
1806 foreach ($drawItemHooks as $hookClass) {
1807 $hookObject = t3lib_div::getUserObj($hookClass);
1808
1809 if (!($hookObject instanceof tx_cms_layout_tt_content_drawItemHook)) {
1810 throw new UnexpectedValueException('$hookObject must implement interface tx_cms_layout_tt_content_drawItemHook', 1218547409);
1811 }
1812
1813 $hookObject->preProcess($this, $drawItem, $outHeader, $out, $row);
1814 }
1815 }
1816
1817 // Draw preview of the item depending on its CType (if not disabled by previous hook):
1818 if ($drawItem) {
1819 switch ($row['CType']) {
1820 case 'header':
1821 if ($row['subheader']) {
1822 $out .= $this->linkEditContent($this->renderText($row['subheader']), $row) . '<br />';
1823 }
1824 break;
1825 case 'text':
1826 case 'textpic':
1827 case 'image':
1828 if ($row['CType'] == 'text' || $row['CType'] == 'textpic') {
1829 if ($row['bodytext']) {
1830 $this->getProcessedValue('tt_content', 'text_align,text_face,text_size,text_color,text_properties', $row, $infoArr);
1831 $out .= $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
1832 }
1833 }
1834 if ($row['CType'] == 'textpic' || $row['CType'] == 'image') {
1835 if ($row['image']) {
1836 $out .= $this->thumbCode($row, 'tt_content', 'image') . '<br />';
1837 if ($row['imagecaption']) {
1838 $out .= $this->linkEditContent($this->renderText($row['imagecaption']), $row) . '<br />';
1839 }
1840 }
1841 }
1842 break;
1843 case 'bullets':
1844 case 'table':
1845 case 'mailform':
1846 if ($row['bodytext']) {
1847 $out .= $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
1848 }
1849 break;
1850 case 'uploads':
1851 if ($row['media']) {
1852 $out .= $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
1853 }
1854 break;
1855 case 'multimedia':
1856 if ($row['multimedia']) {
1857 $out .= $this->renderText($row['multimedia']) . '<br />';
1858 $out .= $this->renderText($row['parameters']) . '<br />';
1859 }
1860 break;
1861 case 'splash':
1862 if ($row['bodytext']) {
1863 $out .= $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
1864 }
1865 if ($row['image']) {
1866 $out .= $this->thumbCode($row, 'tt_content', 'image') . '<br />';
1867 }
1868 break;
1869 case 'menu':
1870 if ($row['pages']) {
1871 $out .= $this->linkEditContent($row['pages'], $row) . '<br />';
1872 }
1873 break;
1874 case 'shortcut':
1875 if ($row['records']) {
1876 $out .= $this->linkEditContent($row['shortcut'], $row) . '<br />';
1877 }
1878 break;
1879 case 'list':
1880 $out .= $GLOBALS['LANG']->sL(t3lib_BEfunc::getItemLabel('tt_content', 'list_type'), 1) . ' ' .
1881 $GLOBALS['LANG']->sL(t3lib_BEfunc::getLabelFromItemlist('tt_content', 'list_type', $row['list_type']), 1) . '<br />';
1882 $hookArr = array();
1883 $hookOut = '';
1884 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['list_type_Info'][$row['list_type']])) {
1885 $hookArr = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['list_type_Info'][$row['list_type']];
1886 } elseif (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['list_type_Info']['_DEFAULT'])) {
1887 $hookArr = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['list_type_Info']['_DEFAULT'];
1888 }
1889 if (count($hookArr) > 0) {
1890 $_params = array('pObj' => &$this, 'row' => $row, 'infoArr' => $infoArr);
1891 foreach ($hookArr as $_funcRef) {
1892 $hookOut .= t3lib_div::callUserFunction($_funcRef, $_params, $this);
1893 }
1894 }
1895 if (strcmp($hookOut, '')) {
1896 $out .= $hookOut;
1897 } else {
1898 $out .= $GLOBALS['LANG']->sL(t3lib_BEfunc::getItemLabel('tt_content', 'select_key'), 1) . ' ' . $row['select_key'] . '<br />';
1899 }
1900
1901 $out .= $GLOBALS['LANG']->sL(t3lib_BEfunc::getLabelFromItemlist('tt_content', 'pages', $row['pages']), 1) . '<br />';
1902 break;
1903 case 'script':
1904 $out .= $GLOBALS['LANG']->sL(t3lib_BEfunc::getItemLabel('tt_content', 'select_key'), 1) . ' ' . $row['select_key'] . '<br />';
1905 $out .= '<br />' . $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
1906 $out .= '<br />' . $this->linkEditContent($this->renderText($row['imagecaption']), $row) . '<br />';
1907 break;
1908 default:
1909 if ($row['bodytext']) {
1910 $out .= $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
1911 }
1912 break;
1913 }
1914 }
1915
1916 // Wrap span-tags:
1917 $out = '
1918 <span class="exampleContent">' . $out . '</span>';
1919 // Add header:
1920 $out = $outHeader . $out;
1921 // Add RTE button:
1922 if ($isRTE) {
1923 $out .= $this->linkRTEbutton($row);
1924 }
1925
1926 // Return values:
1927 if ($this->isDisabled('tt_content', $row)) {
1928 return $GLOBALS['TBE_TEMPLATE']->dfw($out);
1929 } else {
1930 return $out;
1931 }
1932 }
1933
1934 /**
1935 * Filters out all tt_content uids which are already translated so only non-translated uids is left.
1936 * Selects across columns, but within in the same PID. Columns are expect to be the same for translations and original but this may be a conceptual error (?)
1937 *
1938 * @param array Numeric array with uids of tt_content elements in the default language
1939 * @param integer Page pid
1940 * @param integer Sys language UID
1941 * @return array Modified $defLanguageCount
1942 */
1943 function getNonTranslatedTTcontentUids($defLanguageCount, $id, $lP) {
1944 if ($lP && count($defLanguageCount)) {
1945
1946 // Select all translations here:
1947 $queryParts = $this->makeQueryArray('tt_content', $id, 'AND sys_language_uid=' . intval($lP) . ' AND l18n_parent IN (' . implode(',', $defLanguageCount) . ')');
1948 $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
1949
1950 // Flip uids:
1951 $defLanguageCount = array_flip($defLanguageCount);
1952
1953 // Traverse any selected elements and unset original UID if any:
1954 $rowArr = $this->getResult($result);
1955 foreach ($rowArr as $row) {
1956 unset($defLanguageCount[$row['l18n_parent']]);
1957 }
1958
1959 // Flip again:
1960 $defLanguageCount = array_keys($defLanguageCount);
1961 }
1962
1963 return $defLanguageCount;
1964 }
1965
1966 /**
1967 * Creates button which is used to create copies of records..
1968 *
1969 * @param array Numeric array with uids of tt_content elements in the default language
1970 * @param integer Sys language UID
1971 * @return string "Copy languages" button, if available.
1972 */
1973 function newLanguageButton($defLanguageCount, $lP) {
1974 if ($this->doEdit && count($defLanguageCount) && $lP) {
1975
1976 $params = '';
1977 foreach ($defLanguageCount as $uidVal) {
1978 $params .= '&cmd[tt_content][' . $uidVal . '][localize]=' . $lP;
1979 }
1980
1981 // Copy for language:
1982 $onClick = "window.location.href='" . $GLOBALS['SOBE']->doc->issueCommand($params) . "'; return false;";
1983 $theNewButton = $GLOBALS['SOBE']->doc->t3Button($onClick, $GLOBALS['LANG']->getLL('newPageContent_copyForLang') . ' [' . count($defLanguageCount) . ']');
1984 return $theNewButton;
1985 }
1986 }
1987
1988 /**
1989 * Returns an icon, which has its title attribute set to a massive amount of information about the element.
1990 *
1991 * @param array Array where values are human readable output of field values (not htmlspecialchars()'ed though). The values are imploded by a linebreak.
1992 * @return string HTML img tag if applicable.
1993 * @deprecated since TYPO3 4.4, this function will be removed in TYPO3 4.6
1994 */
1995 function infoGif($infoArr) {
1996 t3lib_div::logDeprecatedFunction();
1997
1998 if (count($infoArr) && $this->tt_contentConfig['showInfo']) {
1999 return t3lib_iconWorks::getSpriteIcon('actions-document-info', array('title' => htmlspecialchars(implode(LF, $infoArr))));
2000 }
2001 }
2002
2003 /**
2004 * Creates onclick-attribute content for a new content element
2005 *
2006 * @param integer Page id where to create the element.
2007 * @param integer Preset: Column position value
2008 * @param integer Preset: Sys langauge value
2009 * @return string String for onclick attribute.
2010 * @see getTable_tt_content()
2011 */
2012 function newContentElementOnClick($id, $colPos, $sys_language) {
2013 if ($this->option_newWizard) {
2014 $onClick = "window.location.href='db_new_content_el.php?id=" . $id . '&colPos=' . $colPos . '&sys_language_uid=' . $sys_language . '&uid_pid=' . $id . '&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . "';";
2015 } else {
2016 $onClick = t3lib_BEfunc::editOnClick('&edit[tt_content][' . $id . ']=new&defVals[tt_content][colPos]=' . $colPos . '&defVals[tt_content][sys_language_uid]=' . $sys_language, $this->backPath);
2017 }
2018 return $onClick;
2019 }
2020
2021 /**
2022 * Will create a link on the input string and possible a big button after the string which links to editing in the RTE
2023 * Used for content element content displayed so the user can click the content / "Edit in Rich Text Editor" button
2024 *
2025 * @param string String to link. Must be prepared for HTML output.
2026 * @param array The row.
2027 * @return string If the whole thing was editable ($this->doEdit) $str is return with link around. Otherwise just $str.
2028 * @see getTable_tt_content()
2029 */
2030 function linkEditContent($str, $row) {
2031 $addButton = '';
2032 $onClick = '';
2033
2034 if ($this->doEdit) {
2035 // Setting onclick action for content link:
2036 $onClick = t3lib_BEfunc::editOnClick('&edit[tt_content][' . $row['uid'] . ']=edit', $this->backPath);
2037 }
2038 // Return link
2039 return $onClick ? '<a href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $GLOBALS['LANG']->getLL('edit', 1) . '">' . $str . '</a>' . $addButton : $str;
2040 }
2041
2042 /**
2043 * Adds a button to edit the row in RTE wizard
2044 *
2045 * @param array The row of tt_content element
2046 * @return string Button to click if you want to edit in RTE wizard.
2047 */
2048 function linkRTEbutton($row) {
2049 $params = array();
2050 $params['table'] = 'tt_content';
2051 $params['uid'] = $row['uid'];
2052 $params['pid'] = $row['pid'];
2053 $params['field'] = 'bodytext';
2054 $params['returnUrl'] = t3lib_div::linkThisScript();
2055 $RTEonClick = "window.location.href='" . $this->backPath . "wizard_rte.php?" . t3lib_div::implodeArrayForUrl('', array('P' => $params)) . "';return false;";
2056 $addButton = $this->option_showBigButtons && $this->doEdit ? $GLOBALS['SOBE']->doc->t3Button($RTEonClick, $GLOBALS['LANG']->getLL('editInRTE')) : '';
2057
2058 return $addButton;
2059 }
2060
2061 /**
2062 * Make selector box for creating new translation in a language
2063 * Displays only languages which are not yet present for the current page and
2064 * that are not disabled with page TS.
2065 *
2066 * @param integer Page id for which to create a new language (pages_language_overlay record)
2067 * @return string <select> HTML element (if there were items for the box anyways...)
2068 * @see getTable_tt_content()
2069 */
2070 function languageSelector($id) {
2071 if ($GLOBALS['BE_USER']->check('tables_modify', 'pages_language_overlay')) {
2072
2073 // First, select all
2074 $res = $GLOBALS['SOBE']->exec_languageQuery(0);
2075 $langSelItems = array();
2076 $langSelItems[0] = '
2077 <option value="0"></option>';
2078 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
2079 if ($GLOBALS['BE_USER']->checkLanguageAccess($row['uid'])) {
2080 $langSelItems[$row['uid']] = '
2081 <option value="' . $row['uid'] . '">' . htmlspecialchars($row['title']) . '</option>';
2082 }
2083 }
2084
2085 // Then, subtract the languages which are already on the page:
2086 $res = $GLOBALS['SOBE']->exec_languageQuery($id);
2087 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
2088 unset($langSelItems[$row['uid']]);
2089 }
2090 // Remove disallowed languages
2091 if (count($langSelItems) > 1 &&
2092 !$GLOBALS['BE_USER']->user['admin'] &&
2093 strlen($GLOBALS['BE_USER']->groupData['allowed_languages'])) {
2094
2095 $allowed_languages = array_flip(explode(',', $GLOBALS['BE_USER']->groupData['allowed_languages']));
2096
2097 if (count($allowed_languages)) {
2098 foreach ($langSelItems as $key => $value) {
2099 if (!isset($allowed_languages[$key]) && $key != 0) {
2100 unset($langSelItems[$key]);
2101 }
2102 }
2103 }
2104 }
2105 // Remove disabled languages
2106 $modSharedTSconfig = t3lib_BEfunc::getModTSconfig($id, 'mod.SHARED');
2107 $disableLanguages = isset($modSharedTSconfig['properties']['disableLanguages']) ? t3lib_div::trimExplode(',', $modSharedTSconfig['properties']['disableLanguages'], 1) : array();
2108 if (count($langSelItems) && count($disableLanguages)) {
2109 foreach ($disableLanguages as $language) {
2110 if ($language != 0 && isset($langSelItems[$language])) {
2111 unset($langSelItems[$language]);
2112 }
2113 }
2114 }
2115
2116 // If any languages are left, make selector:
2117 if (count($langSelItems) > 1) {
2118 $onChangeContent = 'window.location.href=\'' . $this->backPath . 'alt_doc.php?&edit[pages_language_overlay][' . $id . ']=new&overrideVals[pages_language_overlay][doktype]=' . (int) $this->pageRecord['doktype'] . '&overrideVals[pages_language_overlay][sys_language_uid]=\'+this.options[this.selectedIndex].value+\'&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')) . '\'';
2119 return $GLOBALS['LANG']->getLL('new_language', 1) . ': <select name="createNewLanguage" onchange="' . htmlspecialchars($onChangeContent) . '">
2120 ' . implode('', $langSelItems) . '
2121 </select><br /><br />';
2122 }
2123 }
2124 }
2125
2126 /**
2127 * Traverse the result pointer given, adding each record to array and setting some internal values at the same time.
2128 *
2129 * @param pointer SQL result pointer for select query.
2130 * @param string Table name defaulting to tt_content
2131 * @return array The selected rows returned in this array.
2132 */
2133 function getResult($result, $table = 'tt_content') {
2134
2135 // Initialize:
2136 $editUidList = '';
2137 $recs = Array();
2138 $nextTree = $this->nextThree;
2139 $c = 0;
2140 $output = Array();
2141
2142 // Traverse the result:
2143 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
2144
2145 t3lib_BEfunc::workspaceOL($table, $row, -99, TRUE);
2146
2147 if ($row) {
2148 // Add the row to the array:
2149 $output[] = $row;
2150
2151 // Set an internal register:
2152 $recs[$c] = $row['uid'];
2153
2154 // Create the list of the next three ids (for editing links...)
2155 for ($a = 0; $a < $nextTree; $a++) {
2156 if (isset($recs[$c - $a])) {
2157 $this->tt_contentData['nextThree'][$recs[$c - $a]] .= $row['uid'] . ',';
2158 }
2159 }
2160
2161 // Set next/previous ids:
2162 if (isset($recs[$c - 1])) {
2163 if (isset($recs[$c - 2])) {
2164 $this->tt_contentData['prev'][$row['uid']] = -$recs[$c - 2];
2165 } else {
2166 $this->tt_contentData['prev'][$row['uid']] = $row['pid'];
2167 }
2168 $this->tt_contentData['next'][$recs[$c - 1]] = -$row['uid'];
2169 }
2170 $c++;
2171 }
2172 }
2173
2174 // Return selected records
2175 return $output;
2176 }
2177
2178
2179 /**********************************
2180 *
2181 * Additional functions; Message board items (tt_board)
2182 *
2183 **********************************/
2184
2185 /**
2186 * Traverses recursively a branch in a message board.
2187 *
2188 * @param array Array of rows (build up recursively)
2189 * @param integer tt_content parent uid
2190 * @param integer Page id
2191 * @param string Additional query part.
2192 * @param string HTML content to prefix items with (to draw the proper tree-graphics)
2193 * @return array $theRows, but with added content
2194 */
2195 function tt_board_getTree($theRows, $parent, $pid, $qWhere, $treeIcons) {
2196
2197 // Select tt_board elements:
2198 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'tt_board', 'pid=' . intval($pid) . ' AND parent=' . intval($parent) . $qWhere, '', 'crdate');
2199
2200 // Traverse the results:
2201 $c = 0;
2202 $rc = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
2203 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
2204 $c++;
2205 $row['treeIcons'] = $treeIcons . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . ($rc == $c ? 'joinbottom.gif' : 'join.gif'), 'width="18" height="16"') . ' alt="" />';
2206 $theRows[] = $row;
2207
2208 // Get the branch
2209 $theRows = $this->tt_board_getTree(
2210 $theRows,
2211 $row['uid'],
2212 $row['pid'],
2213 $qWhere,
2214 $treeIcons . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . ($rc == $c ? 'blank.gif' : 'line.gif'), 'width="18" height="16"') . ' alt="" />'
2215 );
2216 }
2217
2218 // Return modified rows:
2219 return $theRows;
2220 }
2221
2222 /**
2223 * Adds an element to the tt_board listing:
2224 *
2225 * @param string Table name
2226 * @param array The record row
2227 * @param string Reply count, if applicable.
2228 * @return string Return content of element (table row)
2229 */
2230 function tt_board_drawItem($table, $row, $re) {
2231
2232 // Building data-arary with content:
2233 $theData = Array();
2234 $theData['subject'] = t3lib_div::fixed_lgd_cs(htmlspecialchars($row['subject']), 25) . '&nbsp; &nbsp;';
2235 $theData['author'] = t3lib_div::fixed_lgd_cs(htmlspecialchars($row['author']), 15) . '&nbsp; &nbsp;';
2236 $theData['date'] = t3lib_div::fixed_lgd_cs(t3lib_BEfunc::datetime($row['crdate']), 20) . '&nbsp; &nbsp;';
2237 $theData['age'] = t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME'] - $row['crdate'], $this->agePrefixes) . '&nbsp; &nbsp;';
2238 if ($re) {
2239 $theData['replys'] = $re;
2240 }
2241
2242 // Subject is built:
2243 $theData['subject'] =
2244 $row['treeIcons'] .
2245 $this->getIcon($table, $row) .
2246 $theData['subject'];
2247
2248 // Adding element:
2249 return $this->addelement(1, '', $theData);
2250 }
2251
2252
2253 /********************************
2254 *
2255 * Various helper functions
2256 *
2257 ********************************/
2258
2259 /**
2260 * Counts and returns the number of records on the page with $pid
2261 *
2262 * @param string Table name
2263 * @param integer Page id
2264 * @return integer Number of records.
2265 */
2266 function numberOfRecords($table, $pid) {
2267 if ($GLOBALS['TCA'][$table]) {
2268 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
2269 'uid',
2270 $table,
2271 'pid=' . intval($pid) .
2272 t3lib_BEfunc::deleteClause($table) .
2273 t3lib_BEfunc::versioningPlaceholderClause($table)
2274 );
2275 }
2276 return intval($count);
2277 }
2278
2279 /**
2280 * Processing of larger amounts of text (usually from RTE/bodytext fields) with word wrapping etc.
2281 *
2282 * @param string Input string
2283 * @return string Output string
2284 */
2285 function renderText($input) {
2286 $input = $this->strip_tags($input, true);
2287 $input = t3lib_div::fixed_lgd_cs($input, 1500);
2288 return nl2br(htmlspecialchars(trim($this->wordWrapper($input))));
2289 }
2290
2291 /**
2292 * Creates the icon image tag for record from table and wraps it in a link which will trigger the click menu.
2293 *
2294 * @param string Table name
2295 * @param array Record array
2296 * @param string Record title (NOT USED)
2297 * @return string HTML for the icon
2298 */
2299 function getIcon($table, $row) {
2300
2301 // Initialization
2302 $alttext = t3lib_BEfunc::getRecordIconAltText($row, $table);
2303 $iconImg = t3lib_iconWorks::getSpriteIconForRecord($table, $row, array('title' => $alttext));
2304 $this->counter++;
2305
2306 // The icon with link
2307 $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, $table, $row['uid']);
2308
2309 return $theIcon;
2310 }
2311
2312 /**
2313 * Creates processed values for all fieldnames in $fieldList based on values from $row array.
2314 * The result is 'returned' through $info which is passed as a reference
2315 *
2316 * @param string Table name
2317 * @param string Commalist of fields.
2318 * @param array Record from which to take values for processing.
2319 * @param array Array to which the processed values are added.
2320 * @return void
2321 */
2322 function getProcessedValue($table, $fieldList, $row, &$info) {
2323
2324 // Splitting values from $fieldList:
2325 $fieldArr = explode(',', $fieldList);
2326
2327 // Traverse fields from $fieldList:
2328 foreach ($fieldArr as $field) {
2329 if ($row[$field]) {
2330 $info[] = htmlspecialchars($this->itemLabels[$field]) . ' ' . htmlspecialchars(t3lib_BEfunc::getProcessedValue($table, $field, $row[$field]));
2331 }
2332 }
2333 }
2334
2335 /**
2336 * Returns true, if the record given as parameters is NOT visible based on hidden/starttime/endtime (if available)
2337 *
2338 * @param string Tablename of table to test
2339 * @param array Record row.
2340 * @return boolean Returns true, if disabled.
2341 */
2342 function isDisabled($table, $row) {
2343 global $TCA;
2344 if (
2345 ($TCA[$table]['ctrl']['enablecolumns']['disabled'] && $row[$TCA[$table]['ctrl']['enablecolumns']['disabled']]) ||
2346 ($TCA[$table]['ctrl']['enablecolumns']['starttime'] && $row[$TCA[$table]['ctrl']['enablecolumns']['starttime']] > $GLOBALS['EXEC_TIME']) ||
2347 ($TCA[$table]['ctrl']['enablecolumns']['endtime'] && $row[$TCA[$table]['ctrl']['enablecolumns']['endtime']] && $row[$TCA[$table]['ctrl']['enablecolumns']['endtime']] < $GLOBALS['EXEC_TIME'])
2348 ) {
2349 return true;
2350 }
2351 }
2352
2353 /**
2354 * Will perform "word-wrapping" on the input string. What it does is to split by space or linebreak, then find any word longer than $max and if found, a hyphen is inserted.
2355 * Works well on normal texts, little less well when HTML is involved (since much HTML will have long strings that will be broken).
2356 *
2357 * @param string Content to word-wrap.
2358 * @param integer Max number of chars in a word before it will be wrapped.
2359 * @param string Character to insert when wrapping.
2360 * @return string Processed output.
2361 */
2362 function wordWrapper($content, $max = 50, $char = ' -') {
2363 $array = preg_split('/[ ' . LF . ']/', $content);
2364 foreach ($array as $val) {
2365 if (strlen($val) > $max) {
2366 $content = str_replace($val, substr(chunk_split($val, $max, $char), 0, -1), $content);
2367 }
2368 }
2369 return $content;
2370 }
2371
2372 /**
2373 * Returns icon for "no-edit" of a record.
2374 * Basically, the point is to signal that this record could have had an edit link if the circumstances were right. A placeholder for the regular edit icon...
2375 *
2376 * @param string Label key from LOCAL_LANG
2377 * @return string IMG tag for icon.
2378 */
2379 function noEditIcon($label = 'noEditItems') {
2380 return t3lib_iconWorks::getSpriteIcon('status-edit-read-only', array('title' => $GLOBALS['LANG']->getLL($label, TRUE)));
2381 }
2382
2383 /**
2384 * Function, which fills in the internal array, $this->allowedTableNames with all tables to which the user has access. Also a set of standard tables (pages, static_template, sys_filemounts, etc...) are filtered out. So what is left is basically all tables which makes sense to list content from.
2385 *
2386 * @return void
2387 */
2388 function cleanTableNames() {
2389 global $TCA;
2390
2391 // Get all table names:
2392 $tableNames = array_flip(array_keys($TCA));
2393
2394 // Unset common names:
2395 unset($tableNames['pages']);
2396 unset($tableNames['static_template']);
2397 unset($tableNames['sys_filemounts']);
2398 unset($tableNames['sys_action']);
2399 unset($tableNames['sys_workflows']);
2400 unset($tableNames['be_users']);
2401 unset($tableNames['be_groups']);
2402
2403 $this->allowedTableNames = array();
2404
2405 // Traverse table names and set them in allowedTableNames array IF they can be read-accessed by the user.
2406 if (is_array($tableNames)) {
2407 foreach ($tableNames as $k => $v) {
2408 if ($GLOBALS['BE_USER']->check('tables_select', $k)) {
2409 $this->allowedTableNames['table_' . $k] = $k;
2410 }
2411 }
2412 }
2413 }
2414
2415 /**
2416 * Checking if the RTE is available/enabled for a certain table/field and if so, it returns true.
2417 * Used to determine if the RTE button should be displayed.
2418 *
2419 * @param string Table name
2420 * @param array Record row (needed, if there are RTE dependencies based on other fields in the record)
2421 * @param string Field name
2422 * @return boolean Returns true if the rich text editor would be enabled/available for the field name specified.
2423 */
2424 function isRTEforField($table, $row, $field) {
2425 $specConf = $this->getSpecConfForField($table, $row, $field);
2426 $p = t3lib_BEfunc::getSpecConfParametersFromArray($specConf['rte_transform']['parameters']);
2427 if (isset($specConf['richtext']) && (!$p['flag'] || !$row[$p['flag']])) {
2428 t3lib_BEfunc::fixVersioningPid($table, $row);
2429 list($tscPID, $thePidValue) = t3lib_BEfunc::getTSCpid($table, $row['uid'], $row['pid']);
2430 if ($thePidValue >= 0) { // If the pid-value is not negative (that is, a pid could NOT be fetched)
2431 $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE', t3lib_BEfunc::getPagesTSconfig($tscPID));
2432 $RTEtypeVal = t3lib_BEfunc::getTCAtypeValue($table, $row);
2433 $thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'], $table, $field, $RTEtypeVal);
2434 if (!$thisConfig['disabled']) {
2435 return TRUE;
2436 }
2437 }
2438 }
2439
2440 return FALSE;
2441 }
2442
2443 /**
2444 * Returns "special" configuration from the "types" configuration in TCA for the record given by tablename/fieldname.
2445 * Used by isRTEforField() in the process of finding whether a field has RTE enabled or not.
2446 *
2447 * @param string Table name
2448 * @param array Record array
2449 * @param string Field name
2450 * @return array Spec. conf (if available)
2451 * @access private
2452 * @see isRTEforField()
2453 */
2454 function getSpecConfForField($table, $row, $field) {
2455
2456 // Get types-configuration for the record:
2457 $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table, $row);
2458
2459 // Find the given field and return the spec key value if found:
2460 if (is_array($types_fieldConfig)) {
2461 foreach ($types_fieldConfig as $vconf) {
2462 if ($vconf['field'] == $field) {
2463 return $vconf['spec'];
2464 }
2465 }
2466 }
2467 }
2468
2469
2470 /*****************************************
2471 *
2472 * External renderings
2473 *
2474 *****************************************/
2475
2476 /**
2477 * Creates an info-box for the current page (identified by input record).
2478 *
2479 * @param array Page record
2480 * @param boolean If set, there will be shown an edit icon, linking to editing of the page properties.
2481 * @return string HTML for the box.
2482 */
2483 function getPageInfoBox($rec, $edit = 0) {
2484 global $LANG;
2485
2486 // If editing of the page properties is allowed:
2487 if ($edit) {
2488 $params = '&edit[pages][' . $rec['uid'] . ']=edit';
2489 $editIcon = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc::editOnClick($params, $this->backPath)) . '" title="' . $GLOBALS['LANG']->getLL('edit', TRUE) . '">' .
2490 t3lib_iconWorks::getSpriteIcon('actions-document-open') .
2491 '</a>';
2492 } else {
2493 $editIcon = $this->noEditIcon('noEditPage');
2494 }
2495
2496 // Setting page icon, link, title:
2497 $outPutContent = t3lib_iconWorks::getSpriteIconForRecord('pages', $rec, array('title' => t3lib_BEfunc::titleAttribForPages($rec))) .
2498 $editIcon .
2499 '&nbsp;' .
2500 htmlspecialchars($rec['title']);
2501
2502
2503 // Init array where infomation is accumulated as label/value pairs.
2504 $lines = array();
2505
2506 // Owner user/group:
2507 if ($this->pI_showUser) {
2508 // User:
2509 $users = t3lib_BEfunc::getUserNames('username,usergroup,usergroup_cached_list,uid,realName');
2510 $groupArray = explode(',', $GLOBALS['BE_USER']->user['usergroup_cached_list']);
2511 $users = t3lib_BEfunc::blindUserNames($users, $groupArray);
2512 $lines[] = array($LANG->getLL('pI_crUser') . ':', htmlspecialchars($users[$rec['cruser_id']]['username']) . ' (' . $users[$rec['cruser_id']]['realName'] . ')');
2513 }
2514
2515 // Created:
2516 $lines[] = array(
2517 $LANG->getLL('pI_crDate') . ':',
2518 t3lib_BEfunc::datetime($rec['crdate']) . ' (' . t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME'] - $rec['crdate'], $this->agePrefixes) . ')',
2519 );
2520
2521 // Last change:
2522 $lines[] = array(
2523 $LANG->getLL('pI_lastChange') . ':',
2524 t3lib_BEfunc::datetime($rec['tstamp']) . ' (' . t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME'] - $rec['tstamp'], $this->agePrefixes) . ')',
2525 );
2526
2527 // Last change of content:
2528 if ($rec['SYS_LASTCHANGED']) {
2529 $lines[] = array(
2530 $LANG->getLL('pI_lastChangeContent') . ':',
2531 t3lib_BEfunc::datetime($rec['SYS_LASTCHANGED']) . ' (' . t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME'] - $rec['SYS_LASTCHANGED'], $this->agePrefixes) . ')',
2532 );
2533 }
2534
2535 // Spacer:
2536 $lines[] = '';
2537
2538 // Display contents of certain page fields, if any value:
2539 $dfields = explode(',', 'alias,target,hidden,starttime,endtime,fe_group,no_cache,cache_timeout,newUntil,lastUpdated,subtitle,keywords,description,abstract,author,author_email');
2540 foreach ($dfields as $fV) {
2541 if ($rec[$fV]) {
2542 $lines[] = array($GLOBALS['LANG']->sL(t3lib_BEfunc::getItemLabel('pages', $fV)), t3lib_BEfunc::getProcessedValue('pages', $fV, $rec[$fV]));
2543 }
2544 }
2545
2546 // Page hits (depends on "sys_stat" extension)
2547 if ($this->pI_showStat && t3lib_extMgm::isLoaded('sys_stat')) {
2548
2549 // Counting total hits:
2550 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'sys_stat', 'page_id=' . intval($rec['uid']));
2551 if ($count) {
2552
2553 // Get min/max
2554 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('min(tstamp) AS min,max(tstamp) AS max', 'sys_stat', 'page_id=' . intval($rec['uid']));
2555 $rrow2 = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
2556
2557 $lines[] = '';
2558 $lines[] = array($LANG->getLL('pI_hitsPeriod') . ':', t3lib_BEfunc::date($rrow2[0]) . ' - ' . t3lib_BEfunc::date($rrow2[1]) . ' (' . t3lib_BEfunc::calcAge($rrow2[1] - $rrow2[0], $this->agePrefixes) . ')');
2559 $lines[] = array($LANG->getLL('pI_hitsTotal') . ':', $rrow2[0]);
2560
2561
2562 // Last 10 days
2563 $nextMidNight = mktime(0, 0, 0) + 1 * 3600 * 24;
2564
2565 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*), FLOOR((' . $nextMidNight . '-tstamp)/(24*3600)) AS day', 'sys_stat', 'page_id=' . intval($rec['uid']) . ' AND tstamp>' . ($nextMidNight - 10 * 24 * 3600), 'day');
2566 $days = array();
2567 while ($rrow = $GLOBALS['TYPO3_DB']->sql_fetch_row($res)) {
2568 $days[$rrow[1]] = $rrow[0];
2569 }
2570
2571 $headerH = array();
2572 $contentH = array();
2573 for ($a = 9; $a >= 0; $a--) {
2574 $headerH[] = '
2575 <td class="bgColor5" nowrap="nowrap">&nbsp;' . date('d', $nextMidNight - ($a + 1) * 24 * 3600) . '&nbsp;</td>';
2576 $contentH[] = '
2577 <td align="center">' . ($days[$a] ? intval($days[$a]) : '-') . '</td>';
2578 }
2579
2580 // Compile first hit-table (last 10 days)
2581 $hitTable = '
2582 <table border="0" cellpadding="0" cellspacing="1" class="typo3-page-hits">
2583 <tr>' . implode('', $headerH) . '</tr>
2584 <tr>' . implode('', $contentH) . '</tr>
2585 </table>';
2586 $lines[] = array($LANG->getLL('pI_hits10days') . ':', $hitTable, 1);
2587
2588
2589 // Last 24 hours
2590 $nextHour = mktime(date('H'), 0, 0) + 3600;
2591 $hours = 16;
2592
2593 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*), FLOOR((' . $nextHour . '-tstamp)/3600) AS hours', 'sys_stat', 'page_id=' . intval($rec['uid']) . ' AND tstamp>' . ($nextHour - $hours * 3600), 'hours');
2594 $days = array();
2595 while ($rrow = $GLOBALS['TYPO3_DB']->sql_fetch_row($res)) {
2596 $days[$rrow[1]] = $rrow[0];
2597 }
2598
2599 $headerH = array();
2600 $contentH = array();
2601 for ($a = ($hours - 1); $a >= 0; $a--) {
2602 $headerH[] = '
2603 <td class="bgColor5" nowrap="nowrap">&nbsp;' . intval(date('H', $nextHour - ($a + 1) * 3600)) . '&nbsp;</td>';
2604 $contentH[] = '
2605 <td align="center">' . ($days[$a] ? intval($days[$a]) : '-') . '</td>';
2606 }
2607
2608 // Compile second hit-table (last 24 hours)
2609 $hitTable = '
2610 <table border="0" cellpadding="0" cellspacing="1" class="typo3-page-stat">
2611 <tr>' . implode('', $headerH) . '</tr>
2612 <tr>' . implode('', $contentH) . '</tr>
2613 </table>';
2614 $lines[] = array($LANG->getLL('pI_hits24hours') . ':', $hitTable, 1);
2615 }
2616 }
2617
2618
2619 // Finally, wrap the elements in the $lines array in table cells/rows
2620 foreach ($lines as $fV) {
2621 if (is_array($fV)) {
2622 if (!$fV[2]) {
2623 $fV[1] = htmlspecialchars($fV[1]);
2624 }
2625 $out .= '
2626 <tr>
2627 <td class="bgColor4" nowrap="nowrap"><strong>' . htmlspecialchars($fV[0]) . '&nbsp;&nbsp;</strong></td>
2628 <td class="bgColor4">' . $fV[1] . '</td>
2629 </tr>';
2630 } else {
2631 $out .= '
2632 <tr>
2633 <td colspan="2"><img src="clear.gif" width="1" height="3" alt="" /></td>
2634 </tr>';
2635 }
2636 }
2637
2638 // Wrap table tags around...
2639 $outPutContent .= '
2640
2641
2642
2643 <!--
2644 Page info box:
2645 -->
2646 <table border="0" cellpadding="0" cellspacing="1" id="typo3-page-info">
2647 ' . $out . '
2648 </table>';
2649
2650 // ... and return it.
2651 return $outPutContent;
2652 }
2653
2654 /**
2655 * Creates a menu of the tables that can be listed by this function
2656 * Only tables which has records on the page will be included.
2657 * Notice: The function also fills in the internal variable $this->activeTables with icon/titles.
2658 *
2659 * @param integer Page id from which we are listing records (the function will look up if there are records on the page)
2660 * @return string HTML output.
2661 */
2662 function getTableMenu($id) {
2663 global $TCA;
2664
2665 // Initialize:
2666 $this->activeTables = array();
2667 $theTables = explode(',', 'tt_content,fe_users,tt_address,tt_links,tt_board,tt_guest,tt_calender,tt_products,tt_news'); // NOTICE: This serves double function: Both being tables names (all) and for most others also being extension keys for the extensions they are related to!
2668
2669 // External tables:
2670 if (is_array($this->externalTables)) {
2671 $theTables = array_unique(array_merge($theTables, array_keys($this->externalTables)));
2672 }
2673
2674 // Traverse tables to check:
2675 foreach ($theTables as $tName) {
2676
2677 // Check access and whether the proper extensions are loaded:
2678 if ($GLOBALS['BE_USER']->check('tables_select', $tName) && (t3lib_extMgm::isLoaded($tName) || t3lib_div::inList('fe_users,tt_content', $tName) || isset($this->externalTables[$tName]))) {
2679
2680 // Make query to count records from page:
2681 $c = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
2682 'uid',
2683 $tName,
2684 'pid=' . intval($id) .
2685 t3lib_BEfunc::deleteClause($tName) .
2686 t3lib_BEfunc::versioningPlaceholderClause($tName)
2687 );
2688
2689 // If records were found (or if "tt_content" is the table...):
2690 if ($c || t3lib_div::inList('tt_content', $tName)) {
2691
2692 // Add row to menu:
2693 $out .= '
2694 <td><a href="#' . $tName . '"></a>' .
2695 t3lib_iconWorks::getSpriteIconForRecord($tName, Array(), array('title' => $GLOBALS['LANG']->sL($TCA[$tName]['ctrl']['title'], 1))) .
2696 '</td>';
2697
2698 // ... and to the internal array, activeTables we also add table icon and title (for use elsewhere)
2699 $this->activeTables[$tName] =
2700 t3lib_iconWorks::getSpriteIconForRecord($tName, Array(), array('title' => $GLOBALS['LANG']->sL($TCA[$tName]['ctrl']['title'], 1) . ': ' . $c . ' ' . $GLOBALS['LANG']->getLL('records', 1))) .
2701 '&nbsp;' .
2702 $GLOBALS['LANG']->sL($TCA[$tName]['ctrl']['title'], 1);
2703 }
2704 }
2705 }
2706
2707 // Wrap cells in table tags:
2708 $out = '
2709
2710
2711
2712 <!--
2713 Menu of tables on the page (table menu)
2714 -->
2715 <table border="0" cellpadding="0" cellspacing="0" id="typo3-page-tblMenu">
2716 <tr>' . $out . '
2717 </tr>
2718 </table>';
2719
2720 // Return the content:
2721 return $out;
2722 }
2723
2724 /**
2725 * Enhancement for the strip_tags function that provides the feature to fill in empty tags.
2726 * Example <link email@hostname.com></link> is accepted by TYPO3 but would not displayed in the Backend otherwise.
2727 *
2728 * @param string Input string
2729 * @param boolean If true, empty tags will be filled with the first attribute of the tag before.
2730 * @return string Input string with all HTML and PHP tags stripped
2731 */
2732 function strip_tags($content, $fillEmptyContent = false) {
2733 if ($fillEmptyContent && strstr($content, '><')) {
2734 $content = preg_replace('/(<[^ >]* )([^ >]*)([^>]*>)(<\/[^>]*>)/', '$1$2$3$2$4', $content);
2735 }
2736 $content = preg_replace('/<br.?\/?>/', LF, $content);
2737
2738 return strip_tags($content);
2739 }
2740 }
2741