2 namespace TYPO3\CMS\Workspaces\Service;
49 $availableWorkspaces = array();
51 if (
$GLOBALS[
'BE_USER']->checkWorkspace(array(
'uid' => (
string)self::LIVE_WORKSPACE_ID))) {
52 $availableWorkspaces[self::LIVE_WORKSPACE_ID] = self::getWorkspaceTitle(self::LIVE_WORKSPACE_ID);
55 $customWorkspaces =
$GLOBALS[
'TYPO3_DB']->exec_SELECTgetRows(
'uid, title, adminusers, members',
'sys_workspace',
'pid = 0' .
BackendUtility::deleteClause(
'sys_workspace'),
'',
'title');
56 if (!empty($customWorkspaces)) {
57 foreach ($customWorkspaces as $workspace) {
58 if (
$GLOBALS[
'BE_USER']->checkWorkspace($workspace)) {
59 $availableWorkspaces[$workspace[
'uid']] = $workspace[
'title'];
63 return $availableWorkspaces;
73 $workspaceId =
$GLOBALS[
'BE_USER']->workspace;
74 $activeId =
$GLOBALS[
'BE_USER']->getSessionData(
'tx_workspace_activeWorkspace');
77 if ($activeId !== null && $activeId !== self::SELECT_ALL_WORKSPACES) {
79 if (!isset($availableWorkspaces[$activeId])) {
84 if ($activeId !== null) {
85 $workspaceId = $activeId;
102 case self::LIVE_WORKSPACE_ID:
103 $title =
$GLOBALS[
'LANG']->sL(
'LLL:EXT:lang/locallang_misc.xlf:shortcut_onlineWS');
106 $labelField =
$GLOBALS[
'TCA'][
'sys_workspace'][
'ctrl'][
'label'];
108 if (is_array($wsRecord)) {
109 $title = $wsRecord[$labelField];
112 if ($title ===
false) {
113 throw new \InvalidArgumentException(
'No such workspace defined');
131 if ($wsid >= -1 && $wsid !== 0) {
136 if ($workspaceRec[
'publish_access'] & 1) {
137 $stage = \TYPO3\CMS\Workspaces\Service\StagesService::STAGE_PUBLISH_ID;
143 foreach ($versions as $table => $records) {
144 foreach ($records as $rec) {
146 $cmd[$table][$rec[
't3ver_oid']][
'version'] = array(
'action' =>
'swap',
'swapWith' => $rec[
'uid'],
'swapIntoWS' => $doSwap ? 1 : 0);
166 if ($wsid >= -1 && $wsid !== 0) {
172 foreach ($versions as $table => $records) {
173 foreach ($records as $rec) {
175 $cmd[$table][$rec[
'uid']][
'version'] = array(
'action' => $flush ?
'flush' :
'clearWSID');
196 public function selectVersionsInWorkspace($wsid, $filter = 0, $stage = -99, $pageId = -1, $recursionLevel = 0, $selectionType =
'tables_select', $language = null)
199 $filter = (int)$filter;
202 if ($pageId != -1 && $recursionLevel > 0) {
203 $pageList = $this->getTreeUids($pageId, $wsid, $recursionLevel);
204 }
elseif ($pageId != -1) {
209 $mountPoints = array_map(
'intval',
$GLOBALS[
'BE_USER']->returnWebmounts());
210 $mountPoints = array_unique($mountPoints);
211 if (!in_array(0, $mountPoints)) {
212 $tempPageIds = array();
213 foreach ($mountPoints as $mountPoint) {
214 $tempPageIds[] = $this->getTreeUids($mountPoint, $wsid, $recursionLevel);
216 $pageList = implode(
',', $tempPageIds);
217 $pageList = implode(
',', array_unique(explode(
',', $pageList)));
221 foreach (
$GLOBALS[
'TCA'] as $table => $cfg) {
223 if (!
$GLOBALS[
'BE_USER']->check($selectionType, $table)) {
226 if (
$GLOBALS[
'TCA'][$table][
'ctrl'][
'versioningWS']) {
229 $recs = array_merge($recs, $moveRecs);
232 $output[$table] = $recs;
257 $languageParentField =
'';
260 if ($isTableLocalizable ===
false && $language > 0) {
262 }
elseif ($isTableLocalizable) {
263 $languageParentField =
'A.' .
$GLOBALS[
'TCA'][$table][
'ctrl'][
'transOrigPointerField'] .
', ';
265 $fields =
'A.uid, A.t3ver_oid, A.t3ver_stage, ' . $languageParentField .
'B.pid AS wspid, B.pid AS livepid';
266 if ($isTableLocalizable) {
267 $fields .=
', A.' .
$GLOBALS[
'TCA'][$table][
'ctrl'][
'languageField'];
269 $from = $table .
' A,' . $table .
' B';
273 $pidField = $table ===
'pages' ?
'uid' :
'pid';
274 $pidConstraint = strstr($pageList,
',') ?
' IN (' . $pageList .
')' :
'=' . $pageList;
275 $where .=
' AND B.' . $pidField . $pidConstraint;
278 $where .=
' AND A.' .
$GLOBALS[
'TCA'][$table][
'ctrl'][
'languageField'] .
'=' . $language;
283 if ($wsid > self::SELECT_ALL_WORKSPACES) {
284 $where .=
' AND A.t3ver_wsid=' . $wsid;
285 }
elseif ($wsid === self::SELECT_ALL_WORKSPACES) {
286 $where .=
' AND A.t3ver_wsid!=0';
291 if ($filter === 1 || $filter === 2) {
292 $where .=
' AND A.t3ver_count ' . ($filter === 1 ?
'= 0' :
'> 0');
295 $where .=
' AND A.t3ver_stage=' . (int)$stage;
298 $where .=
' AND B.pid>=0';
300 $where .=
' AND A.t3ver_oid=B.uid';
307 return is_array($res) ? $res : array();
326 $fields =
'A.pid AS wspid, B.uid AS t3ver_oid, C.uid AS uid, B.pid AS livepid';
327 $from = $table .
' A, ' . $table .
' B,' . $table .
' C';
331 if ($wsid > self::SELECT_ALL_WORKSPACES) {
332 $where .=
' AND A.t3ver_wsid=' . $wsid .
' AND C.t3ver_wsid=' . $wsid;
333 }
elseif ($wsid === self::SELECT_ALL_WORKSPACES) {
334 $where .=
' AND A.t3ver_wsid!=0 AND C.t3ver_wsid!=0 ';
339 if ($filter === 1 || $filter === 2) {
340 $where .=
' AND C.t3ver_count ' . ($filter === 1 ?
'= 0' :
'> 0');
343 $where .=
' AND C.t3ver_stage=' . (int)$stage;
346 $pidField = $table ===
'pages' ?
'B.uid' :
'A.pid';
347 $pidConstraint = strstr($pageList,
',') ?
' IN (' . $pageList .
')' :
'=' . $pageList;
348 $where .=
' AND ' . $pidField . $pidConstraint;
350 $where .=
' AND A.t3ver_move_id = B.uid AND B.uid = C.t3ver_oid';
355 return is_array($res) ? $res : array();
366 protected function getTreeUids($pageId, $wsid, $recursionLevel)
370 $perms_clause =
$GLOBALS[
'BE_USER']->getPagePermsClause(1);
374 $pageList = $searchObj->getTreeList($pageId, $recursionLevel, 0, $perms_clause);
376 $mountPoints =
$GLOBALS[
'BE_USER']->uc[
'pageTree_temporaryMountPoint'];
377 if (!is_array($mountPoints) || empty($mountPoints)) {
378 $mountPoints = array_map(
'intval',
$GLOBALS[
'BE_USER']->returnWebmounts());
379 $mountPoints = array_unique($mountPoints);
382 foreach ($mountPoints as $mountPoint) {
383 $newList[] = $searchObj->getTreeList($mountPoint, $recursionLevel, 0, $perms_clause);
385 $pageList = implode(
',', $newList);
390 $movedAwayPages =
$GLOBALS[
'TYPO3_DB']->exec_SELECTgetRows(
'uid, pid, t3ver_move_id',
'pages',
't3ver_move_id IN (' . $pageList .
') AND t3ver_wsid=' . (
int)$wsid .
BackendUtility::deleteClause(
'pages'),
'',
'uid',
'',
't3ver_move_id');
393 $newList = array_diff($pageIds, array_keys($movedAwayPages));
395 $newList[] = $pageId;
399 foreach ($movedAwayPages as $uid => $rec) {
400 if (in_array($rec[
'pid'], $newList) && !in_array($uid, $newList)) {
406 $pageList = implode(
',', $newList);
411 if (!in_array($pageId, $pageIds)) {
412 $pageIds[] = $pageId;
414 foreach ($pageIds as $pageId) {
415 if ((
int)$pages[$pageId][
't3ver_move_id'] > 0) {
416 $newList[] = (int)$pages[$pageId][
't3ver_move_id'];
418 $newList[] = $pageId;
421 $pageList = implode(
',', $newList);
435 $permittedElements = array();
436 if (is_array($recs)) {
437 foreach ($recs as $rec) {
439 $permittedElements[] = $rec;
443 return $permittedElements;
455 $pageIdField = $table ===
'pages' ?
'uid' :
'wspid';
456 $pageId = isset($record[$pageIdField]) ? (int)$record[$pageIdField] : null;
457 if ($pageId === null) {
463 $page =
BackendUtility::getRecord(
'pages', $pageId,
'uid,pid,perms_userid,perms_user,perms_groupid,perms_group,perms_everybody');
465 return $GLOBALS[
'BE_USER']->doesUserHaveAccess($page, 1);
478 $languageUid = $record[
$GLOBALS[
'TCA'][$table][
'ctrl'][
'languageField']];
482 return $GLOBALS[
'BE_USER']->checkLanguageAccess($languageUid);
493 $cacheKey =
'workspace-oldstyleworkspace-notused';
494 $cacheResult =
$GLOBALS[
'BE_USER']->getSessionData($cacheKey);
496 $where =
'adminusers != \'\' AND adminusers NOT LIKE \'%be_users%\' AND adminusers NOT LIKE \'%be_groups%\' AND deleted=0';
497 $count =
$GLOBALS[
'TYPO3_DB']->exec_SELECTcountRows(
'uid',
'sys_workspace', $where);
498 $oldStyleWorkspaceIsUsed = $count > 0;
499 $GLOBALS[
'BE_USER']->setAndSaveSessionData($cacheKey, !$oldStyleWorkspaceIsUsed);
501 $oldStyleWorkspaceIsUsed = !$cacheResult;
503 return $oldStyleWorkspaceIsUsed;
518 $whereClause =
'pid = ' . (int)$id;
519 $whereClause .=
' AND ' .
$GLOBALS[
'TCA'][
'pages_language_overlay'][
'ctrl'][
'languageField'] .
' = ' . (int)$language;
520 $whereClause .=
' AND t3ver_wsid = ' . (int)
$GLOBALS[
'BE_USER']->workspace;
522 $res =
$GLOBALS[
'TYPO3_DB']->exec_SELECTquery(
't3ver_state',
'pages_language_overlay', $whereClause);
523 if ($row =
$GLOBALS[
'TYPO3_DB']->sql_fetch_assoc($res)) {
528 if (is_array($rec)) {
545 public static function viewSingleRecord($table, $uid, array $liveRecord = null, array $versionRecord = null)
547 if ($table ===
'pages') {
551 if ($liveRecord === null) {
554 if ($versionRecord === null) {
562 $previewPageId = (empty($movePlaceholder[
'pid']) ? $liveRecord[
'pid'] : $movePlaceholder[
'pid']);
563 $additionalParameters =
'&tx_workspaces_web_workspacesworkspaces[previewWS]=' . $versionRecord[
't3ver_wsid'];
566 $languageField =
$GLOBALS[
'TCA'][$table][
'ctrl'][
'languageField'];
567 if ($versionRecord[$languageField] > 0) {
568 $additionalParameters .=
'&L=' . $versionRecord[$languageField];
576 if ($table ===
'pages_language_overlay' || $table ===
'tt_content') {
579 }
elseif (!empty($pageTsConfig[
'options.'][
'workspaces.'][
'previewPageId.'][$table]) || !empty($pageTsConfig[
'options.'][
'workspaces.'][
'previewPageId'])) {
580 if (!empty($pageTsConfig[
'options.'][
'workspaces.'][
'previewPageId.'][$table])) {
581 $previewConfiguration = $pageTsConfig[
'options.'][
'workspaces.'][
'previewPageId.'][$table];
583 $previewConfiguration = $pageTsConfig[
'options.'][
'workspaces.'][
'previewPageId'];
586 list($previewKey, $previewValue) = explode(
':', $previewConfiguration, 2);
587 if ($previewKey ===
'field') {
588 $previewPageId = (int)$liveRecord[$previewValue];
590 $previewPageId = (int)$previewConfiguration;
594 }
elseif (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'workspaces'][
'viewSingleRecord'])) {
598 'record' => $liveRecord,
599 'liveRecord' => $liveRecord,
600 'versionRecord' => $versionRecord,
602 $_funcRef =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'workspaces'][
'viewSingleRecord'];
620 if ($pageUid > 0 && $workspaceUid > 0) {
644 $timeToLiveHours = $previewObject->getPreviewLinkLifetime();
645 $previewKeyword = $previewObject->compilePreviewKeyword(
'',
$GLOBALS[
'BE_USER']->user[
'uid'], $timeToLiveHours * 3600, $this->
getCurrentWorkspace());
647 'ADMCMD_prev' => $previewKeyword,
660 public function generateWorkspaceSplittedPreviewLink($uid, $addDomain =
false)
667 $uriBuilder = $this->
getObjectManager()->get(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class);
668 $redirect =
'index.php?redirect_url=';
672 $viewScript = $uriBuilder->uriFor(
'index', array(),
'Preview',
'workspaces',
'web_workspacesworkspaces') .
'&id=';
674 if ($addDomain ===
true) {
675 return BackendUtility::getViewDomain($uid) . $redirect . urlencode($viewScript) . $uid;
690 $previewLanguages = $this->getAvailableLanguages($uid);
691 $previewLinks = array();
693 foreach ($previewLanguages as $languageUid => $language) {
694 $previewLinks[$language] = $previewUrl .
'&L=' . $languageUid;
697 return $previewLinks;
710 if (!isset($this->pageCache[$uid])) {
712 if (is_array($pageRecord)) {
713 $this->pageCache[$uid] = $pageRecord[
't3ver_oid'] ? $pageRecord[
't3ver_oid'] : $uid;
715 throw new \InvalidArgumentException(
'uid is supposed to point to an existing page - given value was:' . $uid, 1290628113);
718 return $this->pageCache[$uid];
730 $workspace = (int)$workspace;
731 $pageId = (int)$pageId;
732 if ($workspace === 0) {
736 if (isset($this->versionsOnPageCache[$pageId][$workspace])) {
737 return $this->versionsOnPageCache[$pageId][$workspace];
740 if (!empty($this->versionsOnPageCache)) {
744 $this->versionsOnPageCache[$pageId][$workspace] =
false;
745 foreach (
$GLOBALS[
'TCA'] as $tableName => $tableConfiguration) {
746 if ($tableName ===
'pages' || empty($tableConfiguration[
'ctrl'][
'versioningWS'])) {
751 $joinStatement =
'(A.t3ver_oid=B.uid AND A.t3ver_state<>' . $movePointer
752 .
' OR A.t3ver_oid=B.t3ver_move_id AND A.t3ver_state=' . $movePointer .
')';
757 'B.uid as live_uid, B.pid as live_pid, A.uid as offline_uid',
758 $tableName .
' A,' . $tableName .
' B',
759 'A.pid=-1 AND A.t3ver_wsid=' . $workspace .
' AND ' . $joinStatement .
764 if (!empty($records)) {
765 foreach ($records as $record) {
766 $this->versionsOnPageCache[$record[
'live_pid']][$workspace] =
true;
771 return $this->versionsOnPageCache[$pageId][$workspace];
796 public function getAvailableLanguages($pageId)
798 $languageOptions = array();
800 $translationConfigurationProvider =
GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider::class);
801 $systemLanguages = $translationConfigurationProvider->getSystemLanguages($pageId);
803 if (
$GLOBALS[
'BE_USER']->checkLanguageAccess(0)) {
805 $languageOptions[0] = $systemLanguages[0][
'title'];
809 if (!is_array($pages)) {
810 return $languageOptions;
813 foreach ($pages as $page) {
814 $languageId = (int)$page[
'sys_language_uid'];
816 if (isset($systemLanguages[$languageId]) &&
$GLOBALS[
'BE_USER']->checkLanguageAccess($languageId)) {
817 $languageOptions[$page[
'sys_language_uid']] = $systemLanguages[$languageId][
'title'];
821 return $languageOptions;