/** * @param array $params * @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $pObj * @param string $hookType */ protected function contentPostProc($params, $pObj, $hookType) { if ($this->extensionConfiguration->shouldIncludeEofe() && !$this->extensionConfiguration->hasIncludedEofe()) { $this->extensionConfiguration->setIncludedEofe(true); $eofe = $pObj->cObj->cObjGetSingle($pObj->tmpl->setup['config.']['extbase_hijax.']['eofe'], $pObj->tmpl->setup['config.']['extbase_hijax.']['eofe.']); $pObj->content = str_ireplace('</body>', $eofe . '</body>', $pObj->content); } if ($this->extensionConfiguration->shouldIncludeSofe() && !$this->extensionConfiguration->hasIncludedSofe()) { $this->extensionConfiguration->setIncludedSofe(true); $sofe = $pObj->cObj->cObjGetSingle($pObj->tmpl->setup['config.']['extbase_hijax.']['sofe'], $pObj->tmpl->setup['config.']['extbase_hijax.']['sofe.']); $pObj->content = preg_replace('/<body([^>]*)>/msU', '<body$1>' . $sofe, $pObj->content); } $bodyClass = $pObj->tmpl->setup['config.']['extbase_hijax.']['bodyClass']; if ($bodyClass && !$this->extensionConfiguration->hasAddedBodyClass()) { $matches = array(); preg_match('/<body([^>]*)class="([^>]*)">/msU', $pObj->content, $matches); $count = 0; if (count($matches)) { $classes = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(" ", $matches[2], true); if (!in_array($bodyClass, $classes)) { $pObj->content = preg_replace('/<body([^>]*)class="([^>]*)">/msU', '<body$1class="$2 ' . $bodyClass . '">', $pObj->content, -1, $count); } } else { $pObj->content = preg_replace('/<body([^>]*)>/msU', '<body$1 class="' . $bodyClass . '">', $pObj->content, -1, $count); } if ($count) { $this->extensionConfiguration->setAddedBodyClass(true); } } if ($hookType == 'output') { while ($this->hijaxEventDispatcher->hasPendingNextPhaseEvents()) { // trick to force double rendering of some content elements $GLOBALS['TSFE']->recordRegister = array(); // trick to force loading of full TS template if (!$pObj->tmpl->loaded) { $pObj->forceTemplateParsing = TRUE; $pObj->getConfigArray(); } $this->hijaxEventDispatcher->promoteNextPhaseEvents(); $this->hijaxEventDispatcher->parseAndRunEventListeners($pObj->content); if (!$pObj->config['INTincScript']) { $pObj->config['INTincScript'] = array(); } $pObj->INTincScript(); if (self::$loopCount++ > 99) { // preventing dead loops break; } } } if ($hookType == 'output' || $pObj->isStaticCacheble()) { $this->hijaxEventDispatcher->replaceXMLCommentsWithDivs($pObj->content); } if ($hookType == 'output') { if (count($this->nonCacheableFooterCode)) { ksort($this->nonCacheableFooterCode); $pObj->content = $this->str_lreplace('</body>', '<!-- x123456 -->' . implode('', $this->nonCacheableFooterCode) . '</body>', $pObj->content); } if (count($this->nonCacheableHeaderCode)) { ksort($this->nonCacheableHeaderCode); $pObj->content = $this->str_lreplace('</head>', '<!-- x123456 -->' . implode('', $this->nonCacheableHeaderCode) . '</head>', $pObj->content); } } }
/** * Called by ajax.php / eID.php * Builds an extbase context and returns the response. * * @return void */ public function dispatch() { $this->setIsActive(true); $callback = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('callback'); $requests = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('r'); $eventsToListen = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('evts') ? \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('evts') : \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('e'); $preventDirectOutput = false; try { $this->initializeDatabase(); $this->hijaxEventDispatcher->promoteNextPhaseEvents(); $responses = array('original' => array(), 'affected' => array()); foreach ($requests as $r) { if ($r['secureLocalStorage']) { echo file_get_contents(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('extbase_hijax', 'Resources/Private/Templates/SecureLocalStorage/IFrame.html')); exit; } $skipProcessing = FALSE; $configuration = array(); $allowCaching = FALSE; if ($r['chash']) { /* @var $cacheHash \TYPO3\CMS\Frontend\Page\CacheHashCalculator */ $cacheHash = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\CacheHashCalculator'); $allowCaching = $r['chash'] == $cacheHash->calculateCacheHash(array('encryptionKey' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], 'action' => $r['action'], 'controller' => $r['controller'], 'extension' => $r['extension'], 'plugin' => $r['plugin'], 'arguments' => $r['arguments'], 'settingsHash' => $r['settingsHash'])); } if ($r['tsSource']) { $this->initialize(); if ($this->serviceContent->isAllowedTypoScriptPath($r['tsSource'])) { /* @var $listener \EssentialDots\ExtbaseHijax\Event\Listener */ $encodedSettings = str_replace('.', '---', $r['tsSource']); $settingsHash = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac($encodedSettings); $listener = $this->listenerFactory->findById('h-' . $settingsHash . '-' . $encodedSettings); $configuration = $listener->getConfiguration(); $r['extension'] = $configuration['extensionName']; $r['plugin'] = $configuration['pluginName']; $r['controller'] = $configuration['controller']; $r['action'] = $configuration['action']; } else { throw new \Exception('Path not allowed.', 503); } } elseif ($r['settingsHash']) { /* @var $listener \EssentialDots\ExtbaseHijax\Event\Listener */ $listener = $this->listenerFactory->findById($r['settingsHash']); } $bootstrap = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Core\\Bootstrap'); // load settings saved under settingsHash if ($listener) { $configuration = $listener->getConfiguration(); $request = $listener->getRequest(); $bootstrap->cObj = $listener->getCObj(); $this->checkAllowedControllerActions($configuration, $r); } elseif (\EssentialDots\ExtbaseHijax\Utility\Extension::isAllowedHijaxAction($r['extension'], $r['controller'], $r['action'], $r['vendor'])) { $allowCaching = FALSE; // we do not want to cache this request $configuration['extensionName'] = $r['extension']; $configuration['vendorName'] = $r['vendor']; $configuration['pluginName'] = $r['plugin']; $configuration['controller'] = $r['controller']; $configuration['action'] = $r['action']; } else { $skipProcessing = TRUE; } if (!$skipProcessing) { if ($allowCaching && $this->cacheRepository) { $cacheConf = array('contentFunc' => array($this, 'handleFrontendRequest'), 'contentFuncParams' => array($bootstrap, $configuration, $r, $request, $listener, TRUE)); if ($configuration['settings']['extbaseHijaxDefaultCacheExpiryPeriod']) { $cacheConf['expire_on_datetime'] = $GLOBALS['EXEC_TIME'] + $configuration['settings']['extbaseHijaxDefaultCacheExpiryPeriod']; } $cachedResponse = $this->cacheRepository->getByKey('hijax_' . $r['chash'], $cacheConf, $bootstrap->cObj); $cachedResponse['id'] = $r['id']; $responses['original'][] = $cachedResponse; } else { $responses['original'][] = $this->handleFrontendRequest($bootstrap, $configuration, $r, $request, $listener, FALSE); } } } // see if there are affected elements on the page as well // and run their code generation again $this->parseAndRunEventListeners($responses, $eventsToListen, FALSE); while ($this->hijaxEventDispatcher->hasPendingNextPhaseEvents()) { $this->hijaxEventDispatcher->promoteNextPhaseEvents(); $this->parseAndRunEventListeners($responses, $eventsToListen); if (self::$loopCount++ > 99) { // preventing dead loops break; } } foreach ($responses['original'] as $i => $response) { $this->hijaxEventDispatcher->replaceXMLCommentsWithDivs($responses['original'][$i]['response'], $responses['original'][$i]['format']); if ($responses['original'][$i]['format'] == 'json') { // yes, non-optimal, but no time for now to change the extbase core... $responses['original'][$i]['response'] = json_decode($responses['original'][$i]['response']); } } foreach ($responses['affected'] as $i => $response) { $this->hijaxEventDispatcher->replaceXMLCommentsWithDivs($responses['affected'][$i]['response'], $responses['affected'][$i]['format']); if ($responses['affected'][$i]['format'] == 'json') { // yes, non-optimal, but no time for now to change the extbase core... $responses['affected'][$i]['response'] = json_decode($responses['affected'][$i]['response']); } } $this->cleanShutDown(); } catch (\EssentialDots\ExtbaseHijax\MVC\Exception\RedirectAction $redirectException) { $responses = array('redirect' => array('url' => $redirectException->getUrl(), 'code' => $redirectException->getHttpStatus())); $preventDirectOutput = true; } catch (\Exception $e) { header('HTTP/1.1 503 Service Unavailable'); header('Status: 503 Service Unavailable'); error_log($e->getMessage()); $responses = array('success' => false, 'code' => $e->getCode()); } if (!$preventDirectOutput && $responses['original'][0]['format'] != 'html' && is_string($responses['original'][0]['response'])) { foreach ($responses['original'][0]['headers'] as $header) { header(trim($header)); } header('Cache-control: private'); header('Connection: Keep-Alive'); header('Content-Length: ' . strlen($responses['original'][0]['response'])); echo $responses['original'][0]['response']; } elseif ($callback) { header('Content-type: text/javascript'); echo $callback . '(' . json_encode($responses) . ')'; } else { header('Content-type: application/x-json'); echo json_encode($responses); } $this->setIsActive(false); }