089be9585f5d627cc17d9d71f4f3aee410f8360e
[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\DatabaseConnection;
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 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 parent::initializeView($view);
120 $view->assign(
121 'previewUrl',
122 BackendUtility::viewonclick(
123 $this->pageInfo['uid'], '',
124 BackendUtility::BEgetRootLine($this->pageInfo['uid'])
125 )
126 );
127
128 // the view of the update action has a different view class
129 if ($view instanceof BackendTemplateView) {
130 $view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Beuser/Permissions');
131 $view->getModuleTemplate()->addJavaScriptCode(
132 'jumpToUrl',
133 '
134 function jumpToUrl(URL) {
135 window.location.href = URL;
136 return false;
137 }
138 '
139 );
140 $this->registerDocHeaderButtons();
141 $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
142 }
143 }
144
145 /**
146 * Registers the Icons into the docheader
147 *
148 * @return void
149 * @throws \InvalidArgumentException
150 */
151 protected function registerDocHeaderButtons()
152 {
153 /** @var ButtonBar $buttonBar */
154 $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
155 $currentRequest = $this->request;
156 $moduleName = $currentRequest->getPluginName();
157 $getVars = $this->request->getArguments();
158
159 $extensionName = $currentRequest->getControllerExtensionName();
160 if (empty($getVars)) {
161 $modulePrefix = strtolower('tx_' . $extensionName . '_' . $moduleName);
162 $getVars = array('id', 'M', $modulePrefix);
163 }
164 $shortcutButton = $buttonBar->makeShortcutButton()
165 ->setModuleName($moduleName)
166 ->setGetVariables($getVars);
167 $buttonBar->addButton($shortcutButton);
168
169 if ($this->id > 0) {
170 $iconFactory = $this->view->getModuleTemplate()->getIconFactory();
171 $viewButton = $buttonBar->makeLinkButton()
172 ->setOnClick(BackendUtility::viewOnClick($this->pageInfo['uid'], '',
173 BackendUtility::BEgetRootLine($this->pageInfo['uid'])))
174 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage'))
175 ->setIcon($iconFactory->getIcon('actions-document-view', Icon::SIZE_SMALL))
176 ->setHref('#');
177
178 $buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 3);
179 }
180 }
181
182 /**
183 * Index action
184 *
185 * @return void
186 */
187 public function indexAction()
188 {
189 if (!$this->id) {
190 $this->pageInfo = array('title' => '[root-level]', 'uid' => 0, 'pid' => 0);
191 }
192
193 if ($this->getBackendUser()->workspace != 0) {
194 // Adding section with the permission setting matrix:
195 $this->addFlashMessage(
196 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarningText', 'beuser'),
197 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarning', 'beuser'),
198 FlashMessage::WARNING
199 );
200 }
201
202 // depth options
203 $depthOptions = array();
204 $url = $this->uriBuilder->reset()->setArguments(array(
205 'action' => 'index',
206 'depth' => '__DEPTH__',
207 'id' => $this->id
208 ))->buildBackendUri();
209 foreach (array(1, 2, 3, 4, 10) as $depthLevel) {
210 $depthOptions[$depthLevel] = $depthLevel . ' ' . LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:levels', 'beuser');
211 }
212 $this->view->assign('depthBaseUrl', $url);
213 $this->view->assign('depth', $this->depth);
214 $this->view->assign('depthOptions', $depthOptions);
215
216 $beUserArray = BackendUtility::getUserNames();
217 $this->view->assign('beUsers', $beUserArray);
218 $beGroupArray = BackendUtility::getGroupNames();
219 $this->view->assign('beGroups', $beGroupArray);
220
221 /** @var $tree PageTreeView */
222 $tree = GeneralUtility::makeInstance(PageTreeView::class);
223 $tree->init();
224 $tree->addField('perms_user', true);
225 $tree->addField('perms_group', true);
226 $tree->addField('perms_everybody', true);
227 $tree->addField('perms_userid', true);
228 $tree->addField('perms_groupid', true);
229 $tree->addField('hidden');
230 $tree->addField('fe_group');
231 $tree->addField('starttime');
232 $tree->addField('endtime');
233 $tree->addField('editlock');
234
235 // Create the tree from $this->id
236 if ($this->id) {
237 $tree->tree[] = array('row' => $this->pageInfo, 'HTML' => $tree->getIcon($this->id));
238 } else {
239 $tree->tree[] = array('row' => $this->pageInfo, 'HTML' => $tree->getRootIcon($this->pageInfo));
240 }
241 $tree->getTree($this->id, $this->depth);
242 $this->view->assign('viewTree', $tree->tree);
243
244 // CSH for permissions setting
245 $this->view->assign('cshItem', BackendUtility::cshItem('xMOD_csh_corebe', 'perm_module', null, '<span class="btn btn-default btn-sm">|</span>'));
246 }
247
248 /**
249 * Edit action
250 *
251 * @return void
252 */
253 public function editAction()
254 {
255 $this->view->assign('id', $this->id);
256 $this->view->assign('depth', $this->depth);
257
258 if (!$this->id) {
259 $this->pageInfo = array('title' => '[root-level]', 'uid' => 0, 'pid' => 0);
260 }
261 if ($this->getBackendUser()->workspace != 0) {
262 // Adding FlashMessage with the permission setting matrix:
263 $this->addFlashMessage(
264 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarningText', 'beuser'),
265 LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarning', 'beuser'),
266 FlashMessage::WARNING
267 );
268 }
269 // Get usernames and groupnames
270 $beGroupArray = BackendUtility::getListGroupNames('title,uid');
271 $beUserArray = BackendUtility::getUserNames();
272
273 // Owner selector
274 $beUserDataArray = array(0 => LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectNone', 'beuser'));
275 foreach ($beUserArray as $uid => &$row) {
276 $beUserDataArray[$uid] = $row['username'];
277 }
278 $beUserDataArray[-1] = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectUnchanged', 'beuser');
279 $this->view->assign('currentBeUser', $this->pageInfo['perms_userid']);
280 $this->view->assign('beUserData', $beUserDataArray);
281
282 // Group selector
283 $beGroupDataArray = array(0 => LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectNone', 'beuser'));
284 foreach ($beGroupArray as $uid => $row) {
285 $beGroupDataArray[$uid] = $row['title'];
286 }
287 $beGroupDataArray[-1] = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:selectUnchanged', 'beuser');
288 $this->view->assign('currentBeGroup', $this->pageInfo['perms_groupid']);
289 $this->view->assign('beGroupData', $beGroupDataArray);
290 $this->view->assign('pageInfo', $this->pageInfo);
291 $this->view->assign('returnId', $this->returnId);
292 $this->view->assign('recursiveSelectOptions', $this->getRecursiveSelectOptions());
293 }
294
295 /**
296 * Update action
297 *
298 * @param array $data
299 * @param array $mirror
300 * @return void
301 */
302 protected function updateAction(array $data, array $mirror)
303 {
304 if (!empty($data['pages'])) {
305 foreach ($data['pages'] as $pageUid => $properties) {
306 // if the owner and group field shouldn't be touched, unset the option
307 if ((int)$properties['perms_userid'] === -1) {
308 unset($properties['perms_userid']);
309 }
310 if ((int)$properties['perms_groupid'] === -1) {
311 unset($properties['perms_groupid']);
312 }
313 $this->getDatabaseConnection()->exec_UPDATEquery(
314 'pages',
315 'uid = ' . (int)$pageUid,
316 $properties
317 );
318 if (!empty($mirror['pages'][$pageUid])) {
319 $mirrorPages = GeneralUtility::trimExplode(',', $mirror['pages'][$pageUid]);
320 foreach ($mirrorPages as $mirrorPageUid) {
321 $this->getDatabaseConnection()->exec_UPDATEquery(
322 'pages',
323 'uid = ' . (int)$mirrorPageUid,
324 $properties
325 );
326 }
327 }
328 }
329 }
330 $this->redirect('index', null, null, array('id' => $this->returnId, 'depth' => $this->depth));
331 }
332
333 /**
334 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
335 */
336 protected function getBackendUser()
337 {
338 return $GLOBALS['BE_USER'];
339 }
340
341 /**
342 * @return DatabaseConnection
343 */
344 protected function getDatabaseConnection()
345 {
346 return $GLOBALS['TYPO3_DB'];
347 }
348
349 /**
350 * Finding tree and offer setting of values recursively.
351 *
352 * @return array
353 */
354 protected function getRecursiveSelectOptions()
355 {
356 // Initialize tree object:
357 $tree = GeneralUtility::makeInstance(PageTreeView::class);
358 $tree->init();
359 $tree->addField('perms_userid', true);
360 $tree->makeHTML = 0;
361 $tree->setRecs = 1;
362 // Make tree:
363 $tree->getTree($this->id, $this->getLevels, '');
364 $options = array();
365 $options[''] = '';
366 // If there are a hierarchy of page ids, then...
367 if ($this->getBackendUser()->user['uid'] && !empty($tree->orig_ids_hierarchy)) {
368 // Init:
369 $labelRecursive = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:recursive', 'beuser');
370 $labelLevels = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:levels', 'beuser');
371 $labelPagesAffected = LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:pages_affected', 'beuser');
372 $theIdListArr = array();
373 // Traverse the number of levels we want to allow recursive
374 // setting of permissions for:
375 for ($a = $this->getLevels; $a > 0; $a--) {
376 if (is_array($tree->orig_ids_hierarchy[$a])) {
377 foreach ($tree->orig_ids_hierarchy[$a] as $theId) {
378 $theIdListArr[] = $theId;
379 }
380 $lKey = $this->getLevels - $a + 1;
381 $options[implode(',', $theIdListArr)] = $labelRecursive . ' ' . $lKey . ' ' . $labelLevels .
382 ' (' . count($theIdListArr) . ' ' . $labelPagesAffected . ')';
383 }
384 }
385 }
386 return $options;
387 }
388
389 /**
390 * Returns LanguageService
391 *
392 * @return \TYPO3\CMS\Lang\LanguageService
393 */
394 protected function getLanguageService()
395 {
396 return $GLOBALS['LANG'];
397 }
398 }