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,108 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Variable;
/*
* 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\Object\ObjectManager;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* ### Convert ViewHelper
*
* Converts $value to $type which can be one of 'string', 'integer',
* 'float', 'boolean', 'array' or 'ObjectStorage'. If $value is NULL
* sensible defaults are assigned or $default which obviously has to
* be of $type as well.
*
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
* @package Vhs
* @subpackage ViewHelpers\Var
*/
class ConvertViewHelper extends AbstractViewHelper {
/**
* Initialize arguments
*/
public function initializeArguments() {
$this->registerArgument('value', 'mixed', 'Value to convert into a different type', FALSE, NULL);
$this->registerArgument('type', 'string', 'Data type to convert the value into. Can be one of "string", "integer", "float", "boolean", "array" or "ObjectStorage".', TRUE);
$this->registerArgument('default', 'mixed', 'Optional default value to assign to the converted variable in case it is NULL.', FALSE, NULL);
}
/**
* Render method
*
* @throws \RuntimeException
* @return mixed
*/
public function render() {
if (TRUE === isset($this->arguments['value'])) {
$value = $this->arguments['value'];
} else {
$value = $this->renderChildren();
}
$type = $this->arguments['type'];
if (gettype($value) === $type) {
return $value;
}
if (NULL !== $value) {
if ('ObjectStorage' === $type && 'array' === gettype($value)) {
/** @var ObjectManager $objectManager */
$objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
/** @var ObjectStorage $storage */
$storage = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage');
foreach ($value as $item) {
$storage->attach($item);
}
$value = $storage;
} elseif ('array' === $type && TRUE === $value instanceof \Traversable) {
$value = iterator_to_array($value, FALSE);
} elseif ('array' === $type) {
$value = array($value);
} else {
settype($value, $type);
}
} else {
if (TRUE === isset($this->arguments['default'])) {
$default = $this->arguments['default'];
if (gettype($default) !== $type) {
throw new \RuntimeException('Supplied argument "default" is not of the type "' . $type .'"', 1364542576);
}
$value = $default;
} else {
switch ($type) {
case 'string':
$value = '';
break;
case 'integer':
$value = 0;
break;
case 'boolean':
$value = FALSE;
break;
case 'float':
$value = 0.0;
break;
case 'array':
$value = array();
break;
case 'ObjectStorage':
$objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$value = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage');
break;
default:
throw new \RuntimeException('Provided argument "type" is not valid', 1364542884);
}
}
}
return $value;
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Variable;
/*
* 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;
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
/**
* ### ExtConf ViewHelper
*
* Reads settings from ext_conf_template.txt
*
* ### Examples
*
* {v:variable.extensionConfiguration(extensionKey:'foo',path:'bar.baz')}
*
* Returns setting 'bar.baz' from extension 'foo' located in ext_conf_template.txt
*
* @author Harry Glatz <glatz@analog.de>
* @author Cedric Ziel <cedric@cedric-ziel.com>
* @author Stefan Neufeind <info@speedpartner.de>
* @package Vhs
* @subpackage ViewHelpers
*/
class ExtensionConfigurationViewHelper extends AbstractViewHelper {
/**
* @param array $source TypoScript-array with dots: $source['foo.']['bar.']['baz']
* @param string $path
* @return mixed
*/
protected function extractFromArrayByPath($source, $path) {
$result = $source;
$pathParts = explode('.', $path);
$pathParts = array_diff($pathParts, array(''));
foreach ($pathParts as $part) {
if (array_key_exists($part . '.', $result)) {
$result = $result[$part . '.'];
} elseif (array_key_exists($part, $result)) {
$result = $result[$part];
} else {
return NULL;
}
}
return $result;
}
/**
* @param string $path
* @param string $extensionKey
* @param string $name (deprecated, just use $path instead)
* @return string
* @throws Exception
*/
public function render($path = NULL, $extensionKey = NULL, $name = NULL) {
if (NULL !== $path) {
$pathToExtract = $path;
} elseif (NULL !== $name) {
$pathToExtract = $name;
GeneralUtility::deprecationLog('v:variable.extensionConfiguration was called with parameter "name" which is deprecated. Use "path" instead.');
} else {
throw new Exception('v:variable.extensionConfiguration requires the "path" attribute to be filled.', 1446998437);
}
if (NULL === $extensionKey) {
$extensionName = $this->controllerContext->getRequest()->getControllerExtensionName();
$extensionKey = GeneralUtility::camelCaseToLowerCaseUnderscored($extensionName);
}
if (FALSE === array_key_exists($extensionKey, $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'])) {
return NULL;
}
$extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$extensionKey]);
return $this->extractFromArrayByPath($extConf, $path);
}
}

View File

@@ -0,0 +1,102 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Variable;
/*
* 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\Reflection\ObjectAccess;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* ### Variable: Get
*
* ViewHelper used to read the value of a current template
* variable. Can be used with dynamic indices in arrays:
*
* <v:variable.get name="array.{dynamicIndex}" />
* <v:variable.get name="array.{v:variable.get(name: 'arrayOfSelectedKeys.{indexInArray}')}" />
* <f:for each="{v:variable.get(name: 'object.arrayProperty.{dynamicIndex}')}" as="nestedObject">
* ...
* </f:for>
*
* Or to read names of variables which contain dynamic parts:
*
* <!-- if {variableName} is "Name", outputs value of {dynamicName} -->
* {v:variable.get(name: 'dynamic{variableName}')}
*
* If your target object is an array with unsequential yet
* numeric indices (e.g. {123: 'value1', 513: 'value2'},
* commonly seen in reindexed UID map arrays) use
* `useRawIndex="TRUE"` to indicate you do not want your
* array/QueryResult/Iterator to be accessed by locating
* the Nth element - which is the default behavior.
*
* ```warning
* Do not try `useRawKeys="TRUE"` on QueryResult or
* ObjectStorage unless you are fully aware what you are
* doing. These particular types require an unpredictable
* index value - the SPL object hash value - when accessing
* members directly. This SPL indexing and the very common
* occurrences of QueryResult and ObjectStorage variables
* in templates is the very reason why `useRawKeys` by
* default is set to `FALSE`.
* ```
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Var
*/
class GetViewHelper extends AbstractViewHelper {
/**
* @param string $name
* @param boolean $useRawKeys
* @return mixed
*/
public function render($name, $useRawKeys = FALSE) {
if (FALSE === strpos($name, '.')) {
if (TRUE === $this->templateVariableContainer->exists($name)) {
return $this->templateVariableContainer->get($name);
}
} else {
$segments = explode('.', $name);
$lastSegment = array_shift($segments);
$templateVariableRootName = $lastSegment;
if (TRUE === $this->templateVariableContainer->exists($templateVariableRootName)) {
$templateVariableRoot = $this->templateVariableContainer->get($templateVariableRootName);
if (TRUE === $useRawKeys) {
return ObjectAccess::getPropertyPath($templateVariableRoot, implode('.', $segments));
}
try {
$value = $templateVariableRoot;
foreach ($segments as $segment) {
if (TRUE === ctype_digit($segment)) {
$segment = intval($segment);
$index = 0;
// Note: this loop approach is not a stupid solution. If you doubt this,
// attempt to feth a number at a numeric index from ObjectStorage ;)
foreach ($value as $possibleValue) {
if ($index === $segment) {
$value = $possibleValue;
break;
}
++ $index;
}
continue;
}
$value = ObjectAccess::getProperty($value, $segment);
}
return $value;
} catch (\Exception $e) {
return NULL;
}
}
}
return NULL;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Variable\Register;
/*
* 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;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
/**
* ### Variable\Register: Get
*
* ViewHelper used to read the value of a TSFE-register
* Can be used to read names of variables which contain dynamic parts:
*
* <!-- if {variableName} is "Name", outputs value of {dynamicName} -->
* {v:variable.register.get(name: 'dynamic{variableName}')}
*
* @author Stefan Neufeind <info (at) speedpartner.de>
* @package Vhs
* @subpackage ViewHelpers\Var
*/
class GetViewHelper extends AbstractViewHelper {
/**
* @return void
*/
public function initializeArguments() {
$this->registerArgument('name', 'string', 'Name of register', TRUE);
}
/**
* @return string
*/
public function render() {
if (FALSE === $GLOBALS['TSFE'] instanceof TypoScriptFrontendController) {
return NULL;
}
$name = $this->arguments['name'];
$value = NULL;
if (TRUE === isset($GLOBALS['TSFE']->register[$name])) {
$value = $GLOBALS['TSFE']->register[$name];
}
return $value;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Variable\Register;
/*
* 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;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
/**
* ### Variable\Register: Set
*
* Sets a single register in the TSFE-register.
*
* Using as `{value -> v:variable.register.set(name: 'myVar')}` makes $GLOBALS["TSFE"]->register['myVar']
* contain `{value}`.
*
* @author Stefan Neufeind <info (at) speedpartner.de>
* @package Vhs
* @subpackage ViewHelpers\Var
*/
class SetViewHelper extends AbstractViewHelper {
/**
* @return void
*/
public function initializeArguments() {
$this->registerArgument('value', 'mixed', 'Value to set', FALSE, NULL);
$this->registerArgument('name', 'string', 'Name of register', TRUE);
}
/**
* Set (override) the value in register $name.
*/
public function render() {
if (FALSE === $GLOBALS['TSFE'] instanceof TypoScriptFrontendController) {
return NULL;
}
$name = $this->arguments['name'];
$value = $this->arguments['value'];
if (NULL === $value) {
$value = $this->renderChildren();
}
$GLOBALS['TSFE']->register[$name] = $value;
return NULL;
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Variable;
/*
* 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\Reflection\ObjectAccess;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* ### Variable: Set
*
* Sets a single variable in the TemplateVariableContainer
* scope. The variable then becomes accessible as {var}.
*
* Combines well with `v:variable.get` to set shorter variable
* names referencing dynamic variables, such as:
*
* <v:variable.set name="myObject" value="{v:variable.get(name: 'arrayVariable.{offset}')}" />
* <!-- If {index} == 4 then {myObject} is now == {arrayVariable.4} -->
* {myObject.name} <!-- corresponds to {arrayVariable.4.name} -->
*
* Note that `{arrayVariable.{offset}.name}` is not possible
* due to the way Fluid parses nodes; the above piece of
* code would try reading `arrayVariable.{offset}.name`
* as a variable actually called "arrayVariable.{offset}.name"
* rather than the correct `arrayVariable[offset][name]`.
*
* In many ways this ViewHelper works like `f:alias`
* with one exception: in `f:alias` the variable only
* becomes accessible in the tag content, whereas `v:variable.set`
* inserts the variable in the template and leaves it there
* (it "leaks" the variable).
*
* If $name contains a dot, VHS will attempt to load the object
* stored under the named used as the first segment part and
* set the value at the remaining path. E.g.
* `{value -> v:variable.set(name: 'object.property.subProperty')}`
* would attempt to load `{object}` first, then set
* `property.subProperty` on that object/array using
* ObjectAccess::setPropertyPath(). If `{object}` is not
* an object or an array, the variable will not be set. Please
* note: Extbase does not currently support setting variables
* deeper than two levels, meaning a `name` of fx `foo.bar.baz`
* will be ignored. To set values deeper than two levels you
* must first extract the second-level object then set the
* value on that object.
*
* Using as `{value -> v:variable.set(name: 'myVar')}` makes `{myVar}` contain
* `{value}`.
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Var
*/
class SetViewHelper extends AbstractViewHelper {
/**
* Set (override) the variable in $name.
*
* @param string $name
* @param mixed $value
* @return void
*/
public function render($name, $value = NULL) {
if (NULL === $value) {
$value = $this->renderChildren();
}
if (FALSE === strpos($name, '.')) {
if (TRUE === $this->templateVariableContainer->exists($name)) {
$this->templateVariableContainer->remove($name);
}
$this->templateVariableContainer->add($name, $value);
} elseif (1 === substr_count($name, '.')) {
$parts = explode('.', $name);
$objectName = array_shift($parts);
$path = implode('.', $parts);
if (FALSE === $this->templateVariableContainer->exists($objectName)) {
return NULL;
}
$object = $this->templateVariableContainer->get($objectName);
try {
ObjectAccess::setProperty($object, $path, $value);
// Note: re-insert the variable to ensure unreferenced values like arrays also get updated
$this->templateVariableContainer->remove($objectName);
$this->templateVariableContainer->add($objectName, $object);
} catch (\Exception $error) {
return NULL;
}
}
return NULL;
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Variable;
/*
* 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\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* ### Variable: TypoScript
*
* Accesses Typoscript paths. Contrary to the Fluid-native
* `f:cObject` this ViewHelper does not render objects but
* rather retrieves the values. For example, if you retrieve
* a TypoScript path to a TMENU object you will receive the
* array of TypoScript defining the menu - not the rendered
* menu HTML.
*
* A great example of how to use this ViewHelper is to very
* quickly migrate a TypoScript-menu-based site (for example
* currently running TemplaVoila + TMENU-objects) to a Fluid
* ViewHelper menu based on `v:page.menu` or `v:page.breadCrumb`
* by accessing key configuration options such as `entryLevel`
* and even various `wrap` definitions.
*
* A quick example of how to parse a `wrap` TypoScript setting
* into two variables usable for a menu item:
*
* <!-- This piece to be added as far up as possible in order to prevent multiple executions -->
* <v:variable.set name="menuSettings" value="{v:variable.typoscript(path: 'lib.menu.main.stdWrap')}" />
* <v:variable.set name="wrap" value="{menuSettings.wrap -> v:iterator.explode(glue: '|')}" />
*
* <!-- This in the loop which renders the menu (see "VHS: manual menu rendering" in FAQ): -->
* {wrap.0}{menuItem.title}{wrap.1}
*
* <!-- An additional example to demonstrate very compact conditions which prevent wraps from being displayed -->
* {wrap.0 -> f:if(condition: settings.wrapBefore)}{menuItem.title}{wrap.1 -> f:if(condition: settings.wrapAfter)}
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Var
*/
class TyposcriptViewHelper extends AbstractViewHelper {
/**
* @var ConfigurationManagerInterface
*/
protected $configurationManager;
/**
* @param ConfigurationManagerInterface $configurationManager
* @return void
*/
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager) {
$this->configurationManager = $configurationManager;
}
/**
* Render
*
* @param string $path
* @return mixed
*/
public function render($path = NULL) {
if (NULL === $path) {
$path = $this->renderChildren();
}
if (TRUE === empty($path)) {
return NULL;
}
$all = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
$segments = explode('.', $path);
$value = $all;
foreach ($segments as $path) {
$value = (TRUE === isset($value[$path . '.']) ? $value[$path . '.'] : $value[$path]);
}
if (TRUE === is_array($value)) {
$value = GeneralUtility::removeDotsFromTS($value);
}
return $value;
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Variable;
/*
* 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;
/**
* ### Variable: Unset
*
* Quite simply, removes a currently available variable
* from the TemplateVariableContainer:
*
* <!-- Data: {person: {name: 'Elvis', nick: 'King'}} -->
* I'm {person.name}. Call me "{person.nick}". A ding-dang doo!
* <v:variable.unset name="person" />
* <f:if condition="{person}">
* <f:else>
* You saw this coming...
* <em>Elvis has left the building</em>
* </f:else>
* </f:if>
*
* At the time of writing this, `v:variable.unset` is not able
* to remove members of for example arrays:
*
* <!-- DOES NOT WORK! -->
* <v:variable.unset name="myObject.propertyName" />
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Var
*/
class UnsetViewHelper extends AbstractViewHelper {
/**
* Unsets variable $name if it exists in the container
*
* @param string $name
* @return void
*/
public function render($name) {
if (TRUE === $this->templateVariableContainer->exists($name)) {
$this->templateVariableContainer->remove($name);
}
}
}