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