Initial commit

This commit is contained in:
2018-04-02 08:07:38 +02:00
commit 7330c1ed3e
2054 changed files with 405203 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* ### Base class for all rendering ViewHelpers.
*
* If errors occur they can be graciously ignored and
* replaced by a small error message or the error itself.
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Render
*/
abstract class AbstractRenderViewHelper extends AbstractViewHelper {
/**
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
*/
protected $objectManager;
/**
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
*/
protected $configurationManager;
/**
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
* @return void
*/
public function injectObjectManager(ObjectManagerInterface $objectManager) {
$this->objectManager = $objectManager;
}
/**
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
* @return void
*/
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager) {
$this->configurationManager = $configurationManager;
}
/**
* Initialize arguments
*
* @return void
*/
public function initializeArguments() {
$this->registerArgument('onError', 'string', 'Optional error message to display if error occur while rendering. If NULL, lets the error Exception pass trough (and break rendering)', FALSE, NULL);
$this->registerArgument('graceful', 'boolean', 'If forced to FALSE, errors are not caught but rather "transmitted" as every other error would be', FALSE, FALSE);
}
/**
* @return array
*/
protected function getPreparedNamespaces() {
$namespaces = array();
foreach ((array) $this->arguments['namespaces'] as $namespaceIdentifier => $namespace) {
$addedOverriddenNamespace = '{namespace ' . $namespaceIdentifier . '=' . $namespace . '}';
array_push($namespaces, $addedOverriddenNamespace);
}
return $namespaces;
}
/**
* @return \TYPO3\CMS\Fluid\View\StandaloneView
*/
protected function getPreparedClonedView() {
$view = $this->getPreparedView();
$view->setControllerContext(clone $this->controllerContext);
$view->setFormat($this->controllerContext->getRequest()->getFormat());
$view->assignMultiple($this->templateVariableContainer->getAll());
return $view;
}
/**
* @return \TYPO3\CMS\Fluid\View\StandaloneView
*/
protected function getPreparedView() {
/** @var $view \TYPO3\CMS\Fluid\View\StandaloneView */
$view = $this->objectManager->get('TYPO3\\CMS\\Fluid\\View\\StandaloneView');
return $view;
}
/**
* @param \TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view
* @throws \Exception
* @return string
*/
protected function renderView(ViewInterface $view) {
try {
$content = $view->render();
} catch (\Exception $error) {
if (!$this->arguments['graceful']) {
throw $error;
}
$content = $error->getMessage() . ' (' . $error->getCode() . ')';
}
return $content;
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* ### Render: ASCII Character
*
* Renders a single character identified by its charset number.
*
* For example: `<v:render.character ascii="10" /> renders a UNIX linebreak
* as does {v:render.character(ascii: 10)}. Can be used in combination with
* `v:iterator.loop` to render sequences or repeat the same character:
*
* {v:render.ascii(ascii: 10) -> v:iterator.loop(count: 5)}
*
* And naturally you can feed any integer variable or ViewHelper return value
* into the `ascii` parameter throught `renderChildren` to allow chaining:
*
* {variableWithAsciiInteger -> v:render.ascii()}
*
* And arrays are also supported - they will produce a string of characters
* from each number in the array:
*
* {v:render.ascii(ascii: {0: 13, 1: 10})}
*
* Will produce a Windows line break, \r\n
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Render
*/
class AsciiViewHelper extends AbstractViewHelper {
/**
* @param mixed $ascii
* @return string
*/
public function render($ascii = NULL) {
if (NULL === $ascii) {
$ascii = $this->renderChildren();
}
if (TRUE === is_numeric($ascii)) {
return chr((integer) $ascii);
}
if (TRUE === is_array($ascii) || TRUE === $ascii instanceof \Traversable) {
$string = '';
foreach ($ascii as $characterNumber) {
$string .= chr($characterNumber);
}
return $string;
}
return '';
}
}

View File

@@ -0,0 +1,132 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface;
/**
* ### Cache Rendering ViewHelper
*
* Caches the child content (any type supported as long as it
* can be serialized). Because of the added overhead you should
* only use this if what you are caching is complex enough that
* it performs many DB request (for example when displaying an
* object with many lazy properties which don't load until the
* template asks for the property value). In short, applies to
* just about the same use cases as any other cache - but remember
* that Fluid is already a very efficient rendering engine so don't
* just assume that using the ViewHelper will increase performance
* or decrease memory usage.
*
* Works forcibly, i.e. can only re-render its content if the
* cache is cleared. A CTRL+Refresh in the browser does nothing,
* even if a BE user is logged in. Only use this ViewHelper around
* content which you are absolutely sure it makes sense to cache
* along with an identity - for example, if rendering an uncached
* plugin which contains a Partial template that is in all aspects
* just a solid-state HTML representation of something like a list
* of current news.
*
* The cache behind this ViewHelper is the Extbase object cache,
* which is cleared when you clear the page content cache.
*
* Do not use on form elements, it will invalidate the checksum.
*
* Do not use around ViewHelpers which add header data or which
* interact with the PageRenderer or other "live" objects; this
* includes many of the VHS ViewHelpers!
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Render
*/
class CacheViewHelper extends AbstractRenderViewHelper {
const ID_PREFIX = 'vhs-render-cache-viewhelper';
const ID_SEPARATOR = '-';
/**
* @var \TYPO3\CMS\Core\Cache\Frontend\StringFrontend
*/
protected $cache;
/**
* @return void
*/
public function initialize() {
$cacheManager = isset($GLOBALS['typo3CacheManager']) ? $GLOBALS['typo3CacheManager'] : GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Cache\\CacheManager');
$this->cache = $cacheManager->getCache('vhs_main');
}
/**
* Render
*
* @param mixed $identity Identifier for the cached content (usage preferred)
* @param mixed $content Value to be cached
* @return mixed
* @throws \RuntimeException
*/
public function render($identity, $content = NULL) {
if (FALSE === ctype_alnum(preg_replace('/[\-_]/i', '', $identity))) {
if (TRUE === $identity instanceof DomainObjectInterface) {
$identity = get_class($identity) . self::ID_SEPARATOR . $identity->getUid();
} elseif (TRUE === method_exists($identity, '__toString')) {
$identity = (string) $identity;
} else {
throw new \RuntimeException(
'Parameter $identity for Render/CacheViewHelper was not a string or a string-convertible object',
1352581782
);
}
}
// Hash the cache-key to circumvent disallowed chars
$identity = sha1($identity);
if (TRUE === $this->has($identity)) {
return $this->retrieve($identity);
}
if (NULL === $content) {
$content = $this->renderChildren();
}
$this->store($content, $identity);
return $content;
}
/**
* @param string $id
* @return boolean
*/
protected function has($id) {
return (boolean) $this->cache->has(self::ID_PREFIX . self::ID_SEPARATOR . $id);
}
/**
* @param mixed $value
* @param string $id
* @return void
*/
protected function store($value, $id) {
$this->cache->set(self::ID_PREFIX . self::ID_SEPARATOR . $id, $value);
}
/**
* @param string $id
* @return mixed
*/
protected function retrieve($id) {
if ($this->cache->has(self::ID_PREFIX . self::ID_SEPARATOR . $id)) {
return $this->cache->get(self::ID_PREFIX . self::ID_SEPARATOR . $id);
}
return NULL;
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
/**
* ### Render: Inline
*
* Render as string containing Fluid as if it were
* part of the template currently being rendered.
*
* Environment (template variables etc.) is cloned
* but not re-merged after rendering, which means that
* any and all changes in variables that happen while
* rendering this inline code will be destroyed after
* sub-rendering is finished.
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Render
*/
class InlineViewHelper extends AbstractRenderViewHelper {
/**
* Initialize arguments
*
* @return void
*/
public function initializeArguments() {
parent::initializeArguments();
$this->registerArgument('namespaces', 'array', 'Optional additional/overridden namespaces, array("ns" => "Tx_MyExt_ViewHelpers")', FALSE, array());
}
/**
* Renders an outside string as if it were Fluid code,
* using additional (or overridden) namespaces if so
* desired.
*
* @param string $content
* @return string
*/
public function render($content = NULL) {
if (NULL === $content) {
$content = $this->renderChildren();
}
$namespaces = $this->getPreparedNamespaces();
$namespaceHeader = implode(LF, $namespaces);
foreach ($namespaces as $namespace) {
$content = str_replace($namespace, '', $content);
}
$view = $this->getPreparedClonedView();
$view->setTemplateSource($namespaceHeader . $content);
return $this->renderView($view);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use FluidTYPO3\Vhs\ViewHelpers\Content\AbstractContentViewHelper;
/**
* ViewHelper used to render raw content records typically fetched
* with <v:content.get(column: '0', render: FALSE) />
*
* @author Björn Fromme, <fromme@dreipunktnull.com>, dreipunktnull
* @package Vhs
* @subpackage ViewHelpers\Render
*/
class RecordViewHelper extends AbstractContentViewHelper {
/**
* Render method
*
* @param array $record
* @return string
*/
public function render(array $record = array()) {
if (FALSE === isset($record['uid'])) {
return NULL;
}
return $this->renderRecord($record);
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Mvc\Dispatcher;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
/**
* ### Render: Request
*
* Renders a sub-request to the desired Extension, Plugin,
* Controller and action with the desired arguments.
*
* Note: arguments must not be wrapped with the prefix used
* in GET/POST parameters but must be provided as if the
* arguments were sent directly to the Controller action.
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Render
*/
class RequestViewHelper extends AbstractRenderViewHelper {
/**
* @var \TYPO3\CMS\Extbase\Mvc\Dispatcher
*/
protected $dispatcher;
/**
* @var string
*/
protected $requestType = 'TYPO3\CMS\Extbase\Mvc\Web\Request';
/**
* @var string
*/
protected $responseType = 'TYPO3\CMS\Extbase\Mvc\Web\Response';
/**
* @param \TYPO3\CMS\Extbase\Mvc\Dispatcher $dispatcher
* @return void
*/
public function injectDispatcher(Dispatcher $dispatcher) {
$this->dispatcher = $dispatcher;
}
/**
* Dispatch Request
*
* Dispatches (as a completely new Request) a Request that will
* execute a configured Plugin->Controller->action() which means
* that the Plugin, Controller and Action you use must be allowed
* by the plugin configuration of the target controller.
*
* @param string|NULL $action
* @param string|NULL $controller
* @param string|NULL $extensionName
* @param string|NULL $pluginName
* @param string|NULL $vendorName
* @param array $arguments
* @return \TYPO3\CMS\Extbase\Mvc\ResponseInterface
* @throws \Exception
* @api
*/
public function render(
$action = NULL,
$controller = NULL,
$extensionName = NULL,
$pluginName = NULL,
$vendorName = NULL,
array $arguments = array()
) {
$contentObjectBackup = $this->configurationManager->getContentObject();
if (TRUE === isset($this->request)) {
$configurationBackup = $this->configurationManager->getConfiguration(
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
$this->request->getControllerExtensionName(),
$this->request->getPluginName()
);
}
$temporaryContentObject = new ContentObjectRenderer();
/** @var \TYPO3\CMS\Extbase\Mvc\Web\Request $request */
$request = $this->objectManager->get($this->requestType);
$request->setControllerActionName($action);
$request->setControllerName($controller);
$request->setPluginName($pluginName);
$request->setControllerExtensionName($extensionName);
$request->setArguments($arguments);
// TODO: remove for 6.2 LTS
if (FALSE === empty($vendorName)) {
$request->setControllerVendorName($vendorName);
}
try {
/** @var \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response */
$response = $this->objectManager->get($this->responseType);
$this->configurationManager->setContentObject($temporaryContentObject);
$this->configurationManager->setConfiguration(
$this->configurationManager->getConfiguration(
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
$extensionName,
$pluginName
)
);
$this->dispatcher->dispatch($request, $response);
$this->configurationManager->setContentObject($contentObjectBackup);
if (TRUE === isset($configurationBackup)) {
$this->configurationManager->setConfiguration($configurationBackup);
}
return $response;
} catch (\Exception $error) {
if (FALSE === (boolean) $this->arguments['graceful']) {
throw $error;
}
if (FALSE === empty($this->arguments['onError'])) {
return sprintf($this->arguments['onError'], array($error->getMessage()), $error->getCode());
}
return $error->getMessage() . ' (' . $error->getCode() . ')';
}
}
}

View File

@@ -0,0 +1,95 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* ### Render: Template
*
* Render a template file (with arguments if desired).
*
* Supports passing variables and controlling the format,
* paths can be overridden and uses the same format as TS
* settings a' la plugin.tx_myext.view, which means that
* this can be done (from any extension, not just "foo")
*
* <v:render.template
* file="EXT:foo/Resources/Private/Templates/Action/Show.html"
* variables="{object: customLoadedObject}"
* paths="{v:variable.typoscript(path: 'plugin.tx_foo.view')}"
* format="xml" />
*
* Which would render the "show" action's template from
* EXT:foo using paths define in that extension's typoscript
* but using a custom loaded object when rendering the template
* rather than the object defined by the "Action" controller
* of EXT:foo. The output would be in XML format and this
* format would also be respected by Layouts and Partials
* which are rendered from the Show.html template.
*
* As such this is very similar to Render/RequestViewHelper
* with two major differences:
*
* 1. A true ControllerContext is not present when rendering which
* means that links generated in the template should be made
* always including all parameters from ExtensionName over
* PluginName through the usual action etc.
* 2. The Controller from EXT:foo is not involved in any way,
* which means that any custom variables the particular
* template depends on must be added manually through
* the "variables" argument
*
* Consider using Render/InlineViewHelper if you are rendering
* templates from the same plugin.
*
* Consider using Render/RequestViewHelper if you require a
* completely isolated rendering identical to that which takes
* place when rendering an Extbase plugin's content object.
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Render
*/
class TemplateViewHelper extends AbstractRenderViewHelper {
/**
* Renders a template using custom variables, format and paths
*
* @param string $file Path to template file, EXT:myext/... paths supported
* @param array $variables Optional array of template variables when rendering
* @param string $format Optional format of the template(s) being rendered
* @param string $paths Optional array (plugin.tx_myext.view style) of paths, EXT:mypath/... paths supported
* @return string
*/
public function render($file = NULL, $variables = array(), $format = NULL, $paths = NULL) {
if (NULL === $file) {
$file = $this->renderChildren();
}
$file = GeneralUtility::getFileAbsFileName($file);
$view = $this->getPreparedView();
$view->setTemplatePathAndFilename($file);
$view->assignMultiple($variables);
if (NULL !== $format) {
$view->setFormat($format);
}
if (TRUE === is_array($paths)) {
if (TRUE === isset($paths['layoutRootPath'])) {
$paths['layoutRootPath'] = 0 === strpos($paths['layoutRootPath'], 'EXT:') ? GeneralUtility::getFileAbsFilename($paths['layoutRootPath']) : $paths['layoutRootPath'];
$view->setLayoutRootPath($paths['layoutRootPath']);
}
if (TRUE === isset($paths['partialRootPath'])) {
$paths['partialRootPath'] = 0 === strpos($paths['partialRootPath'], 'EXT:') ? GeneralUtility::getFileAbsFilename($paths['partialRootPath']) : $paths['partialRootPath'];
$view->setPartialRootPath($paths['partialRootPath']);
}
}
return $this->renderView($view);
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* Uncaches partials. Use like ``f:render``.
* The partial will then be rendered each time.
* Please be aware that this will impact render time.
* Arguments must be serializable and will be cached.
*
* @author Danilo Bürger <danilo.buerger@hmspl.de>, Heimspiel GmbH
* @package Vhs
* @subpackage ViewHelpers\Render
*/
class UncacheViewHelper extends AbstractViewHelper {
/**
* Initialize
*
* @return void
*/
public function initializeArguments() {
$this->registerArgument('partial', 'string', 'Reference to a partial.', TRUE);
$this->registerArgument('section', 'string', 'Name of section inside the partial to render.', FALSE, NULL);
$this->registerArgument('arguments', 'array', 'Arguments to pass to the partial.', FALSE, NULL);
}
/**
* @return string
*/
public function render() {
$partialArguments = $this->arguments['arguments'];
if (FALSE === is_array($partialArguments)) {
$partialArguments = array();
}
if (FALSE === isset($partialArguments['settings']) && TRUE === $this->templateVariableContainer->exists('settings')) {
$partialArguments['settings'] = $this->templateVariableContainer->get('settings');
}
$substKey = 'INT_SCRIPT.' . $GLOBALS['TSFE']->uniqueHash();
$content = '<!--' . $substKey . '-->';
$templateView = GeneralUtility::makeInstance('FluidTYPO3\\Vhs\\View\\UncacheTemplateView');
$GLOBALS['TSFE']->config['INTincScript'][$substKey] = array(
'type' => 'POSTUSERFUNC',
'cObj' => serialize($templateView),
'postUserFunc' => 'render',
'conf' => array(
'partial' => $this->arguments['partial'],
'section' => $this->arguments['section'],
'arguments' => $partialArguments,
'controllerContext' => $this->renderingContext->getControllerContext()
),
'content' => $content
);
return $content;
}
}