[TASK] Decouple adminPanel from frontend
[Packages/TYPO3.CMS.git] / typo3 / sysext / adminpanel / Classes / Service / EditToolbarService.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Adminpanel\Service;
5
6 use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
7 use TYPO3\CMS\Backend\Routing\UriBuilder;
8 use TYPO3\CMS\Backend\Utility\BackendUtility;
9 use TYPO3\CMS\Core\Database\ConnectionPool;
10 use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
11 use TYPO3\CMS\Core\Imaging\Icon;
12 use TYPO3\CMS\Core\Imaging\IconFactory;
13 use TYPO3\CMS\Core\Localization\LanguageService;
14 use TYPO3\CMS\Core\Type\Bitmask\Permission;
15 use TYPO3\CMS\Core\Utility\GeneralUtility;
16 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
17
18 /**
19 * Class for the Edit Toolbar
20 *
21 * @internal
22 */
23 class EditToolbarService
24 {
25
26 /**
27 * Creates the tool bar links for the "edit" section of the Admin Panel.
28 *
29 * @return string A string containing images wrapped in <a>-tags linking them to proper functions.
30 */
31 public function createToolbar(): string
32 {
33 $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
34 $tsfe = $this->getTypoScriptFrontendController();
35 // If mod.newContentElementWizard.override is set, use that extension's create new content wizard instead:
36 $tsConfig = BackendUtility::getModTSconfig($tsfe->page['uid'], 'mod');
37 $moduleName = $tsConfig['properties']['newContentElementWizard.']['override'] ?? 'new_content_element';
38 /** @var UriBuilder $uriBuilder */
39 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
40 $perms = $this->getBackendUser()->calcPerms($tsfe->page);
41 $langAllowed = $this->getBackendUser()->checkLanguageAccess($tsfe->sys_language_uid);
42 $id = $tsfe->id;
43 $returnUrl = GeneralUtility::getIndpEnv('REQUEST_URI');
44 $classes = 'typo3-adminPanel-btn typo3-adminPanel-btn-default';
45 $output = [];
46 $output[] = '<div class="typo3-adminPanel-form-group">';
47 $output[] = ' <div class="typo3-adminPanel-btn-group" role="group">';
48
49 // History
50 /** @var UriBuilder $uriBuilder */
51 $link = (string)$uriBuilder->buildUriFromRoute(
52 'record_history',
53 [
54 'element' => 'pages:' . $id,
55 'returnUrl' => $returnUrl,
56 ]
57 );
58 $title = $this->extGetLL('edit_recordHistory');
59 $output[] = '<a class="' .
60 $classes .
61 '" href="' .
62 htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
63 '#latest" title="' .
64 $title .
65 '">';
66 $output[] = ' ' . $iconFactory->getIcon('actions-document-history-open', Icon::SIZE_SMALL)->render();
67 $output[] = '</a>';
68
69 // New Content
70 if ($perms & Permission::CONTENT_EDIT && $langAllowed) {
71 $linkParameters = [
72 'id' => $id,
73 'returnUrl' => $returnUrl,
74 ];
75 if (!empty($tsfe->sys_language_uid)) {
76 $linkParameters['sys_language_uid'] = $tsfe->sys_language_uid;
77 }
78 $link = (string)$uriBuilder->buildUriFromRoute($moduleName, $linkParameters);
79 $icon = $iconFactory->getIcon('actions-add', Icon::SIZE_SMALL)->render();
80 $title = $this->extGetLL('edit_newContentElement');
81 $output[] = '<a class="' .
82 $classes .
83 '" href="' .
84 htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
85 '" title="' .
86 $title .
87 '">';
88 $output[] = ' ' . $icon;
89 $output[] = '</a>';
90 }
91
92 // Move Page
93 if ($perms & Permission::PAGE_EDIT) {
94 $link = (string)$uriBuilder->buildUriFromRoute(
95 'move_element',
96 [
97 'table' => 'pages',
98 'uid' => $id,
99 'returnUrl' => $returnUrl,
100 ]
101 );
102 $icon = $iconFactory->getIcon('actions-document-move', Icon::SIZE_SMALL)->render();
103 $title = $this->extGetLL('edit_move_page');
104 $output[] = '<a class="' .
105 $classes .
106 '" href="' .
107 htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
108 '" title="' .
109 $title .
110 '">';
111 $output[] = ' ' . $icon;
112 $output[] = '</a>';
113 }
114
115 // New Page
116 if ($perms & Permission::PAGE_NEW) {
117 $link = (string)$uriBuilder->buildUriFromRoute(
118 'db_new',
119 [
120 'id' => $id,
121 'pagesOnly' => 1,
122 'returnUrl' => $returnUrl,
123 ]
124 );
125 $icon = $iconFactory->getIcon('actions-page-new', Icon::SIZE_SMALL)->render();
126 $title = $this->extGetLL('edit_newPage');
127 $output[] = '<a class="' .
128 $classes .
129 '" href="' .
130 htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
131 '" title="' .
132 $title .
133 '">';
134 $output[] = ' ' . $icon;
135 $output[] = '</a>';
136 }
137
138 // Edit Page
139 if ($perms & Permission::PAGE_EDIT) {
140 $link = (string)$uriBuilder->buildUriFromRoute(
141 'record_edit',
142 [
143 'edit[pages][' . $id . ']' => 'edit',
144 'noView' => 1,
145 'returnUrl' => $returnUrl,
146 ]
147 );
148 $icon = $iconFactory->getIcon('actions-page-open', Icon::SIZE_SMALL)->render();
149 $title = $this->extGetLL('edit_editPageProperties');
150 $output[] = '<a class="' .
151 $classes .
152 '" href="' .
153 htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
154 '" title="' .
155 $title .
156 '">';
157 $output[] = ' ' . $icon;
158 $output[] = '</a>';
159 }
160
161 // Edit Page Overlay
162 if ($perms & Permission::PAGE_EDIT && $tsfe->sys_language_uid && $langAllowed) {
163 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
164 ->getQueryBuilderForTable('pages');
165 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
166 $row = $queryBuilder
167 ->select('uid', 'pid', 't3ver_state')
168 ->from('pages')
169 ->where(
170 $queryBuilder->expr()->eq(
171 $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
172 $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
173 ),
174 $queryBuilder->expr()->eq(
175 $GLOBALS['TCA']['pages']['ctrl']['languageField'],
176 $queryBuilder->createNamedParameter($tsfe->sys_language_uid, \PDO::PARAM_INT)
177 )
178 )
179 ->setMaxResults(1)
180 ->execute()
181 ->fetch();
182 $tsfe->sys_page->versionOL('pages', $row);
183 if (is_array($row)) {
184 $link = (string)$uriBuilder->buildUriFromRoute(
185 'record_edit',
186 [
187 'edit[pages][' . $row['uid'] . ']' => 'edit',
188 'noView' => 1,
189 'returnUrl' => $returnUrl,
190 ]
191 );
192 $icon = $iconFactory->getIcon('mimetypes-x-content-page-language-overlay', Icon::SIZE_SMALL)
193 ->render();
194 $title = $this->extGetLL('edit_editPageOverlay');
195 $output[] = '<a class="' .
196 $classes .
197 '" href="' .
198 htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
199 '" title="' .
200 $title .
201 '">';
202 $output[] = ' ' . $icon;
203 $output[] = '</a>';
204 }
205 }
206
207 // Open list view
208 if ($this->getBackendUser()->check('modules', 'web_list')) {
209 $link = (string)$uriBuilder->buildUriFromRoute(
210 'web_list',
211 [
212 'id' => $id,
213 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI'),
214 ]
215 );
216 $icon = $iconFactory->getIcon('actions-system-list-open', Icon::SIZE_SMALL)->render();
217 $title = $this->extGetLL('edit_db_list');
218 $output[] = '<a class="' .
219 $classes .
220 '" href="' .
221 htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
222 '" title="' .
223 $title .
224 '">';
225 $output[] = ' ' . $icon;
226 $output[] = '</a>';
227 }
228
229 $output[] = ' </div>';
230 $output[] = '</div>';
231 return implode('', $output);
232 }
233
234 /**
235 * Translate given key
236 *
237 * @param string $key Key for a label in the $LOCAL_LANG array of "sysext/lang/Resources/Private/Language/locallang_tsfe.xlf
238 * @param bool $convertWithHtmlspecialchars If TRUE the language-label will be sent through htmlspecialchars
239 * @return string The value for the $key
240 */
241 protected function extGetLL($key, $convertWithHtmlspecialchars = true): ?string
242 {
243 $labelStr = $this->getLanguageService()->getLL($key);
244 if ($convertWithHtmlspecialchars) {
245 $labelStr = htmlspecialchars($labelStr, ENT_QUOTES | ENT_HTML5);
246 }
247 return $labelStr;
248 }
249
250 /**
251 * @return FrontendBackendUserAuthentication
252 */
253 protected function getBackendUser(): FrontendBackendUserAuthentication
254 {
255 return $GLOBALS['BE_USER'];
256 }
257
258 /**
259 * @return LanguageService
260 */
261 protected function getLanguageService(): LanguageService
262 {
263 return $GLOBALS['LANG'];
264 }
265
266 /**
267 * @return TypoScriptFrontendController
268 */
269 protected function getTypoScriptFrontendController(): TypoScriptFrontendController
270 {
271 return $GLOBALS['TSFE'];
272 }
273 }