[TASK] Call explicit render() on icon objects
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / NewRecordController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Psr\Http\Message\ServerRequestInterface;
18 use Psr\Http\Message\ResponseInterface;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
20 use TYPO3\CMS\Core\Database\DatabaseConnection;
21 use TYPO3\CMS\Core\Imaging\Icon;
22 use TYPO3\CMS\Core\Imaging\IconFactory;
23 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\CMS\Backend\Template\DocumentTemplate;
26 use TYPO3\CMS\Backend\Tree\View\PagePositionMap;
27 use TYPO3\CMS\Backend\Tree\View\NewRecordPageTreeView;
28 use TYPO3\CMS\Core\Utility\HttpUtility;
29 use TYPO3\CMS\Frontend\Page\PageRepository;
30
31
32 /**
33 * Script class for 'db_new'
34 */
35 class NewRecordController {
36
37 /**
38 * @var array
39 */
40 public $pageinfo;
41
42 /**
43 * @var array
44 */
45 public $pidInfo;
46
47 /**
48 * @var array
49 */
50 protected $newRecordSortList;
51
52 /**
53 * @var int
54 */
55 public $newPagesInto;
56
57 /**
58 * @var int
59 */
60 public $newContentInto;
61
62 /**
63 * @var int
64 */
65 public $newPagesAfter;
66
67 /**
68 * Determines, whether "Select Position" for new page should be shown
69 *
70 * @var bool
71 */
72 protected $newPagesSelectPosition = TRUE;
73
74 /**
75 * @var array
76 */
77 public $web_list_modTSconfig;
78
79 /**
80 * @var array
81 */
82 public $allowedNewTables;
83
84 /**
85 * @var array
86 */
87 public $deniedNewTables;
88
89 /**
90 * @var array
91 */
92 public $web_list_modTSconfig_pid;
93
94 /**
95 * @var array
96 */
97 public $allowedNewTables_pid;
98
99 /**
100 * @var array
101 */
102 public $deniedNewTables_pid;
103
104 /**
105 * @var string
106 */
107 public $code;
108
109 /**
110 * @var string
111 */
112 public $R_URI;
113
114 /**
115 * @var int
116 */
117 public $id;
118
119 /**
120 * @var string
121 */
122 public $returnUrl;
123
124 /**
125 * pagesOnly flag.
126 *
127 * @var int
128 */
129 public $pagesOnly;
130
131 /**
132 * @var string
133 */
134 public $perms_clause;
135
136 /**
137 * Document template object
138 *
139 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
140 */
141 public $doc;
142
143 /**
144 * Accumulated HTML output
145 *
146 * @var string
147 */
148 public $content;
149
150 /**
151 * @var array
152 */
153 public $tRows;
154
155 /**
156 * @var IconFactory
157 */
158 protected $iconFactory;
159
160 /**
161 * Constructor
162 */
163 public function __construct() {
164 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
165 $GLOBALS['SOBE'] = $this;
166 $this->getLanguageService()->includeLLFile('EXT:lang/locallang_misc.xlf');
167 $this->init();
168 }
169
170 /**
171 * Constructor function for the class
172 *
173 * @return void
174 */
175 protected function init() {
176 $beUser = $this->getBackendUserAuthentication();
177 // Page-selection permission clause (reading)
178 $this->perms_clause = $beUser->getPagePermsClause(1);
179 // This will hide records from display - it has nothing to do with user rights!!
180 if ($pidList = $beUser->getTSConfigVal('options.hideRecords.pages')) {
181 if ($pidList = $this->getDatabaseConnection()->cleanIntList($pidList)) {
182 $this->perms_clause .= ' AND pages.uid NOT IN (' . $pidList . ')';
183 }
184 }
185 // Setting GPvars:
186 // The page id to operate from
187 $this->id = (int)GeneralUtility::_GP('id');
188 $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'));
189 $this->pagesOnly = GeneralUtility::_GP('pagesOnly');
190 // Create instance of template class for output
191 $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
192 $this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/db_new.html');
193 $this->doc->JScode = '';
194 // Setting up the context sensitive menu:
195 $this->doc->getContextMenuCode();
196 // Creating content
197 $this->content = '';
198 $this->content .= $this->doc->header($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:db_new.php.pagetitle'));
199 // Id a positive id is supplied, ask for the page record with permission information contained:
200 if ($this->id > 0) {
201 $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
202 }
203 // If a page-record was returned, the user had read-access to the page.
204 if ($this->pageinfo['uid']) {
205 // Get record of parent page
206 $this->pidInfo = BackendUtility::getRecord('pages', $this->pageinfo['pid']);
207 // Checking the permissions for the user with regard to the parent page: Can he create new pages, new content record, new page after?
208 if ($beUser->doesUserHaveAccess($this->pageinfo, 8)) {
209 $this->newPagesInto = 1;
210 }
211 if ($beUser->doesUserHaveAccess($this->pageinfo, 16)) {
212 $this->newContentInto = 1;
213 }
214 if (($beUser->isAdmin() || is_array($this->pidInfo)) && $beUser->doesUserHaveAccess($this->pidInfo, 8)) {
215 $this->newPagesAfter = 1;
216 }
217 } elseif ($beUser->isAdmin()) {
218 // Admins can do it all
219 $this->newPagesInto = 1;
220 $this->newContentInto = 1;
221 $this->newPagesAfter = 0;
222 } else {
223 // People with no permission can do nothing
224 $this->newPagesInto = 0;
225 $this->newContentInto = 0;
226 $this->newPagesAfter = 0;
227 }
228 }
229
230 /**
231 * Injects the request object for the current request or subrequest
232 * As this controller goes only through the main() method, it is rather simple for now
233 *
234 * @param ServerRequestInterface $request the current request
235 * @param ResponseInterface $response
236 * @return ResponseInterface the response with the content
237 */
238 public function mainAction(ServerRequestInterface $request, ResponseInterface $response) {
239 $this->main();
240
241 $response->getBody()->write($this->content);
242 return $response;
243 }
244
245 /**
246 * Main processing, creating the list of new record tables to select from
247 *
248 * @return void
249 */
250 public function main() {
251 // If there was a page - or if the user is admin (admins has access to the root) we proceed:
252 if ($this->pageinfo['uid'] || $this->getBackendUserAuthentication()->isAdmin()) {
253 // Acquiring TSconfig for this module/current page:
254 $this->web_list_modTSconfig = BackendUtility::getModTSconfig($this->pageinfo['uid'], 'mod.web_list');
255 $this->allowedNewTables = GeneralUtility::trimExplode(',', $this->web_list_modTSconfig['properties']['allowedNewTables'], TRUE);
256 $this->deniedNewTables = GeneralUtility::trimExplode(',', $this->web_list_modTSconfig['properties']['deniedNewTables'], TRUE);
257 // Acquiring TSconfig for this module/parent page:
258 $this->web_list_modTSconfig_pid = BackendUtility::getModTSconfig($this->pageinfo['pid'], 'mod.web_list');
259 $this->allowedNewTables_pid = GeneralUtility::trimExplode(',', $this->web_list_modTSconfig_pid['properties']['allowedNewTables'], TRUE);
260 $this->deniedNewTables_pid = GeneralUtility::trimExplode(',', $this->web_list_modTSconfig_pid['properties']['deniedNewTables'], TRUE);
261 // More init:
262 if (!$this->showNewRecLink('pages')) {
263 $this->newPagesInto = 0;
264 }
265 if (!$this->showNewRecLink('pages', $this->allowedNewTables_pid, $this->deniedNewTables_pid)) {
266 $this->newPagesAfter = 0;
267 }
268 // Set header-HTML and return_url
269 if (is_array($this->pageinfo) && $this->pageinfo['uid']) {
270 $iconImgTag = '<span title="' . htmlspecialchars($this->pageinfo['_thePath']) . '">' . $this->iconFactory->getIconForRecord('pages', $this->pageinfo, Icon::SIZE_SMALL)->render() . '</span>';
271 $title = strip_tags($this->pageinfo[$GLOBALS['TCA']['pages']['ctrl']['label']]);
272 } else {
273 $iconImgTag = '<span title="' . htmlspecialchars($this->pageinfo['_thePath']) . '">' . $this->iconFactory->getIcon('apps-pagetree-root', Icon::SIZE_SMALL)->render() . '</span>';
274 $title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
275 }
276 $this->code = '<span class="typo3-moduleHeader">' . $this->doc->wrapClickMenuOnIcon($iconImgTag, 'pages', $this->pageinfo['uid']) . htmlspecialchars(GeneralUtility::fixed_lgd_cs($title, 45)) . '</span><br />';
277 $this->R_URI = $this->returnUrl;
278 // GENERATE the HTML-output depending on mode (pagesOnly is the page wizard)
279 // Regular new element:
280 if (!$this->pagesOnly) {
281 $this->regularNew();
282 } elseif ($this->showNewRecLink('pages')) {
283 // Pages only wizard
284 $this->pagesOnly();
285 }
286 // Add all the content to an output section
287 $this->content .= $this->doc->section('', $this->code);
288 // Setting up the buttons and markers for docheader
289 $docHeaderButtons = $this->getButtons();
290 $markers['CSH'] = $docHeaderButtons['csh'];
291 $markers['CONTENT'] = $this->content;
292 // Build the <body> for the module
293 $this->content = $this->doc->startPage($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:db_new.php.pagetitle'));
294 $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
295 $this->content .= $this->doc->endPage();
296 $this->content = $this->doc->insertStylesAndJS($this->content);
297 }
298 }
299
300 /**
301 * Create the panel of buttons for submitting the form or otherwise perform operations.
302 *
303 * @return array All available buttons as an assoc. array
304 */
305 protected function getButtons() {
306 $buttons = array(
307 'csh' => '',
308 'back' => '',
309 'view' => '',
310 'new_page' => ''
311 );
312 // Regular new element:
313 if (!$this->pagesOnly) {
314 // New page
315 if ($this->showNewRecLink('pages')) {
316 $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) . '">'
317 . $this->iconFactory->getIcon('actions-page-new', Icon::SIZE_SMALL)->render()
318 . '</a>';
319 }
320 // CSH
321 $buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'new_regular');
322 } elseif ($this->showNewRecLink('pages')) {
323 // Pages only wizard
324 // CSH
325 $buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'new_pages');
326 }
327 // Back
328 if ($this->R_URI) {
329 $buttons['back'] = '<a href="' . htmlspecialchars($this->R_URI) . '" class="typo3-goBack" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.goBack', TRUE) . '">' . $this->iconFactory->getIcon('actions-view-go-back', Icon::SIZE_SMALL)->render() . '</a>';
330 }
331 if (is_array($this->pageinfo) && $this->pageinfo['uid']) {
332 // View
333 $pagesTSconfig = BackendUtility::getPagesTSconfig($this->pageinfo['uid']);
334 if (isset($pagesTSconfig['TCEMAIN.']['preview.']['disableButtonForDokType'])) {
335 $excludeDokTypes = GeneralUtility::intExplode(',', $pagesTSconfig['TCEMAIN.']['preview.']['disableButtonForDokType'], TRUE);
336 } else {
337 // exclude sysfolders and recycler by default
338 $excludeDokTypes = array(PageRepository::DOKTYPE_RECYCLER, PageRepository::DOKTYPE_SYSFOLDER, PageRepository::DOKTYPE_SPACER);
339 }
340 if (!in_array((int)$this->pageinfo['doktype'], $excludeDokTypes, TRUE)) {
341 $buttons['view'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($this->pageinfo['uid'], '', BackendUtility::BEgetRootLine($this->pageinfo['uid']))) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', TRUE) . '">' . $this->iconFactory->getIcon('actions-document-view', Icon::SIZE_SMALL)->render() . '</a>';
342 }
343 }
344 return $buttons;
345 }
346
347 /**
348 * Creates the position map for pages wizard
349 *
350 * @return void
351 */
352 public function pagesOnly() {
353 $numberOfPages = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'pages', '1=1' . BackendUtility::deleteClause('pages'));
354 if ($numberOfPages > 0) {
355 $this->code .= '
356 <h3>' . htmlspecialchars($this->getLanguageService()->getLL('selectPosition')) . ':</h3>
357 ';
358 $positionMap = GeneralUtility::makeInstance(PagePositionMap::class, NewRecordPageTreeView::class);
359 /** @var $positionMap \TYPO3\CMS\Backend\Tree\View\PagePositionMap */
360 $this->code .= $positionMap->positionTree($this->id, $this->pageinfo, $this->perms_clause, $this->R_URI);
361 } else {
362 // No pages yet, no need to prompt for position, redirect to page creation.
363 $urlParameters = [
364 'edit' => [
365 'pages' => [
366 0 => 'new'
367 ]
368 ],
369 'returnNewPageId' => 1,
370 'returnUrl' => BackendUtility::getModuleUrl('db_new', array('id' => $this->id, 'pagesOnly' => '1'))
371 ];
372 $url = BackendUtility::getModuleUrl('record_edit', $urlParameters);
373 @ob_end_clean();
374 HttpUtility::redirect($url);
375 }
376 }
377
378 /**
379 * Create a regular new element (pages and records)
380 *
381 * @return void
382 */
383 public function regularNew() {
384
385 /** @var IconFactory $iconFactory */
386 $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
387 $lang = $this->getLanguageService();
388 // Initialize array for accumulating table rows:
389 $this->tRows = array();
390 // Get TSconfig for current page
391 $pageTS = BackendUtility::getPagesTSconfig($this->id);
392 // Finish initializing new pages options with TSconfig
393 // Each new page option may be hidden by TSconfig
394 // Enabled option for the position of a new page
395 $this->newPagesSelectPosition = !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageSelectPosition']);
396 // Pseudo-boolean (0/1) for backward compatibility
397 $displayNewPagesIntoLink = $this->newPagesInto && !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageInside']) ? 1 : 0;
398 $displayNewPagesAfterLink = $this->newPagesAfter && !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageAfter']) ? 1 : 0;
399 // Slight spacer from header:
400 $this->code .= '';
401 // New Page
402 $table = 'pages';
403 $v = $GLOBALS['TCA'][$table];
404 $pageIcon = $this->iconFactory->getIconForRecord($table, array(), Icon::SIZE_SMALL)->render();
405 $newPageIcon = $this->iconFactory->getIcon('actions-page-new', Icon::SIZE_SMALL)->render();
406 $rowContent = '';
407 // New pages INSIDE this pages
408 $newPageLinks = array();
409 if ($displayNewPagesIntoLink && $this->isTableAllowedForThisPage($this->pageinfo, 'pages') && $this->getBackendUserAuthentication()->check('tables_modify', 'pages') && $this->getBackendUserAuthentication()->workspaceCreateNewRecord(($this->pageinfo['_ORIG_uid'] ?: $this->id), 'pages')) {
410 // Create link to new page inside:
411 $newPageLinks[] = $this->linkWrap($this->iconFactory->getIconForRecord($table, array(), Icon::SIZE_SMALL)->render() . $lang->sL($v['ctrl']['title'], TRUE) . ' (' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:db_new.php.inside', TRUE) . ')', $table, $this->id);
412 }
413 // New pages AFTER this pages
414 if ($displayNewPagesAfterLink && $this->isTableAllowedForThisPage($this->pidInfo, 'pages') && $this->getBackendUserAuthentication()->check('tables_modify', 'pages') && $this->getBackendUserAuthentication()->workspaceCreateNewRecord($this->pidInfo['uid'], 'pages')) {
415 $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);
416 }
417 // New pages at selection position
418 if ($this->newPagesSelectPosition && $this->showNewRecLink('pages')) {
419 // Link to page-wizard:
420 $newPageLinks[] = '<a href="' . htmlspecialchars(GeneralUtility::linkThisScript(array('pagesOnly' => 1))) . '">' . $pageIcon . htmlspecialchars($lang->getLL('pageSelectPosition')) . '</a>';
421 }
422 // Assemble all new page links
423 $numPageLinks = count($newPageLinks);
424 for ($i = 0; $i < $numPageLinks; $i++) {
425 $rowContent .= '<li>' . $newPageLinks[$i] . '</li>';
426 }
427 if ($this->showNewRecLink('pages')) {
428 $rowContent = '<ul class="list-tree"><li>' .$newPageIcon . '<strong>' .
429 $lang->getLL('createNewPage') . '</strong><ul>' . $rowContent . '</ul></li>';
430 } else {
431 $rowContent = '<ul class="list-tree"><li><ul>' . $rowContent . '</li></ul>';
432 }
433 // Compile table row
434 $startRows = array($rowContent);
435 $iconFile = array();
436 // New tables (but not pages) INSIDE this pages
437 $isAdmin = $this->getBackendUserAuthentication()->isAdmin();
438 $newContentIcon = $iconFactory->getIcon('actions-document-new', Icon::SIZE_SMALL)->render();
439 if ($this->newContentInto) {
440 if (is_array($GLOBALS['TCA'])) {
441 $groupName = '';
442 foreach ($GLOBALS['TCA'] as $table => $v) {
443 if ($table != 'pages'
444 && $this->showNewRecLink($table)
445 && $this->isTableAllowedForThisPage($this->pageinfo, $table)
446 && $this->getBackendUserAuthentication()->check('tables_modify', $table)
447 && (($v['ctrl']['rootLevel'] xor $this->id) || $v['ctrl']['rootLevel'] == -1)
448 && $this->getBackendUserAuthentication()->workspaceCreateNewRecord(($this->pageinfo['_ORIG_uid'] ? $this->pageinfo['_ORIG_uid'] : $this->id), $table)
449 ) {
450 $newRecordIcon = $this->iconFactory->getIconForRecord($table, array(), Icon::SIZE_SMALL)->render();
451 $rowContent = '';
452 $thisTitle = '';
453 // Create new link for record:
454 $newLink = $this->linkWrap($newRecordIcon . $lang->sL($v['ctrl']['title'], TRUE), $table, $this->id);
455 // If the table is 'tt_content', create link to wizard
456 if ($table == 'tt_content') {
457 $groupName = $lang->getLL('createNewContent');
458 $rowContent = $newContentIcon . '<strong>' . $lang->getLL('createNewContent') . '</strong><ul>';
459 // If mod.web_list.newContentWiz.overrideWithExtension is set, use that extension's wizard instead:
460 $overrideExt = $this->web_list_modTSconfig['properties']['newContentWiz.']['overrideWithExtension'];
461 $pathToWizard = ExtensionManagementUtility::isLoaded($overrideExt) ? ExtensionManagementUtility::extRelPath($overrideExt) . 'mod1/db_new_content_el.php?' : BackendUtility::getModuleUrl('new_content_element') . '&';
462 $href = $pathToWizard . 'id=' . $this->id . '&returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'));
463 $rowContent .= '<li>' . $newLink . ' ' . BackendUtility::wrapInHelp($table, '') . '</li><li><a href="' . htmlspecialchars($href) . '">' . $newContentIcon . htmlspecialchars($lang->getLL('clickForWizard')) . '</a></li></ul>';
464 } else {
465 // Get the title
466 if ($v['ctrl']['readOnly'] || $v['ctrl']['hideTable'] || $v['ctrl']['is_static']) {
467 continue;
468 }
469 if ($v['ctrl']['adminOnly'] && !$isAdmin) {
470 continue;
471 }
472 $nameParts = explode('_', $table);
473 $thisTitle = '';
474 $_EXTKEY = '';
475 if ($nameParts[0] == 'tx' || $nameParts[0] == 'tt') {
476 // Try to extract extension name
477 if (substr($v['ctrl']['title'], 0, 8) == 'LLL:EXT:') {
478 $_EXTKEY = substr($v['ctrl']['title'], 8);
479 $_EXTKEY = substr($_EXTKEY, 0, strpos($_EXTKEY, '/'));
480 if ($_EXTKEY != '') {
481 // First try to get localisation of extension title
482 $temp = explode(':', substr($v['ctrl']['title'], 9 + strlen($_EXTKEY)));
483 $langFile = $temp[0];
484 $thisTitle = $lang->sL('LLL:EXT:' . $_EXTKEY . '/' . $langFile . ':extension.title');
485 // If no localisation available, read title from ext_emconf.php
486 $extEmConfFile = ExtensionManagementUtility::extPath($_EXTKEY) . 'ext_emconf.php';
487 if (!$thisTitle && is_file($extEmConfFile)) {
488 $EM_CONF = array();
489 include $extEmConfFile;
490 $thisTitle = $EM_CONF[$_EXTKEY]['title'];
491 }
492 $iconFile[$_EXTKEY] = '<img ' . 'src="' . ExtensionManagementUtility::extRelPath($_EXTKEY) . $GLOBALS['TYPO3_LOADED_EXT'][$_EXTKEY]['ext_icon'] . '" ' . 'width="16" height="16" ' . 'alt="' . $thisTitle . '" />';
493 }
494 }
495 if (empty($thisTitle)) {
496 $_EXTKEY = $nameParts[1];
497 $thisTitle = $nameParts[1];
498 $iconFile[$_EXTKEY] = '';
499 }
500 } else {
501 if ($table === 'pages_language_overlay' && !$this->checkIfLanguagesExist()) {
502 continue;
503 }
504 $_EXTKEY = 'system';
505 $thisTitle = $lang->getLL('system_records');
506 $iconFile['system'] = $this->iconFactory->getIcon('apps-pagetree-root', Icon::SIZE_SMALL)->render();
507 }
508 if ($groupName == '' || $groupName != $_EXTKEY) {
509 $groupName = empty($v['ctrl']['groupName']) ? $_EXTKEY : $v['ctrl']['groupName'];
510 }
511 $rowContent .= $newLink;
512 }
513 // Compile table row:
514 if ($table == 'tt_content') {
515 $startRows[] = '<li>' . $rowContent . '</li>';
516 } else {
517 $this->tRows[$groupName]['title'] = $thisTitle;
518 $this->tRows[$groupName]['html'][] = $rowContent;
519 $this->tRows[$groupName]['table'][] = $table;
520 }
521 }
522 }
523 }
524 }
525 // User sort
526 if (isset($pageTS['mod.']['wizards.']['newRecord.']['order'])) {
527 $this->newRecordSortList = GeneralUtility::trimExplode(',', $pageTS['mod.']['wizards.']['newRecord.']['order'], TRUE);
528 }
529 uksort($this->tRows, array($this, 'sortNewRecordsByConfig'));
530 // Compile table row:
531 $finalRows = array();
532 $finalRows[] = implode('', $startRows);
533 foreach ($this->tRows as $key => $value) {
534 $row = '<li>' . $iconFile[$key] . ' <strong>' . $value['title'] . '</strong><ul>';
535 foreach ($value['html'] as $recordKey => $record) {
536 $row .= '<li>' . $record . ' ' . BackendUtility::wrapInHelp($value['table'][$recordKey], '') . '</li>';
537 }
538 $row .= '</ul></li>';
539 $finalRows[] = $row;
540 }
541 // Make table:
542 $this->code .= implode('', $finalRows);
543 }
544
545 /**
546 * User array sort function used by regularNew
547 *
548 * @param string $a First array element for compare
549 * @param string $b First array element for compare
550 * @return int -1 for lower, 0 for equal, 1 for greater
551 */
552 public function sortNewRecordsByConfig($a, $b) {
553 if (!empty($this->newRecordSortList)) {
554 if (in_array($a, $this->newRecordSortList) && in_array($b, $this->newRecordSortList)) {
555 // Both are in the list, return relative to position in array
556 $sub = array_search($a, $this->newRecordSortList) - array_search($b, $this->newRecordSortList);
557 $ret = ($sub < 0 ? -1 : $sub == 0) ? 0 : 1;
558 } elseif (in_array($a, $this->newRecordSortList)) {
559 // First element is in array, put to top
560 $ret = -1;
561 } elseif (in_array($b, $this->newRecordSortList)) {
562 // Second element is in array, put first to bottom
563 $ret = 1;
564 } else {
565 // No element is in array, return alphabetic order
566 $ret = strnatcasecmp($this->tRows[$a]['title'], $this->tRows[$b]['title']);
567 }
568 return $ret;
569 } else {
570 // Return alphabetic order
571 return strnatcasecmp($this->tRows[$a]['title'], $this->tRows[$b]['title']);
572 }
573 }
574
575 /**
576 * Ending page output and echo'ing content to browser.
577 *
578 * @return void
579 * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8, use mainAction() instead
580 */
581 public function printContent() {
582 GeneralUtility::logDeprecatedFunction();
583 echo $this->content;
584 }
585
586 /**
587 * Links the string $code to a create-new form for a record in $table created on page $pid
588 *
589 * @param string $linkText Link text
590 * @param string $table Table name (in which to create new record)
591 * @param int $pid PID value for the "&edit['.$table.']['.$pid.']=new" command (positive/negative)
592 * @param bool $addContentTable If $addContentTable is set, then a new tt_content record is created together with pages
593 * @return string The link.
594 */
595 public function linkWrap($linkText, $table, $pid, $addContentTable = FALSE) {
596 $urlParameters = [
597 'edit' => [
598 $table => [
599 $pid => 'new'
600 ]
601 ],
602 'returnUrl' => $this->returnUrl
603 ];
604 if ($table == 'pages' && $addContentTable) {
605 $urlParameters['tt_content']['prev'] = 'new';
606 $urlParameters['returnNewPageId'] = 1;
607 } elseif ($table == 'pages_language_overlay') {
608 $urlParameters['overrideVals']['pages_language_overlay']['doktype'] = (int)$this->pageinfo['doktype'];
609 }
610 $url = BackendUtility::getModuleUrl('record_edit', $urlParameters);
611 return '<a href="' . htmlspecialchars($url) . '">' . $linkText . '</a>';
612 }
613
614 /**
615 * Returns TRUE if the tablename $checkTable is allowed to be created on the page with record $pid_row
616 *
617 * @param array $pid_row Record for parent page.
618 * @param string $checkTable Table name to check
619 * @return bool Returns TRUE if the tablename $checkTable is allowed to be created on the page with record $pid_row
620 */
621 public function isTableAllowedForThisPage($pid_row, $checkTable) {
622 if (!is_array($pid_row)) {
623 return $this->getBackendUserAuthentication()->isAdmin();
624 }
625 // be_users and be_groups may not be created anywhere but in the root.
626 if ($checkTable == 'be_users' || $checkTable == 'be_groups') {
627 return FALSE;
628 }
629 // Checking doktype:
630 $doktype = (int)$pid_row['doktype'];
631 if (!($allowedTableList = $GLOBALS['PAGES_TYPES'][$doktype]['allowedTables'])) {
632 $allowedTableList = $GLOBALS['PAGES_TYPES']['default']['allowedTables'];
633 }
634 // If all tables or the table is listed as an allowed type, return TRUE
635 if (strstr($allowedTableList, '*') || GeneralUtility::inList($allowedTableList, $checkTable)) {
636 return TRUE;
637 }
638
639 return FALSE;
640 }
641
642 /**
643 * Returns TRUE if:
644 * - $allowedNewTables and $deniedNewTables are empty
645 * - the table is not found in $deniedNewTables and $allowedNewTables is not set or the $table tablename is found in $allowedNewTables
646 *
647 * If $table tablename is found in $allowedNewTables and $deniedNewTables, $deniedNewTables
648 * has priority over $allowedNewTables.
649 *
650 * @param string $table Table name to test if in allowedTables
651 * @param array $allowedNewTables Array of new tables that are allowed.
652 * @param array $deniedNewTables Array of new tables that are not allowed.
653 * @return bool Returns TRUE if a link for creating new records should be displayed for $table
654 */
655 public function showNewRecLink($table, array $allowedNewTables = array(), array $deniedNewTables = array()) {
656
657 if (!$this->getBackendUserAuthentication()->check('tables_modify', $table)) {
658 return FALSE;
659 }
660
661 $allowedNewTables = $allowedNewTables ?: $this->allowedNewTables;
662 $deniedNewTables = $deniedNewTables ?: $this->deniedNewTables;
663 // No deny/allow tables are set:
664 if (empty($allowedNewTables) && empty($deniedNewTables)) {
665 return TRUE;
666 }
667
668 return !in_array($table, $deniedNewTables) && (empty($allowedNewTables) || in_array($table, $allowedNewTables));
669 }
670
671 /**
672 * Checks if sys_language records are present
673 *
674 * @return bool
675 */
676 protected function checkIfLanguagesExist() {
677 $languageCount = $this->getDatabaseConnection()->exec_SELECTcountRows('uid', 'sys_language', '1=1');
678 if ($languageCount) {
679 $languageCount = TRUE;
680 }
681 return $languageCount;
682 }
683
684 /**
685 * Return language service instance
686 *
687 * @return \TYPO3\CMS\Lang\LanguageService
688 */
689 protected function getLanguageService() {
690 return $GLOBALS['LANG'];
691 }
692
693 /**
694 * Returns the global BackendUserAuthentication object.
695 *
696 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
697 */
698 protected function getBackendUserAuthentication() {
699 return $GLOBALS['BE_USER'];
700 }
701
702 /**
703 * Returns the database connection
704 *
705 * @return DatabaseConnection
706 */
707 protected function getDatabaseConnection() {
708 return $GLOBALS['TYPO3_DB'];
709 }
710
711 }