[TASK] Use trait for public method access deprecation
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / ContentElement / ElementInformationController.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Backend\Controller\ContentElement;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use Psr\Http\Message\ResponseInterface;
19 use Psr\Http\Message\ServerRequestInterface;
20 use TYPO3\CMS\Backend\Backend\Avatar\Avatar;
21 use TYPO3\CMS\Backend\Template\ModuleTemplate;
22 use TYPO3\CMS\Backend\Utility\BackendUtility;
23 use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
24 use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
25 use TYPO3\CMS\Core\Database\ConnectionPool;
26 use TYPO3\CMS\Core\Http\HtmlResponse;
27 use TYPO3\CMS\Core\Imaging\Icon;
28 use TYPO3\CMS\Core\Imaging\IconFactory;
29 use TYPO3\CMS\Core\Resource\AbstractFile;
30 use TYPO3\CMS\Core\Resource\File;
31 use TYPO3\CMS\Core\Resource\Folder;
32 use TYPO3\CMS\Core\Resource\ResourceFactory;
33 use TYPO3\CMS\Core\Type\Bitmask\Permission;
34 use TYPO3\CMS\Core\Utility\GeneralUtility;
35 use TYPO3\CMS\Fluid\View\StandaloneView;
36
37 /**
38 * Script Class for showing information about an item.
39 */
40 class ElementInformationController
41 {
42 use PublicMethodDeprecationTrait;
43 use PublicPropertyDeprecationTrait;
44
45 /**
46 * @var array
47 */
48 private $deprecatedPublicMethods = [
49 'getLabelForTableColumn' => 'Using ElementInformationController::getLabelForTableColumn() is deprecated and will not be possible anymore in TYPO3 v10.',
50 ];
51
52 /**
53 * Properties which have been moved to protected status from public
54 *
55 * @var array
56 */
57 private $deprecatedPublicProperties = [
58 'table' => 'Using $table of class ElementInformationController from the outside is discouraged, as this variable is only used for internal storage.',
59 'uid' => 'Using $uid of class ElementInformationController from the outside is discouraged, as this variable is only used for internal storage.',
60 'access' => 'Using $access of class ElementInformationController from the outside is discouraged, as this variable is only used for internal storage.',
61 'type' => 'Using $type of class ElementInformationController from the outside is discouraged, as this variable is only used for internal storage.',
62 'pageInfo' => 'Using $pageInfo of class ElementInformationController from the outside is discouraged, as this variable is only used for internal storage.',
63 ];
64
65 /**
66 * Record table name
67 *
68 * @var string
69 */
70 protected $table;
71
72 /**
73 * Record uid
74 *
75 * @var int
76 */
77 protected $uid;
78
79 /**
80 * @var string
81 */
82 protected $permsClause;
83
84 /**
85 * @var bool
86 */
87 protected $access = false;
88
89 /**
90 * Which type of element:
91 * - "file"
92 * - "db"
93 *
94 * @var string
95 */
96 protected $type = '';
97
98 /**
99 * @var ModuleTemplate
100 */
101 protected $moduleTemplate;
102
103 /**
104 * For type "db": Set to page record of the parent page of the item set
105 * (if type="db")
106 *
107 * @var array
108 */
109 protected $pageInfo;
110
111 /**
112 * Database records identified by table/uid
113 *
114 * @var array
115 */
116 protected $row;
117
118 /**
119 * @var \TYPO3\CMS\Core\Resource\File
120 */
121 protected $fileObject;
122
123 /**
124 * @var Folder
125 */
126 protected $folderObject;
127
128 /**
129 * @var IconFactory
130 */
131 protected $iconFactory;
132
133 /**
134 * Constructor
135 */
136 public function __construct()
137 {
138 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
139 $GLOBALS['SOBE'] = $this;
140
141 // @deprecated since v9, will be obsolete in v10 with removal of init()
142 $request = $GLOBALS['TYPO3_REQUEST'];
143 // @deprecated since v9, will be moved out of __construct() in v10
144 $this->init($request);
145 }
146
147 /**
148 * Injects the request object for the current request or subrequest
149 * As this controller goes only through the main() method, it is rather simple for now
150 *
151 * @param ServerRequestInterface $request the current request
152 * @return ResponseInterface the response with the content
153 */
154 public function mainAction(ServerRequestInterface $request): ResponseInterface
155 {
156 $this->main($request);
157 return new HtmlResponse($this->moduleTemplate->renderContent());
158 }
159
160 /**
161 * Determines if table/uid point to database record or file and
162 * if user has access to view information
163 *
164 * @param ServerRequestInterface|null $request
165 */
166 public function init(ServerRequestInterface $request = null): void
167 {
168 if ($request === null) {
169 // Missing argument? This method must have been called from outside.
170 // Method will be protected and $request mandatory in v10, giving core freedom to move stuff around
171 // New v10 signature: "protected function init(ServerRequestInterface $request): void"
172 // @deprecated since TYPO3 v9, method argument $request will be set to mandatory
173 trigger_error('Method init() will be set to protected in v10. Do not call from other extension', E_USER_DEPRECATED);
174 $request = $GLOBALS['TYPO3_REQUEST'];
175 }
176
177 $queryParams = $request->getQueryParams();
178
179 $this->table = $queryParams['table'] ?? null;
180 $this->uid = $queryParams['uid'] ?? null;
181
182 $this->permsClause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW);
183 $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
184 $this->moduleTemplate->getDocHeaderComponent()->disable();
185
186 if (isset($GLOBALS['TCA'][$this->table])) {
187 $this->initDatabaseRecord();
188 } elseif ($this->table === '_FILE' || $this->table === '_FOLDER' || $this->table === 'sys_file') {
189 $this->initFileOrFolderRecord();
190 }
191 }
192
193 /**
194 * Init database records (table)
195 */
196 protected function initDatabaseRecord()
197 {
198 $this->type = 'db';
199 $this->uid = (int)$this->uid;
200
201 // Check permissions and uid value:
202 if ($this->uid && $this->getBackendUser()->check('tables_select', $this->table)) {
203 if ((string)$this->table === 'pages') {
204 $this->pageInfo = BackendUtility::readPageAccess($this->uid, $this->permsClause);
205 $this->access = is_array($this->pageInfo);
206 $this->row = $this->pageInfo;
207 } else {
208 $this->row = BackendUtility::getRecordWSOL($this->table, $this->uid);
209 if ($this->row) {
210 $this->pageInfo = BackendUtility::readPageAccess($this->row['pid'], $this->permsClause);
211 $this->access = is_array($this->pageInfo);
212 }
213 }
214 }
215 }
216
217 /**
218 * Init file/folder parameters
219 */
220 protected function initFileOrFolderRecord()
221 {
222 $fileOrFolderObject = ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->uid);
223
224 if ($fileOrFolderObject instanceof Folder) {
225 $this->folderObject = $fileOrFolderObject;
226 $this->access = $this->folderObject->checkActionPermission('read');
227 $this->type = 'folder';
228 } elseif ($fileOrFolderObject instanceof File) {
229 $this->fileObject = $fileOrFolderObject;
230 $this->access = $this->fileObject->checkActionPermission('read');
231 $this->type = 'file';
232 $this->table = 'sys_file';
233
234 try {
235 $this->row = BackendUtility::getRecordWSOL($this->table, $fileOrFolderObject->getUid());
236 } catch (\Exception $e) {
237 $this->row = [];
238 }
239 }
240 }
241
242 /**
243 * Compiles the whole content to be outputted, which is then set as content to the moduleTemplate
244 * There is a hook to do a custom rendering of a record.
245 *
246 * @param ServerRequestInterface $request
247 */
248 public function main(ServerRequestInterface $request = null): void
249 {
250 if ($request === null) {
251 // Missing argument? This method must have been called from outside.
252 // @deprecated since TYPO3 v9, method argument $request will be set to mandatory
253 trigger_error('Method main() will be set to protected in v10. Do not call from other extension', E_USER_DEPRECATED);
254 $request = $GLOBALS['TYPO3_REQUEST'];
255 }
256
257 $content = '';
258
259 // Rendering of the output via fluid
260 $view = GeneralUtility::makeInstance(StandaloneView::class);
261 $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
262 $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
263 $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
264 'EXT:backend/Resources/Private/Templates/ContentElement/ElementInformation.html'
265 ));
266
267 if ($this->access) {
268 // render type by user func
269 $typeRendered = false;
270 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/show_item.php']['typeRendering'] ?? [] as $className) {
271 $typeRenderObj = GeneralUtility::makeInstance($className);
272 if (is_object($typeRenderObj) && method_exists($typeRenderObj, 'isValid') && method_exists($typeRenderObj, 'render')) {
273 if ($typeRenderObj->isValid($this->type, $this)) {
274 $content .= $typeRenderObj->render($this->type, $this);
275 $typeRendered = true;
276 break;
277 }
278 }
279 }
280
281 if (!$typeRendered) {
282 $view->assign('accessAllowed', true);
283 $view->assignMultiple($this->getPageTitle());
284 $view->assignMultiple($this->getPreview());
285 $view->assignMultiple($this->getPropertiesForTable());
286 $view->assignMultiple($this->getReferences($request));
287 $view->assign('returnUrl', GeneralUtility::sanitizeLocalUrl($request->getQueryParams()['returnUrl']));
288 $view->assign('maxTitleLength', $this->getBackendUser()->uc['titleLen'] ?? 20);
289 $content .= $view->render();
290 }
291 } else {
292 $content .= $view->render();
293 }
294
295 $this->moduleTemplate->setContent($content);
296 }
297
298 /**
299 * Get page title with icon, table title and record title
300 *
301 * @return array
302 */
303 protected function getPageTitle(): array
304 {
305 $pageTitle = [
306 'title' => BackendUtility::getRecordTitle($this->table, $this->row, false)
307 ];
308 if ($this->type === 'folder') {
309 $pageTitle['table'] = $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:folder');
310 $pageTitle['icon'] = $this->iconFactory->getIconForResource($this->folderObject, Icon::SIZE_SMALL)->render();
311 } elseif ($this->type === 'file') {
312 $pageTitle['table'] = $this->getLanguageService()->sL($GLOBALS['TCA'][$this->table]['ctrl']['title']);
313 $pageTitle['icon'] = $this->iconFactory->getIconForResource($this->fileObject, Icon::SIZE_SMALL)->render();
314 } else {
315 $pageTitle['table'] = $this->getLanguageService()->sL($GLOBALS['TCA'][$this->table]['ctrl']['title']);
316 $pageTitle['icon'] = $this->iconFactory->getIconForRecord($this->table, $this->row, Icon::SIZE_SMALL);
317 }
318 $this->moduleTemplate->setTitle($pageTitle['table'] . ': ' . $pageTitle['title']);
319 return $pageTitle;
320 }
321
322 /**
323 * Get preview for current record
324 *
325 * @return array
326 */
327 protected function getPreview(): array
328 {
329 $preview = [];
330 // Perhaps @todo in future: Also display preview for records - without fileObject
331 if (!$this->fileObject) {
332 return $preview;
333 }
334
335 // check if file is marked as missing
336 if ($this->fileObject->isMissing()) {
337 $preview['missingFile'] = $this->fileObject->getName();
338 } else {
339 /** @var \TYPO3\CMS\Core\Resource\Rendering\RendererRegistry $rendererRegistry */
340 $rendererRegistry = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Rendering\RendererRegistry::class);
341 $fileRenderer = $rendererRegistry->getRenderer($this->fileObject);
342 $fileExtension = $this->fileObject->getExtension();
343 $preview['url'] = $this->fileObject->getPublicUrl(true);
344
345 $width = '590m';
346 $heigth = '400m';
347
348 // Check if there is a FileRenderer
349 if ($fileRenderer !== null) {
350 $preview['fileRenderer'] = $fileRenderer->render(
351 $this->fileObject,
352 $width,
353 $heigth,
354 [],
355 true
356 );
357
358 // else check if we can create an Image preview
359 } elseif (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileExtension)) {
360 $preview['fileObject'] = $this->fileObject;
361 $preview['width'] = $width;
362 $preview['heigth'] = $heigth;
363 }
364 }
365 return $preview;
366 }
367
368 /**
369 * Get property array for html table
370 *
371 * @return array
372 */
373 protected function getPropertiesForTable(): array
374 {
375 $propertiesForTable = [];
376 $lang = $this->getLanguageService();
377
378 $extraFields = [
379 'uid' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.uid'))
380 ];
381
382 if (in_array($this->type, ['folder', 'file'], true)) {
383 if ($this->type === 'file') {
384 $extraFields['creation_date'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationDate'));
385 $extraFields['modification_date'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.timestamp'));
386 if ($this->fileObject->getType() === AbstractFile::FILETYPE_IMAGE) {
387 $extraFields['width'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.width'));
388 $extraFields['height'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.height'));
389 }
390 }
391 $extraFields['storage'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file.storage'));
392 $extraFields['folder'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:folder'));
393 } else {
394 $extraFields['crdate'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationDate'));
395 $extraFields['cruser_id'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationUserId'));
396 $extraFields['tstamp'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.timestamp'));
397
398 // check if the special fields are defined in the TCA ctrl section of the table
399 foreach ($extraFields as $fieldName => $fieldLabel) {
400 if (isset($GLOBALS['TCA'][$this->table]['ctrl'][$fieldName])) {
401 $extraFields[$GLOBALS['TCA'][$this->table]['ctrl'][$fieldName]] = $fieldLabel;
402 } elseif ($fieldName !== 'uid') {
403 unset($extraFields[$fieldName]);
404 }
405 }
406 }
407
408 foreach ($extraFields as $name => $fieldLabel) {
409 $rowValue = '';
410 $thisRow = [];
411 if (!isset($this->row[$name])) {
412 $resourceObject = $this->fileObject ?: $this->folderObject;
413 if ($name === 'storage') {
414 $rowValue = $resourceObject->getStorage()->getName();
415 } elseif ($name === 'folder') {
416 $rowValue = $resourceObject->getParentFolder()->getReadablePath();
417 } elseif ($name === 'width') {
418 $rowValue = $this->fileObject->getProperty('width') . 'px';
419 } elseif ($name === 'height') {
420 $rowValue = $this->fileObject->getProperty('height') . 'px';
421 }
422 } elseif ($name === 'creation_date' || $name === 'modification_date' || $name === 'tstamp' || $name === 'crdate') {
423 $rowValue = BackendUtility::datetime($this->row[$name]);
424 } else {
425 $rowValue = BackendUtility::getProcessedValueExtra($this->table, $name, $this->row[$name]);
426 }
427 $thisRow['value'] = $rowValue;
428 $thisRow['fieldLabel'] = rtrim($fieldLabel, ':');
429 // show the backend username who created the issue
430 if ($name === 'cruser_id' && $rowValue) {
431 $creatorRecord = BackendUtility::getRecord('be_users', $rowValue);
432 if ($creatorRecord) {
433 /** @var Avatar $avatar */
434 $avatar = GeneralUtility::makeInstance(Avatar::class);
435 $creatorRecord['icon'] = $avatar->render($creatorRecord);
436 $thisRow['creatorRecord'] = $creatorRecord;
437 $thisRow['value'] = '';
438 }
439 }
440 $propertiesForTable['extraFields'][] = $thisRow;
441 }
442
443 // Traverse the list of fields to display for the record:
444 $fieldList = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$this->table]['interface']['showRecordFieldList'], true);
445 foreach ($fieldList as $name) {
446 $thisRow = [];
447 $name = trim($name);
448 $uid = $this->row['uid'];
449
450 if (!isset($GLOBALS['TCA'][$this->table]['columns'][$name])) {
451 continue;
452 }
453
454 // Storage is already handled above
455 if ($this->type === 'file' && $name === 'storage') {
456 continue;
457 }
458
459 // format file size as bytes/kilobytes/megabytes
460 if ($this->type === 'file' && $name === 'size') {
461 $this->row[$name] = GeneralUtility::formatSize($this->row[$name], htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:byteSizeUnits')));
462 }
463
464 $isExcluded = !(!$GLOBALS['TCA'][$this->table]['columns'][$name]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', $this->table . ':' . $name));
465 if ($isExcluded) {
466 continue;
467 }
468
469 $thisRow['fieldValue'] = BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, 0, false, $uid);
470 $thisRow['fieldLabel'] = htmlspecialchars($lang->sL(BackendUtility::getItemLabel($this->table, $name)));
471 $propertiesForTable['fields'][] = $thisRow;
472 }
473 return $propertiesForTable;
474 }
475
476 /**
477 * Get references section (references from and references to current record)
478 *
479 * @param ServerRequestInterface $request
480 * @return array
481 */
482 protected function getReferences(ServerRequestInterface $request): array
483 {
484 $references = [];
485 switch ($this->type) {
486 case 'db': {
487 $references['refLines'] = $this->makeRef($this->table, $this->row['uid'], $request);
488 $references['refFromLines'] = $this->makeRefFrom($this->table, $this->row['uid'], $request);
489 break;
490 }
491
492 case 'file': {
493 if ($this->fileObject && $this->fileObject->isIndexed()) {
494 $references['refLines'] = $this->makeRef('_FILE', $this->fileObject, $request);
495 }
496 break;
497 }
498 }
499 return $references;
500 }
501
502 /**
503 * Get field name for specified table/column name
504 *
505 * @param string $tableName Table name
506 * @param string $fieldName Column name
507 * @return string label
508 */
509 protected function getLabelForTableColumn($tableName, $fieldName)
510 {
511 if ($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label'] !== null) {
512 $field = $this->getLanguageService()->sL($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label']);
513 if (trim($field) === '') {
514 $field = $fieldName;
515 }
516 } else {
517 $field = $fieldName;
518 }
519 return $field;
520 }
521
522 /**
523 * Returns the record actions
524 *
525 * @param string $table
526 * @param int $uid
527 * @param ServerRequestInterface $request
528 * @return array
529 */
530 protected function getRecordActions($table, $uid, ServerRequestInterface $request): array
531 {
532 if ($table === '' || $uid < 0) {
533 return [];
534 }
535
536 $actions = [];
537 // Edit button
538 $urlParameters = [
539 'edit' => [
540 $table => [
541 $uid => 'edit'
542 ]
543 ],
544 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri()
545 ];
546 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
547 $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
548 $actions['recordEditUrl'] = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
549
550 // History button
551 $urlParameters = [
552 'element' => $table . ':' . $uid,
553 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri()
554 ];
555 $actions['recordHistoryUrl'] = (string)$uriBuilder->buildUriFromRoute('record_history', $urlParameters);
556
557 if ($table === 'pages') {
558 // Recordlist button
559 $actions['webListUrl'] = (string)$uriBuilder->buildUriFromRoute('web_list', ['id' => $uid, 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri()]);
560
561 // View page button
562 $actions['viewOnClick'] = BackendUtility::viewOnClick($uid, '', BackendUtility::BEgetRootLine($uid));
563 }
564
565 return $actions;
566 }
567
568 /**
569 * Make reference display
570 *
571 * @param string $table Table name
572 * @param string|\TYPO3\CMS\Core\Resource\File $ref Filename or uid
573 * @param ServerRequestInterface $request
574 * @return array
575 */
576 protected function makeRef($table, $ref, ServerRequestInterface $request)
577 {
578 $refLines = [];
579 $lang = $this->getLanguageService();
580 // Files reside in sys_file table
581 if ($table === '_FILE') {
582 $selectTable = 'sys_file';
583 $selectUid = $ref->getUid();
584 } else {
585 $selectTable = $table;
586 $selectUid = $ref;
587 }
588 /** @var $queryBuilder \TYPO3\CMS\Core\Database\Query\QueryBuilder */
589 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
590 ->getQueryBuilderForTable('sys_refindex');
591 $rows = $queryBuilder
592 ->select('*')
593 ->from('sys_refindex')
594 ->where(
595 $queryBuilder->expr()->eq(
596 'ref_table',
597 $queryBuilder->createNamedParameter($selectTable, \PDO::PARAM_STR)
598 ),
599 $queryBuilder->expr()->eq(
600 'ref_uid',
601 $queryBuilder->createNamedParameter($selectUid, \PDO::PARAM_INT)
602 ),
603 $queryBuilder->expr()->eq(
604 'deleted',
605 $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
606 )
607 )
608 ->execute()
609 ->fetchAll();
610
611 // Compile information for title tag:
612 foreach ($rows as $row) {
613 if ($row['tablename'] === 'sys_file_reference') {
614 $row = $this->transformFileReferenceToRecordReference($row);
615 if ($row['tablename'] === null || $row['recuid'] === null) {
616 return;
617 }
618 }
619 $line = [];
620 $record = BackendUtility::getRecord($row['tablename'], $row['recuid']);
621 if ($record) {
622 $parentRecord = BackendUtility::getRecord('pages', $record['pid']);
623 $parentRecordTitle = is_array($parentRecord)
624 ? BackendUtility::getRecordTitle('pages', $parentRecord)
625 : '';
626 $urlParameters = [
627 'edit' => [
628 $row['tablename'] => [
629 $row['recuid'] => 'edit'
630 ]
631 ],
632 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri()
633 ];
634 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
635 $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
636 $url = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
637 $line['url'] = $url;
638 $line['icon'] = $this->iconFactory->getIconForRecord($row['tablename'], $record, Icon::SIZE_SMALL)->render();
639 $line['row'] = $row;
640 $line['record'] = $record;
641 $line['recordTitle'] = BackendUtility::getRecordTitle($row['tablename'], $record, false, true);
642 $line['parentRecordTitle'] = $parentRecordTitle;
643 $line['title'] = $lang->sL($GLOBALS['TCA'][$row['tablename']]['ctrl']['title']);
644 $line['labelForTableColumn'] = $this->getLabelForTableColumn($row['tablename'], $row['field']);
645 $line['actions'] = $this->getRecordActions($row['tablename'], $row['recuid'], $request);
646 } else {
647 $line['row'] = $row;
648 $line['title'] = $lang->sL($GLOBALS['TCA'][$row['tablename']]['ctrl']['title']) ?: $row['tablename'];
649 $line['labelForTableColumn'] = $this->getLabelForTableColumn($row['tablename'], $row['field']);
650 }
651 $refLines[] = $line;
652 }
653 return $refLines;
654 }
655
656 /**
657 * Make reference display (what this elements points to)
658 *
659 * @param string $table Table name
660 * @param string $ref Filename or uid
661 * @param ServerRequestInterface $request
662 * @return array
663 */
664 protected function makeRefFrom($table, $ref, ServerRequestInterface $request): array
665 {
666 $refFromLines = [];
667 $lang = $this->getLanguageService();
668
669 /** @var $queryBuilder \TYPO3\CMS\Core\Database\Query\QueryBuilder */
670 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
671 ->getQueryBuilderForTable('sys_refindex');
672 $rows = $queryBuilder
673 ->select('*')
674 ->from('sys_refindex')
675 ->where(
676 $queryBuilder->expr()->eq(
677 'tablename',
678 $queryBuilder->createNamedParameter($table, \PDO::PARAM_STR)
679 ),
680 $queryBuilder->expr()->eq(
681 'recuid',
682 $queryBuilder->createNamedParameter($ref, \PDO::PARAM_INT)
683 )
684 )
685 ->execute()
686 ->fetchAll();
687
688 // Compile information for title tag:
689 foreach ($rows as $row) {
690 $line = [];
691 $record = BackendUtility::getRecord($row['ref_table'], $row['ref_uid']);
692 if ($record) {
693 $urlParameters = [
694 'edit' => [
695 $row['ref_table'] => [
696 $row['ref_uid'] => 'edit'
697 ]
698 ],
699 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri()
700 ];
701 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
702 $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
703 $url = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
704 $line['url'] = $url;
705 $line['icon'] = $this->iconFactory->getIconForRecord($row['tablename'], $record, Icon::SIZE_SMALL)->render();
706 $line['row'] = $row;
707 $line['record'] = $record;
708 $line['recordTitle'] = BackendUtility::getRecordTitle($row['ref_table'], $record, false, true);
709 $line['title'] = $lang->sL($GLOBALS['TCA'][$row['ref_table']]['ctrl']['title']);
710 $line['labelForTableColumn'] = $this->getLabelForTableColumn($table, $row['field']);
711 $line['actions'] = $this->getRecordActions($row['ref_table'], $row['ref_uid'], $request);
712 } else {
713 $line['row'] = $row;
714 $line['title'] = $lang->sL($GLOBALS['TCA'][$row['ref_table']]['ctrl']['title']);
715 $line['labelForTableColumn'] = $this->getLabelForTableColumn($table, $row['field']);
716 }
717 $refFromLines[] = $line;
718 }
719 return $refFromLines;
720 }
721
722 /**
723 * Convert FAL file reference (sys_file_reference) to reference index (sys_refindex) table format
724 *
725 * @param array $referenceRecord
726 * @return array
727 */
728 protected function transformFileReferenceToRecordReference(array $referenceRecord)
729 {
730 /** @var $queryBuilder \TYPO3\CMS\Core\Database\Query\QueryBuilder */
731 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
732 ->getQueryBuilderForTable('sys_file_reference');
733 $queryBuilder->getRestrictions()->removeAll();
734 $fileReference = $queryBuilder
735 ->select('*')
736 ->from('sys_file_reference')
737 ->where(
738 $queryBuilder->expr()->eq(
739 'uid',
740 $queryBuilder->createNamedParameter($referenceRecord['recuid'], \PDO::PARAM_INT)
741 )
742 )
743 ->execute()
744 ->fetch();
745
746 return [
747 'recuid' => $fileReference['uid_foreign'],
748 'tablename' => $fileReference['tablenames'],
749 'field' => $fileReference['fieldname'],
750 'flexpointer' => '',
751 'softref_key' => '',
752 'sorting' => $fileReference['sorting_foreign']
753 ];
754 }
755
756 /**
757 * Returns LanguageService
758 *
759 * @return \TYPO3\CMS\Core\Localization\LanguageService
760 */
761 protected function getLanguageService()
762 {
763 return $GLOBALS['LANG'];
764 }
765
766 /**
767 * Returns the current BE user.
768 *
769 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
770 */
771 protected function getBackendUser()
772 {
773 return $GLOBALS['BE_USER'];
774 }
775 }