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