‪TYPO3CMS  10.4
PreviewUriBuilder.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\UriInterface;
36 
43 {
47  protected ‪$pageCache = [];
48 
52  protected ‪$workspaceService;
53 
57  protected ‪$previewLinkLifetime;
58 
59  public function ‪__construct()
60  {
61  $this->workspaceService = GeneralUtility::makeInstance(WorkspaceService::class);
62  $this->previewLinkLifetime = $this->workspaceService->getPreviewLinkLifetime();
63  }
64 
72  public function ‪buildUriForPage(int $uid, int $languageId = 0): string
73  {
74  $previewKeyword = $this->‪compilePreviewKeyword(
75  $this->previewLinkLifetime * 3600,
76  $this->workspaceService->getCurrentWorkspace()
77  );
78 
79  $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
80  try {
81  $site = $siteFinder->getSiteByPageId($uid);
82  try {
83  $language = $site->getLanguageById($languageId);
84  } catch (\InvalidArgumentException $e) {
85  $language = $site->getDefaultLanguage();
86  }
87  $uri = $site->getRouter()->generateUri($uid, ['ADMCMD_prev' => $previewKeyword, '_language' => $language], '');
88  return (string)$uri;
90  throw new ‪UnableToLinkToPageException('The page ' . $uid . ' had no proper connection to a site, no link could be built.', 1559794916);
91  }
92  }
93 
100  public function ‪buildUrisForAllLanguagesOfPage(int $pageId): array
101  {
102  $previewLanguages = $this->‪getAvailableLanguages($pageId);
103  $previewLinks = [];
104 
105  foreach ($previewLanguages as $languageUid => $language) {
106  $previewLinks[$language] = $this->‪buildUriForPage($pageId, $languageUid);
107  }
108 
109  return $previewLinks;
110  }
111 
119  public function ‪buildUriForWorkspaceSplitPreview(int $uid): UriInterface
120  {
121  // In case a $pageUid is submitted we need to make sure it points to a live-page
122  if ($uid > 0) {
123  $uid = $this->‪getLivePageUid($uid);
124  }
125  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
126  return $uriBuilder->buildUriFromRoute(
127  'workspace_previewcontrols',
128  ['id' => $uid],
130  );
131  }
132 
142  public function ‪buildUriForElement(string $table, int $uid, array $liveRecord = null, array $versionRecord = null): string
143  {
144  $movePlaceholder = [];
145  if ($table === 'pages') {
147  }
148 
149  if ($liveRecord === null) {
150  $liveRecord = ‪BackendUtility::getLiveVersionOfRecord($table, $uid);
151  }
152  if ($versionRecord === null) {
153  $versionRecord = ‪BackendUtility::getRecord($table, $uid);
154  }
155  if (‪VersionState::cast($versionRecord['t3ver_state'])->equals(‪VersionState::MOVE_POINTER)) {
156  $movePlaceholder = ‪BackendUtility::getMovePlaceholder($table, $liveRecord['uid'], 'pid');
157  }
158 
159  // Directly use pid value and consider move placeholders
160  $previewPageId = (empty($movePlaceholder['pid']) ? $liveRecord['pid'] : $movePlaceholder['pid']);
161  $additionalParameters = '&previewWS=' . $versionRecord['t3ver_wsid'];
162  // Add language parameter if record is a localization
164  $languageField = ‪$GLOBALS['TCA'][$table]['ctrl']['languageField'];
165  if ($versionRecord[$languageField] > 0) {
166  $additionalParameters .= '&L=' . $versionRecord[$languageField];
167  }
168  }
169 
170  $pageTsConfig = ‪BackendUtility::getPagesTSconfig($previewPageId);
171  $viewUrl = '';
172 
173  // Directly use determined direct page id
174  if ($table === 'tt_content') {
175  $viewUrl = ‪BackendUtility::viewOnClick($previewPageId, '', null, '', '', $additionalParameters);
176  } elseif (!empty($pageTsConfig['options.']['workspaces.']['previewPageId.'][$table]) || !empty($pageTsConfig['options.']['workspaces.']['previewPageId'])) {
177  // Analyze Page TSconfig options.workspaces.previewPageId
178  if (!empty($pageTsConfig['options.']['workspaces.']['previewPageId.'][$table])) {
179  $previewConfiguration = $pageTsConfig['options.']['workspaces.']['previewPageId.'][$table];
180  } else {
181  $previewConfiguration = $pageTsConfig['options.']['workspaces.']['previewPageId'];
182  }
183  // Extract possible settings (e.g. "field:pid")
184  [$previewKey, $previewValue] = explode(':', $previewConfiguration, 2);
185  if ($previewKey === 'field') {
186  $previewPageId = (int)$liveRecord[$previewValue];
187  } else {
188  $previewPageId = (int)$previewConfiguration;
189  }
190  $viewUrl = ‪BackendUtility::viewOnClick($previewPageId, '', null, '', '', $additionalParameters);
191  } elseif (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['workspaces']['viewSingleRecord'])) {
192  // Call user function to render the single record view
193  $_params = [
194  'table' => $table,
195  'uid' => $uid,
196  'record' => $liveRecord,
197  'liveRecord' => $liveRecord,
198  'versionRecord' => $versionRecord,
199  ];
200  $_funcRef = ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['workspaces']['viewSingleRecord'];
201  $null = null;
202  $viewUrl = GeneralUtility::callUserFunction($_funcRef, $_params, $null);
203  }
204 
205  return $viewUrl;
206  }
207 
215  protected function ‪compilePreviewKeyword(int $ttl = 172800, int $workspaceId = null): string
216  {
217  $keyword = md5(‪StringUtility::getUniqueId());
218  GeneralUtility::makeInstance(ConnectionPool::class)
219  ->getConnectionForTable('sys_preview')
220  ->insert(
221  'sys_preview',
222  [
223  'keyword' => $keyword,
224  'tstamp' => ‪$GLOBALS['EXEC_TIME'],
225  'endtime' => ‪$GLOBALS['EXEC_TIME'] + $ttl,
226  'config' => json_encode([
227  'fullWorkspace' => $workspaceId
228  ])
229  ]
230  );
231 
232  return $keyword;
233  }
234 
243  protected function ‪getLivePageUid(int $uid): int
244  {
245  if (!isset($this->pageCache[$uid])) {
246  $pageRecord = ‪BackendUtility::getRecord('pages', $uid);
247  if (is_array($pageRecord)) {
248  $this->pageCache[$uid] = $pageRecord['t3ver_oid'] ? (int)$pageRecord['t3ver_oid'] : $uid;
249  } else {
250  throw new \InvalidArgumentException('uid is supposed to point to an existing page - given value was: ' . $uid, 1290628113);
251  }
252  }
253  return $this->pageCache[$uid];
254  }
255 
262  protected function ‪getAvailableLanguages(int $pageId): array
263  {
264  $languageOptions = [];
265  $translationConfigurationProvider = GeneralUtility::makeInstance(TranslationConfigurationProvider::class);
266  $systemLanguages = $translationConfigurationProvider->getSystemLanguages($pageId);
267 
268  if ($this->‪getBackendUser()->checkLanguageAccess(0)) {
269  // Use configured label for default language
270  $languageOptions[0] = $systemLanguages[0]['title'];
271  }
272 
273  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
274  ->getQueryBuilderForTable('pages');
275  $queryBuilder->getRestrictions()
276  ->removeAll()
277  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
278  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, (int)$this->‪getBackendUser()->workspace));
279 
280  $result = $queryBuilder->select('sys_language_uid')
281  ->from('pages')
282  ->where(
283  $queryBuilder->expr()->eq(
284  ‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
285  $queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
286  )
287  )
288  ->execute();
289 
290  while ($row = $result->fetch()) {
291  $languageId = (int)$row['sys_language_uid'];
292  // Only add links to active languages the user has access to
293  if (isset($systemLanguages[$languageId]) && $this->‪getBackendUser()->‪checkLanguageAccess($languageId)) {
294  $languageOptions[$languageId] = $systemLanguages[$languageId]['title'];
295  }
296  }
297 
298  return $languageOptions;
299  }
300 
304  protected function ‪getBackendUser(): ‪BackendUserAuthentication
305  {
306  return ‪$GLOBALS['BE_USER'];
307  }
308 }
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\$pageCache
‪array $pageCache
Definition: PreviewUriBuilder.php:46
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\$workspaceService
‪WorkspaceService $workspaceService
Definition: PreviewUriBuilder.php:50
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\buildUriForWorkspaceSplitPreview
‪UriInterface buildUriForWorkspaceSplitPreview(int $uid)
Definition: PreviewUriBuilder.php:116
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\compilePreviewKeyword
‪string compilePreviewKeyword(int $ttl=172800, int $workspaceId=null)
Definition: PreviewUriBuilder.php:212
‪TYPO3\CMS\Core\Exception\SiteNotFoundException
Definition: SiteNotFoundException.php:26
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪TYPO3\CMS\Backend\Utility\BackendUtility\getLiveVersionIdOfRecord
‪static int null getLiveVersionIdOfRecord($table, $uid)
Definition: BackendUtility.php:3765
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\$previewLinkLifetime
‪int $previewLinkLifetime
Definition: PreviewUriBuilder.php:54
‪TYPO3\CMS\Core\Versioning\VersionState\MOVE_POINTER
‪const MOVE_POINTER
Definition: VersionState.php:73
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\__construct
‪__construct()
Definition: PreviewUriBuilder.php:56
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\buildUriForPage
‪string buildUriForPage(int $uid, int $languageId=0)
Definition: PreviewUriBuilder.php:69
‪TYPO3\CMS\Core\Type\Enumeration\cast
‪static static cast($value)
Definition: Enumeration.php:186
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\getAvailableLanguages
‪array getAvailableLanguages(int $pageId)
Definition: PreviewUriBuilder.php:259
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:38
‪TYPO3\CMS\Backend\Utility\BackendUtility\getLiveVersionOfRecord
‪static array null getLiveVersionOfRecord($table, $uid, $fields=' *')
Definition: BackendUtility.php:3748
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder
Definition: PreviewUriBuilder.php:43
‪TYPO3\CMS\Backend\Utility\BackendUtility\getPagesTSconfig
‪static array getPagesTSconfig($id)
Definition: BackendUtility.php:698
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: PreviewUriBuilder.php:301
‪TYPO3\CMS\Backend\Utility\BackendUtility\getMovePlaceholder
‪static array bool getMovePlaceholder($table, $uid, $fields=' *', $workspace=null)
Definition: BackendUtility.php:3851
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkLanguageAccess
‪bool checkLanguageAccess($langValue)
Definition: BackendUserAuthentication.php:709
‪TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException
Definition: InvalidRouteArgumentsException.php:26
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Workspaces\Service\WorkspaceService
Definition: WorkspaceService.php:36
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:95
‪TYPO3\CMS\Core\Versioning\VersionState
Definition: VersionState.php:24
‪TYPO3\CMS\Backend\Utility\BackendUtility\viewOnClick
‪static string viewOnClick( $pageUid, $backPath='', $rootLine=null, $anchorSection='', $alternativeUrl='', $additionalGetVars='', $switchFocus=true)
Definition: BackendUtility.php:2359
‪TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider
Definition: TranslationConfigurationProvider.php:35
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static string getUniqueId($prefix='')
Definition: StringUtility.php:92
‪TYPO3\CMS\Backend\Utility\BackendUtility\isTableLocalizable
‪static bool isTableLocalizable($table)
Definition: BackendUtility.php:578
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Workspaces\Preview
Definition: PreviewUriBuilder.php:18
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\buildUrisForAllLanguagesOfPage
‪array buildUrisForAllLanguagesOfPage(int $pageId)
Definition: PreviewUriBuilder.php:97
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\buildUriForElement
‪string buildUriForElement(string $table, int $uid, array $liveRecord=null, array $versionRecord=null)
Definition: PreviewUriBuilder.php:139
‪TYPO3\CMS\Backend\Routing\UriBuilder\ABSOLUTE_URL
‪const ABSOLUTE_URL
Definition: UriBuilder.php:42
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:22
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder\getLivePageUid
‪int getLivePageUid(int $uid)
Definition: PreviewUriBuilder.php:240
‪TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction
Definition: WorkspaceRestriction.php:39