[BUGFIX] BE-Module "Access": Fixed "weird" styling and behavior
[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\View\BackendTemplateView;
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\Utility\GeneralUtility;
24 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
25 use TYPO3\CMS\Backend\Utility\BackendUtility;
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 int
46 */
47 protected $returnId;
48
49 /**
50 * @var int
51 */
52 protected $depth;
53
54 /**
55 * @var int
56 */
57 protected $lastEdited;
58
59 /**
60 * Number of levels to enable recursive settings for
61 *
62 * @var int
63 */
64 protected $getLevels = 10;
65
66 /**
67 * @var array
68 */
69 protected $pageInfo = array();
70
71 /**
72 * Backend Template Container
73 *
74 * @var string
75 */
76 protected $defaultViewObjectName = BackendTemplateView::class;
77
78 /**
79 * BackendTemplateContainer
80 *
81 * @var BackendTemplateView
82 */
83 protected $view;
84
85 /**
86 * Initialize action
87 *
88 * @return void
89 */
90 protected function initializeAction()
91 {
92 // determine id parameter
93 $this->id = (int)GeneralUtility::_GP('id');
94 if ($this->request->hasArgument('id')) {
95 $this->id = (int)$this->request->getArgument('id');
96 }
97
98 // determine depth parameter
99 $this->depth = ((int)GeneralUtility::_GP('depth') > 0)
100 ? (int) GeneralUtility::_GP('depth')
101 : $this->getBackendUser()->getSessionData(self::SESSION_PREFIX . 'depth');
102 if ($this->request->hasArgument('depth')) {
103 $this->depth = (int)$this->request->getArgument('depth');
104 }
105 $this->getBackendUser()->setAndSaveSessionData(self::SESSION_PREFIX . 'depth', $this->depth);
106 $this->lastEdited = GeneralUtility::_GP('lastEdited');
107 $this->returnId = GeneralUtility::_GP('returnId');
108 $this->pageInfo = BackendUtility::readPageAccess($this->id, ' 1=1');
109 }
110
111 /**
112 * Initializes view
113 *
114 * @param ViewInterface $view The view to be initialized
115 * @return void
116 */
117 protected function initializeView(ViewInterface $view)
118 {
119 /** @var BackendTemplateView $view */
120 parent::initializeView($view);
121 $view->assign(
122 'previewUrl',
123 BackendUtility::viewonclick(
124 $this->pageInfo['uid'], '',
125 BackendUtility::BEgetRootLine($this->pageInfo['uid'])
126 )
127 );
128 $this->view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Beuser/Permissions');
129 $this->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 }
140
141 /**
142 * Registers the Icons into the docheader
143 *
144 * @return void
145 * @throws \InvalidArgumentException
146 */
147 protected function registerDocheaderButtons()
148 {
149 /** @var ButtonBar $buttonBar */
150 $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
151 $currentRequest = $this->request;
152 $moduleName = $currentRequest->getPluginName();
153 $getVars = $this->request->getArguments();
154
155 $extensionName = $currentRequest->getControllerExtensionName();
156 if (empty($getVars)) {
157 $modulePrefix = strtolower('tx_' . $extensionName . '_' . $moduleName);
158 $getVars = array('id', 'M', $modulePrefix);
159 }
160 $shortcutButton = $buttonBar->makeShortcutButton()
161 ->setModuleName($moduleName)
162 ->setGetVariables($getVars);
163 $buttonBar->addButton($shortcutButton);
164
165 if ($this->id > 0) {
166 $iconFactory = $this->view->getModuleTemplate()->getIconFactory();
167 $viewButton = $buttonBar->makeLinkButton()
168 ->setOnClick(htmlspecialchars(BackendUtility::viewOnClick($this->pageInfo['uid'], '',
169 BackendUtility::BEgetRootLine($this->pageInfo['uid']))))
170 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', true))
171 ->setIcon($iconFactory->getIcon('actions-document-view', Icon::SIZE_SMALL))
172 ->setHref('#');
173
174 $buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 3);
175 }
176 }
177
178 /**
179 * Index action
180 *
181 * @return void
182 */
183 public function indexAction()
184 {
185 if (!$this->id) {
186 $this->pageInfo = array('title' => '[root-level]', 'uid' => 0, 'pid' => 0);
187 }
188
189 if ($this->getBackendUser()->workspace != 0) {
190 // Adding section with the permission setting matrix:
191 $this->addFlashMessage(
192 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarningText',
193 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarning',
194 FlashMessage::WARNING
195 );
196 }
197
198 // depth options
199 $depthOptions = array();
200 $url = $this->uriBuilder->reset()->setArguments(array(
201 'action' => 'index',
202 'depth' => '__DEPTH__',
203 'id' => $this->id
204 ))->buildBackendUri();
205 foreach (array(1, 2, 3, 4, 10) as $depthLevel) {
206 $depthOptions[$depthLevel] = $depthLevel . ' ' . LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:levels', 'beuser');
207 }
208 $this->view->assign('depthBaseUrl', $url);
209 $this->view->assign('depth', $this->depth);
210 $this->view->assign('depthOptions', $depthOptions);
211
212 $beUserArray = BackendUtility::getUserNames();
213 $this->view->assign('beUsers', $beUserArray);
214 $beGroupArray = BackendUtility::getGroupNames();
215 $this->view->assign('beGroups', $beGroupArray);
216
217 /** @var $tree PageTreeView */
218 $tree = GeneralUtility::makeInstance(PageTreeView::class);
219 $tree->init();
220 $tree->addField('perms_user', true);
221 $tree->addField('perms_group', true);
222 $tree->addField('perms_everybody', true);
223 $tree->addField('perms_userid', true);
224 $tree->addField('perms_groupid', true);
225 $tree->addField('hidden');
226 $tree->addField('fe_group');
227 $tree->addField('starttime');
228 $tree->addField('endtime');
229 $tree->addField('editlock');
230
231 // Create the tree from $this->id
232 if ($this->id) {
233 $tree->tree[] = array('row' => $this->pageInfo, 'HTML' => $tree->getIcon($this->id));
234 } else {
235 $tree->tree[] = array('row' => $this->pageInfo, 'HTML' => $tree->getRootIcon($this->pageInfo));
236 }
237 $tree->getTree($this->id, $this->depth);
238 $this->view->assign('viewTree', $tree->tree);
239
240 // CSH for permissions setting
241 $this->view->assign('cshItem', BackendUtility::cshItem('xMOD_csh_corebe', 'perm_module'));
242 }
243
244 /**
245 * Edit action
246 *
247 * @return void
248 */
249 public function editAction()
250 {
251 $this->view->assign('id', $this->id);
252 $this->view->assign('depth', $this->depth);
253
254 if (!$this->id) {
255 $this->pageInfo = array('title' => '[root-level]', 'uid' => 0, 'pid' => 0);
256 }
257 if ($this->getBackendUser()->workspace != 0) {
258 // Adding FlashMessage with the permission setting matrix:
259 $this->addFlashMessage(
260 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarningText', 'beuser'),
261 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarning', 'beuser'),
262 FlashMessage::WARNING
263 );
264 }
265 // Get usernames and groupnames
266 $beGroupArray = BackendUtility::getListGroupNames('title,uid');
267 $beUserArray = BackendUtility::getUserNames();
268
269 // Owner selector
270 $beUserDataArray = array(0 => LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectNone', 'beuser'));
271 foreach ($beUserArray as $uid => &$row) {
272 $beUserDataArray[$uid] = $row['username'];
273 }
274 $beUserDataArray[-1] = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectUnchanged', 'beuser');
275 $this->view->assign('currentBeUser', $this->pageInfo['perms_userid']);
276 $this->view->assign('beUserData', $beUserDataArray);
277
278 // Group selector
279 $beGroupDataArray = array(0 => LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectNone', 'beuser'));
280 foreach ($beGroupArray as $uid => $row) {
281 $beGroupDataArray[$uid] = $row['title'];
282 }
283 $beGroupDataArray[-1] = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectUnchanged', 'beuser');
284 $this->view->assign('currentBeGroup', $this->pageInfo['perms_groupid']);
285 $this->view->assign('beGroupData', $beGroupDataArray);
286 $this->view->assign('pageInfo', $this->pageInfo);
287 $this->view->assign('returnId', $this->returnId);
288 $this->view->assign('recursiveSelectOptions', $this->getRecursiveSelectOptions());
289 }
290
291 /**
292 * Update action
293 *
294 * @param array $data
295 * @param array $mirror
296 * @return void
297 */
298 protected function updateAction(array $data, array $mirror)
299 {
300 if (!empty($data['pages'])) {
301 foreach ($data['pages'] as $pageUid => $properties) {
302 // if the owner and group field shouldn't be touched, unset the option
303 if ((int)$properties['perms_userid'] === -1) {
304 unset($properties['perms_userid']);
305 }
306 if ((int)$properties['perms_groupid'] === -1) {
307 unset($properties['perms_groupid']);
308 }
309 $this->getDatabaseConnection()->exec_UPDATEquery(
310 'pages',
311 'uid = ' . (int)$pageUid,
312 $properties
313 );
314 if (!empty($mirror['pages'][$pageUid])) {
315 $mirrorPages = GeneralUtility::trimExplode(',', $mirror['pages'][$pageUid]);
316 foreach ($mirrorPages as $mirrorPageUid) {
317 $this->getDatabaseConnection()->exec_UPDATEquery(
318 'pages',
319 'uid = ' . (int)$mirrorPageUid,
320 $properties
321 );
322 }
323 }
324 }
325 }
326 $this->redirect('index', null, null, array('id' => $this->returnId, 'depth' => $this->depth));
327 }
328
329 /**
330 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
331 */
332 protected function getBackendUser()
333 {
334 return $GLOBALS['BE_USER'];
335 }
336
337 /**
338 * @return DatabaseConnection
339 */
340 protected function getDatabaseConnection()
341 {
342 return $GLOBALS['TYPO3_DB'];
343 }
344
345 /**
346 * Finding tree and offer setting of values recursively.
347 *
348 * @return array
349 */
350 protected function getRecursiveSelectOptions()
351 {
352 // Initialize tree object:
353 $tree = GeneralUtility::makeInstance(PageTreeView::class);
354 $tree->init();
355 $tree->addField('perms_userid', true);
356 $tree->makeHTML = 0;
357 $tree->setRecs = 1;
358 // Make tree:
359 $tree->getTree($this->id, $this->getLevels, '');
360 $options = array();
361 $options[''] = '';
362 // If there are a hierarchy of page ids, then...
363 if ($this->getBackendUser()->user['uid'] && !empty($tree->orig_ids_hierarchy)) {
364 // Init:
365 $labelRecursive = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:recursive', 'beuser');
366 $labelLevels = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:levels', 'beuser');
367 $labelPagesAffected = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:pages_affected', 'beuser');
368 $theIdListArr = array();
369 // Traverse the number of levels we want to allow recursive
370 // setting of permissions for:
371 for ($a = $this->getLevels; $a > 0; $a--) {
372 if (is_array($tree->orig_ids_hierarchy[$a])) {
373 foreach ($tree->orig_ids_hierarchy[$a] as $theId) {
374 $theIdListArr[] = $theId;
375 }
376 $lKey = $this->getLevels - $a + 1;
377 $options[implode(',', $theIdListArr)] = $labelRecursive . ' ' . $lKey . ' ' . $labelLevels .
378 ' (' . count($theIdListArr) . ' ' . $labelPagesAffected . ')';
379 }
380 }
381 }
382 return $options;
383 }
384
385 /**
386 * Returns LanguageService
387 *
388 * @return \TYPO3\CMS\Lang\LanguageService
389 */
390 protected function getLanguageService()
391 {
392 return $GLOBALS['LANG'];
393 }
394 }