bookmark-pages/Classes/ViewHelpers/Bookmark2ViewHelper.php
2021-08-20 13:33:13 +02:00

246 lines
9.0 KiB
PHP

<?php
/*
* This file is part of the package thucke/th-rating.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/
namespace WapplerSystems\BookmarksLikesRatings\ViewHelpers;
use TYPO3\CMS\Core\Log\LogLevel;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
/**
*
*
*/
class Bookmark2ViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;
/**
* Disable escaping of this node's output
*
* @var bool
*/
protected $escapeOutput = false;
/**
* @noinspection PhpUnnecessaryFullyQualifiedNameInspection
* @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
* contains a backup of the current['TSFE'] if used in BE mode
*/
protected static $tsfeBackup;
/**
* @noinspection PhpFullyQualifiedNameUsageInspection
* @var \TYPO3\CMS\Core\Log\Logger $logger
*/
protected $logger;
/**
* @var array
*/
protected $typoScriptSetup;
/**
* @noinspection PhpUnnecessaryFullyQualifiedNameInspection
* @var \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService
*/
protected $extensionHelperService;
public function initializeArguments(): void
{
$this->registerArgument('action', 'string', 'The rating action');
$this->registerArgument('ratetable', 'string', 'The rating tablename');
$this->registerArgument('ratefield', 'string', 'The rating fieldname');
$this->registerArgument('ratedobjectuid', 'integer', 'The ratingobject uid', true);
$this->registerArgument('ratingobject', 'integer', 'The ratingobject');
$this->registerArgument('display', 'string', 'The display configuration');
}
/**
* Renders the ratingView
*
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return mixed
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
* @noinspection PhpFullyQualifiedNameUsageInspection
*/
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
$typoscriptObjectPath = 'plugin.tx_thrating';
$ratedobjectuid = $arguments['ratedobjectuid'];
$action = $arguments['action'];
$ratingobject = $arguments['ratingobject'];
$ratetable = $arguments['ratetable'];
$ratefield = $arguments['ratefield'];
$display = $arguments['display'];
$extensionHelperService = static::getExtensionHelperService();
$contentObjectRenderer = static::getContentObjectRenderer();
//instantiate the logger
$logger = $extensionHelperService->getLogger(__CLASS__);
$logger->log(
LogLevel::DEBUG,
'Entry point',
[
'Viewhelper parameters' => [
'action' => $action,
'ratingobject' => $ratingobject,
'ratetable' => $ratetable,
'ratefield' => $ratefield,
'ratedobjectuid' => $ratedobjectuid,
'display' => $display, ],
'typoscript' => static::getConfigurationManager()
->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT),
]
);
if (TYPO3_MODE === 'BE') {
static::simulateFrontendEnvironment();
}
$contentObjectRenderer->start([]);
$pathSegments = GeneralUtility::trimExplode('.', $typoscriptObjectPath);
$lastSegment = array_pop($pathSegments);
$setup = static::getConfigurationManager()
->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
foreach ($pathSegments as $segment) {
if (!array_key_exists($segment . '.', $setup)) {
$logger->log(
LogLevel::CRITICAL,
'TypoScript object path does not exist',
[
'Typoscript object path' => htmlspecialchars($typoscriptObjectPath),
'Setup' => $setup,
'errorCode' => 1253191023, ]
);
throw new \TYPO3Fluid\Fluid\Core\ViewHelper\Exception(
'TypoScript object path "' . $typoscriptObjectPath . '" does not exist',
1549388144
);
}
$setup = $setup[$segment . '.'];
}
if (!isset($setup[$lastSegment])) {
throw new \TYPO3Fluid\Fluid\Core\ViewHelper\Exception(
'No Content Object definition found at TypoScript object path "' . $typoscriptObjectPath . '"',
1549388123
);
}
if (!empty($action)) {
$setup[$lastSegment . '.']['action'] = $action;
$setup[$lastSegment . '.']['switchableControllerActions.']['Vote.']['1'] = $action;
}
if (!empty($ratingobject)) {
$setup[$lastSegment . '.']['settings.']['ratingobject'] = $ratingobject;
} elseif (!empty($ratetable) && !empty($ratefield)) {
$setup[$lastSegment . '.']['settings.']['ratetable'] = $ratetable;
$setup[$lastSegment . '.']['settings.']['ratefield'] = $ratefield;
} else {
$logger->log(
LogLevel::CRITICAL,
'ratingobject not specified or ratetable/ratfield not set',
['errorCode' => 1399727698]
);
throw new Exception('ratingobject not specified or ratetable/ratfield not set', 1399727698);
}
if (!empty($ratedobjectuid)) {
$setup[$lastSegment . '.']['settings.']['ratedobjectuid'] = $ratedobjectuid;
} else {
$logger->log(LogLevel::CRITICAL, 'ratedobjectuid not set', ['errorCode' => 1304624408]);
throw new Exception('ratedobjectuid not set', 1304624408);
}
if (!empty($display)) {
$setup[$lastSegment . '.']['settings.']['display'] = $display;
}
$logger->log(
LogLevel::DEBUG,
'Single contentObjectRenderer to get',
[
'contentObjectRenderer type' => $setup[$lastSegment],
'cOjb config' => $setup[$lastSegment . '.'], ]
);
$content = $contentObjectRenderer->cObjGetSingle($setup[$lastSegment], $setup[$lastSegment . '.'] ?? []);
if (TYPO3_MODE === 'BE') {
static::resetFrontendEnvironment();
}
$logger->log(LogLevel::INFO, 'Generated content', ['content' => $content]);
$logger->log(LogLevel::DEBUG, 'Exit point');
return $content;
}
/**
* @return \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService
*/
protected static function getExtensionHelperService(): ExtensionHelperService
{
return GeneralUtility::makeInstance(ObjectManager::class)->get(ExtensionHelperService::class);
}
/**
* @return object|\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
*/
protected static function getConfigurationManager()
{
return GeneralUtility::makeInstance(ObjectManager::class)->get(ConfigurationManagerInterface::class);
}
/**
* @return \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
*/
protected static function getContentObjectRenderer(): ContentObjectRenderer
{
return GeneralUtility::makeInstance(
ContentObjectRenderer::class,
$GLOBALS['TSFE'] ?? GeneralUtility::makeInstance(TypoScriptFrontendController::class, null, 0, 0)
);
}
/**
* Sets the $TSFE->cObjectDepthCounter in Backend mode
* This somewhat hacky work around is currently needed because the cObjGetSingle() function
* of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer relies on this setting
*/
protected static function simulateFrontendEnvironment(): void
{
static::$tsfeBackup = $GLOBALS['TSFE'] ?? null;
/** @noinspection PhpFullyQualifiedNameUsageInspection */
$GLOBALS['TSFE'] = new \stdClass();
$GLOBALS['TSFE']->cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
$GLOBALS['TSFE']->cObjectDepthCounter = 100;
}
/**
* Resets $GLOBALS['TSFE'] if it was previously changed by simulateFrontendEnvironment()
*
* @see simulateFrontendEnvironment()
*/
protected static function resetFrontendEnvironment(): void
{
$GLOBALS['TSFE'] = static::$tsfeBackup;
}
}