first commit

This commit is contained in:
salam committed 2026-10-19 08:18:39 +02:00
commit 1218dd1517
12716 files changed
+989233

No files matched your search

@@ -0,0 +1,67 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Template\DocumentTemplate;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* The abstract base class for all backend ViewHelpers
* Note: backend ViewHelpers are still experimental!
*/
abstract class AbstractBackendViewHelper extends AbstractViewHelper
{
/**
* Gets instance of template if exists or create a new one.
* Saves instance in viewHelperVariableContainer
*
* @return DocumentTemplate $doc
*/
public function getDocInstance()
{
$viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
if ($viewHelperVariableContainer->exists(self::class, 'DocumentTemplate')) {
$doc = $viewHelperVariableContainer->get(self::class, 'DocumentTemplate');
} else {
/** @var DocumentTemplate $doc */
$doc = GeneralUtility::makeInstance(DocumentTemplate::class);
$viewHelperVariableContainer->add(self::class, 'DocumentTemplate', $doc);
}
return $doc;
}
/**
* Gets instance of PageRenderer if exists or create a new one.
* Saves instance in viewHelperVariableContainer
*
* @return PageRenderer
*/
public function getPageRenderer()
{
$viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
if ($viewHelperVariableContainer->exists(self::class, 'PageRenderer')) {
$pageRenderer = $viewHelperVariableContainer->get(self::class, 'PageRenderer');
} else {
/** @var DocumentTemplate $doc */
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
$viewHelperVariableContainer->add(self::class, 'PageRenderer', $pageRenderer);
}
return $pageRenderer;
}
}
@@ -0,0 +1,115 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Buttons;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
/**
* ViewHelper which returns CSH (context sensitive help) button with icon.
*
* .. note::
* The CSH button will only work, if the current BE user has the "Context
* Sensitive Help mode" set to something else than "Display no help
* information" in the Users settings.
*
* .. note::
* This ViewHelper is experimental!
*
* Examples
* ========
*
* Default::
*
* <f:be.buttons.csh />
*
* CSH button as known from the TYPO3 backend.
*
* Full configuration::
*
* <f:be.buttons.csh table="xMOD_csh_corebe" field="someCshKey" />
*
* CSH button as known from the TYPO3 backend with some custom settings.
*
* Full configuration with content::
*
* <f:be.buttons.csh table="xMOD_csh_corebe" field="someCshKey">
* some text to link
* </f:be.buttons.csh>
*
* A link with text "some text to link" to link the help.
*/
class CshViewHelper extends AbstractBackendViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('table', 'string', 'Table name (\'_MOD_\'+module name). If not set, the current module name will be used');
$this->registerArgument('field', 'string', 'Field name (CSH locallang main key)', false, '');
$this->registerArgument('wrap', 'string', 'Markup to wrap around the CSH, split by "|"', false, '');
}
/**
* Render context sensitive help (CSH) for the given table
*
* @return string the rendered CSH icon
*/
public function render()
{
return static::renderStatic(
$this->arguments,
$this->buildRenderChildrenClosure(),
$this->renderingContext
);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$table = $arguments['table'];
$field = $arguments['field'];
$wrap = $arguments['wrap'];
if ($table === null) {
$currentRequest = $renderingContext->getControllerContext()->getRequest();
$moduleName = $currentRequest->getPluginName();
$table = '_MOD_' . $moduleName;
}
$content = (string)$renderChildrenClosure();
if ($content !== '') {
return BackendUtility::wrapInHelp($table, $field, $content);
}
return '<div class="docheader-csh">' . BackendUtility::cshItem($table, $field, '', $wrap) . '</div>';
}
}
@@ -0,0 +1,113 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Buttons;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Template\DocumentTemplate;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
/**
* ViewHelper which returns shortcut button with icon.
*
* .. note::
* This ViewHelper is experimental!
*
* Examples
* ========
*
* Default::
*
* <f:be.buttons.shortcut />
*
* Shortcut button as known from the TYPO3 backend.
* By default the current page id, module name and all module arguments will be stored.
*
* Explicitly set parameters to be stored in the shortcut::
*
* <f:be.buttons.shortcut getVars="{0: 'route', 1: 'myOwnPrefix'}" setVars="{0: 'function'}" />
*
* Shortcut button as known from the TYPO3 backend.
* This time only the specified GET parameters and SET[]-settings will be stored.
*
* .. note:
*
* Normally you won't need to set getVars & setVars parameters in Extbase modules.
*/
class ShortcutViewHelper extends AbstractBackendViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('getVars', 'array', 'List of GET variables to store. By default the current id, module and all module arguments will be stored', false, []);
$this->registerArgument('setVars', 'array', 'List of SET[] variables to store. See DocumentTemplate::makeShortcutIcon(). Normally won\'t be used by Extbase modules', false, []);
}
/**
* Renders a shortcut button as known from the TYPO3 backend
*
* @return string the rendered shortcut button
* @see \TYPO3\CMS\Backend\Template\DocumentTemplate::makeShortcutIcon()
*/
public function render()
{
return static::renderStatic(
$this->arguments,
$this->buildRenderChildrenClosure(),
$this->renderingContext
);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$getVars = $arguments['getVars'];
$setVars = $arguments['setVars'];
$mayMakeShortcut = $GLOBALS['BE_USER']->mayMakeShortcut();
if ($mayMakeShortcut) {
$doc = GeneralUtility::makeInstance(DocumentTemplate::class);
$currentRequest = $renderingContext->getControllerContext()->getRequest();
$extensionName = $currentRequest->getControllerExtensionName();
$moduleName = $currentRequest->getPluginName();
if (count($getVars) === 0) {
$modulePrefix = strtolower('tx_' . $extensionName . '_' . $moduleName);
$getVars = ['id', 'route', $modulePrefix];
}
$getList = implode(',', $getVars);
$setList = implode(',', $setVars);
return $doc->makeShortcutIcon($getList, $setList, $moduleName);
}
return '';
}
}
@@ -0,0 +1,120 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* ViewHelper which allows you to create extbase based modules in the style of TYPO3 default modules.
*
* Examples
* ========
*
* Simple::
*
* <f:be.container>your module content</f:be.container>
*
* "your module content" wrapped with proper head & body tags.
* Default backend CSS styles and JavaScript will be included.
*
* All options::
*
* <f:be.container pageTitle="foo"
* includeCssFiles="{0: '{f:uri.resource(path:\'Css/Styles.css\')}'}"
* includeJsFiles="{0: '{f:uri.resource(path:\'JavaScript/Library1.js\')}', 1: '{f:uri.resource(path:\'JavaScript/Library2.js\')}'}"
* addJsInlineLabels="{0: 'label1', 1: 'label2'}"
* >
* your module content
* </f:be.container>
*
* "your module content" wrapped with proper head & body tags.
* Custom CSS file :file:`EXT:your_extension/Resources/Public/Css/styles.css` and
* JavaScript files :file:`EXT:your_extension/Resources/Public/JavaScript/Library1.js` and
* :file:`EXT:your_extension/Resources/Public/JavaScript/Library2.js`
* will be loaded, plus some inline labels for usage in JS code.
*/
class ContainerViewHelper extends AbstractBackendViewHelper
{
/**
* @var bool
*/
protected $escapeOutput = false;
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('pageTitle', 'string', 'Title tag of the module. Not required by default, as BE modules are shown in a frame', false, '');
$this->registerArgument('includeCssFiles', 'array', 'List of custom CSS file to be loaded');
$this->registerArgument('includeJsFiles', 'array', 'List of custom JavaScript file to be loaded');
$this->registerArgument('addJsInlineLabels', 'array', 'Custom labels to add to JavaScript inline labels');
$this->registerArgument('includeRequireJsModules', 'array', 'List of RequireJS modules to be loaded');
}
/**
* Render start page with \TYPO3\CMS\Backend\Template\DocumentTemplate and pageTitle
*
* @return string
* @see \TYPO3\CMS\Backend\Template\DocumentTemplate
* @see \TYPO3\CMS\Core\Page\PageRenderer
*/
public function render()
{
$pageTitle = $this->arguments['pageTitle'];
$includeCssFiles = $this->arguments['includeCssFiles'];
$includeJsFiles = $this->arguments['includeJsFiles'];
$addJsInlineLabels = $this->arguments['addJsInlineLabels'];
$includeRequireJsModules = $this->arguments['includeRequireJsModules'];
$pageRenderer = $this->getPageRenderer();
$doc = $this->getDocInstance();
$doc->JScode .= GeneralUtility::wrapJS($doc->redirectUrls());
// Include custom CSS and JS files
if (is_array($includeCssFiles) && count($includeCssFiles) > 0) {
foreach ($includeCssFiles as $addCssFile) {
$pageRenderer->addCssFile($addCssFile);
}
}
if (is_array($includeJsFiles) && count($includeJsFiles) > 0) {
foreach ($includeJsFiles as $addJsFile) {
$pageRenderer->addJsFile($addJsFile);
}
}
if (is_array($includeRequireJsModules) && count($includeRequireJsModules) > 0) {
foreach ($includeRequireJsModules as $addRequireJsFile) {
$pageRenderer->loadRequireJsModule($addRequireJsFile);
}
}
// Add inline language labels
if (is_array($addJsInlineLabels) && count($addJsInlineLabels) > 0) {
$extensionKey = $this->renderingContext->getControllerContext()->getRequest()->getControllerExtensionKey();
foreach ($addJsInlineLabels as $key) {
$label = LocalizationUtility::translate($key, $extensionKey);
$pageRenderer->addInlineLanguageLabel($key, $label);
}
}
// Render the content and return it
$output = $this->renderChildren();
$output = $doc->startPage($pageTitle) . $output;
$output .= $doc->endPage();
return $output;
}
}
@@ -0,0 +1,150 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithContentArgumentAndRenderStatic;
/**
* ViewHelper for rendering a styled content infobox markup.
*
* States
* ======
*
* The Infobox provides different context sensitive states that
* can be used to provide an additional visual feedback to the
* to the user to underline the meaning of the information.
*
* Possible values are in range from ``-2`` to ``2``. Please choose a
* meaningful value from the following list.
*
* ``-2``
* Notices (Default)
* ``-1``
* Information
* ``0``
* Positive feedback
* ``1``
* Warnings
* ``2``
* Error
*
* Examples
* ========
*
* Simple::
*
* <f:be.infobox title="Message title">your box content</f:be.infobox>
*
* All options::
*
* <f:be.infobox title="Message title" message="your box content" state="-2" iconName="check" disableIcon="true" />
*/
class InfoboxViewHelper extends AbstractViewHelper
{
use CompileWithContentArgumentAndRenderStatic;
const STATE_NOTICE = -2;
const STATE_INFO = -1;
const STATE_OK = 0;
const STATE_WARNING = 1;
const STATE_ERROR = 2;
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
$this->registerArgument('message', 'string', 'The message of the info box, if NULL tag content is used');
$this->registerArgument('title', 'string', 'The title of the info box');
$this->registerArgument('state', 'int', 'The state of the box, InfoboxViewHelper::STATE_*', false, self::STATE_NOTICE);
$this->registerArgument('iconName', 'string', 'The icon name from font awesome, NULL sets default icon');
$this->registerArgument('disableIcon', 'bool', 'If set to TRUE, the icon is not rendered.', false, false);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$title = $arguments['title'];
$message = $renderChildrenClosure();
$state = $arguments['state'];
$isInRange = MathUtility::isIntegerInRange($state, -2, 2);
if (!$isInRange) {
$state = -2;
}
$iconName = $arguments['iconName'];
$disableIcon = $arguments['disableIcon'];
$classes = [
self::STATE_NOTICE => 'notice',
self::STATE_INFO => 'info',
self::STATE_OK => 'success',
self::STATE_WARNING => 'warning',
self::STATE_ERROR => 'danger'
];
$icons = [
self::STATE_NOTICE => 'lightbulb-o',
self::STATE_INFO => 'info',
self::STATE_OK => 'check',
self::STATE_WARNING => 'exclamation',
self::STATE_ERROR => 'times'
];
$stateClass = $classes[$state];
$icon = $icons[$state];
if ($iconName !== null) {
$icon = $iconName;
}
$iconTemplate = '';
if (!$disableIcon) {
$iconTemplate = '' .
'<div class="media-left">' .
'<span class="fa-stack fa-lg callout-icon">' .
'<i class="fa fa-circle fa-stack-2x"></i>' .
'<i class="fa fa-' . htmlspecialchars($icon) . ' fa-stack-1x"></i>' .
'</span>' .
'</div>';
}
$titleTemplate = '';
if ($title !== null) {
$titleTemplate = '<h4 class="callout-title">' . htmlspecialchars($title) . '</h4>';
}
return '<div class="callout callout-' . htmlspecialchars($stateClass) . '">' .
'<div class="media">' .
$iconTemplate .
'<div class="media-body">' .
$titleTemplate .
'<div class="callout-body">' . $message . '</div>' .
'</div>' .
'</div>' .
'</div>';
}
}
@@ -0,0 +1,117 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Labels;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
/**
* ViewHelper which returns CSH (context sensitive help) label with icon hover.
*
* .. note::
* The CSH label will only work, if the current BE user has the "Context
* Sensitive Help mode" set to something else than "Display no help
* information" in the Users settings.
*
* .. note::
* This ViewHelper is experimental!
*
* Examples
* ========
*
* Default::
*
* <f:be.labels.csh />
*
* CSH label as known from the TYPO3 backend.
*
* Full configuration::
*
* <f:be.labels.csh table="xMOD_csh_corebe" field="someCshKey" label="lang/Resources/Private/Language/locallang/header.languages" />
*
* CSH label as known from the TYPO3 backend with some custom settings.
*/
class CshViewHelper extends AbstractBackendViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Returns the Language Service
* @return LanguageService
*/
protected static function getLanguageService()
{
return $GLOBALS['LANG'];
}
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('table', 'string', 'Table name (\'_MOD_\'+module name). If not set, the current module name will be used');
$this->registerArgument('field', 'string', 'Field name (CSH locallang main key)', false, '');
$this->registerArgument('label', 'string', 'Language label which is wrapped with the CSH', false, '');
}
/**
* Render context sensitive help (CSH) for the given table
*
* @return string the rendered CSH icon
*/
public function render()
{
return static::renderStatic(
$this->arguments,
$this->buildRenderChildrenClosure(),
$this->renderingContext
);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$table = $arguments['table'];
$field = $arguments['field'];
$label = $arguments['label'];
if ($table === null) {
$currentRequest = $renderingContext->getControllerContext()->getRequest();
$moduleName = $currentRequest->getPluginName();
$table = '_MOD_' . $moduleName;
}
if (strpos($label, 'LLL:') === 0) {
$label = self::getLanguageService()->sL($label);
}
// Double encode can be set to true, once the typo3fluid/fluid fix is released and required
$label = '<label>' . htmlspecialchars($label, ENT_QUOTES, null, false) . '</label>';
return BackendUtility::wrapInHelp($table, $field, $label);
}
}
@@ -0,0 +1,85 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
/**
* A ViewHelper for creating URIs to modules.
*
* Examples
* ========
*
* URI to the web_ts module on page 92::
*
* <f:be.link route="web_ts" parameters="{id: 92}">Go to web_ts</f:be.link>
*
* ``<a href="/typo3/index.php?route=%2module%2web_ts%2&moduleToken=b6e9c9f?id=92">Go to web_ts</a>``
*/
class LinkViewHelper extends AbstractTagBasedViewHelper
{
/**
* @var string
*/
protected $tagName = 'a';
/**
* Arguments initialization
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('route', 'string', 'The name of the route', true);
$this->registerArgument('parameters', 'array', 'An array of parameters', false, []);
$this->registerArgument('referenceType', 'string', 'The type of reference to be generated (one of the constants)', false, UriBuilder::ABSOLUTE_PATH);
$this->registerTagAttribute('name', 'string', 'Specifies the name of an anchor');
$this->registerTagAttribute(
'rel',
'string',
'Specifies the relationship between the current document and the linked document'
);
$this->registerTagAttribute(
'rev',
'string',
'Specifies the relationship between the linked document and the current document'
);
$this->registerTagAttribute('target', 'string', 'Specifies where to open the linked document');
$this->registerUniversalTagAttributes();
}
/**
* @return string Rendered link
*/
public function render()
{
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$route = $this->arguments['route'];
$parameters = $this->arguments['parameters'];
$referenceType = $this->arguments['referenceType'];
$uri = $uriBuilder->buildUriFromRoute($route, $parameters, $referenceType);
$this->tag->addAttribute('href', $uri);
$this->tag->setContent($this->renderChildren());
$this->tag->forceClosingTag(true);
return $this->tag->render();
}
}
@@ -0,0 +1,75 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Menus;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
/**
* ViewHelper which groups options of an option tag.
*
* Example
* =======
*
* ::
*
* <f:be.menus.actionMenu>
* <f:be.menus.actionMenuItem label="Default: Welcome" controller="Default" action="index" />
* <f:be.menus.actionMenuItem label="Community: get in touch" controller="Community" action="index" />
*
* <f:be.menus.actionMenuItemGroup label="Information">
* <f:be.menus.actionMenuItem label="PHP Information" controller="Information" action="listPhpInfo" />
* <f:be.menus.actionMenuItem label="Documentation" controller="Information" action="documentation" />
* <f:be.menus.actionMenuItem label="Hooks" controller="Information" action="hooks" />
* <f:be.menus.actionMenuItem label="Signals" controller="Information" action="signals" />
* <f:be.menus.actionMenuItem label="XClasses" controller="Information" action="xclass" />
* </f:be.menus.actionMenuItemGroup>
* </f:be.menus.actionMenu>
*/
class ActionMenuItemGroupViewHelper extends ActionMenuViewHelper
{
/**
* @var string
*/
protected $tagName = 'optgroup';
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('label', 'string', 'label', false, '');
}
/**
* @return string
*/
public function render()
{
$label = $this->arguments['label'];
$this->tag->addAttribute('label', $label);
$options = '';
foreach ($this->childNodes as $childNode) {
if ($childNode instanceof ViewHelperNode) {
$options .= $childNode->evaluate($this->renderingContext);
}
}
$this->tag->setContent($options);
return $this->tag->render();
}
}
@@ -0,0 +1,116 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Menus;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
/**
* ViewHelper which returns an option tag.
* This ViewHelper only works in conjunction with :php:`\TYPO3\CMS\Fluid\ViewHelpers\Be\Menus\ActionMenuViewHelper`.
*
* .. note::
* This ViewHelper is experimental!
*
* Examples
* ========
*
* Simple::
*
* <f:be.menus.actionMenu>
* <f:be.menus.actionMenuItem label="Overview" controller="Blog" action="index" />
* <f:be.menus.actionMenuItem label="Create new Blog" controller="Blog" action="new" />
* <f:be.menus.actionMenuItem label="List Posts" controller="Post" action="index" arguments="{blog: blog}" />
* </f:be.menus.actionMenu>
*
* Selectbox with the options "Overview", "Create new Blog" and "List Posts".
*
* Localized::
*
* <f:be.menus.actionMenu>
* <f:be.menus.actionMenuItem label="{f:translate(key='overview')}" controller="Blog" action="index" />
* <f:be.menus.actionMenuItem label="{f:translate(key='create_blog')}" controller="Blog" action="new" />
* </f:be.menus.actionMenu>
*
* Localized selectbox.
*/
class ActionMenuItemViewHelper extends AbstractTagBasedViewHelper
{
/**
* @var string
*/
protected $tagName = 'option';
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('label', 'string', 'label of the option tag', true);
$this->registerArgument('controller', 'string', 'controller to be associated with this ActionMenuItem', true);
$this->registerArgument('action', 'string', 'the action to be associated with this ActionMenuItem', true);
$this->registerArgument('arguments', 'array', 'additional controller arguments to be passed to the action when this ActionMenuItem is selected', false, []);
}
/**
* Renders an ActionMenu option tag
*
* @return string the rendered option tag
* @see \TYPO3\CMS\Fluid\ViewHelpers\Be\Menus\ActionMenuViewHelper
*/
public function render()
{
$label = $this->arguments['label'];
$controller = $this->arguments['controller'];
$action = $this->arguments['action'];
$arguments = $this->arguments['arguments'];
$uri = $this->renderingContext->getControllerContext()->getUriBuilder()->reset()->uriFor($action, $arguments, $controller);
$this->tag->addAttribute('value', $uri);
if (!$this->tag->hasAttribute('selected')) {
$this->evaluateSelectItemState($controller, $action, $arguments);
}
$this->tag->setContent(
// Double encode can be set to true, once the typo3fluid/fluid fix is released and required
htmlspecialchars($label, ENT_QUOTES, null, false)
);
return $this->tag->render();
}
protected function evaluateSelectItemState(string $controller, string $action, array $arguments): void
{
$currentRequest = $this->renderingContext->getControllerContext()->getRequest();
$flatRequestArguments = ArrayUtility::flatten(
array_merge([
'controller' => $currentRequest->getControllerName(),
'action' => $currentRequest->getControllerActionName()
], $currentRequest->getArguments())
);
$flatViewHelperArguments = ArrayUtility::flatten(
array_merge(['controller' => $controller, 'action' => $action], $arguments)
);
if (
$this->arguments['selected'] ||
array_diff($flatRequestArguments, $flatViewHelperArguments) === []
) {
$this->tag->addAttribute('selected', 'selected');
}
}
}
@@ -0,0 +1,106 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Menus;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
/**
* ViewHelper which returns a select box, that can be used to switch between
* multiple actions and controllers and looks similar to TYPO3s funcMenu.
*
* .. note::
* This ViewHelper is experimental!
*
* Examples
* ========
*
* Simple::
*
* <f:be.menus.actionMenu>
* <f:be.menus.actionMenuItem label="Overview" controller="Blog" action="index" />
* <f:be.menus.actionMenuItem label="Create new Blog" controller="Blog" action="new" />
* <f:be.menus.actionMenuItem label="List Posts" controller="Post" action="index" arguments="{blog: blog}" />
* </f:be.menus.actionMenu>
*
* Selectbox with the options "Overview", "Create new Blog" and "List Posts".
*
* Localized::
*
* <f:be.menus.actionMenu>
* <f:be.menus.actionMenuItem label="{f:translate(key:'overview')}" controller="Blog" action="index" />
* <f:be.menus.actionMenuItem label="{f:translate(key:'create_blog')}" controller="Blog" action="new" />
* </f:be.menus.actionMenu>
*
* Localized selectbox.
*/
class ActionMenuViewHelper extends AbstractTagBasedViewHelper
{
/**
* @var string
*/
protected $tagName = 'select';
/**
* An array of \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
*
* @var array
*/
protected $childNodes = [];
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('defaultController', 'string', 'defaultController');
}
/**
* Render FunctionMenu
*
* @return string
*/
public function render()
{
$this->tag->addAttribute('onchange', 'jumpToUrl(this.options[this.selectedIndex].value, this);');
$options = '';
foreach ($this->childNodes as $childNode) {
if ($childNode instanceof ViewHelperNode) {
$options .= $childNode->evaluate($this->renderingContext);
}
}
$this->tag->setContent($options);
return '<div class="docheader-funcmenu">' . $this->tag->render() . '</div>';
}
/**
* @param string $argumentsName
* @param string $closureName
* @param string $initializationPhpCode
* @param ViewHelperNode $node
* @param TemplateCompiler $compiler
*/
public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
{
// @TODO: replace with a true compiling method to make compilable!
$compiler->disable();
return null;
}
}
@@ -0,0 +1,97 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
/**
* ViewHelper which return page info icon as known from TYPO3 backend modules.
*
* .. note::
* This ViewHelper is experimental!
*
* Examples
* ========
*
* Default::
*
* <f:be.pageInfo />
*
* Page info icon with context menu
*/
class PageInfoViewHelper extends AbstractBackendViewHelper
{
/**
* This ViewHelper renders HTML, thus output must not be escaped
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Render javascript in header
*
* @return string the rendered page info icon
* @see \TYPO3\CMS\Backend\Template\DocumentTemplate::getPageInfo() Note: can't call this method as it's protected!
*/
public function render()
{
return static::renderStatic(
[],
$this->buildRenderChildrenClosure(),
$this->renderingContext
);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$id = GeneralUtility::_GP('id');
$pageRecord = BackendUtility::readPageAccess($id, $GLOBALS['BE_USER']->getPagePermsClause(Permission::PAGE_SHOW));
// Add icon with context menu, etc:
/** @var IconFactory $iconFactory */
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
if ($pageRecord['uid']) {
// If there IS a real page
$altText = BackendUtility::getRecordIconAltText($pageRecord, 'pages');
$theIcon = '<span title="' . $altText . '">' . $iconFactory->getIconForRecord('pages', $pageRecord, Icon::SIZE_SMALL)->render() . '</span>';
// Make Icon:
$theIcon = BackendUtility::wrapClickMenuOnIcon($theIcon, 'pages', $pageRecord['uid']);
// Setting icon with context menu + uid
$theIcon .= ' <em>[PID: ' . $pageRecord['uid'] . ']</em>';
} else {
// On root-level of page tree
// Make Icon
$theIcon = '<span title="' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . '">' . $iconFactory->getIcon('apps-pagetree-page-domain', Icon::SIZE_SMALL)->render() . '</span>';
if ($GLOBALS['BE_USER']->isAdmin()) {
$theIcon = BackendUtility::wrapClickMenuOnIcon($theIcon, 'pages');
}
}
return $theIcon;
}
}
@@ -0,0 +1,92 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
/**
* ViewHelper which returns the current page path as known from TYPO3 backend modules.
*
* .. note::
* This ViewHelper is experimental!
*
* Examples
* ========
*
* Default::
*
* <f:be.pagePath />
*
* Current page path, prefixed with "Path:" and wrapped in a span with the class ``typo3-docheader-pagePath``.
*/
class PagePathViewHelper extends AbstractBackendViewHelper
{
/**
* This ViewHelper renders HTML, thus output must not be escaped
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Renders the current page path
*
* @return string the rendered page path
* @see \TYPO3\CMS\Backend\Template\DocumentTemplate::getPagePath() Note: can't call this method as it's protected!
*/
public function render()
{
return static::renderStatic(
[],
$this->buildRenderChildrenClosure(),
$this->renderingContext
);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$id = GeneralUtility::_GP('id');
$pageRecord = BackendUtility::readPageAccess($id, $GLOBALS['BE_USER']->getPagePermsClause(Permission::PAGE_SHOW));
// Is this a real page
if ($pageRecord['uid']) {
$title = $pageRecord['_thePathFull'];
} else {
$title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
}
// Setting the path of the page
$pagePath = htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.path')) . ': <span class="typo3-docheader-pagePath">';
// crop the title to title limit (or 50, if not defined)
$cropLength = empty($GLOBALS['BE_USER']->uc['titleLen']) ? 50 : $GLOBALS['BE_USER']->uc['titleLen'];
$croppedTitle = GeneralUtility::fixed_lgd_cs($title, -$cropLength);
if ($croppedTitle !== $title) {
$pagePath .= '<abbr title="' . htmlspecialchars($title) . '">' . htmlspecialchars($croppedTitle) . '</abbr>';
} else {
$pagePath .= htmlspecialchars($title);
}
$pagePath .= '</span>';
return $pagePath;
}
}
@@ -0,0 +1,118 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
/**
* ViewHelper which allows you to create extbase based modules in the style of TYPO3 default modules.
*
* Examples
* ========
*
* All options::
*
* <f:be.pageRenderer pageTitle="foo"
* includeCssFiles="{0: '{f:uri.resource(path:\'Css/Styles.css\')}'}"
* includeJsFiles="{0: '{f:uri.resource(path:\'JavaScript/Library1.js\')}', 1: '{f:uri.resource(path:\'JavaScript/Library2.js\')}'}"
* addJsInlineLabels="{0: 'label1', 1: 'label2'}" />
*
* Custom CSS file :file:`EXT:your_extension/Resources/Public/Css/styles.css` and
* JavaScript files :file:`EXT:your_extension/Resources/Public/JavaScript/Library1.js` and
* :file:`EXT:your_extension/Resources/Public/JavaScript/Library2.js`
* will be loaded, plus some inline labels for usage in JS code.
*/
class PageRendererViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
$this->registerArgument('pageTitle', 'string', 'title tag of the module. Not required by default, as BE modules are shown in a frame', false, '');
$this->registerArgument('includeCssFiles', 'array', 'List of custom CSS file to be loaded');
$this->registerArgument('includeJsFiles', 'array', 'List of custom JavaScript file to be loaded');
$this->registerArgument('addJsInlineLabels', 'array', 'Custom labels to add to JavaScript inline labels');
$this->registerArgument('includeRequireJsModules', 'array', 'List of RequireJS modules to be loaded');
$this->registerArgument('addInlineSettings', 'array', 'Adds Javascript Inline Setting');
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$pageRenderer = static::getPageRenderer();
$pageTitle = $arguments['pageTitle'];
$includeCssFiles = $arguments['includeCssFiles'];
$includeJsFiles = $arguments['includeJsFiles'];
$addJsInlineLabels = $arguments['addJsInlineLabels'];
$includeRequireJsModules = $arguments['includeRequireJsModules'];
$addInlineSettings = $arguments['addInlineSettings'];
if ($pageTitle) {
$pageRenderer->setTitle($pageTitle);
}
// Include custom CSS and JS files
if (is_array($includeCssFiles) && count($includeCssFiles) > 0) {
foreach ($includeCssFiles as $addCssFile) {
$pageRenderer->addCssFile($addCssFile);
}
}
if (is_array($includeJsFiles) && count($includeJsFiles) > 0) {
foreach ($includeJsFiles as $addJsFile) {
$pageRenderer->addJsFile($addJsFile);
}
}
if (is_array($includeRequireJsModules) && count($includeRequireJsModules) > 0) {
foreach ($includeRequireJsModules as $addRequireJsFile) {
$pageRenderer->loadRequireJsModule($addRequireJsFile);
}
}
if (is_array($addInlineSettings) && count($addInlineSettings) > 0) {
$pageRenderer->addInlineSettingArray(null, $addInlineSettings);
}
// Add inline language labels
if (is_array($addJsInlineLabels) && count($addJsInlineLabels) > 0) {
$extensionKey = $renderingContext->getControllerContext()->getRequest()->getControllerExtensionKey();
foreach ($addJsInlineLabels as $key) {
$label = LocalizationUtility::translate($key, $extensionKey);
$pageRenderer->addInlineLanguageLabel($key, $label);
}
}
}
/**
* @return PageRenderer
*/
protected static function getPageRenderer()
{
return GeneralUtility::makeInstance(PageRenderer::class);
}
}
@@ -0,0 +1,61 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Security;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
/**
* This ViewHelper implements an ifAuthenticated/else condition for backend
* users and backend groups.
*
* Examples
* ========
*
* Basic usage::
*
* <f:be.security.ifAuthenticated>
* This is being shown whenever a BE user is logged in
* </f:be.security.ifAuthenticated>
*
* Everything inside the :html:`<f:be.ifAuthenticated>` tag is being displayed
* if the user is authenticated with any backend user account.
*
* IfAuthenticated / then / else::
*
* <f:be.security.ifAuthenticated>
* <f:then>
* This is being shown in case you have access.
* </f:then>
* <f:else>
* This is being displayed in case you do not have access.
* </f:else>
* </f:be.security.ifAuthenticated>
*
* Everything inside the :html:`<f:then></f:then>` is displayed the backend user is logged in.
* :html:`<f:else></f:else>` is displayed if no backend user is logged in.
*/
class IfAuthenticatedViewHelper extends AbstractConditionViewHelper
{
/**
* This method decides if the condition is TRUE or FALSE. It can be overridden in extending viewhelpers to adjust functionality.
*
* @param array $arguments ViewHelper arguments to evaluate the condition for this ViewHelper, allows for flexiblity in overriding this method.
* @return bool
*/
protected static function evaluateCondition($arguments = null)
{
return isset($GLOBALS['BE_USER']) && $GLOBALS['BE_USER']->user['uid'] > 0;
}
}
@@ -0,0 +1,103 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Security;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
/**
* This ViewHelper implements an ifHasRole/else condition for backend users
* and backend groups.
*
* Role refers to backend user groups. The :html:`role` attribute can either be
* the title of a group, or the uid.
*
* Examples
* ========
*
* Basic usage::
*
* <f:be.security.ifHasRole role="Administrator">
* This is being shown in case the current BE user belongs to a BE usergroup (aka role) titled "Administrator" (case sensitive)
* </f:be.security.ifHasRole>
*
* Everything inside the :html:`<f:ifHasRole>` tag is being displayed if the
* logged in backend user belongs to the specified backend group.
*
* Using the usergroup uid as role identifier::
*
* <f:be.security.ifHasRole role="1">
* This is being shown in case the current BE user belongs to a BE usergroup (aka role) with the uid "1"
* </f:be.security.ifHasRole>
*
* Everything inside the :html:`<f:ifHasRole>` tag is being displayed if the
* logged in backend user belongs to the specified backend group.
*
* IfRole / then / else::
*
* <f:be.security.ifHasRole role="Administrator">
* <f:then>
* This is being shown in case you have the role.
* </f:then>
* <f:else>
* This is being displayed in case you do not have the role.
* </f:else>
* </f:be.security.ifHasRole>
*
* Everything inside the :html:`<f:then></f:then>` tag is displayed if the
* logged in backend user belongs to the specified backend group.
* Otherwise, everything inside the :html:`<f:else></f:else>` tag is displayed.
*/
class IfHasRoleViewHelper extends AbstractConditionViewHelper
{
/**
* Initializes the "role" argument.
* Renders <f:then> child if the current logged in BE user belongs to the specified role (aka usergroup)
* otherwise renders <f:else> child.
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('role', 'string', 'The usergroup (either the usergroup uid or its title).');
}
/**
* This method decides if the condition is TRUE or FALSE. It can be overridden in extending viewhelpers to adjust functionality.
*
* @param array $arguments ViewHelper arguments to evaluate the condition for this ViewHelper, allows for flexiblity in overriding this method.
* @return bool
*/
protected static function evaluateCondition($arguments = null)
{
$role = $arguments['role'];
if (!is_array($GLOBALS['BE_USER']->userGroups)) {
return false;
}
if (is_numeric($role)) {
foreach ($GLOBALS['BE_USER']->userGroups as $userGroup) {
if ((int)$userGroup['uid'] === (int)$role) {
return true;
}
}
} else {
foreach ($GLOBALS['BE_USER']->userGroups as $userGroup) {
if ($userGroup['title'] === $role) {
return true;
}
}
}
return false;
}
}
@@ -0,0 +1,155 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* ViewHelper which renders a record list as known from the TYPO3 list module.
*
* .. note::
* This feature is experimental!
*
* Examples
* ========
*
* Minimal::
*
* <f:be.tableList tableName="fe_users" />
*
* List of all "Website user" records stored in the configured storage PID.
* Records will be editable, if the current backend user has got edit rights for the table ``fe_users``.
*
* Only the title column (username) will be shown.
*
* Context menu is active.
*
* Full::
*
* <f:be.tableList tableName="fe_users" fieldList="{0: 'name', 1: 'email'}"
* storagePid="1"
* levels="2"
* filter="foo"
* recordsPerPage="10"
* sortField="name"
* sortDescending="true"
* readOnly="true"
* enableClickMenu="false"
* clickTitleMode="info"
* />
*
* List of "Website user" records with a text property of ``foo`` stored on PID ``1`` and two levels down.
* Clicking on a username will open the TYPO3 info popup for the respective record
*/
class TableListViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
*/
protected $configurationManager;
/**
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
*/
public function injectConfigurationManager(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager)
{
$this->configurationManager = $configurationManager;
}
/**
* Initialize arguments.
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('tableName', 'string', 'name of the database table', true);
$this->registerArgument('fieldList', 'array', 'list of fields to be displayed. If empty, only the title column (configured in $TCA[$tableName][\'ctrl\'][\'title\']) is shown', false, []);
$this->registerArgument('storagePid', 'int', 'by default, records are fetched from the storage PID configured in persistence.storagePid. With this argument, the storage PID can be overwritten');
$this->registerArgument('levels', 'int', 'corresponds to the level selector of the TYPO3 list module. By default only records from the current storagePid are fetched', false, 0);
$this->registerArgument('filter', 'string', 'corresponds to the "Search String" textbox of the TYPO3 list module. If not empty, only records matching the string will be fetched', false, '');
$this->registerArgument('recordsPerPage', 'int', 'amount of records to be displayed at once. Defaults to $TCA[$tableName][\'interface\'][\'maxSingleDBListItems\'] or (if that\'s not set) to 100', false, 0);
$this->registerArgument('sortField', 'string', 'table field to sort the results by', false, '');
$this->registerArgument('sortDescending', 'bool', 'if TRUE records will be sorted in descending order', false, false);
$this->registerArgument('readOnly', 'bool', 'if TRUE, the edit icons won\'t be shown. Otherwise edit icons will be shown, if the current BE user has edit rights for the specified table!', false, false);
$this->registerArgument('enableClickMenu', 'bool', 'enables context menu', false, true);
$this->registerArgument('clickTitleMode', 'string', 'one of "edit", "show" (only pages, tt_content), "info');
}
/**
* Renders a record list as known from the TYPO3 list module
* Note: This feature is experimental!
*
* @return string the rendered record list
* @see \TYPO3\CMS\Recordlist\RecordList\DatabaseRecordList
*/
public function render()
{
$tableName = $this->arguments['tableName'];
$fieldList = $this->arguments['fieldList'];
$storagePid = $this->arguments['storagePid'];
$levels = $this->arguments['levels'];
$filter = $this->arguments['filter'];
$recordsPerPage = $this->arguments['recordsPerPage'];
$sortField = $this->arguments['sortField'];
$sortDescending = $this->arguments['sortDescending'];
$readOnly = $this->arguments['readOnly'];
$enableClickMenu = $this->arguments['enableClickMenu'];
$clickTitleMode = $this->arguments['clickTitleMode'];
$this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Recordlist/Recordlist');
$pageinfo = BackendUtility::readPageAccess(GeneralUtility::_GP('id'), $GLOBALS['BE_USER']->getPagePermsClause(Permission::PAGE_SHOW));
/** @var \TYPO3\CMS\Recordlist\RecordList\DatabaseRecordList $dblist */
$dblist = GeneralUtility::makeInstance(\TYPO3\CMS\Recordlist\RecordList\DatabaseRecordList::class);
$dblist->pageRow = $pageinfo;
if ($readOnly === false) {
$dblist->calcPerms = $GLOBALS['BE_USER']->calcPerms($pageinfo);
}
$dblist->showClipboard = false;
$dblist->disableSingleTableView = true;
$dblist->clickTitleMode = $clickTitleMode;
$dblist->clickMenuEnabled = $enableClickMenu;
if ($storagePid === null) {
$frameworkConfiguration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
$storagePid = $frameworkConfiguration['persistence']['storagePid'];
}
$dblist->start($storagePid, $tableName, (int)GeneralUtility::_GP('pointer'), $filter, $levels, $recordsPerPage);
$dblist->allFields = true;
$dblist->dontShowClipControlPanels = true;
$dblist->displayFields = false;
$dblist->setFields = [$tableName => $fieldList];
$dblist->noControlPanels = true;
$dblist->sortField = $sortField;
$dblist->sortRev = $sortDescending;
$dblist->script = $_SERVER['REQUEST_URI'];
$dblist->generateList();
$js = 'var T3_THIS_LOCATION = ' . GeneralUtility::quoteJSvalue(rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI')));
$html = GeneralUtility::wrapJS($js) . $dblist->HTMLcode;
return $html;
}
}
@@ -0,0 +1,74 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* A ViewHelper for creating URIs to modules.
*
* Examples
* ========
*
* URI to the web_ts module on page 92::
*
* <f:be.uri route="web_ts" parameters="{id: 92}"/>
*
* ``/typo3/index.php?M=web_ts&moduleToken=b6e9c9f?id=92``
*
* Inline notation::
*
* {f:be.uri(route: 'web_ts', parameters: '{id: 92}')}
*
* ``/typo3/index.php?route=%2module%2web_ts%2&moduleToken=b6e9c9f?id=92``
*/
class UriViewHelper extends AbstractBackendViewHelper
{
/**
* Arguments initialization
*
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('route', 'string', 'The name of the route', true);
$this->registerArgument('parameters', 'array', 'An array of parameters', false, []);
$this->registerArgument(
'referenceType',
'string',
'The type of reference to be generated (one of the constants)',
false,
UriBuilder::ABSOLUTE_PATH
);
}
/**
* @return string Rendered link
*/
public function render()
{
/** @var UriBuilder $uriBuilder */
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$route = $this->arguments['route'];
$parameters = $this->arguments['parameters'];
$referenceType = $this->arguments['referenceType'];
$uri = $uriBuilder->buildUriFromRoute($route, $parameters, $referenceType);
return (string)$uri;
}
}
@@ -0,0 +1,127 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Widget\Controller;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
/**
* Class PaginateController
*/
class PaginateController extends \TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController
{
/**
* @var array
*/
protected $configuration = ['itemsPerPage' => 10, 'insertAbove' => false, 'insertBelow' => true, 'recordsLabel' => ''];
/**
* @var \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
*/
protected $objects;
/**
* @var int
*/
protected $currentPage = 1;
/**
* @var int
*/
protected $numberOfPages = 1;
/**
* @var int
*/
protected $offset = 0;
/**
* @var int
*/
protected $itemsPerPage = 0;
/**
* @var int
*/
protected $numberOfObjects = 0;
/**
* Initializes necessary variables for all actions.
*/
public function initializeAction()
{
$this->objects = $this->widgetConfiguration['objects'];
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($this->configuration, $this->widgetConfiguration['configuration'], false);
$this->numberOfObjects = count($this->objects);
$itemsPerPage = (int)$this->configuration['itemsPerPage'];
$this->numberOfPages = $itemsPerPage > 0 ? ceil($this->numberOfObjects / $itemsPerPage) : 0;
}
/**
* @param int $currentPage
*/
public function indexAction($currentPage = 1)
{
// set current page
$this->currentPage = (int)$currentPage;
if ($this->currentPage < 1) {
$this->currentPage = 1;
}
if ($this->currentPage > $this->numberOfPages) {
// set $modifiedObjects to NULL if the page does not exist
$modifiedObjects = null;
} else {
// modify query
$this->itemsPerPage = (int)$this->configuration['itemsPerPage'];
$query = $this->objects->getQuery();
$query->setLimit($this->itemsPerPage);
$this->offset = $this->itemsPerPage * ($this->currentPage - 1);
if ($this->currentPage > 1) {
$query->setOffset($this->offset);
}
$modifiedObjects = $query->execute();
}
$this->view->assign('contentArguments', [
$this->widgetConfiguration['as'] => $modifiedObjects
]);
$this->view->assign('configuration', $this->configuration);
$this->view->assign('pagination', $this->buildPagination());
}
/**
* Returns an array with the keys "current", "numberOfPages", "nextPage", "previousPage", "startRecord", "endRecord"
*
* @return array
*/
protected function buildPagination()
{
$endRecord = $this->offset + $this->itemsPerPage;
if ($endRecord > $this->numberOfObjects) {
$endRecord = $this->numberOfObjects;
}
$pagination = [
'current' => $this->currentPage,
'numberOfPages' => $this->numberOfPages,
'hasLessPages' => $this->currentPage > 1,
'hasMorePages' => $this->currentPage < $this->numberOfPages,
'startRecord' => $this->offset + 1,
'endRecord' => $endRecord
];
if ($this->currentPage < $this->numberOfPages) {
$pagination['nextPage'] = $this->currentPage + 1;
}
if ($this->currentPage > 1) {
$pagination['previousPage'] = $this->currentPage - 1;
}
return $pagination;
}
}
@@ -0,0 +1,83 @@
<?php
namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Widget;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
/**
* This ViewHelper renders a Pagination of objects for the TYPO3 Backend.
*
* Examples
* ========
*
* Minimum call with required arguments only::
*
* <f:be.widget.paginate objects="{blogs}" as="paginatedBlogs">
* use {paginatedBlogs} as you used {blogs} before, most certainly inside
* a <f:for> loop.
* </f:be.widget.paginate>
*
* Full example with all configuration options::
*
* <f:be.widget.paginate objects="{blogs}" as="paginatedBlogs" configuration="{itemsPerPage: 5, insertAbove: 1, insertBelow: 0, recordsLabel: 'MyRecords'}">
* use {paginatedBlogs} as you used {blogs} before, most certainly inside
* a <f:for> loop.
* </f:be.widget.paginate>
*
* The ``recordsLabel`` option can be used to replace the text in "Records 1 - 99" with a custom label.
*
* Performance characteristics
* ===========================
*
* In the above examples, it looks like ``{blogs}`` contains all Blog objects, thus
* you might wonder if all objects were fetched from the database.
* However, the blogs are NOT fetched from the database until you actually use them,
* so the paginate ViewHelper will adjust the query sent to the database and receive
* only the small subset of objects.
* So, there is no negative performance overhead in using the Be Paginate Widget.
*/
class PaginateViewHelper extends \TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetViewHelper
{
/**
* @var \TYPO3\CMS\Fluid\ViewHelpers\Be\Widget\Controller\PaginateController
*/
protected $controller;
/**
* @param \TYPO3\CMS\Fluid\ViewHelpers\Be\Widget\Controller\PaginateController $controller
*/
public function injectPaginateController(\TYPO3\CMS\Fluid\ViewHelpers\Be\Widget\Controller\PaginateController $controller)
{
$this->controller = $controller;
}
/**
* Initialize arguments.
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('objects', QueryResultInterface::class, 'The QueryResult containing all objects.', true);
$this->registerArgument('as', 'string', 'as', true);
$this->registerArgument('configuration', 'array', 'configuration', false, ['itemsPerPage' => 10, 'insertAbove' => false, 'insertBelow' => true, 'maximumNumberOfLinks' => 99]);
}
/**
* @return string
*/
public function render()
{
return $this->initiateSubRequest();
}
}