Skip to content

Instantly share code, notes, and snippets.

@stephanschuler
Created May 15, 2017 18:45
Show Gist options
  • Save stephanschuler/50e9fbbd9084c874a1d90622db2de552 to your computer and use it in GitHub Desktop.
Save stephanschuler/50e9fbbd9084c874a1d90622db2de552 to your computer and use it in GitHub Desktop.
<?php
namespace Netlogix\Nxseobasics\Domain\Service;
/***************************************************************
* Copyright notice
*
* (c) 2015 Stephan Schuler <stephan.schuler@netlogix.de>, netlogix GmbH & Co. KG
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Error\Http\PageNotFoundException;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\TimeTracker\NullTimeTracker;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
use TYPO3\CMS\Frontend\Utility\EidUtility;
class FrontendSimulatorService extends BackendConfigurationManager implements SingletonInterface
{
/**
* @var TypoScriptFrontendController
*/
public $typoScriptFrontendController;
/**
* @var \TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager
* @inject
*/
protected $backendConfigurationManager;
/**
* @var array
*/
protected $preserveStates = [];
/**
* @param callable $callback
* @param integer $pageId
* @return mixed
*/
public function callInFrontendContext(callable $callback, $pageId)
{
$this->simulateFrontend($pageId);
$result = call_user_func($callback);
$this->tearDown();
return $result;
}
/**
* @param integer $pageId
* @return TypoScriptFrontendController
*/
protected function simulateFrontend($pageId)
{
array_push($this->preserveStates, [
'_GET' => $GLOBALS['_GET'],
'_SERVER' => $GLOBALS['_SERVER'],
'TSFE' => $GLOBALS['TSFE'],
'currentPageId' => $this->backendConfigurationManager->currentPageId,
'pageId' => $pageId,
]);
$rootline = BackendUtility::BEgetRootLine($pageId);
$host = BackendUtility::firstDomainRecord($rootline);
$_SERVER['HTTP_HOST'] = $host;
$pageNotFoundHandling = $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'];
$GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'] = sprintf('USER_FUNCTION:%s->interceptPageNotFoundHandling',
get_class($this));
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'][__CLASS__] = get_class($this) . '->exportTslibFe';
EidUtility::initFeUser();
unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'][__CLASS__]);
$GLOBALS['TT'] = new NullTimeTracker();
GeneralUtility::_GETset($pageId, 'id');
$GLOBALS['TSFE'] = $this->typoScriptFrontendController;
$this->typoScriptFrontendController->id = $pageId;
$this->typoScriptFrontendController->set_no_cache('SitemapCommandController', true);
$this->typoScriptFrontendController->fetch_the_id();
$this->typoScriptFrontendController->initTemplate();
$this->typoScriptFrontendController->getConfigArray();
if ($this->backendConfigurationManager->currentPageId !== $pageId) {
$this->backendConfigurationManager->currentPageId = null;
$this->backendConfigurationManager->getCurrentPageId();
}
$GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'] = $pageNotFoundHandling;
return $this->typoScriptFrontendController;
}
/**
* @throws \Exception
*/
protected function tearDown()
{
$stateToRestore = array_pop($this->preserveStates);
if (is_null($stateToRestore)) {
throw new \Exception('There is no frontend state to clean up.', 1441812955);
}
$GLOBALS['_GET'] = $stateToRestore['_GET'];
$GLOBALS['_SERVER'] = $stateToRestore['_SERVER'];
if ($stateToRestore['TSFE']) {
$GLOBALS['TSFE'] = $stateToRestore['TSFE'];
} else {
unset($GLOBALS['TSFE']);
}
if ($this->backendConfigurationManager->currentPageId !== $stateToRestore['currentPageId']) {
$this->backendConfigurationManager->currentPageId = null;
$this->backendConfigurationManager->getCurrentPageId();
}
}
/**
* @param array $params
* @param TypoScriptFrontendController $typoScriptFrontendController
*/
public function exportTslibFe(
array $params,
TypoScriptFrontendController $typoScriptFrontendController
) {
$this->typoScriptFrontendController = $typoScriptFrontendController;
}
/**
* If a "page not found" exception is triggered somewhere, the default pageNotFound_handling
* mechanism is called. This method makes sure the exception doesn't lead to "echo" some
* error message to stdout but make the exception apear in the error log.
*
* @throws PageNotFoundException
*/
public function interceptPageNotFoundHandling()
{
throw new PageNotFoundException('The requested root page was not found to create a sitemap.xml for.',
1428937181);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment