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