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,168 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers;
/*
* 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\Exception\PropertyNotAccessibleException;
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
use TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode;
use TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface;
/**
* ### ViewHelper Debug ViewHelper (sic)
*
* Debugs instances of other ViewHelpers and language
* structures. Use in conjunction with other ViewHelpers
* to inspect their current and possible arguments and
* render their documentation:
*
* <v:debug><f:format.html>{variable}</f:format.html></v:debug>
*
* Or the same expression in inline syntax:
*
* {variable -> f:format.html() -> v:debug()}
*
* Can also be used to inspect `ObjectAccessor` instances
* (e.g. variables you try to access) and rather than just
* dumping the entire contents of the variable as is done
* by `<f:debug />`, this ViewHelper makes a very simple
* dump with a warning if the variable is not defined. If
* an object is encountered (for example a domain object)
* this ViewHelper will not dump the object but instead
* will scan it for accessible properties (e.g. properties
* which have a getter method!) and only present those
* properties which can be accessed, along with the type
* of variable that property currently contains:
*
* {domainObject -> v:debug()}
*
* Assuming that `{domainObject}` is an instance of an
* object which has two methods: `getUid()` and `getTitle()`,
* debugging that instance will render something like this
* in plain text:
*
* Path: {domainObject}
* Value type: object
* Accessible properties on {domainObject}:
* {form.uid} (integer)
* {form.title} (string)
*
* The class itself can contain any number of protected
* properties, but only those which have a getter method
* can be accessed by Fluid and as therefore we only dump
* those properties which you **can in fact access**.
*
* @package Vhs
* @subpackage ViewHelpers
*/
class DebugViewHelper extends AbstractViewHelper implements ChildNodeAccessInterface {
/**
* @var ViewHelperNode[]
*/
protected $childViewHelperNodes = array();
/**
* @var ObjectAccessorNode[]
*/
protected $childObjectAccessorNodes = array();
/**
* With this flag, you can disable the escaping interceptor inside this ViewHelper.
* THIS MIGHT CHANGE WITHOUT NOTICE, NO PUBLIC API!
* @var boolean
*/
protected $escapingInterceptorEnabled = FALSE;
/**
* @return string
*/
public function render() {
$nodes = array();
foreach ($this->childViewHelperNodes as $viewHelperNode) {
$viewHelper = $viewHelperNode->getUninitializedViewHelper();
$arguments = $viewHelper->prepareArguments();
$givenArguments = $viewHelperNode->getArguments();
$viewHelperReflection = new \ReflectionClass($viewHelper);
$viewHelperDescription = $viewHelperReflection->getDocComment();
$viewHelperDescription = htmlentities($viewHelperDescription);
$viewHelperDescription = '[CLASS DOC]' . LF . $viewHelperDescription . LF;
$renderMethodDescription = $viewHelperReflection->getMethod('render')->getDocComment();
$renderMethodDescription = htmlentities($renderMethodDescription);
$renderMethodDescription = implode(LF, array_map('trim', explode(LF, $renderMethodDescription)));
$renderMethodDescription = '[RENDER METHOD DOC]' . LF . $renderMethodDescription . LF;
$argumentDefinitions = array();
foreach ($arguments as $argument) {
$name = $argument->getName();
$argumentDefinitions[$name] = ObjectAccess::getGettableProperties($argument);
}
$sections = array(
$viewHelperDescription,
DebuggerUtility::var_dump($argumentDefinitions, '[ARGUMENTS]', 4, TRUE, FALSE, TRUE),
DebuggerUtility::var_dump($givenArguments, '[CURRENT ARGUMENTS]', 4, TRUE, FALSE, TRUE),
$renderMethodDescription
);
array_push($nodes, implode(LF, $sections));
}
if (0 < count($this->childObjectAccessorNodes)) {
array_push($nodes, '[VARIABLE ACCESSORS]');
$templateVariables = $this->templateVariableContainer->getAll();
foreach ($this->childObjectAccessorNodes as $objectAccessorNode) {
$path = $objectAccessorNode->getObjectPath();
$segments = explode('.', $path);
try {
$value = ObjectAccess::getProperty($templateVariables, array_shift($segments));
foreach ($segments as $segment) {
$value = ObjectAccess::getProperty($value, $segment);
}
$type = gettype($value);
} catch (PropertyNotAccessibleException $error) {
$value = NULL;
$type = 'UNDEFINED/INACCESSIBLE';
}
$sections = array(
'Path: {' . $path . '}',
'Value type: ' . $type,
);
if (TRUE === is_object($value)) {
$sections[] = 'Accessible properties on {' . $path . '}:';
$gettable = ObjectAccess::getGettablePropertyNames($value);
unset($gettable[0]);
foreach ($gettable as $gettableProperty) {
$sections[] = ' {' . $path . '.' . $gettableProperty . '} (' . gettype(ObjectAccess::getProperty($value, $gettableProperty)) . ')';
}
} elseif (NULL !== $value) {
$sections[] = DebuggerUtility::var_dump($value, 'Dump of variable "' . $path . '"', 4, TRUE, FALSE, TRUE);
}
array_push($nodes, implode(LF, $sections));
}
}
return '<pre>' . implode(LF . LF, $nodes) . '</pre>';
}
/**
* Sets the direct child nodes of the current syntax tree node.
*
* @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode[] $childNodes
* @return void
*/
public function setChildNodes(array $childNodes) {
foreach ($childNodes as $childNode) {
if (TRUE === $childNode instanceof ViewHelperNode) {
array_push($this->childViewHelperNodes, $childNode);
}
if (TRUE === $childNode instanceof ObjectAccessorNode) {
array_push($this->childObjectAccessorNodes, $childNode);
}
}
}
}