101c9bee217d403887c4d27fd394f2b31940c9ec
[Packages/TYPO3.CMS.git] / typo3 / sysext / beuser / Classes / Controller / PermissionController.php
1 <?php
2 namespace TYPO3\CMS\Beuser\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\Template\Components\ButtonBar;
18 use TYPO3\CMS\Backend\Tree\View\PageTreeView;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
20 use TYPO3\CMS\Backend\View\BackendTemplateView;
21 use TYPO3\CMS\Core\Database\ConnectionPool;
22 use TYPO3\CMS\Core\Imaging\Icon;
23 use TYPO3\CMS\Core\Messaging\FlashMessage;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
26 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
27 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
28
29 /**
30 * Backend module page permissions
31 */
32 class PermissionController extends ActionController
33 {
34 /**
35 * @var string prefix for session
36 */
37 const SESSION_PREFIX = 'tx_Beuser_';
38
39 /**
40 * @var int the current page id
41 */
42 protected $id;
43
44 /**
45 * @var string
46 */
47 protected $returnUrl = '';
48
49 /**
50 * @var int
51 */
52 protected $depth;
53
54 /**
55 * Number of levels to enable recursive settings for
56 *
57 * @var int
58 */
59 protected $getLevels = 10;
60
61 /**
62 * @var array
63 */
64 protected $pageInfo = [];
65
66 /**
67 * Backend Template Container
68 *
69 * @var string
70 */
71 protected $defaultViewObjectName = BackendTemplateView::class;
72
73 /**
74 * BackendTemplateContainer
75 *
76 * @var BackendTemplateView
77 */
78 protected $view;
79
80 /**
81 * Initialize action
82 */
83 protected function initializeAction()
84 {
85 // determine depth parameter
86 $this->depth = (int)GeneralUtility::_GP('depth') > 0
87 ? (int)GeneralUtility::_GP('depth')
88 : (int)$this->getBackendUser()->getSessionData(self::SESSION_PREFIX . 'depth');
89 if ($this->request->hasArgument('depth')) {
90 $this->depth = (int)$this->request->getArgument('depth');
91 }
92 $this->getBackendUser()->setAndSaveSessionData(self::SESSION_PREFIX . 'depth', $this->depth);
93
94 // determine id parameter
95 $this->id = (int)GeneralUtility::_GP('id');
96 if ($this->request->hasArgument('id')) {
97 $this->id = (int)$this->request->getArgument('id');
98 }
99
100 $this->returnUrl = GeneralUtility::_GP('returnUrl');
101 if ($this->request->hasArgument('returnUrl')) {
102 $this->returnUrl = $this->request->getArgument('returnUrl');
103 }
104
105 $this->pageInfo = BackendUtility::readPageAccess($this->id, ' 1=1');
106 }
107
108 /**
109 * Initializes view
110 *
111 * @param ViewInterface $view The view to be initialized
112 */
113 protected function initializeView(ViewInterface $view)
114 {
115 parent::initializeView($view);
116 $view->assign(
117 'previewUrl',
118 BackendUtility::viewOnClick(
119 (int)$this->pageInfo['uid'],
120 '',
121 BackendUtility::BEgetRootLine((int)$this->pageInfo['uid'])
122 )
123 );
124
125 // the view of the update action has a different view class
126 if ($view instanceof BackendTemplateView) {
127 $view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Beuser/Permissions');
128 $view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip');
129 $view->getModuleTemplate()->addJavaScriptCode(
130 'jumpToUrl',
131 '
132 function jumpToUrl(URL) {
133 window.location.href = URL;
134 return false;
135 }
136 '
137 );
138 $this->registerDocHeaderButtons();
139 $this->view->getModuleTemplate()->getDocHeaderComponent()->setMetaInformation($this->pageInfo);
140 $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
141 }
142 }
143
144 /**
145 * Registers the Icons into the docheader
146 *
147 * @throws \InvalidArgumentException
148 */
149 protected function registerDocHeaderButtons()
150 {
151 /** @var ButtonBar $buttonBar */
152 $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
153 $currentRequest = $this->request;
154 $moduleName = $currentRequest->getPluginName();
155 $getVars = $this->request->getArguments();
156 $lang = $this->getLanguageService();
157
158 $extensionName = $currentRequest->getControllerExtensionName();
159 if (empty($getVars)) {
160 $modulePrefix = strtolower('tx_' . $extensionName . '_' . $moduleName);
161 $getVars = ['id', 'route', $modulePrefix];
162 }
163
164 if ($currentRequest->getControllerActionName() === 'edit') {
165 // CLOSE button:
166 $closeButton = $buttonBar->makeLinkButton()
167 ->setHref($this->returnUrl)
168 ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))
169 ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon(
170 'actions-close',
171 Icon::SIZE_SMALL
172 ));
173 $buttonBar->addButton($closeButton);
174
175 // SAVE button:
176 $saveButton = $buttonBar->makeInputButton()
177 ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveCloseDoc'))
178 ->setName('tx_beuser_system_beusertxpermission[submit]')
179 ->setValue('Save')
180 ->setForm('PermissionControllerEdit')
181 ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon(
182 'actions-document-save',
183 Icon::SIZE_SMALL
184 ))
185 ->setShowLabelText(true);
186
187 $buttonBar->addButton($saveButton);
188 }
189
190 // SHORTCUT botton:
191 $shortcutButton = $buttonBar->makeShortcutButton()
192 ->setModuleName($moduleName)
193 ->setGetVariables($getVars);
194 $buttonBar->addButton($shortcutButton);
195 }
196
197 /**
198 * Index action
199 */
200 public function indexAction()
201 {
202 if (!$this->id) {
203 $this->pageInfo = ['title' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'], 'uid' => 0, 'pid' => 0];
204 }
205
206 if ($this->getBackendUser()->workspace != 0) {
207 // Adding section with the permission setting matrix:
208 $this->addFlashMessage(
209 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarningText', 'beuser'),
210 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarning', 'beuser'),
211 FlashMessage::WARNING
212 );
213 }
214
215 // depth options
216 $depthOptions = [];
217 $url = $this->uriBuilder->reset()->setArguments([
218 'action' => 'index',
219 'depth' => '__DEPTH__',
220 'id' => $this->id
221 ])->buildBackendUri();
222 foreach ([1, 2, 3, 4, 10] as $depthLevel) {
223 $levelLabel = $depthLevel === 1 ? 'level' : 'levels';
224 $depthOptions[$depthLevel] = $depthLevel . ' ' . LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:' . $levelLabel, 'beuser');
225 }
226 $this->view->assign('currentId', $this->id);
227 $this->view->assign('depthBaseUrl', $url);
228 $this->view->assign('depth', $this->depth);
229 $this->view->assign('depthOptions', $depthOptions);
230
231 $beUserArray = BackendUtility::getUserNames();
232 $this->view->assign('beUsers', $beUserArray);
233 $beGroupArray = BackendUtility::getGroupNames();
234 $this->view->assign('beGroups', $beGroupArray);
235
236 /** @var $tree PageTreeView */
237 $tree = GeneralUtility::makeInstance(PageTreeView::class);
238 $tree->init();
239 $tree->addField('perms_user', true);
240 $tree->addField('perms_group', true);
241 $tree->addField('perms_everybody', true);
242 $tree->addField('perms_userid', true);
243 $tree->addField('perms_groupid', true);
244 $tree->addField('hidden');
245 $tree->addField('fe_group');
246 $tree->addField('starttime');
247 $tree->addField('endtime');
248 $tree->addField('editlock');
249
250 // Create the tree from $this->id
251 if ($this->id) {
252 $tree->tree[] = ['row' => $this->pageInfo, 'HTML' => $tree->getIcon($this->id)];
253 } else {
254 $tree->tree[] = ['row' => $this->pageInfo, 'HTML' => $tree->getRootIcon($this->pageInfo)];
255 }
256 $tree->getTree($this->id, $this->depth);
257 $this->view->assign('viewTree', $tree->tree);
258
259 // CSH for permissions setting
260 $this->view->assign('cshItem', BackendUtility::cshItem('xMOD_csh_corebe', 'perm_module', null, '<span class="btn btn-default btn-sm">|</span>'));
261 }
262
263 /**
264 * Edit action
265 */
266 public function editAction()
267 {
268 $this->view->assign('id', $this->id);
269 $this->view->assign('depth', $this->depth);
270
271 if (!$this->id) {
272 $this->pageInfo = ['title' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'], 'uid' => 0, 'pid' => 0];
273 }
274 if ($this->getBackendUser()->workspace != 0) {
275 // Adding FlashMessage with the permission setting matrix:
276 $this->addFlashMessage(
277 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarningText', 'beuser'),
278 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarning', 'beuser'),
279 FlashMessage::WARNING
280 );
281 }
282 // Get user names and group names
283 $beGroupArray = BackendUtility::getGroupNames();
284 $beUserArray = BackendUtility::getUserNames();
285
286 // Owner selector
287 $beUserDataArray = [0 => LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectNone', 'beuser')];
288 foreach ($beUserArray as $uid => &$row) {
289 $beUserDataArray[$uid] = $row['username'];
290 }
291 $beUserDataArray[-1] = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectUnchanged', 'beuser');
292 $this->view->assign('currentBeUser', $this->pageInfo['perms_userid']);
293 $this->view->assign('beUserData', $beUserDataArray);
294
295 // Group selector
296 $beGroupDataArray = [0 => LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectNone', 'beuser')];
297 foreach ($beGroupArray as $uid => $row) {
298 $beGroupDataArray[$uid] = $row['title'];
299 }
300 $beGroupDataArray[-1] = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectUnchanged', 'beuser');
301 $this->view->assign('currentBeGroup', $this->pageInfo['perms_groupid']);
302 $this->view->assign('beGroupData', $beGroupDataArray);
303 $this->view->assign('pageInfo', $this->pageInfo);
304 $this->view->assign('returnUrl', $this->returnUrl);
305 $this->view->assign('recursiveSelectOptions', $this->getRecursiveSelectOptions());
306 }
307
308 /**
309 * Update action
310 *
311 * @param array $data
312 * @param array $mirror
313 */
314 protected function updateAction(array $data, array $mirror)
315 {
316 if (!empty($data['pages'])) {
317 foreach ($data['pages'] as $pageUid => $properties) {
318 // if the owner and group field shouldn't be touched, unset the option
319 if ((int)$properties['perms_userid'] === -1) {
320 unset($properties['perms_userid']);
321 }
322 if ((int)$properties['perms_groupid'] === -1) {
323 unset($properties['perms_groupid']);
324 }
325 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages');
326 $connection->update(
327 'pages',
328 $properties,
329 ['uid' => (int)$pageUid]
330 );
331
332 if (!empty($mirror['pages'][$pageUid])) {
333 $mirrorPages = GeneralUtility::trimExplode(',', $mirror['pages'][$pageUid]);
334 foreach ($mirrorPages as $mirrorPageUid) {
335 $connection->update(
336 'pages',
337 $properties,
338 ['uid' => (int)$mirrorPageUid]
339 );
340 }
341 }
342 }
343 }
344 $this->redirectToUri($this->returnUrl);
345 }
346
347 /**
348 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
349 */
350 protected function getBackendUser()
351 {
352 return $GLOBALS['BE_USER'];
353 }
354
355 /**
356 * Finding tree and offer setting of values recursively.
357 *
358 * @return array
359 */
360 protected function getRecursiveSelectOptions()
361 {
362 // Initialize tree object:
363 $tree = GeneralUtility::makeInstance(PageTreeView::class);
364 $tree->init();
365 $tree->addField('perms_userid', true);
366 $tree->makeHTML = 0;
367 $tree->setRecs = 1;
368 // Make tree:
369 $tree->getTree($this->id, $this->getLevels, '');
370 $options = [];
371 $options[''] = '';
372 // If there are a hierarchy of page ids, then...
373 if ($this->getBackendUser()->user['uid'] && !empty($tree->orig_ids_hierarchy)) {
374 // Init:
375 $labelRecursive = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:recursive', 'beuser');
376 $labelLevel = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:level', 'beuser');
377 $labelLevels = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:levels', 'beuser');
378 $labelPageAffected = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:page_affected', 'beuser');
379 $labelPagesAffected = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:pages_affected', 'beuser');
380 $theIdListArr = [];
381 // Traverse the number of levels we want to allow recursive
382 // setting of permissions for:
383 for ($a = $this->getLevels; $a > 0; $a--) {
384 if (is_array($tree->orig_ids_hierarchy[$a])) {
385 foreach ($tree->orig_ids_hierarchy[$a] as $theId) {
386 $theIdListArr[] = $theId;
387 }
388 $lKey = $this->getLevels - $a + 1;
389 $pagesCount = count($theIdListArr);
390 $options[implode(',', $theIdListArr)] = $labelRecursive . ' ' . $lKey . ' ' . ($lKey === 1 ? $labelLevel : $labelLevels) .
391 ' (' . $pagesCount . ' ' . ($pagesCount === 1 ? $labelPageAffected : $labelPagesAffected) . ')';
392 }
393 }
394 }
395 return $options;
396 }
397
398 /**
399 * Returns LanguageService
400 *
401 * @return \TYPO3\CMS\Core\Localization\LanguageService
402 */
403 protected function getLanguageService()
404 {
405 return $GLOBALS['LANG'];
406 }
407 }