PageRenderTime 498ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Classes/Xclass/Frontend/ContentObject/ContentObjectRenderer.php

https://bitbucket.org/imia_de/t3ext-imia-base
PHP | 501 lines | 341 code | 73 blank | 87 comment | 96 complexity | 9c537d7c12eedc34c5ff118b2bdedd84 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /***************************************************************
  3. * Copyright notice
  4. *
  5. * (c) 2016 IMIA net based solutions (info@imia.de)
  6. * All rights reserved
  7. *
  8. * This script is part of the TYPO3 project. The TYPO3 project is
  9. * free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * The GNU General Public License can be found at
  15. * http://www.gnu.org/copyleft/gpl.html.
  16. *
  17. * This script is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * This copyright notice MUST APPEAR in all copies of the script!
  23. ***************************************************************/
  24. namespace IMIA\ImiaBase\Xclass\Frontend\ContentObject;
  25. use TYPO3\CMS\Backend\Utility\BackendUtility;
  26. use TYPO3\CMS\Core\Cache\CacheManager;
  27. use TYPO3\CMS\Core\Database\ConnectionPool;
  28. use TYPO3\CMS\Core\Database\DatabaseConnection;
  29. use TYPO3\CMS\Core\LinkHandling\LinkService;
  30. use TYPO3\CMS\Core\TimeTracker\TimeTracker;
  31. use TYPO3\CMS\Core\Utility\GeneralUtility;
  32. use TYPO3\CMS\Frontend\ContentObject\ContentObjectOneSourceCollectionHookInterface;
  33. use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
  34. use TYPO3\CMS\Frontend\Page\CacheHashCalculator;
  35. use TYPO3\CMS\Frontend\View\AdminPanelView;
  36. /**
  37. * @package imia_base
  38. * @subpackage Xclass
  39. * @author David Frerich <d.frerich@imia.de>
  40. */
  41. class ContentObjectRenderer extends \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
  42. {
  43. /**
  44. * @var bool
  45. */
  46. static protected $includeHidden = false;
  47. /**
  48. * @var string
  49. */
  50. static protected $cHash;
  51. /**
  52. * @var \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface|boolean
  53. */
  54. static protected $cache = null;
  55. /**
  56. * @param string $name
  57. * @param array $conf
  58. * @param string $TSkey
  59. * @return string
  60. */
  61. public function cObjGetSingle($name, $conf, $TSkey = '__')
  62. {
  63. $result = null;
  64. $cacheKey = 'contentelement-' . $this->data['uid'] . '-' . $this->data['pid'] . '-' . $GLOBALS['TSFE']->sys_language_uid . '_' . self::getCHash();
  65. if ($name == '< lib.contentElement' || $name == '<lib.contentElement') {
  66. if (self::getCache() && TYPO3_MODE == 'FE') {
  67. if (self::getCache()->has($cacheKey)) {
  68. $result = self::getCache()->get($cacheKey);
  69. if (strtoupper($_SERVER['REQUEST_METHOD']) === 'POST' && stripos($result, '<!--PLUGIN_INCLUDED') !== false) {
  70. $result = null;
  71. }
  72. }
  73. } else {
  74. $cacheKey = null;
  75. }
  76. } else {
  77. $cacheKey = null;
  78. }
  79. if (!$result) {
  80. $result = parent::cObjGetSingle($name, $conf, $TSkey);
  81. if ($cacheKey && stripos($result, '<!--INT_SCRIPT') === false && stripos($result, '<!--NO_CONTENT_CACHE') === false) {
  82. if ($conf['templateName'] == 'List') {
  83. $result .= '<!--PLUGIN_INCLUDED-->';
  84. }
  85. $lifetime = 0;
  86. if (isset($GLOBALS['ContentCache-Lifetime'][$this->data['uid']])) {
  87. $lifetime = (int)$GLOBALS['ContentCache-Lifetime'][$this->data['uid']];
  88. $result .= '<!--NO_CONTENT_CACHE-->';
  89. }
  90. self::getCache()->set($cacheKey, $result, ['content-' . $this->data['uid'], 'pagecontent-' . $this->data['pid']], $lifetime);
  91. }
  92. }
  93. $result = str_replace('<!--PLUGIN_INCLUDED-->', '', $result);
  94. return $result;
  95. }
  96. /**
  97. * @inheritdoc
  98. */
  99. public function getRecords($tableName, array $queryConfiguration)
  100. {
  101. self::$includeHidden = true;
  102. $records = parent::getRecords($tableName, $queryConfiguration);
  103. self::$includeHidden = false;
  104. $orderBy = $GLOBALS['TCA'][$tableName]['ctrl']['sortby'] ?: 'uid';
  105. if (isset($queryConfiguration['orderBy'])) {
  106. $orderByArr = array_map('trim', explode(',', $queryConfiguration['orderBy']));
  107. if ($orderByArr[0]) {
  108. $orderBy = $orderByArr[0];
  109. }
  110. }
  111. $hiddenField = $GLOBALS['TCA'][$tableName]['ctrl']['enablecolumns']['disabled'];
  112. if ($orderBy) {
  113. $newRecords = [];
  114. foreach ($records as $key => $record) {
  115. if (!$hiddenField || !$record[$hiddenField]) {
  116. $newRecords[] = $record;
  117. }
  118. }
  119. usort($newRecords, function ($a, $b) use ($orderBy) {
  120. return $a[$orderBy] <=> $b[$orderBy];
  121. });
  122. $records = $newRecords;
  123. }
  124. return $records;
  125. }
  126. /**
  127. * @inheritdoc
  128. */
  129. public function enableFields($table, $show_hidden = false, array $ignore_array = [])
  130. {
  131. if (self::$includeHidden) {
  132. $show_hidden = true;
  133. $ignore_array['starttime'] = true;
  134. $ignore_array['endtime'] = true;
  135. }
  136. return parent::enableFields($table, (bool)$show_hidden, $ignore_array);
  137. }
  138. /**
  139. * @inheritdoc
  140. */
  141. public function getSlidePids($pidList, $pidConf)
  142. {
  143. $whereHidDel = $this->getTypoScriptFrontendController()->sys_page->where_hid_del;
  144. if ($this->getTypoScriptFrontendController()->sys_page->versioningPreview) {
  145. /** @var ConnectionPool $connectionPool */
  146. $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
  147. $expressionBuilder = $connectionPool->getQueryBuilderForTable('pages')->expr();
  148. $this->getTypoScriptFrontendController()->sys_page->where_hid_del = ' AND ' . $expressionBuilder->andX(
  149. $expressionBuilder->eq('pages.deleted', 0),
  150. $expressionBuilder->orX(
  151. $expressionBuilder->eq('pages.t3ver_wsid', 0),
  152. $expressionBuilder->eq('pages.t3ver_wsid', (int)$this->getTypoScriptFrontendController()->sys_page->versioningWorkspaceId)
  153. )
  154. );
  155. } else {
  156. $this->getTypoScriptFrontendController()->sys_page->where_hid_del = $this->getTypoScriptFrontendController()->sys_page
  157. ->enableFields('pages', $this->getTypoScriptFrontendController()->showHiddenPage, ['fe_group' => true], true);
  158. }
  159. $slidePids = parent::getSlidePids($pidList, $pidConf);
  160. if (GeneralUtility::_GP('MP')) {
  161. $mp = explode('-', GeneralUtility::_GP('MP'));
  162. if ($mp[0] == $slidePids) {
  163. $slidePids = $mp[1];
  164. }
  165. }
  166. $this->getTypoScriptFrontendController()->sys_page->where_hid_del = $whereHidDel;
  167. return $slidePids;
  168. }
  169. /**
  170. * @inheritdoc
  171. */
  172. public function __construct(TypoScriptFrontendController $typoScriptFrontendController = null)
  173. {
  174. if (GeneralUtility::_GP('M') !== 'web_FormFormbuilder') {
  175. if ($typoScriptFrontendController && !($typoScriptFrontendController instanceof TypoScriptFrontendController)) {
  176. $typoScriptFrontendController = null;
  177. }
  178. if ($GLOBALS['TSFE'] && !($GLOBALS['TSFE'] instanceof TypoScriptFrontendController)) {
  179. $GLOBALS['TSFE'] = null;
  180. }
  181. if (!$typoScriptFrontendController && !$GLOBALS['TSFE']) {
  182. if (!$GLOBALS['TSFE_BACKUP']) {
  183. $pageUid = 0;
  184. $editconf = GeneralUtility::_GP('edit');
  185. if ($editconf && is_array($editconf) && count($editconf) > 0) {
  186. foreach ($editconf as $tableName => $tableCmds) {
  187. foreach ($tableCmds as $id => $cmd) {
  188. if ($cmd == 'new' && $id < 0) {
  189. $id *= -1;
  190. } elseif ($cmd == 'new') {
  191. $tableName = 'pages';
  192. }
  193. $record = BackendUtility::getRecord($tableName, $id);
  194. if ($record) {
  195. if ($tableName == 'pages') {
  196. $pageUid = $record['uid'];
  197. } else {
  198. $pageUid = $record['pid'];
  199. }
  200. }
  201. }
  202. }
  203. }
  204. $record = $this->getPageRecord((int)$_REQUEST['id']);
  205. if ($record) {
  206. $pageUid = $record['uid'];
  207. }
  208. $typoScriptFrontendController = $this->initFrontend($pageUid);
  209. if (!$GLOBALS['TSFE']) {
  210. $GLOBALS['TSFE'] = $typoScriptFrontendController;
  211. }
  212. $GLOBALS['TSFE_BACKUP'] = $typoScriptFrontendController;
  213. } else {
  214. $typoScriptFrontendController = $GLOBALS['TSFE'] = $GLOBALS['TSFE_BACKUP'];
  215. }
  216. }
  217. }
  218. parent::__construct($typoScriptFrontendController);
  219. }
  220. /**
  221. * @inheritdoc
  222. */
  223. public function cImage($file, $conf)
  224. {
  225. $layoutKey = $this->stdWrap($conf['layoutKey'], $conf['layoutKey.']);
  226. $sourceCollection = $this->getImageSourceCollection($layoutKey, $conf, $file);
  227. if (!$sourceCollection) {
  228. $conf['layoutKey'] = 'default';
  229. }
  230. return parent::cImage($file, $conf);
  231. }
  232. /**
  233. * @param integer $pageUid
  234. * @return array
  235. */
  236. protected function getPageRecord($pageUid)
  237. {
  238. $record = $this->getDb()->exec_SELECTgetSingleRow(
  239. 'uid, pid, fe_group, doktype, starttime, endtime, hidden',
  240. 'pages',
  241. 'uid = ' . $pageUid
  242. );
  243. if ($record) {
  244. if (in_array($record['doktype'], [199, 254, 255])) {
  245. $record = $this->getPageRecord($record['pid']);
  246. }
  247. }
  248. return $record;
  249. }
  250. /**
  251. * @inheritdoc
  252. * @throws \Exception
  253. */
  254. public function typoLink($linktxt, $conf)
  255. {
  256. if ($GLOBALS['TSFE'] && ($GLOBALS['TSFE'] instanceof TypoScriptFrontendController)) {
  257. if (!$this->typoScriptFrontendController) {
  258. $this->typoScriptFrontendController = $GLOBALS['TSFE'];
  259. } else {
  260. $this->typoScriptFrontendController->sys_language_uid = $GLOBALS['TSFE']->sys_language_uid;
  261. $this->typoScriptFrontendController->sys_language_content = $GLOBALS['TSFE']->sys_language_content;
  262. $this->typoScriptFrontendController->linkVars = $GLOBALS['TSFE']->linkVars;
  263. }
  264. }
  265. // HTTPS Schema Fix START
  266. $linkParameter = trim(isset($conf['parameter.']) ? $this->stdWrap($conf['parameter'], $conf['parameter.']) : $conf['parameter']);
  267. $resolvedLinkParameters = $this->resolveMixedLinkParameter($linktxt, $linkParameter, $conf);
  268. if ($resolvedLinkParameters && isset($resolvedLinkParameters['href'])) {
  269. $linkParameter = $resolvedLinkParameters['href'];
  270. if ($linkParameter) {
  271. // Detecting kind of link and resolve all necessary parameters
  272. $linkService = GeneralUtility::makeInstance(LinkService::class);
  273. $linkDetails = $linkService->resolve($linkParameter);
  274. if ($linkDetails['type'] == 'page') {
  275. $tsfe = $this->getTypoScriptFrontendController();
  276. if (isset($conf['linkAccessRestrictedPages'])) {
  277. $disableGroupAccessCheck = (bool)$conf['linkAccessRestrictedPages'];
  278. } else {
  279. $disableGroupAccessCheck = (bool)$tsfe->config['config']['typolinkLinkAccessRestrictedPages'];
  280. }
  281. $page = $tsfe->sys_page->getPage($linkParameter, $disableGroupAccessCheck);
  282. if (substr((string)$page['doktype'], -1) == '3' && $page['url']) {
  283. // do nothing special for external urls
  284. } elseif ($tsfe->config['config']['typolinkEnableLinksAcrossDomains'] && $tsfe->config['config']['typolinkCheckRootline']) {
  285. $targetDomain = $tsfe->getDomainNameForPid($page['uid']);
  286. if ($targetDomain && !$tsfe->domainNameMatchesCurrentRequest($targetDomain)) {
  287. // Special mount point optimization START
  288. $addedMP = false;
  289. if ($GLOBALS['TYPO3_CONF_VARS']['FE']['specialMountRoots'] && stripos($conf['additionalParams'] ?: '', '&MP=') === false) {
  290. $specialMountRoots = array_map('intval', explode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['specialMountRoots']));
  291. $targetPageRootline = $tsfe->sys_page->getRootLine($page['uid']);
  292. $specialMountTargetPageUids = [];
  293. $isInSpecialMountRoots = false;
  294. foreach ($targetPageRootline as $rootlinePage) {
  295. if (in_array($rootlinePage['uid'], $specialMountRoots)) {
  296. $isInSpecialMountRoots = true;
  297. }
  298. $specialMountTargetPageUids[] = $rootlinePage['uid'];
  299. }
  300. if ($isInSpecialMountRoots) {
  301. $result = $this->getDb()->exec_SELECTquery('uid, mount_pid', 'pages',
  302. 'mount_pid IN (' . implode(',', $specialMountTargetPageUids) . ')' . $this->enableFields('pages'));
  303. while ($row = $this->getDb()->sql_fetch_assoc($result)) {
  304. $specialTargetDomain = $tsfe->getDomainNameForPid($row['uid']);
  305. if ($tsfe->domainNameMatchesCurrentRequest($specialTargetDomain)) {
  306. if (!$conf['additionalParams']) {
  307. $conf['additionalParams'] = '';
  308. }
  309. $conf['additionalParams'] .= '&MP=' . $row['mount_pid'] . '-' . $row['uid'];
  310. $addedMP = true;
  311. break;
  312. }
  313. }
  314. }
  315. }
  316. // Special mount point optimization END
  317. if (!$addedMP) {
  318. $conf['forceAbsoluteUrl'] = true;
  319. }
  320. }
  321. }
  322. }
  323. }
  324. }
  325. // HTTPS Schema Fix END
  326. $link = parent::typoLink($linktxt, $conf);
  327. return $link;
  328. }
  329. /**
  330. * @param integer $pageUid
  331. * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
  332. */
  333. protected function initFrontend($pageUid = 0)
  334. {
  335. $tsfeSafe = $GLOBALS['TSFE'];
  336. $pageNotFoundHandling = $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'];
  337. unset($GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling']);
  338. $typoScriptFrontendController = null;
  339. $orgRequest = $_SERVER['REQUEST_URI'] ?: '';
  340. $orgScriptName = $_SERVER['SCRIPT_NAME'] ?: '';
  341. ob_start();
  342. try {
  343. if (!$pageUid) {
  344. $root = $this->getDb()->exec_SELECTgetSingleRow('uid', 'pages', 'pid = 0 AND is_siteroot = 1 AND doktype NOT IN (254,255,199)' .
  345. BackendUtility::BEenableFields('pages') . BackendUtility::deleteClause('pages'), '', 'pages.sorting');
  346. if ($root && $root['uid']) {
  347. $pageUid = $root['uid'];
  348. }
  349. }
  350. if (!$_SERVER['HTTP_HOST'] && $pageUid) {
  351. $rootline = BackendUtility::BEgetRootLine($pageUid);
  352. $host = BackendUtility::firstDomainRecord($rootline);
  353. $_SERVER['HTTP_HOST'] = $host;
  354. }
  355. $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = 'typo3';
  356. if (!is_object($GLOBALS['TT'])) {
  357. $GLOBALS['TT'] = GeneralUtility::makeInstance(TimeTracker::class);
  358. $GLOBALS['TT']->start();
  359. }
  360. /** @var TypoScriptFrontendController $typoScriptFrontendController */
  361. $GLOBALS['TSFE'] = GeneralUtility::makeInstance(
  362. TypoScriptFrontendController::class, $GLOBALS['TYPO3_CONF_VARS'], $pageUid, 0, 1);
  363. $GLOBALS['TSFE']->cObj = $this;
  364. $GLOBALS['TSFE']->connectToDB();
  365. $GLOBALS['TSFE']->initFEuser();
  366. $GLOBALS['TSFE']->determineId();
  367. $GLOBALS['TSFE']->initTemplate();
  368. $GLOBALS['TSFE']->tmpl->getFileName_backPath = PATH_site;
  369. $GLOBALS['TSFE']->forceTemplateParsing = 1;
  370. $GLOBALS['TSFE']->getConfigArray();
  371. $typoScriptFrontendController = $GLOBALS['TSFE'];
  372. } catch (\Exception $e) {
  373. }
  374. ob_end_clean();
  375. if (php_sapi_name() != 'cli') {
  376. $_SERVER['REQUEST_URI'] = $orgRequest;
  377. $_SERVER['SCRIPT_NAME'] = $orgScriptName;
  378. GeneralUtility::flushInternalRuntimeCaches();
  379. }
  380. $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'] = $pageNotFoundHandling;
  381. $GLOBALS['TSFE'] = $tsfeSafe;
  382. return $typoScriptFrontendController;
  383. }
  384. /**
  385. * @return DatabaseConnection
  386. */
  387. protected function getDb()
  388. {
  389. return $GLOBALS['TYPO3_DB'];
  390. }
  391. /**
  392. * @return string
  393. */
  394. protected static function getCHash()
  395. {
  396. if (!self::$cHash) {
  397. if ($GLOBALS['TSFE']->no_cache) {
  398. $cacheHash = GeneralUtility::makeInstance(CacheHashCalculator::class);
  399. $params = GeneralUtility::_GET();
  400. if (isset($GLOBALS['TSFE']->id)) {
  401. $params['id'] = $GLOBALS['TSFE']->id;
  402. }
  403. $GLOBALS['TSFE']->cHash_array = $cacheHash->getRelevantParameters(GeneralUtility::implodeArrayForUrl('', $params));
  404. }
  405. if(method_exists($GLOBALS['TSFE'], 'getHash')){
  406. self::$cHash = $GLOBALS['TSFE']->getHash();
  407. }
  408. }
  409. return self::$cHash;
  410. }
  411. /**
  412. * @return bool|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
  413. */
  414. protected static function getCache()
  415. {
  416. if (self::$cache === null) {
  417. if (getenv('TYPO3_CONTEXT') != 'Development' && $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_imiabase']) {
  418. /** @var CacheManager $cacheManager */
  419. $cacheManager = $contentCache = GeneralUtility::makeInstance(CacheManager::class);
  420. try {
  421. self::$cache = $cacheManager->getCache('tx_imiabase');
  422. } catch (\Exception $e) {
  423. }
  424. }
  425. }
  426. return self::$cache;
  427. }
  428. }