[TASK] Fix CGL errors
[Packages/TYPO3.CMS.git] / typo3 / sysext / recordlist / Classes / LinkHandler / PageLinkHandler.php
1 <?php
2 namespace TYPO3\CMS\Recordlist\LinkHandler;
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 TYPO3\CMS\Backend\Tree\View\ElementBrowserPageTreeView;
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\Messaging\FlashMessage;
23 use TYPO3\CMS\Core\Page\PageRenderer;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\CMS\Core\Utility\MathUtility;
26 use TYPO3\CMS\Recordlist\Tree\View\LinkParameterProviderInterface;
27
28 /**
29 * Link handler for page (and content) links
30 */
31 class PageLinkHandler extends AbstractLinkHandler implements LinkHandlerInterface, LinkParameterProviderInterface
32 {
33 /**
34 * @var int
35 */
36 protected $expandPage = 0;
37
38 /**
39 * Parts of the current link
40 *
41 * @var array
42 */
43 protected $linkParts = [];
44
45 /**
46 * Checks if this is the handler for the given link
47 *
48 * The handler may store this information locally for later usage.
49 *
50 * @param array $linkParts Link parts as returned from TypoLinkCodecService
51 *
52 * @return bool
53 */
54 public function canHandleLink(array $linkParts)
55 {
56 if (!$linkParts['url']) {
57 return false;
58 }
59
60 $id = $linkParts['url'];
61 $parts = explode('#', $id);
62 if (count($parts) > 1) {
63 $id = $parts[0];
64 $anchor = $parts[1];
65 } else {
66 $anchor = '';
67 }
68 // Checking if the id-parameter is an alias.
69 if (!MathUtility::canBeInterpretedAsInteger($id)) {
70 $records = BackendUtility::getRecordsByField('pages', 'alias', $id);
71 if (empty($records)) {
72 return false;
73 }
74 $id = (int)$records[0]['uid'];
75 }
76 $pageRow = BackendUtility::getRecordWSOL('pages', $id);
77 if (!$pageRow) {
78 return false;
79 }
80
81 $this->linkParts = $linkParts;
82 $this->linkParts['pageid'] = $id;
83 $this->linkParts['anchor'] = $anchor;
84
85 return true;
86 }
87
88 /**
89 * Format the current link for HTML output
90 *
91 * @return string
92 */
93 public function formatCurrentUrl()
94 {
95 $lang = $this->getLanguageService();
96 $titleLen = (int)$this->getBackendUser()->uc['titleLen'];
97
98 $id = $this->linkParts['pageid'];
99 $pageRow = BackendUtility::getRecordWSOL('pages', $id);
100
101 return $lang->getLL('page', true)
102 . ' \'' . htmlspecialchars(GeneralUtility::fixed_lgd_cs($pageRow['title'], $titleLen)) . '\''
103 . ' (ID:' . $id . ($this->linkParts['anchor'] ? ', #' . $this->linkParts['anchor'] : '') . ')';
104 }
105
106 /**
107 * Render the link handler
108 *
109 * @param ServerRequestInterface $request
110 *
111 * @return string
112 */
113 public function render(ServerRequestInterface $request)
114 {
115 GeneralUtility::makeInstance(PageRenderer::class)->loadRequireJsModule('TYPO3/CMS/Recordlist/PageLinkHandler');
116
117 $this->expandPage = isset($request->getQueryParams()['expandPage']) ? (int)$request->getQueryParams()['expandPage'] : 0;
118 $this->setTemporaryDbMounts();
119
120 $backendUser = $this->getBackendUser();
121
122 /** @var ElementBrowserPageTreeView $pageTree */
123 $pageTree = GeneralUtility::makeInstance(ElementBrowserPageTreeView::class);
124 $pageTree->setLinkParameterProvider($this);
125 $pageTree->ext_showPageId = (bool)$backendUser->getTSConfigVal('options.pageTree.showPageIdWithTitle');
126 $pageTree->ext_showNavTitle = (bool)$backendUser->getTSConfigVal('options.pageTree.showNavTitle');
127 $pageTree->addField('nav_title');
128 $tree = $pageTree->getBrowsableTree();
129
130 return '
131
132 <!--
133 Wrapper table for page tree / record list:
134 -->
135 <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkPages">
136 <tr>
137 <td class="c-wCell" valign="top"><h3>' . $this->getLanguageService()->getLL('pageTree') . ':</h3>'
138 . $this->getTemporaryTreeMountCancelNotice() . $tree . '</td>
139 <td class="c-wCell" valign="top">' . $this->expandPage($this->expandPage) . '</td>
140 </tr>
141 </table>';
142 }
143
144 /**
145 * This displays all content elements on a page and lets you create a link to the element.
146 *
147 * @param int $expPageId Page uid to expand
148 *
149 * @return string HTML output. Returns content only if the ->expandPage value is set (pointing to a page uid to show tt_content records from ...)
150 */
151 public function expandPage($expPageId)
152 {
153 // If there is an anchor value (content element reference) in the element reference, then force an ID to expand:
154 if (!$expPageId && isset($this->linkParts['anchor'])) {
155 // Set to the current link page id.
156 $expPageId = $this->linkParts['pageid'];
157 }
158 // Draw the record list IF there is a page id to expand:
159 if (!$expPageId || !MathUtility::canBeInterpretedAsInteger($expPageId) || !$this->getBackendUser()->isInWebMount($expPageId)) {
160 return '';
161 }
162
163 // Set header:
164 $out = '<h3>' . $this->getLanguageService()->getLL('contentElements') . ':</h3>';
165 // Create header for listing, showing the page title/icon:
166 $mainPageRec = BackendUtility::getRecordWSOL('pages', $expPageId);
167 $db = $this->getDatabaseConnection();
168 $out .= '
169 <ul class="list-tree list-tree-root list-tree-root-clean">
170 <li class="list-tree-control-open">
171 <span class="list-tree-group">
172 <span class="list-tree-icon">' . $this->iconFactory->getIconForRecord('pages', $mainPageRec, Icon::SIZE_SMALL)->render() . '</span>
173 <span class="list-tree-title">' . htmlspecialchars(BackendUtility::getRecordTitle('pages', $mainPageRec, true)) . '</span>
174 </span>
175 <ul>
176 ';
177
178 // Look up tt_content elements from the expanded page:
179 $res = $db->exec_SELECTquery(
180 'uid,header,hidden,starttime,endtime,fe_group,CType,colPos,bodytext',
181 'tt_content',
182 'pid=' . (int)$expPageId . BackendUtility::deleteClause('tt_content')
183 . BackendUtility::versioningPlaceholderClause('tt_content'),
184 '',
185 'colPos,sorting'
186 );
187 // Traverse list of records:
188 $c = 0;
189 while ($row = $db->sql_fetch_assoc($res)) {
190 $c++;
191 $icon = $this->iconFactory->getIconForRecord('tt_content', $row, Icon::SIZE_SMALL)->render();
192 $selected = '';
193 if (!empty($this->linkParts) && (int)$this->linkParts['anchor'] === (int)$row['uid']) {
194 $selected = ' class="active"';
195 }
196 // Putting list element HTML together:
197 $out .= '
198 <li' . $selected . '>
199 <span class="list-tree-group">
200 <span class="list-tree-icon">
201 ' . $icon . '
202 </span>
203 <span class="list-tree-title">
204 <a href="#" class="t3js-pageLink" data-id="' . (int)$expPageId . '" data-anchor="#' . (int)$row['uid'] . '">
205 ' . htmlspecialchars(BackendUtility::getRecordTitle('tt_content', $row, true)) . '
206 </a>
207 </span>
208 </span>
209 </li>
210 ';
211 }
212 $out .= '
213 </ul>
214 </li>
215 </ul>
216 ';
217
218 return $out;
219 }
220
221 /**
222 * Check if a temporary tree mount is set and return a cancel button
223 *
224 * @return string HTML code
225 */
226 protected function getTemporaryTreeMountCancelNotice()
227 {
228 if ((int)$this->getBackendUser()->getSessionData('pageTree_temporaryMountPoint') === 0) {
229 return '';
230 }
231 $link = '<a href="' . htmlspecialchars(GeneralUtility::linkThisScript(array('setTempDBmount' => 0))) . '">'
232 . $this->getLanguageService()->sl('LLL:EXT:lang/locallang_core.xlf:labels.temporaryDBmount', true) . '</a>';
233
234 return GeneralUtility::makeInstance(FlashMessage::class, $link, '', FlashMessage::INFO)->render();
235 }
236
237 /**
238 * @return void
239 */
240 protected function setTemporaryDbMounts()
241 {
242 $backendUser = $this->getBackendUser();
243
244 // Clear temporary DB mounts
245 $tmpMount = GeneralUtility::_GET('setTempDBmount');
246 if (isset($tmpMount)) {
247 $backendUser->setAndSaveSessionData('pageTree_temporaryMountPoint', (int)$tmpMount);
248 }
249 // Set temporary DB mounts
250 $alternativeWebmountPoint = (int)$backendUser->getSessionData('pageTree_temporaryMountPoint');
251 if ($alternativeWebmountPoint) {
252 $alternativeWebmountPoint = GeneralUtility::intExplode(',', $alternativeWebmountPoint);
253 $backendUser->setWebmounts($alternativeWebmountPoint);
254 } else {
255 // Setting alternative browsing mounts (ONLY local to browse_links.php this script so they stay "read-only")
256 $alternativeWebmountPoints = trim($backendUser->getTSConfigVal('options.pageTree.altElementBrowserMountPoints'));
257 $appendAlternativeWebmountPoints = $backendUser->getTSConfigVal('options.pageTree.altElementBrowserMountPoints.append');
258 if ($alternativeWebmountPoints) {
259 $alternativeWebmountPoints = GeneralUtility::intExplode(',', $alternativeWebmountPoints);
260 $this->getBackendUser()->setWebmounts($alternativeWebmountPoints, $appendAlternativeWebmountPoints);
261 }
262 }
263 }
264
265 /**
266 * @return string[] Array of body-tag attributes
267 */
268 public function getBodyTagAttributes()
269 {
270 if (empty($this->linkParts)) {
271 return [];
272 }
273 return [
274 'data-current-link' => $this->linkParts['pageid'] . ($this->linkParts['anchor'] !== '' ? '#' . $this->linkParts['anchor'] : '')
275 ];
276 }
277
278 /**
279 * @param array $values Array of values to include into the parameters or which might influence the parameters
280 *
281 * @return string[] Array of parameters which have to be added to URLs
282 */
283 public function getUrlParameters(array $values)
284 {
285 $parameters = [
286 'expandPage' => isset($values['pid']) ? (int)$values['pid'] : $this->expandPage
287 ];
288 return array_merge($this->linkBrowser->getUrlParameters($values), $parameters);
289 }
290
291 /**
292 * @param array $values Values to be checked
293 *
294 * @return bool Returns TRUE if the given values match the currently selected item
295 */
296 public function isCurrentlySelectedItem(array $values)
297 {
298 return !empty($this->linkParts) && (int)$this->linkParts['pageid'] === (int)$values['pid'];
299 }
300
301 /**
302 * Returns the URL of the current script
303 *
304 * @return string
305 */
306 public function getScriptUrl()
307 {
308 return $this->linkBrowser->getScriptUrl();
309 }
310
311 /**
312 * @param string[] $fieldDefinitions Array of link attribute field definitions
313 * @return string[]
314 */
315 public function modifyLinkAttributes(array $fieldDefinitions)
316 {
317 $configuration = $this->linkBrowser->getConfiguration();
318 if (!empty($configuration['pageIdSelector.']['enabled'])) {
319 $fieldDefinitions['pageIdSelector'] = '
320 <tr>
321 <td>
322 <label>
323 ' . $this->getLanguageService()->getLL('page_id', true) . ':
324 </label>
325 </td>
326 <td colspan="3">
327 <input type="text" size="6" name="luid" id="luid" /> <input class="btn btn-default t3js-pageLink" type="submit" value="'
328 . $this->getLanguageService()->getLL('setLink', true) . '" />
329 </td>
330 </tr>';
331 }
332 return $fieldDefinitions;
333 }
334
335 /**
336 * @return DatabaseConnection
337 */
338 protected function getDatabaseConnection()
339 {
340 return $GLOBALS['TYPO3_DB'];
341 }
342 }