[BUGFIX] Show mountpoint path in record + link browsers if enabled in UserTS
[Packages/TYPO3.CMS.git] / typo3 / sysext / recordlist / Classes / Browser / DatabaseBrowser.php
1 <?php
2 namespace TYPO3\CMS\Recordlist\Browser;
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\RecordList\ElementBrowserRecordList;
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Core\Imaging\Icon;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Core\Utility\MathUtility;
22 use TYPO3\CMS\Recordlist\Tree\View\ElementBrowserPageTreeView;
23 use TYPO3\CMS\Recordlist\Tree\View\LinkParameterProviderInterface;
24
25 /**
26 * Showing a page tree and allows you to browse for records
27 */
28 class DatabaseBrowser extends AbstractElementBrowser implements ElementBrowserInterface, LinkParameterProviderInterface
29 {
30 /**
31 * When you click a page title/expand icon to see the content of a certain page, this
32 * value will contain the ID of the expanded page.
33 * If the value is NOT set by GET parameter, then it will be restored from the module session data.
34 *
35 * @var NULL|int
36 */
37 protected $expandPage;
38
39 /**
40 * @return void
41 */
42 protected function initialize()
43 {
44 parent::initialize();
45 $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/BrowseDatabase');
46 }
47
48 /**
49 * @return void
50 */
51 protected function initVariables()
52 {
53 parent::initVariables();
54 $this->expandPage = GeneralUtility::_GP('expandPage');
55 }
56
57 /**
58 * Session data for this class can be set from outside with this method.
59 *
60 * @param mixed[] $data Session data array
61 * @return array[] Session data and boolean which indicates that data needs to be stored in session because it's changed
62 */
63 public function processSessionData($data)
64 {
65 if ($this->expandPage !== null) {
66 $data['expandPage'] = $this->expandPage;
67 $store = true;
68 } else {
69 $this->expandPage = (int)$data['expandPage'];
70 $store = false;
71 }
72 return [$data, $store];
73 }
74
75 /**
76 * @return string HTML content
77 */
78 public function render()
79 {
80 $this->setTemporaryDbMounts();
81
82 list(, , , $allowedTables) = explode('|', $this->bparams);
83 $backendUser = $this->getBackendUser();
84
85 // Making the browsable pagetree:
86 /** @var ElementBrowserPageTreeView $pageTree */
87 $pageTree = GeneralUtility::makeInstance(ElementBrowserPageTreeView::class);
88 $pageTree->setLinkParameterProvider($this);
89 $pageTree->ext_pArrPages = $allowedTables === 'pages';
90 $pageTree->ext_showNavTitle = (bool)$backendUser->getTSConfigVal('options.pageTree.showNavTitle');
91 $pageTree->ext_showPageId = (bool)$backendUser->getTSConfigVal('options.pageTree.showPageIdWithTitle');
92 $pageTree->ext_showPathAboveMounts = (bool)$backendUser->getTSConfigVal('options.pageTree.showPathAboveMounts');
93 $pageTree->addField('nav_title');
94 $tree = $pageTree->getBrowsableTree();
95
96 $withTree = true;
97 if ($allowedTables !== '' && $allowedTables !== '*') {
98 $tablesArr = GeneralUtility::trimExplode(',', $allowedTables, true);
99 $onlyRootLevel = true;
100 foreach ($tablesArr as $currentTable) {
101 if (isset($GLOBALS['TCA'][$currentTable])) {
102 if (!isset($GLOBALS['TCA'][$currentTable]['ctrl']['rootLevel']) || (int)$GLOBALS['TCA'][$currentTable]['ctrl']['rootLevel'] !== 1) {
103 $onlyRootLevel = false;
104 }
105 }
106 }
107 if ($onlyRootLevel) {
108 $withTree = false;
109 // page to work on is root
110 $this->expandPage = 0;
111 }
112 }
113
114 $renderedRecordList = $this->renderTableRecords($allowedTables);
115
116 $this->initDocumentTemplate();
117 $content = $this->doc->startPage('TBE record selector');
118 $content .= $this->doc->getFlashMessages();
119
120 $content .= '
121
122 <!--
123 Wrapper table for page tree / record list:
124 -->
125 <table border="0" cellpadding="0" cellspacing="0" id="typo3-EBrecords">
126 <tr>';
127 if ($withTree) {
128 $content .= '<td class="c-wCell" valign="top">'
129 . '<h3>' . $this->getLanguageService()->getLL('pageTree', true) . ':</h3>'
130 . $this->getTemporaryTreeMountCancelNotice() . $tree . '</td>';
131 }
132 $content .= '<td class="c-wCell" valign="top">' . $renderedRecordList . '</td>
133 </tr>
134 </table>
135 ';
136
137 // Add some space
138 $content .= '<br /><br />';
139
140 $content .= $this->doc->endPage();
141 return $this->doc->insertStylesAndJS($content);
142 }
143
144 /**
145 * Check if a temporary tree mount is set and return a cancel button
146 *
147 * @return string HTML code
148 */
149 protected function getTemporaryTreeMountCancelNotice()
150 {
151 if ((int)$this->getBackendUser()->getSessionData('pageTree_temporaryMountPoint') === 0) {
152 return '';
153 }
154 $link = '<p><a href="' . htmlspecialchars(GeneralUtility::linkThisScript(['setTempDBmount' => 0])) . '" class="btn btn-primary">'
155 . $this->getLanguageService()->sl('LLL:EXT:lang/locallang_core.xlf:labels.temporaryDBmount', true) . '</a></p>';
156
157 return $link;
158 }
159
160 /**
161 * @return void
162 */
163 protected function setTemporaryDbMounts()
164 {
165 $backendUser = $this->getBackendUser();
166
167 // Clear temporary DB mounts
168 $tmpMount = GeneralUtility::_GET('setTempDBmount');
169 if (isset($tmpMount)) {
170 $backendUser->setAndSaveSessionData('pageTree_temporaryMountPoint', (int)$tmpMount);
171 }
172 // Set temporary DB mounts
173 $alternativeWebmountPoint = (int)$backendUser->getSessionData('pageTree_temporaryMountPoint');
174 if ($alternativeWebmountPoint) {
175 $alternativeWebmountPoint = GeneralUtility::intExplode(',', $alternativeWebmountPoint);
176 $backendUser->setWebmounts($alternativeWebmountPoint);
177 } else {
178 // Setting alternative browsing mounts (ONLY local to browse_links.php this script so they stay "read-only")
179 $alternativeWebmountPoints = trim($backendUser->getTSConfigVal('options.pageTree.altElementBrowserMountPoints'));
180 $appendAlternativeWebmountPoints = $backendUser->getTSConfigVal('options.pageTree.altElementBrowserMountPoints.append');
181 if ($alternativeWebmountPoints) {
182 $alternativeWebmountPoints = GeneralUtility::intExplode(',', $alternativeWebmountPoints);
183 $this->getBackendUser()->setWebmounts($alternativeWebmountPoints, $appendAlternativeWebmountPoints);
184 }
185 }
186 }
187
188 /**
189 * This lists all content elements for the given list of tables
190 *
191 * @param string $tables Comma separated list of tables. Set to "*" if you want all tables.
192 * @return string HTML code
193 */
194 protected function renderTableRecords($tables)
195 {
196 $backendUser = $this->getBackendUser();
197 if ($this->expandPage === null || $this->expandPage < 0 || !$backendUser->isInWebMount($this->expandPage)) {
198 return '';
199 }
200 // Set array with table names to list:
201 if (trim($tables) === '*') {
202 $tablesArr = array_keys($GLOBALS['TCA']);
203 } else {
204 $tablesArr = GeneralUtility::trimExplode(',', $tables, true);
205 }
206
207 $out = '<h3>' . $this->getLanguageService()->getLL('selectRecords', true) . ':</h3>';
208 // Create the header, showing the current page for which the listing is.
209 // Includes link to the page itself, if pages are amount allowed tables.
210 $titleLen = (int)$backendUser->uc['titleLen'];
211 $mainPageRecord = BackendUtility::getRecordWSOL('pages', $this->expandPage);
212 if (is_array($mainPageRecord)) {
213 $pText = htmlspecialchars(GeneralUtility::fixed_lgd_cs($mainPageRecord['title'], $titleLen));
214
215 $out .= $this->iconFactory->getIconForRecord('pages', $mainPageRecord, Icon::SIZE_SMALL)->render();
216 if (in_array('pages', $tablesArr, true)) {
217 $out .= '<span data-uid="' . htmlspecialchars($mainPageRecord['uid']) . '" data-table="pages" data-title="' . htmlspecialchars($mainPageRecord['title']) . '" data-icon="">';
218 $out .= '<a href="#" data-close="0">'
219 . $this->iconFactory->getIcon('actions-edit-add', Icon::SIZE_SMALL)->render()
220 . '</a>'
221 . '<a href="#" data-close="1">'
222 . $pText
223 . '</a>';
224 $out .= '</span>';
225 } else {
226 $out .= $pText;
227 }
228 $out .= '<br />';
229 }
230
231 $permsClause = $backendUser->getPagePermsClause(1);
232 $pageInfo = BackendUtility::readPageAccess($this->expandPage, $permsClause);
233
234 /** @var ElementBrowserRecordList $dbList */
235 $dbList = GeneralUtility::makeInstance(ElementBrowserRecordList::class);
236 $dbList->setOverrideUrlParameters($this->getUrlParameters([]));
237 $dbList->thisScript = $this->thisScript;
238 $dbList->thumbs = false;
239 $dbList->localizationView = true;
240 $dbList->setIsEditable(false);
241 $dbList->calcPerms = $backendUser->calcPerms($pageInfo);
242 $dbList->noControlPanels = true;
243 $dbList->clickMenuEnabled = false;
244 $dbList->tableList = implode(',', $tablesArr);
245
246 // a string like "data[pages][79][storage_pid]"
247 list($fieldPointerString) = explode('|', $this->bparams);
248 // parts like: data, pages], 79], storage_pid]
249 $fieldPointerParts = explode('[', $fieldPointerString);
250 $relatingTableName = substr($fieldPointerParts[1], 0, -1);
251 $relatingFieldName = substr($fieldPointerParts[3], 0, -1);
252 if ($relatingTableName && $relatingFieldName) {
253 $dbList->setRelatingTableAndField($relatingTableName, $relatingFieldName);
254 }
255
256 $dbList->start(
257 $this->expandPage,
258 GeneralUtility::_GP('table'),
259 MathUtility::forceIntegerInRange(GeneralUtility::_GP('pointer'), 0, 100000),
260 GeneralUtility::_GP('search_field'),
261 GeneralUtility::_GP('search_levels'),
262 GeneralUtility::_GP('showLimit')
263 );
264
265 $dbList->setDispFields();
266 $dbList->generateList();
267
268 $out .= $dbList->getSearchBox();
269
270 // Add the HTML for the record list to output variable:
271 $out .= $dbList->HTMLcode;
272
273 // Add support for fieldselectbox in singleTableMode
274 if ($dbList->table) {
275 $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/FieldSelectBox');
276 $out .= $dbList->fieldSelectBox($dbList->table);
277 }
278
279 return $out;
280 }
281
282 /**
283 * @return string[] Array of body-tag attributes
284 */
285 protected function getBodyTagAttributes()
286 {
287 return [
288 'data-mode' => 'db'
289 ];
290 }
291
292 /**
293 * @param array $values Array of values to include into the parameters
294 * @return string[] Array of parameters which have to be added to URLs
295 */
296 public function getUrlParameters(array $values)
297 {
298 $pid = isset($values['pid']) ? $values['pid'] : $this->expandPage;
299 return [
300 'mode' => 'db',
301 'expandPage' => $pid,
302 'bparams' => $this->bparams
303 ];
304 }
305
306 /**
307 * @param array $values Values to be checked
308 * @return bool Returns TRUE if the given values match the currently selected item
309 */
310 public function isCurrentlySelectedItem(array $values)
311 {
312 return false;
313 }
314
315 /**
316 * Returns the URL of the current script
317 *
318 * @return string
319 */
320 public function getScriptUrl()
321 {
322 return $this->thisScript;
323 }
324 }