NewRecordController.php 24.7 KB
Newer Older
1
2
3
<?php
namespace TYPO3\CMS\Backend\Controller;

4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
8
9
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
10
 *
11
12
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
15
 * The TYPO3 project - inspiring people to share!
 */
16

Nicole Cordes's avatar
Nicole Cordes committed
17
18
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\Utility\IconUtility;
19
use TYPO3\CMS\Core\Database\DatabaseConnection;
Nicole Cordes's avatar
Nicole Cordes committed
20
21
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
23
24
25
use TYPO3\CMS\Backend\Template\DocumentTemplate;
use TYPO3\CMS\Backend\Tree\View\PagePositionMap;
use TYPO3\CMS\Backend\Tree\View\NewRecordPageTreeView;
use TYPO3\CMS\Core\Utility\HttpUtility;
Nicole Cordes's avatar
Nicole Cordes committed
26

27
28
29
30
31
32
/**
 * Script class for 'db_new'
 */
class NewRecordController {

	/**
33
	 * @var array
34
35
36
37
	 */
	public $pageinfo;

	/**
38
	 * @var array
39
40
41
	 */
	public $pidInfo;

42
43
44
45
46
	/**
	 * @var array
	 */
	protected $newRecordSortList;

47
	/**
48
	 * @var int
49
50
51
52
	 */
	public $newPagesInto;

	/**
53
	 * @var int
54
55
56
57
	 */
	public $newContentInto;

	/**
58
	 * @var int
59
60
61
62
63
64
	 */
	public $newPagesAfter;

	/**
	 * Determines, whether "Select Position" for new page should be shown
	 *
65
	 * @var bool
66
67
68
69
	 */
	protected $newPagesSelectPosition = TRUE;

	/**
70
	 * @var array
71
72
73
74
	 */
	public $web_list_modTSconfig;

	/**
75
	 * @var array
76
77
78
79
	 */
	public $allowedNewTables;

	/**
80
	 * @var array
81
82
83
84
	 */
	public $deniedNewTables;

	/**
85
	 * @var array
86
87
88
89
	 */
	public $web_list_modTSconfig_pid;

	/**
90
	 * @var array
91
92
93
94
	 */
	public $allowedNewTables_pid;

	/**
95
	 * @var array
96
97
98
99
	 */
	public $deniedNewTables_pid;

	/**
100
	 * @var string
101
102
103
104
	 */
	public $code;

	/**
105
	 * @var string
106
107
108
109
	 */
	public $R_URI;

	/**
110
	 * @var int
111
112
113
114
	 */
	public $id;

	/**
115
	 * @var string
116
117
118
119
	 */
	public $returnUrl;

	/**
120
121
	 * pagesOnly flag.
	 *
122
	 * @var int
123
124
125
126
	 */
	public $pagesOnly;

	/**
127
	 * @var string
128
129
130
131
132
133
	 */
	public $perms_clause;

	/**
	 * Document template object
	 *
134
	 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
135
136
137
138
	 */
	public $doc;

	/**
139
140
	 * Accumulated HTML output
	 *
141
	 * @var string
142
143
144
145
	 */
	public $content;

	/**
146
	 * @var array
147
148
149
	 */
	public $tRows;

150
151
152
153
154
	/**
	 * Constructor
	 */
	public function __construct() {
		$GLOBALS['SOBE'] = $this;
155
		$this->getLanguageService()->includeLLFile('EXT:lang/locallang_misc.xlf');
156
157
158
159
160
		$GLOBALS['BACK_PATH'] = '';

		$this->init();
	}

161
162
163
164
165
	/**
	 * Constructor function for the class
	 *
	 * @return void
	 */
166
	protected function init() {
167
		$beUser = $this->getBackendUserAuthentication();
168
		// Page-selection permission clause (reading)
169
		$this->perms_clause = $beUser->getPagePermsClause(1);
170
		// This will hide records from display - it has nothing to do with user rights!!
171
172
		if ($pidList = $beUser->getTSConfigVal('options.hideRecords.pages')) {
			if ($pidList = $this->getDatabaseConnection()->cleanIntList($pidList)) {
173
				$this->perms_clause .= ' AND pages.uid NOT IN (' . $pidList . ')';
174
175
176
177
			}
		}
		// Setting GPvars:
		// The page id to operate from
178
		$this->id = (int)GeneralUtility::_GP('id');
Nicole Cordes's avatar
Nicole Cordes committed
179
180
		$this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'));
		$this->pagesOnly = GeneralUtility::_GP('pagesOnly');
181
		// Create instance of template class for output
182
		$this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
183
		$this->doc->backPath = $GLOBALS['BACK_PATH'];
184
		$this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/db_new.html');
185
186
187
188
189
		$this->doc->JScode = '';
		// Setting up the context sensitive menu:
		$this->doc->getContextMenuCode();
		// Creating content
		$this->content = '';
190
		$this->content .= $this->doc->header($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:db_new.php.pagetitle'));
191
192
		// Id a positive id is supplied, ask for the page record with permission information contained:
		if ($this->id > 0) {
Nicole Cordes's avatar
Nicole Cordes committed
193
			$this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
194
195
196
197
		}
		// If a page-record was returned, the user had read-access to the page.
		if ($this->pageinfo['uid']) {
			// Get record of parent page
Nicole Cordes's avatar
Nicole Cordes committed
198
			$this->pidInfo = BackendUtility::getRecord('pages', $this->pageinfo['pid']);
199
			// Checking the permissions for the user with regard to the parent page: Can he create new pages, new content record, new page after?
200
			if ($beUser->doesUserHaveAccess($this->pageinfo, 8)) {
201
202
				$this->newPagesInto = 1;
			}
203
			if ($beUser->doesUserHaveAccess($this->pageinfo, 16)) {
204
205
				$this->newContentInto = 1;
			}
206
			if (($beUser->isAdmin() || is_array($this->pidInfo)) && $beUser->doesUserHaveAccess($this->pidInfo, 8)) {
207
208
				$this->newPagesAfter = 1;
			}
209
		} elseif ($beUser->isAdmin()) {
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
			// Admins can do it all
			$this->newPagesInto = 1;
			$this->newContentInto = 1;
			$this->newPagesAfter = 0;
		} else {
			// People with no permission can do nothing
			$this->newPagesInto = 0;
			$this->newContentInto = 0;
			$this->newPagesAfter = 0;
		}
	}

	/**
	 * Main processing, creating the list of new record tables to select from
	 *
	 * @return void
	 */
	public function main() {
		// If there was a page - or if the user is admin (admins has access to the root) we proceed:
229
		if ($this->pageinfo['uid'] || $this->getBackendUserAuthentication()->isAdmin()) {
230
			// Acquiring TSconfig for this module/current page:
Nicole Cordes's avatar
Nicole Cordes committed
231
			$this->web_list_modTSconfig = BackendUtility::getModTSconfig($this->pageinfo['uid'], 'mod.web_list');
232
233
			$this->allowedNewTables = GeneralUtility::trimExplode(',', $this->web_list_modTSconfig['properties']['allowedNewTables'], TRUE);
			$this->deniedNewTables = GeneralUtility::trimExplode(',', $this->web_list_modTSconfig['properties']['deniedNewTables'], TRUE);
234
			// Acquiring TSconfig for this module/parent page:
Nicole Cordes's avatar
Nicole Cordes committed
235
			$this->web_list_modTSconfig_pid = BackendUtility::getModTSconfig($this->pageinfo['pid'], 'mod.web_list');
236
237
			$this->allowedNewTables_pid = GeneralUtility::trimExplode(',', $this->web_list_modTSconfig_pid['properties']['allowedNewTables'], TRUE);
			$this->deniedNewTables_pid = GeneralUtility::trimExplode(',', $this->web_list_modTSconfig_pid['properties']['deniedNewTables'], TRUE);
238
239
240
241
242
243
244
245
246
			// More init:
			if (!$this->showNewRecLink('pages')) {
				$this->newPagesInto = 0;
			}
			if (!$this->showNewRecLink('pages', $this->allowedNewTables_pid, $this->deniedNewTables_pid)) {
				$this->newPagesAfter = 0;
			}
			// Set header-HTML and return_url
			if (is_array($this->pageinfo) && $this->pageinfo['uid']) {
Nicole Cordes's avatar
Nicole Cordes committed
247
				$iconImgTag = IconUtility::getSpriteIconForRecord('pages', $this->pageinfo, array('title' => htmlspecialchars($this->pageinfo['_thePath'])));
248
249
				$title = strip_tags($this->pageinfo[$GLOBALS['TCA']['pages']['ctrl']['label']]);
			} else {
Nicole Cordes's avatar
Nicole Cordes committed
250
				$iconImgTag = IconUtility::getSpriteIcon('apps-pagetree-root', array('title' => htmlspecialchars($this->pageinfo['_thePath'])));
251
252
				$title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
			}
Nicole Cordes's avatar
Nicole Cordes committed
253
			$this->code = '<span class="typo3-moduleHeader">' . $this->doc->wrapClickMenuOnIcon($iconImgTag, 'pages', $this->pageinfo['uid']) . htmlspecialchars(GeneralUtility::fixed_lgd_cs($title, 45)) . '</span><br />';
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
			$this->R_URI = $this->returnUrl;
			// GENERATE the HTML-output depending on mode (pagesOnly is the page wizard)
			// Regular new element:
			if (!$this->pagesOnly) {
				$this->regularNew();
			} elseif ($this->showNewRecLink('pages')) {
				// Pages only wizard
				$this->pagesOnly();
			}
			// Add all the content to an output section
			$this->content .= $this->doc->section('', $this->code);
			// Setting up the buttons and markers for docheader
			$docHeaderButtons = $this->getButtons();
			$markers['CSH'] = $docHeaderButtons['csh'];
			$markers['CONTENT'] = $this->content;
			// Build the <body> for the module
270
			$this->content = $this->doc->startPage($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:db_new.php.pagetitle'));
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
			$this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
			$this->content .= $this->doc->endPage();
			$this->content = $this->doc->insertStylesAndJS($this->content);
		}
	}

	/**
	 * Create the panel of buttons for submitting the form or otherwise perform operations.
	 *
	 * @return array All available buttons as an assoc. array
	 */
	protected function getButtons() {
		$buttons = array(
			'csh' => '',
			'back' => '',
			'view' => '',
			'new_page' => ''
		);
		// Regular new element:
		if (!$this->pagesOnly) {
			// New page
			if ($this->showNewRecLink('pages')) {
Wouter Wolters's avatar
Wouter Wolters committed
293
				$buttons['new_page'] = '<a href="' . htmlspecialchars(GeneralUtility::linkThisScript(array('pagesOnly' => '1'))) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newPage', TRUE) . '">' . IconUtility::getSpriteIcon('actions-page-new') . '</a>';
294
295
			}
			// CSH
Benni Mack's avatar
Benni Mack committed
296
			$buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'new_regular');
297
298
299
		} elseif ($this->showNewRecLink('pages')) {
			// Pages only wizard
			// CSH
Benni Mack's avatar
Benni Mack committed
300
			$buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'new_pages');
301
302
303
		}
		// Back
		if ($this->R_URI) {
304
			$buttons['back'] = '<a href="' . htmlspecialchars($this->R_URI) . '" class="typo3-goBack" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.goBack', TRUE) . '">' . IconUtility::getSpriteIcon('actions-view-go-back') . '</a>';
305
306
307
		}
		if (is_array($this->pageinfo) && $this->pageinfo['uid']) {
			// View
308
			$buttons['view'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($this->pageinfo['uid'], $this->doc->backPath, BackendUtility::BEgetRootLine($this->pageinfo['uid']))) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-view') . '</a>';
309
310
311
312
313
314
315
316
317
318
		}
		return $buttons;
	}

	/**
	 * Creates the position map for pages wizard
	 *
	 * @return void
	 */
	public function pagesOnly() {
319
		$numberOfPages = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'pages', '1=1' . BackendUtility::deleteClause('pages'));
320
		if ($numberOfPages > 0) {
321
			$this->code .= '
322
				<h3>' . htmlspecialchars($this->getLanguageService()->getLL('selectPosition')) . ':</h3>
323
			';
324
			$positionMap = GeneralUtility::makeInstance(PagePositionMap::class, NewRecordPageTreeView::class);
Nicole Cordes's avatar
Nicole Cordes committed
325
			/** @var $positionMap \TYPO3\CMS\Backend\Tree\View\PagePositionMap */
326
327
328
			$this->code .= $positionMap->positionTree($this->id, $this->pageinfo, $this->perms_clause, $this->R_URI);
		} else {
			// No pages yet, no need to prompt for position, redirect to page creation.
329
			$javascript = stripslashes(BackendUtility::editOnClick('&edit[pages][0]=new&returnNewPageId=1', '', BackendUtility::getModuleUrl('db_new', array('id' => $this->id, 'pagesOnly' => '1'))));
330
331
332
333
			$startPos = strpos($javascript, 'href=\'') + 6;
			$endPos = strpos($javascript, '\';');
			$url = substr($javascript, $startPos, $endPos - $startPos);
			@ob_end_clean();
334
			HttpUtility::redirect($url);
335
336
337
338
339
340
341
342
343
		}
	}

	/**
	 * Create a regular new element (pages and records)
	 *
	 * @return void
	 */
	public function regularNew() {
344
		$lang = $this->getLanguageService();
345
346
347
		// Initialize array for accumulating table rows:
		$this->tRows = array();
		// Get TSconfig for current page
Nicole Cordes's avatar
Nicole Cordes committed
348
		$pageTS = BackendUtility::getPagesTSconfig($this->id);
349
350
351
352
353
		// Finish initializing new pages options with TSconfig
		// Each new page option may be hidden by TSconfig
		// Enabled option for the position of a new page
		$this->newPagesSelectPosition = !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageSelectPosition']);
		// Pseudo-boolean (0/1) for backward compatibility
354
355
		$displayNewPagesIntoLink = $this->newPagesInto && !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageInside']) ? 1 : 0;
		$displayNewPagesAfterLink = $this->newPagesAfter && !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageAfter']) ? 1 : 0;
356
		// Slight spacer from header:
357
		$this->code .= '';
358
359
360
		// New Page
		$table = 'pages';
		$v = $GLOBALS['TCA'][$table];
Nicole Cordes's avatar
Nicole Cordes committed
361
362
		$pageIcon = IconUtility::getSpriteIconForRecord($table, array());
		$newPageIcon = IconUtility::getSpriteIcon('actions-page-new');
363
364
365
		$rowContent = '';
		// New pages INSIDE this pages
		$newPageLinks = array();
366
		if ($displayNewPagesIntoLink && $this->isTableAllowedForThisPage($this->pageinfo, 'pages') && $this->getBackendUserAuthentication()->check('tables_modify', 'pages') && $this->getBackendUserAuthentication()->workspaceCreateNewRecord(($this->pageinfo['_ORIG_uid'] ?: $this->id), 'pages')) {
367
			// Create link to new page inside:
368
			$newPageLinks[] = $this->linkWrap(IconUtility::getSpriteIconForRecord($table, array()) . $lang->sL($v['ctrl']['title'], TRUE) . ' (' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:db_new.php.inside', TRUE) . ')', $table, $this->id);
369
370
		}
		// New pages AFTER this pages
371
		if ($displayNewPagesAfterLink && $this->isTableAllowedForThisPage($this->pidInfo, 'pages') && $this->getBackendUserAuthentication()->check('tables_modify', 'pages') && $this->getBackendUserAuthentication()->workspaceCreateNewRecord($this->pidInfo['uid'], 'pages')) {
372
			$newPageLinks[] = $this->linkWrap($pageIcon . $lang->sL($v['ctrl']['title'], TRUE) . ' (' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:db_new.php.after', TRUE) . ')', 'pages', -$this->id);
373
374
375
376
		}
		// New pages at selection position
		if ($this->newPagesSelectPosition) {
			// Link to page-wizard:
377
			$newPageLinks[] = '<a href="' . htmlspecialchars(GeneralUtility::linkThisScript(array('pagesOnly' => 1))) . '">' . $pageIcon . htmlspecialchars($lang->getLL('pageSelectPosition')) . '</a>';
378
379
380
381
		}
		// Assemble all new page links
		$numPageLinks = count($newPageLinks);
		for ($i = 0; $i < $numPageLinks; $i++) {
382
			$rowContent .= '<li>' . $newPageLinks[$i] . '</li>';
383
384
385
		}
		// Add row header and half-line if not empty
		if (!empty($rowContent)) {
386
			$rowContent = '<ul class="list-tree"><li>' .$newPageIcon . '<strong>' .
387
				$lang->getLL('createNewPage') . '</strong><ul>' . $rowContent . '</ul></li>';
388
389
390
391
		}
		// Compile table row to show the icon for "new page (select position)"
		$startRows = array();
		if ($this->showNewRecLink('pages') && !empty($rowContent)) {
392
			$startRows[] = $rowContent;
393
		}
394
		$iconFile = array();
395
		// New tables (but not pages) INSIDE this pages
396
		$isAdmin = $this->getBackendUserAuthentication()->isAdmin();
Nicole Cordes's avatar
Nicole Cordes committed
397
		$newContentIcon = IconUtility::getSpriteIcon('actions-document-new');
398
399
400
401
		if ($this->newContentInto) {
			if (is_array($GLOBALS['TCA'])) {
				$groupName = '';
				foreach ($GLOBALS['TCA'] as $table => $v) {
402
403
404
					if ($table != 'pages'
						&& $this->showNewRecLink($table)
						&& $this->isTableAllowedForThisPage($this->pageinfo, $table)
405
						&& $this->getBackendUserAuthentication()->check('tables_modify', $table)
406
						&& (($v['ctrl']['rootLevel'] xor $this->id) || $v['ctrl']['rootLevel'] == -1)
407
						&& $this->getBackendUserAuthentication()->workspaceCreateNewRecord(($this->pageinfo['_ORIG_uid'] ? $this->pageinfo['_ORIG_uid'] : $this->id), $table)
408
					) {
Nicole Cordes's avatar
Nicole Cordes committed
409
						$newRecordIcon = IconUtility::getSpriteIconForRecord($table, array());
410
						$rowContent = '';
411
						$thisTitle = '';
412
						// Create new link for record:
413
						$newLink = $this->linkWrap($newRecordIcon . $lang->sL($v['ctrl']['title'], TRUE), $table, $this->id);
Wouter Wolters's avatar
Wouter Wolters committed
414
						// If the table is 'tt_content', create link to wizard
415
						if ($table == 'tt_content') {
416
417
							$groupName = $lang->getLL('createNewContent');
							$rowContent = $newContentIcon . '<strong>' . $lang->getLL('createNewContent') . '</strong><ul>';
418
419
							// If mod.web_list.newContentWiz.overrideWithExtension is set, use that extension's wizard instead:
							$overrideExt = $this->web_list_modTSconfig['properties']['newContentWiz.']['overrideWithExtension'];
420
421
							$pathToWizard = ExtensionManagementUtility::isLoaded($overrideExt) ? ExtensionManagementUtility::extRelPath($overrideExt) . 'mod1/db_new_content_el.php?' : BackendUtility::getModuleUrl('new_content_element') . '&';
							$href = $pathToWizard . 'id=' . $this->id . '&returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'));
422
							$rowContent .= '<li>' . $newLink . ' ' . BackendUtility::wrapInHelp($table, '') . '</li><li><a href="' . htmlspecialchars($href) . '">' . $newContentIcon . htmlspecialchars($lang->getLL('clickForWizard')) . '</a></li></ul>';
423
424
						} else {
							// Get the title
425
							if ($v['ctrl']['readOnly'] || $v['ctrl']['hideTable'] || $v['ctrl']['is_static']) {
426
427
428
429
430
431
432
								continue;
							}
							if ($v['ctrl']['adminOnly'] && !$isAdmin) {
								continue;
							}
							$nameParts = explode('_', $table);
							$thisTitle = '';
433
							$_EXTKEY = '';
434
435
436
437
438
439
440
441
442
							if ($nameParts[0] == 'tx' || $nameParts[0] == 'tt') {
								// Try to extract extension name
								if (substr($v['ctrl']['title'], 0, 8) == 'LLL:EXT:') {
									$_EXTKEY = substr($v['ctrl']['title'], 8);
									$_EXTKEY = substr($_EXTKEY, 0, strpos($_EXTKEY, '/'));
									if ($_EXTKEY != '') {
										// First try to get localisation of extension title
										$temp = explode(':', substr($v['ctrl']['title'], 9 + strlen($_EXTKEY)));
										$langFile = $temp[0];
443
										$thisTitle = $lang->sL('LLL:EXT:' . $_EXTKEY . '/' . $langFile . ':extension.title');
444
										// If no localisation available, read title from ext_emconf.php
445
446
447
448
										$extEmConfFile = ExtensionManagementUtility::extPath($_EXTKEY) . 'ext_emconf.php';
										if (!$thisTitle && is_file($extEmConfFile)) {
											$EM_CONF = array();
											include $extEmConfFile;
449
450
											$thisTitle = $EM_CONF[$_EXTKEY]['title'];
										}
Nicole Cordes's avatar
Nicole Cordes committed
451
										$iconFile[$_EXTKEY] = '<img ' . 'src="' . ExtensionManagementUtility::extRelPath($_EXTKEY) . $GLOBALS['TYPO3_LOADED_EXT'][$_EXTKEY]['ext_icon'] . '" ' . 'width="16" height="16" ' . 'alt="' . $thisTitle . '" />';
452
									}
453
454
455
								}
								if (empty($thisTitle)) {
									$_EXTKEY = $nameParts[1];
456
457
458
459
									$thisTitle = $nameParts[1];
									$iconFile[$_EXTKEY] = '';
								}
							} else {
460
461
462
								if ($table === 'pages_language_overlay' && !$this->checkIfLanguagesExist()) {
									continue;
								}
463
								$_EXTKEY = 'system';
464
								$thisTitle = $lang->getLL('system_records');
Nicole Cordes's avatar
Nicole Cordes committed
465
								$iconFile['system'] = IconUtility::getSpriteIcon('apps-pagetree-root');
466
467
468
469
470
471
472
473
							}
							if ($groupName == '' || $groupName != $_EXTKEY) {
								$groupName = empty($v['ctrl']['groupName']) ? $_EXTKEY : $v['ctrl']['groupName'];
							}
							$rowContent .= $newLink;
						}
						// Compile table row:
						if ($table == 'tt_content') {
474
							$startRows[] = '<li>' . $rowContent . '</li>';
475
476
477
478
479
480
481
482
483
484
485
						} else {
							$this->tRows[$groupName]['title'] = $thisTitle;
							$this->tRows[$groupName]['html'][] = $rowContent;
							$this->tRows[$groupName]['table'][] = $table;
						}
					}
				}
			}
		}
		// User sort
		if (isset($pageTS['mod.']['wizards.']['newRecord.']['order'])) {
Nicole Cordes's avatar
Nicole Cordes committed
486
			$this->newRecordSortList = GeneralUtility::trimExplode(',', $pageTS['mod.']['wizards.']['newRecord.']['order'], TRUE);
487
488
489
490
491
492
		}
		uksort($this->tRows, array($this, 'sortNewRecordsByConfig'));
		// Compile table row:
		$finalRows = array();
		$finalRows[] = implode('', $startRows);
		foreach ($this->tRows as $key => $value) {
493
			$row = '<li>' . $iconFile[$key] . ' <strong>' . $value['title'] . '</strong><ul>';
494
			foreach ($value['html'] as $recordKey => $record) {
495
				$row .= '<li>' . $record . ' ' . BackendUtility::wrapInHelp($value['table'][$recordKey], '') . '</li>';
496
			}
497
			$row .= '</ul></li>';
498
499
500
			$finalRows[] = $row;
		}
		// Make table:
501
		$this->code .= implode('', $finalRows);
502
503
504
505
506
507
508
	}

	/**
	 * User array sort function used by regularNew
	 *
	 * @param string $a First array element for compare
	 * @param string $b First array element for compare
509
	 * @return int -1 for lower, 0 for equal, 1 for greater
510
511
	 */
	public function sortNewRecordsByConfig($a, $b) {
512
		if (!empty($this->newRecordSortList)) {
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
			if (in_array($a, $this->newRecordSortList) && in_array($b, $this->newRecordSortList)) {
				// Both are in the list, return relative to position in array
				$sub = array_search($a, $this->newRecordSortList) - array_search($b, $this->newRecordSortList);
				$ret = ($sub < 0 ? -1 : $sub == 0) ? 0 : 1;
			} elseif (in_array($a, $this->newRecordSortList)) {
				// First element is in array, put to top
				$ret = -1;
			} elseif (in_array($b, $this->newRecordSortList)) {
				// Second element is in array, put first to bottom
				$ret = 1;
			} else {
				// No element is in array, return alphabetic order
				$ret = strnatcasecmp($this->tRows[$a]['title'], $this->tRows[$b]['title']);
			}
			return $ret;
		} else {
			// Return alphabetic order
			return strnatcasecmp($this->tRows[$a]['title'], $this->tRows[$b]['title']);
		}
	}

	/**
	 * Ending page output and echo'ing content to browser.
	 *
	 * @return void
	 */
	public function printContent() {
		echo $this->content;
	}

	/**
	 * Links the string $code to a create-new form for a record in $table created on page $pid
	 *
	 * @param string $linkText Link text
	 * @param string $table Table name (in which to create new record)
548
	 * @param int $pid PID value for the "&edit['.$table.']['.$pid.']=new" command (positive/negative)
549
	 * @param bool $addContentTable If $addContentTable is set, then a new tt_content record is created together with pages
550
551
552
	 * @return string The link.
	 */
	public function linkWrap($linkText, $table, $pid, $addContentTable = FALSE) {
553
		$parameters = '&edit[' . $table . '][' . $pid . ']=new';
554
555
		if ($table == 'pages' && $addContentTable) {
			$parameters .= '&edit[tt_content][prev]=new&returnNewPageId=1';
556
		} elseif ($table == 'pages_language_overlay') {
557
			$parameters .= '&overrideVals[pages_language_overlay][doktype]=' . (int)$this->pageinfo['doktype'];
558
		}
Nicole Cordes's avatar
Nicole Cordes committed
559
		$onClick = BackendUtility::editOnClick($parameters, '', $this->returnUrl);
560
		return '<a href="#" onclick="' . htmlspecialchars($onClick) . '">' . $linkText . '</a>';
561
562
563
564
565
566
567
	}

	/**
	 * Returns TRUE if the tablename $checkTable is allowed to be created on the page with record $pid_row
	 *
	 * @param array $pid_row Record for parent page.
	 * @param string $checkTable Table name to check
568
	 * @return bool Returns TRUE if the tablename $checkTable is allowed to be created on the page with record $pid_row
569
570
571
	 */
	public function isTableAllowedForThisPage($pid_row, $checkTable) {
		if (!is_array($pid_row)) {
572
			return $this->getBackendUserAuthentication()->isAdmin();
573
574
575
576
577
578
		}
		// be_users and be_groups may not be created anywhere but in the root.
		if ($checkTable == 'be_users' || $checkTable == 'be_groups') {
			return FALSE;
		}
		// Checking doktype:
579
		$doktype = (int)$pid_row['doktype'];
580
581
582
		if (!($allowedTableList = $GLOBALS['PAGES_TYPES'][$doktype]['allowedTables'])) {
			$allowedTableList = $GLOBALS['PAGES_TYPES']['default']['allowedTables'];
		}
583
		// If all tables or the table is listed as an allowed type, return TRUE
Nicole Cordes's avatar
Nicole Cordes committed
584
		if (strstr($allowedTableList, '*') || GeneralUtility::inList($allowedTableList, $checkTable)) {
585
586
			return TRUE;
		}
587
588

		return FALSE;
589
590
591
592
593
594
595
596
597
598
599
600
601
	}

	/**
	 * Returns TRUE if:
	 * - $allowedNewTables and $deniedNewTables are empty
	 * - the table is not found in $deniedNewTables and $allowedNewTables is not set or the $table tablename is found in $allowedNewTables
	 *
	 * If $table tablename is found in $allowedNewTables and $deniedNewTables, $deniedNewTables
	 * has priority over $allowedNewTables.
	 *
	 * @param string $table Table name to test if in allowedTables
	 * @param array $allowedNewTables Array of new tables that are allowed.
	 * @param array $deniedNewTables Array of new tables that are not allowed.
602
	 * @return bool Returns TRUE if a link for creating new records should be displayed for $table
603
604
	 */
	public function showNewRecLink($table, array $allowedNewTables = array(), array $deniedNewTables = array()) {
605
606
607
608
609

		if (!$this->getBackendUserAuthentication()->check('tables_modify', $table)) {
			return FALSE;
		}

610
611
		$allowedNewTables = $allowedNewTables ?: $this->allowedNewTables;
		$deniedNewTables = $deniedNewTables ?: $this->deniedNewTables;
612
		// No deny/allow tables are set:
613
		if (empty($allowedNewTables) && empty($deniedNewTables)) {
614
615
			return TRUE;
		}
616
617

		return !in_array($table, $deniedNewTables) && (empty($allowedNewTables) || in_array($table, $allowedNewTables));
618
619
	}

620
621
622
623
624
625
626
627
628
629
630
631
632
	/**
	 * Checks if sys_language records are present
	 *
	 * @return bool
	 */
	protected function checkIfLanguagesExist() {
		$languageCount = $this->getDatabaseConnection()->exec_SELECTcountRows('uid', 'sys_language', '1=1');
		if ($languageCount) {
			$languageCount = TRUE;
		}
		return $languageCount;
	}

633
634
635
636
637
638
639
640
641
	/**
	 * Return language service instance
	 *
	 * @return \TYPO3\CMS\Lang\LanguageService
	 */
	protected function getLanguageService() {
		return $GLOBALS['LANG'];
	}

642
643
644
645
646
647
648
649
	/**
	 * Returns the global BackendUserAuthentication object.
	 *
	 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
	 */
	protected function getBackendUserAuthentication() {
		return $GLOBALS['BE_USER'];
	}
650

651
652
653
654
655
656
657
658
659
	/**
	 * Returns the database connection
	 *
	 * @return DatabaseConnection
	 */
	protected function getDatabaseConnection() {
		return $GLOBALS['TYPO3_DB'];
	}

660
}