[TASK] Re-work/simplify copyright header in PHP files - Part 9
[Packages/TYPO3.CMS.git] / typo3 / sysext / workspaces / Classes / Service / StagesService.php
1 <?php
2 namespace TYPO3\CMS\Workspaces\Service;
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\Utility\BackendUtility;
18
19 /**
20 * Stages service
21 *
22 * @author Workspaces Team (http://forge.typo3.org/projects/show/typo3v4-workspaces)
23 */
24 class StagesService {
25
26 const TABLE_STAGE = 'sys_workspace_stage';
27 // if a record is in the "ready to publish" stage STAGE_PUBLISH_ID the nextStage is STAGE_PUBLISH_EXECUTE_ID, this id wont be saved at any time in db
28 const STAGE_PUBLISH_EXECUTE_ID = -20;
29 // ready to publish stage
30 const STAGE_PUBLISH_ID = -10;
31 const STAGE_EDIT_ID = 0;
32 const MODE_NOTIFY_SOMEONE = 0;
33 const MODE_NOTIFY_ALL = 1;
34 const MODE_NOTIFY_ALL_STRICT = 2;
35
36 /**
37 * Path to the locallang file
38 *
39 * @var string
40 */
41 private $pathToLocallang = 'LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf';
42
43 /**
44 * Local cache to reduce number of database queries for stages, groups, etc.
45 *
46 * @var array
47 */
48 protected $workspaceStageCache = array();
49
50 /**
51 * @var array
52 */
53 protected $workspaceStageAllowedCache = array();
54
55 /**
56 * @var array
57 */
58 protected $fetchGroupsCache = array();
59
60 /**
61 * @var array
62 */
63 protected $userGroups = array();
64
65 /**
66 * Getter for current workspace id
67 *
68 * @return integer Current workspace id
69 */
70 public function getWorkspaceId() {
71 return $this->getBackendUser()->workspace;
72 }
73
74 /**
75 * Find the highest possible "previous" stage for all $byTableName
76 *
77 * @param array $workspaceItems
78 * @param array $byTableName
79 * @return array Current and next highest possible stage
80 * @author Michael Klapper <development@morphodo.com>
81 */
82 public function getPreviousStageForElementCollection(
83 $workspaceItems,
84 array $byTableName = array('tt_content', 'pages', 'pages_language_overlay')
85 ) {
86 $currentStage = array();
87 $previousStage = array();
88 $usedStages = array();
89 $found = FALSE;
90 $availableStagesForWS = array_reverse($this->getStagesForWS());
91 $availableStagesForWSUser = $this->getStagesForWSUser();
92 $byTableName = array_flip($byTableName);
93 foreach ($workspaceItems as $tableName => $items) {
94 if (!array_key_exists($tableName, $byTableName)) {
95 continue;
96 }
97 foreach ($items as $item) {
98 $usedStages[$item['t3ver_stage']] = TRUE;
99 }
100 }
101 foreach ($availableStagesForWS as $stage) {
102 if (isset($usedStages[$stage['uid']])) {
103 $currentStage = $stage;
104 $previousStage = $this->getPrevStage($stage['uid']);
105 break;
106 }
107 }
108 foreach ($availableStagesForWSUser as $userWS) {
109 if ($previousStage['uid'] == $userWS['uid']) {
110 $found = TRUE;
111 break;
112 }
113 }
114 if ($found === FALSE) {
115 $previousStage = array();
116 }
117 return array(
118 $currentStage,
119 $previousStage
120 );
121 }
122
123 /**
124 * Retrieve the next stage based on the lowest stage given in the $workspaceItems record array.
125 *
126 * @param array $workspaceItems
127 * @param array $byTableName
128 * @return array Current and next possible stage.
129 * @author Michael Klapper <development@morphodo.com>
130 */
131 public function getNextStageForElementCollection(
132 $workspaceItems,
133 array $byTableName = array('tt_content', 'pages', 'pages_language_overlay')
134 ) {
135 $currentStage = array();
136 $usedStages = array();
137 $nextStage = array();
138 $availableStagesForWS = $this->getStagesForWS();
139 $availableStagesForWSUser = $this->getStagesForWSUser();
140 $byTableName = array_flip($byTableName);
141 $found = FALSE;
142 foreach ($workspaceItems as $tableName => $items) {
143 if (!array_key_exists($tableName, $byTableName)) {
144 continue;
145 }
146 foreach ($items as $item) {
147 $usedStages[$item['t3ver_stage']] = TRUE;
148 }
149 }
150 foreach ($availableStagesForWS as $stage) {
151 if (isset($usedStages[$stage['uid']])) {
152 $currentStage = $stage;
153 $nextStage = $this->getNextStage($stage['uid']);
154 break;
155 }
156 }
157 foreach ($availableStagesForWSUser as $userWS) {
158 if ($nextStage['uid'] == $userWS['uid']) {
159 $found = TRUE;
160 break;
161 }
162 }
163 if ($found === FALSE) {
164 $nextStage = array();
165 }
166 return array(
167 $currentStage,
168 $nextStage
169 );
170 }
171
172 /**
173 * Building an array with all stage ids and titles related to the given workspace
174 *
175 * @return array id and title of the stages
176 */
177 public function getStagesForWS() {
178 $stages = array();
179 if (isset($this->workspaceStageCache[$this->getWorkspaceId()])) {
180 $stages = $this->workspaceStageCache[$this->getWorkspaceId()];
181 } else {
182 $stages[] = array(
183 'uid' => self::STAGE_EDIT_ID,
184 'title' => $GLOBALS['LANG']->sL(($this->pathToLocallang . ':actionSendToStage')) . ' "'
185 . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xlf:stage_editing') . '"'
186 );
187 $workspaceRec = BackendUtility::getRecord('sys_workspace', $this->getWorkspaceId());
188 if ($workspaceRec['custom_stages'] > 0) {
189 // Get all stage records for this workspace
190 $where = 'parentid=' . $this->getWorkspaceId() . ' AND parenttable='
191 . $GLOBALS['TYPO3_DB']->fullQuoteStr('sys_workspace', self::TABLE_STAGE) . ' AND deleted=0';
192 $workspaceStageRecs = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', self::TABLE_STAGE, $where, '', 'sorting', '', 'uid');
193 foreach ($workspaceStageRecs as $stage) {
194 $stage['title'] = $GLOBALS['LANG']->sL(($this->pathToLocallang . ':actionSendToStage')) . ' "' . $stage['title'] . '"';
195 $stages[] = $stage;
196 }
197 }
198 $stages[] = array(
199 'uid' => self::STAGE_PUBLISH_ID,
200 'title' => $GLOBALS['LANG']->sL(($this->pathToLocallang . ':actionSendToStage')) . ' "'
201 . $GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang_mod.xlf:stage_ready_to_publish') . '"'
202 );
203 $stages[] = array(
204 'uid' => self::STAGE_PUBLISH_EXECUTE_ID,
205 'title' => $GLOBALS['LANG']->sL($this->pathToLocallang . ':publish_execute_action_option')
206 );
207 $this->workspaceStageCache[$this->getWorkspaceId()] = $stages;
208 }
209 return $stages;
210 }
211
212 /**
213 * Returns an array of stages, the user is allowed to send to
214 *
215 * @return array id and title of stages
216 */
217 public function getStagesForWSUser() {
218 $stagesForWSUserData = array();
219 $allowedStages = array();
220 $orderedAllowedStages = array();
221 $workspaceStageRecs = $this->getStagesForWS();
222 if (is_array($workspaceStageRecs) && !empty($workspaceStageRecs)) {
223 if ($GLOBALS['BE_USER']->isAdmin()) {
224 $orderedAllowedStages = $workspaceStageRecs;
225 } else {
226 foreach ($workspaceStageRecs as $workspaceStageRec) {
227 if ($workspaceStageRec['uid'] === self::STAGE_EDIT_ID) {
228 $allowedStages[self::STAGE_EDIT_ID] = $workspaceStageRec;
229 $stagesForWSUserData[$workspaceStageRec['uid']] = $workspaceStageRec;
230 } elseif ($this->isStageAllowedForUser($workspaceStageRec['uid'])) {
231 $stagesForWSUserData[$workspaceStageRec['uid']] = $workspaceStageRec;
232 } elseif ($workspaceStageRec['uid'] == self::STAGE_PUBLISH_EXECUTE_ID && $GLOBALS['BE_USER']->workspacePublishAccess($this->getWorkspaceId())) {
233 $allowedStages[] = $workspaceStageRec;
234 $stagesForWSUserData[$workspaceStageRec['uid']] = $workspaceStageRec;
235 }
236 }
237 foreach ($stagesForWSUserData as $allowedStage) {
238 $nextStage = $this->getNextStage($allowedStage['uid']);
239 $prevStage = $this->getPrevStage($allowedStage['uid']);
240 if (isset($prevStage['uid'])) {
241 $allowedStages[$prevStage['uid']] = $prevStage;
242 }
243 if (isset($nextStage['uid'])) {
244 $allowedStages[$nextStage['uid']] = $nextStage;
245 }
246 }
247 $orderedAllowedStages = array_values($allowedStages);
248 }
249 }
250 return $orderedAllowedStages;
251 }
252
253 /**
254 * Check if given workspace has custom staging activated
255 *
256 * @return boolean
257 * @deprecated since TYPO3 6.2, will be removed two versions later
258 * not used anymore in the TYPO3 CMS Core
259 */
260 public function checkCustomStagingForWS() {
261 $workspaceRec = BackendUtility::getRecord('sys_workspace', $this->getWorkspaceId());
262 return $workspaceRec['custom_stages'] > 0;
263 }
264
265 /**
266 * Gets the title of a stage.
267 *
268 * @param integer $ver_stage
269 * @return string
270 */
271 public function getStageTitle($ver_stage) {
272 global $LANG;
273 $stageTitle = '';
274 switch ($ver_stage) {
275 case self::STAGE_PUBLISH_EXECUTE_ID:
276 $stageTitle = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xlf:stage_publish');
277 break;
278 case self::STAGE_PUBLISH_ID:
279 $stageTitle = $GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang_mod.xlf:stage_ready_to_publish');
280 break;
281 case self::STAGE_EDIT_ID:
282 $stageTitle = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xlf:stage_editing');
283 break;
284 default:
285 $stageTitle = $this->getPropertyOfCurrentWorkspaceStage($ver_stage, 'title');
286 if ($stageTitle == NULL) {
287 $stageTitle = $GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:error.getStageTitle.stageNotFound');
288 }
289 }
290 return $stageTitle;
291 }
292
293 /**
294 * Gets a particular stage record.
295 *
296 * @param integer $stageid
297 * @return array
298 */
299 public function getStageRecord($stageid) {
300 return BackendUtility::getRecord('sys_workspace_stage', $stageid);
301 }
302
303 /**
304 * Gets next stage in process for given stage id
305 *
306 * @param integer $stageId Id of the stage to fetch the next one for
307 * @return integer The next stage Id
308 * @throws \InvalidArgumentException
309 */
310 public function getNextStage($stageId) {
311 if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($stageId)) {
312 throw new \InvalidArgumentException($GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:error.stageId.integer'), 1291109987);
313 }
314 $nextStage = FALSE;
315 $workspaceStageRecs = $this->getStagesForWS();
316 if (is_array($workspaceStageRecs) && !empty($workspaceStageRecs)) {
317 reset($workspaceStageRecs);
318 while (!is_null(($workspaceStageRecKey = key($workspaceStageRecs)))) {
319 $workspaceStageRec = current($workspaceStageRecs);
320 if ($workspaceStageRec['uid'] == $stageId) {
321 $nextStage = next($workspaceStageRecs);
322 break;
323 }
324 next($workspaceStageRecs);
325 }
326 } else {
327
328 }
329 if ($nextStage === FALSE) {
330 $nextStage[] = array(
331 'uid' => self::STAGE_EDIT_ID,
332 'title' => $GLOBALS['LANG']->sL(($this->pathToLocallang . ':actionSendToStage')) . ' "'
333 . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xlf:stage_editing') . '"'
334 );
335 }
336 return $nextStage;
337 }
338
339 /**
340 * Recursive function to get all next stages for a record depending on user permissions
341 *
342 * @param array $nextStageArray Next stages
343 * @param integer $stageId Current stage id of the record
344 * @return array Next stages
345 */
346 public function getNextStages(array &$nextStageArray, $stageId) {
347 // Current stage is "Ready to publish" - there is no next stage
348 if ($stageId == self::STAGE_PUBLISH_ID) {
349 return $nextStageArray;
350 } else {
351 $nextStageRecord = $this->getNextStage($stageId);
352 if (empty($nextStageRecord) || !is_array($nextStageRecord)) {
353 // There is no next stage
354 return $nextStageArray;
355 } else {
356 // Check if the user has the permission to for the current stage
357 // If this next stage record is the first next stage after the current the user
358 // has always the needed permission
359 if ($this->isStageAllowedForUser($stageId)) {
360 $nextStageArray[] = $nextStageRecord;
361 return $this->getNextStages($nextStageArray, $nextStageRecord['uid']);
362 } else {
363 // He hasn't - return given next stage array
364 return $nextStageArray;
365 }
366 }
367 }
368 }
369
370 /**
371 * Get next stage in process for given stage id
372 *
373 * @param integer $stageId Id of the stage to fetch the previous one for
374 * @return integer The previous stage Id
375 * @throws \InvalidArgumentException
376 */
377 public function getPrevStage($stageId) {
378 if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($stageId)) {
379 throw new \InvalidArgumentException($GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:error.stageId.integer'));
380 }
381 $prevStage = FALSE;
382 $workspaceStageRecs = $this->getStagesForWS();
383 if (is_array($workspaceStageRecs) && !empty($workspaceStageRecs)) {
384 end($workspaceStageRecs);
385 while (!is_null(($workspaceStageRecKey = key($workspaceStageRecs)))) {
386 $workspaceStageRec = current($workspaceStageRecs);
387 if ($workspaceStageRec['uid'] == $stageId) {
388 $prevStage = prev($workspaceStageRecs);
389 break;
390 }
391 prev($workspaceStageRecs);
392 }
393 } else {
394
395 }
396 return $prevStage;
397 }
398
399 /**
400 * Recursive function to get all prev stages for a record depending on user permissions
401 *
402 * @param array $prevStageArray Prev stages
403 * @param integer $stageId Current stage id of the record
404 * @return array prev stages
405 */
406 public function getPrevStages(array &$prevStageArray, $stageId) {
407 // Current stage is "Editing" - there is no prev stage
408 if ($stageId != self::STAGE_EDIT_ID) {
409 $prevStageRecord = $this->getPrevStage($stageId);
410 if (!empty($prevStageRecord) && is_array($prevStageRecord)) {
411 // Check if the user has the permission to switch to that stage
412 // If this prev stage record is the first previous stage before the current
413 // the user has always the needed permission
414 if ($this->isStageAllowedForUser($stageId)) {
415 $prevStageArray[] = $prevStageRecord;
416 $prevStageArray = $this->getPrevStages($prevStageArray, $prevStageRecord['uid']);
417 }
418 }
419 }
420 return $prevStageArray;
421 }
422
423 /**
424 * Get array of all responsilbe be_users for a stage
425 *
426 * @param integer $stageId Stage id
427 * @param boolean $selectDefaultUserField If field notification_defaults should be selected instead of responsible users
428 * @return array be_users with e-mail and name
429 */
430 public function getResponsibleBeUser($stageId, $selectDefaultUserField = FALSE) {
431 $workspaceRec = BackendUtility::getRecord('sys_workspace', $this->getWorkspaceId());
432 $recipientArray = array();
433 switch ($stageId) {
434 case self::STAGE_PUBLISH_EXECUTE_ID:
435
436 case self::STAGE_PUBLISH_ID:
437 if (!$selectDefaultUserField) {
438 $userList = $this->getResponsibleUser($workspaceRec['adminusers'] . ',' . $workspaceRec['members']);
439 } else {
440 $notification_default_user = $workspaceRec['publish_notification_defaults'];
441 $userList = $this->getResponsibleUser($notification_default_user);
442 }
443 break;
444 case self::STAGE_EDIT_ID:
445 if (!$selectDefaultUserField) {
446 $userList = $this->getResponsibleUser($workspaceRec['adminusers'] . ',' . $workspaceRec['members']);
447 } else {
448 $notification_default_user = $workspaceRec['edit_notification_defaults'];
449 $userList = $this->getResponsibleUser($notification_default_user);
450 }
451 break;
452 default:
453 if (!$selectDefaultUserField) {
454 $responsible_persons = $this->getPropertyOfCurrentWorkspaceStage($stageId, 'responsible_persons');
455 $userList = $this->getResponsibleUser($responsible_persons);
456 } else {
457 $notification_default_user = $this->getPropertyOfCurrentWorkspaceStage($stageId, 'notification_defaults');
458 $userList = $this->getResponsibleUser($notification_default_user);
459 }
460 }
461 if (!empty($userList)) {
462 $userRecords = BackendUtility::getUserNames(
463 'username, uid, email, realName',
464 'AND uid IN (' . $userList . ')' . BackendUtility::BEenableFields('be_users')
465 );
466 }
467 if (!empty($userRecords) && is_array($userRecords)) {
468 foreach ($userRecords as $userUid => $userRecord) {
469 $recipientArray[$userUid] = $userRecord;
470 }
471 }
472 return $recipientArray;
473 }
474
475 /**
476 * Get uids of all responsilbe persons for a stage
477 *
478 * @param string $stageRespValue Responsible_person value from stage record
479 * @return string Uid list of responsible be_users
480 */
481 public function getResponsibleUser($stageRespValue) {
482 $stageValuesArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $stageRespValue, TRUE);
483 $beuserUidArray = array();
484 $begroupUidArray = array();
485
486 foreach ($stageValuesArray as $uidvalue) {
487 if (strstr($uidvalue, 'be_users') !== FALSE) {
488 // Current value is a uid of a be_user record
489 $beuserUidArray[] = str_replace('be_users_', '', $uidvalue);
490 } elseif (strstr($uidvalue, 'be_groups') !== FALSE) {
491 $begroupUidArray[] = str_replace('be_groups_', '', $uidvalue);
492 } elseif ((int)$uidvalue) {
493 $beuserUidArray[] = (int)$uidvalue;
494 }
495 }
496
497 if (!empty($begroupUidArray)) {
498 $allBeUserArray = BackendUtility::getUserNames();
499 $begroupUidList = implode(',', $begroupUidArray);
500 $this->userGroups = array();
501 $begroupUidArray = $this->fetchGroups($begroupUidList);
502 foreach ($begroupUidArray as $groupkey => $groupData) {
503 foreach ($allBeUserArray as $useruid => $userdata) {
504 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($userdata['usergroup_cached_list'], $groupData['uid'])) {
505 $beuserUidArray[] = $useruid;
506 }
507 }
508 }
509 }
510
511 array_unique($beuserUidArray);
512 return implode(',', $beuserUidArray);
513 }
514
515 /**
516 * @param $grList
517 * @param string $idList
518 * @return array
519 */
520 private function fetchGroups($grList, $idList = '') {
521 $cacheKey = md5($grList . $idList);
522 $groupList = array();
523 if (isset($this->fetchGroupsCache[$cacheKey])) {
524 $groupList = $this->fetchGroupsCache[$cacheKey];
525 } else {
526 if ($idList === '') {
527 // we're at the beginning of the recursion and therefore we need to reset the userGroups member
528 $this->userGroups = array();
529 }
530 $groupList = $this->fetchGroupsRecursive($grList);
531 $this->fetchGroupsCache[$cacheKey] = $groupList;
532 }
533 return $groupList;
534 }
535
536 /**
537 * @param array $groups
538 * @return void
539 */
540 private function fetchGroupsFromDB(array $groups) {
541 $whereSQL = 'deleted=0 AND hidden=0 AND pid=0 AND uid IN (' . implode(',', $groups) . ') ';
542 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'be_groups', $whereSQL);
543 // The userGroups array is filled
544 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
545 $this->userGroups[$row['uid']] = $row;
546 }
547 }
548
549 /**
550 * Fetches particular groups recursively.
551 *
552 * @param $grList
553 * @param string $idList
554 * @return array
555 */
556 private function fetchGroupsRecursive($grList, $idList = '') {
557 $requiredGroups = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $grList, TRUE);
558 $existingGroups = array_keys($this->userGroups);
559 $missingGroups = array_diff($requiredGroups, $existingGroups);
560 if (count($missingGroups) > 0) {
561 $this->fetchGroupsFromDB($missingGroups);
562 }
563 // Traversing records in the correct order
564 foreach ($requiredGroups as $uid) {
565 // traversing list
566 // Get row:
567 $row = $this->userGroups[$uid];
568 if (is_array($row) && !\TYPO3\CMS\Core\Utility\GeneralUtility::inList($idList, $uid)) {
569 // Must be an array and $uid should not be in the idList, because then it is somewhere previously in the grouplist
570 // If the localconf.php option isset the user of the sub- sub- groups will also be used
571 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['customStageShowRecipientRecursive'] == 1) {
572 // Include sub groups
573 if (trim($row['subgroup'])) {
574 // Make integer list
575 $theList = implode(',', \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $row['subgroup']));
576 // Get the subarray
577 $subbarray = $this->fetchGroups($theList, $idList . ',' . $uid);
578 list($subUid, $subArray) = each($subbarray);
579 // Merge the subarray to the already existing userGroups array
580 $this->userGroups[$subUid] = $subArray;
581 }
582 }
583 }
584 }
585 return $this->userGroups;
586 }
587
588 /**
589 * Gets a property of a workspaces stage.
590 *
591 * @param integer $stageId
592 * @param string $property
593 * @return string
594 * @throws \InvalidArgumentException
595 */
596 public function getPropertyOfCurrentWorkspaceStage($stageId, $property) {
597 $result = NULL;
598 if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($stageId)) {
599 throw new \InvalidArgumentException($GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:error.stageId.integer'));
600 }
601 $workspaceStage = BackendUtility::getRecord(self::TABLE_STAGE, $stageId);
602 if (is_array($workspaceStage) && isset($workspaceStage[$property])) {
603 $result = $workspaceStage[$property];
604 }
605 return $result;
606 }
607
608 /**
609 * Gets the position of the given workspace in the hole process
610 * f.e. 3 means step 3 of 20, by which 1 is edit and 20 is ready to publish
611 *
612 * @param integer $stageId
613 * @return array position => 3, count => 20
614 */
615 public function getPositionOfCurrentStage($stageId) {
616 $stagesOfWS = $this->getStagesForWS();
617 $countOfStages = count($stagesOfWS);
618 switch ($stageId) {
619 case self::STAGE_PUBLISH_ID:
620 $position = $countOfStages;
621 break;
622 case self::STAGE_EDIT_ID:
623 $position = 1;
624 break;
625 default:
626 $position = 1;
627 foreach ($stagesOfWS as $key => $stageInfoArray) {
628 $position++;
629 if ($stageId == $stageInfoArray['uid']) {
630 break;
631 }
632 }
633 }
634 return array('position' => $position, 'count' => $countOfStages);
635 }
636
637 /**
638 * Check if the user has access to the previous stage, relative to the given stage
639 *
640 * @param integer $stageId
641 * @return boolean
642 */
643 public function isPrevStageAllowedForUser($stageId) {
644 $isAllowed = FALSE;
645 try {
646 $prevStage = $this->getPrevStage($stageId);
647 // if there's no prev-stage the stageIds match,
648 // otherwise we've to check if the user is permitted to use the stage
649 if (!empty($prevStage) && $prevStage['uid'] != $stageId) {
650 // if the current stage is allowed for the user, the user is also allowed to send to prev
651 $isAllowed = $this->isStageAllowedForUser($stageId);
652 }
653 } catch (\Exception $e) {
654
655 }
656 return $isAllowed;
657 }
658
659 /**
660 * Check if the user has access to the next stage, relative to the given stage
661 *
662 * @param integer $stageId
663 * @return boolean
664 */
665 public function isNextStageAllowedForUser($stageId) {
666 $isAllowed = FALSE;
667 try {
668 $nextStage = $this->getNextStage($stageId);
669 // if there's no next-stage the stageIds match,
670 // otherwise we've to check if the user is permitted to use the stage
671 if (!empty($nextStage) && $nextStage['uid'] != $stageId) {
672 // if the current stage is allowed for the user, the user is also allowed to send to next
673 $isAllowed = $this->isStageAllowedForUser($stageId);
674 }
675 } catch (\Exception $e) {
676
677 }
678 return $isAllowed;
679 }
680
681 /**
682 * @param $stageId
683 * @return boolean
684 */
685 protected function isStageAllowedForUser($stageId) {
686 $cacheKey = $this->getWorkspaceId() . '_' . $stageId;
687 $isAllowed = FALSE;
688 if (isset($this->workspaceStageAllowedCache[$cacheKey])) {
689 $isAllowed = $this->workspaceStageAllowedCache[$cacheKey];
690 } else {
691 $isAllowed = $GLOBALS['BE_USER']->workspaceCheckStageForCurrent($stageId);
692 $this->workspaceStageAllowedCache[$cacheKey] = $isAllowed;
693 }
694 return $isAllowed;
695 }
696
697 /**
698 * Determines whether a stage Id is valid.
699 *
700 * @param integer $stageId The stage Id to be checked
701 * @return boolean
702 */
703 public function isValid($stageId) {
704 $isValid = FALSE;
705 $stages = $this->getStagesForWS();
706 foreach ($stages as $stage) {
707 if ($stage['uid'] == $stageId) {
708 $isValid = TRUE;
709 break;
710 }
711 }
712 return $isValid;
713 }
714
715 /**
716 * Returns the notification mode from stage configuration
717 *
718 * Return values:
719 * 0 = notify someone / old way / default setting
720 * 1 = notify all responsible users (some users checked per default and you're not allowed to uncheck them)
721 * 2 = notify all responsible users (all users are checked and nothing can be changed during stage change)
722 *
723 * @param integer $stageId Stage id to return the notification mode for
724 * @return integer
725 * @throws \InvalidArgumentException
726 */
727 public function getNotificationMode($stageId) {
728 if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($stageId)) {
729 throw new \InvalidArgumentException($GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:error.stageId.integer'));
730 }
731 switch ($stageId) {
732 case self::STAGE_PUBLISH_EXECUTE_ID:
733
734 case self::STAGE_PUBLISH_ID:
735 $workspaceRecord = BackendUtility::getRecord('sys_workspace', $this->getWorkspaceId());
736 return $workspaceRecord['publish_notification_mode'];
737 break;
738 case self::STAGE_EDIT_ID:
739 $workspaceRecord = BackendUtility::getRecord('sys_workspace', $this->getWorkspaceId());
740 return $workspaceRecord['edit_notification_mode'];
741 break;
742 default:
743 $workspaceStage = BackendUtility::getRecord(self::TABLE_STAGE, $stageId);
744 if (is_array($workspaceStage) && isset($workspaceStage['notification_mode'])) {
745 return $workspaceStage['notification_mode'];
746 }
747 }
748 }
749
750 /**
751 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
752 */
753 protected function getBackendUser() {
754 return $GLOBALS['BE_USER'];
755 }
756 }