TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Backend\Backend\Avatar\Avatar;
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to render the avatar markup (including the `<img>` tag) for a given backend user.
|
||||
* If the given backend user hasn't added a custom avatar yet, a default one is used.
|
||||
*
|
||||
* ```
|
||||
* <be:avatar backendUser="{user.uid}" size="32" showIcon="true" />
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-avatar
|
||||
*/
|
||||
final class AvatarViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* As this ViewHelper renders HTML, the output must not be escaped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function __construct(
|
||||
private readonly ConnectionPool $connectionPool,
|
||||
private readonly Avatar $avatar
|
||||
) {}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('backendUser', 'int', 'uid of the backend user', false, 0);
|
||||
$this->registerArgument('size', 'int', 'width and height of the image', false, 32);
|
||||
$this->registerArgument('showIcon', 'bool', 'show the record icon as well', false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve user avatar from a given backend user id.
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
if ($this->arguments['backendUser'] > 0) {
|
||||
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('be_users');
|
||||
$queryBuilder->getRestrictions()->removeAll();
|
||||
$backendUser = $queryBuilder
|
||||
->select('*')
|
||||
->from('be_users')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($this->arguments['backendUser'], Connection::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->executeQuery()
|
||||
->fetchAssociative();
|
||||
} else {
|
||||
$backendUser = $GLOBALS['BE_USER']->user;
|
||||
}
|
||||
if ($backendUser === false) {
|
||||
// no BE user can be retrieved from DB, probably deleted
|
||||
return '';
|
||||
}
|
||||
return $this->avatar->render($backendUser, $this->arguments['size'], $this->arguments['showIcon']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumn;
|
||||
use TYPO3\CMS\Backend\View\BackendLayout\Grid\LanguageColumn;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to render a language column in a backend table module.
|
||||
*
|
||||
* ```
|
||||
* <be:languageColumn languageColumn="{someColumn}" columnNumber="{colPos}" />
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-languagecolumn
|
||||
* @internal Not part of the TYPO3 API
|
||||
*/
|
||||
final class LanguageColumnViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('languageColumn', LanguageColumn::class, 'Language column object which is context for column', true);
|
||||
$this->registerArgument('columnNumber', 'int', 'Number (colPos) of column within LanguageColumn to be returned', true);
|
||||
}
|
||||
|
||||
public function render(): GridColumn
|
||||
{
|
||||
return $this->arguments['languageColumn']->getGrid()->getColumns()[$this->arguments['columnNumber']];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Link;
|
||||
|
||||
use TYPO3\CMS\Core\Information\Typo3Information;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
|
||||
/**
|
||||
* Use this ViewHelper to provide a link to the official documentation. The ViewHelper will
|
||||
* use the permalink identifier to generate a permalink to the documentation which is
|
||||
* a redirect to the actual URI.
|
||||
*
|
||||
* The identifier must be given as a string. Be aware that very specific short links into
|
||||
* the documentation may change over time.
|
||||
*
|
||||
* The link will always lead to the documentation of the corresponding TYPO3 version. This
|
||||
* means in a v12 installation, using `foo-bar` as identifier will link to 'foo-bar@12.4',
|
||||
* while in v13 the link will be 'foo-bar@13.4'.
|
||||
*
|
||||
* Example
|
||||
* =======
|
||||
*
|
||||
* Link to the documentation::
|
||||
*
|
||||
* <be:link.documentation identifier="foo-bar">See documentation</be:link.documentation>
|
||||
*
|
||||
* Output::
|
||||
*
|
||||
* <a href="https://docs.typo3.org/permalink/foo-bar@13.4" target="_blank" rel="noreferrer">
|
||||
* See documentation
|
||||
* </a>
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-link-documentation
|
||||
* @internal not part of TYPO3 Core API.
|
||||
*/
|
||||
final class DocumentationViewHelper extends AbstractTagBasedViewHelper
|
||||
{
|
||||
protected $tagName = 'a';
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('identifier', 'string', 'the documentation permalink identifier as displayed in the modal link popup of any rendered documentation manual', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
// Note: This ViewHelper cannot use DI, because it is used in the Install-Tool context where constructor-based DI does not work.
|
||||
// Typo3Information is a simple DO so we do not need to utilize makeInstance() here.
|
||||
$this->tag->addAttribute('href', Typo3Information::getDocsLink($this->arguments['identifier']));
|
||||
$this->tag->addAttribute('target', '_blank');
|
||||
$this->tag->addAttribute('rel', 'noreferrer');
|
||||
$this->tag->setContent($this->renderChildren());
|
||||
$this->tag->forceClosingTag(true);
|
||||
return $this->tag->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Link;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentValueException;
|
||||
|
||||
/**
|
||||
* Use this ViewHelper to provide edit links to records. The ViewHelper will
|
||||
* pass the uid and table to FormEngine.
|
||||
*
|
||||
* The uid must be given as a positive integer.
|
||||
* For new records, use the :ref:`<be:link.newRecordViewHelper> <typo3-backend-link-newrecord>`.
|
||||
*
|
||||
* Examples
|
||||
* ========
|
||||
*
|
||||
* Link to the record-edit action passed to FormEngine::
|
||||
*
|
||||
* <be:link.editRecord uid="42" table="a_table" returnUrl="foo/bar" />
|
||||
*
|
||||
* Output::
|
||||
*
|
||||
* <a href="/typo3/record/edit?edit[a_table][42]=edit&returnUrl=foo/bar">
|
||||
* Edit record
|
||||
* </a>
|
||||
*
|
||||
* Link to edit page uid=3 and then return back to the BE module "web_MyextensionList"::
|
||||
*
|
||||
* <be:link.editRecord uid="3" table="pages" returnUrl="{f:be.uri(route: 'web_MyextensionList')}">
|
||||
*
|
||||
* Link to edit only the fields title and subtitle of page uid=42 and return to foo/bar::
|
||||
*
|
||||
* <be:link.editRecord uid="42" table="pages" fields="title,subtitle" returnUrl="foo/bar">
|
||||
* Edit record
|
||||
* </be:link.editRecord>
|
||||
*
|
||||
* Output::
|
||||
*
|
||||
* <a href="/typo3/record/edit?edit[pages][42]=edit&returnUrl=foo/bar&columnsOnly[pages]=title,subtitle">
|
||||
* Edit record
|
||||
* </a>
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-link-editrecord
|
||||
*/
|
||||
final class EditRecordViewHelper extends AbstractTagBasedViewHelper
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'a';
|
||||
|
||||
public function __construct(
|
||||
private readonly UriBuilder $uriBuilder
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('uid', 'int', 'uid of record to be edited', true);
|
||||
$this->registerArgument('table', 'string', 'target database table', true);
|
||||
$this->registerArgument('fields', 'string', 'Edit only these fields (comma separated list)');
|
||||
$this->registerArgument('module', 'string', 'Set module identifier for context - marking as active when editing the record', false, '');
|
||||
$this->registerArgument('returnUrl', 'string', 'return to this URL after closing the edit dialog', false, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws RouteNotFoundException
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
if ($this->arguments['uid'] < 1) {
|
||||
throw new InvalidArgumentValueException('Uid must be a positive integer, ' . $this->arguments['uid'] . ' given.', 1526127158);
|
||||
}
|
||||
$request = $this->renderingContext->hasAttribute(ServerRequestInterface::class)
|
||||
? $this->renderingContext->getAttribute(ServerRequestInterface::class) : null;
|
||||
|
||||
if (empty($this->arguments['returnUrl']) && $request !== null) {
|
||||
// @todo: We may want to deprecate fetching returnUrl from request
|
||||
$this->arguments['returnUrl'] = $request->getAttribute('normalizedParams')->getRequestUri();
|
||||
}
|
||||
|
||||
$params = [
|
||||
'edit' => [$this->arguments['table'] => [$this->arguments['uid'] => 'edit']],
|
||||
'module' => ($this->arguments['module'] ?? '') ?: ($request?->getAttribute('module')?->getIdentifier() ?? ''),
|
||||
'returnUrl' => $this->arguments['returnUrl'],
|
||||
];
|
||||
if ($this->arguments['fields'] ?? false) {
|
||||
$params['columnsOnly'] = [
|
||||
$this->arguments['table'] => GeneralUtility::trimExplode(',', $this->arguments['fields'], true),
|
||||
];
|
||||
}
|
||||
$uri = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $params);
|
||||
$this->tag->addAttribute('href', $uri);
|
||||
$this->tag->setContent((string)$this->renderChildren());
|
||||
$this->tag->forceClosingTag(true);
|
||||
return $this->tag->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Link;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentException;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentValueException;
|
||||
|
||||
/**
|
||||
* Use this ViewHelper to provide 'create new record' links.
|
||||
* The ViewHelper will pass the command to FormEngine.
|
||||
*
|
||||
* The table argument is mandatory, it decides what record is to be created.
|
||||
*
|
||||
* The pid argument will put the new record on this page, if ``0`` given it will
|
||||
* be placed to the root page.
|
||||
*
|
||||
* The uid argument accepts only negative values. If this is given, the new
|
||||
* record will be placed (by sorting field) behind the record with the uid.
|
||||
* It will end up on the same pid as this given record, so the pid must not
|
||||
* be given explicitly by pid argument.
|
||||
*
|
||||
* An exception will be thrown, if both uid and pid are given.
|
||||
* An exception will be thrown, if the uid argument is not a negative integer.
|
||||
*
|
||||
* To edit records, use the :ref:`<be:link.editRecordViewHelper> <typo3-backend-link-editrecord>`.
|
||||
*
|
||||
* Examples
|
||||
* ========
|
||||
*
|
||||
* Link to create a new record of a_table after record 17 on the same pid::
|
||||
*
|
||||
* <be:link.newRecord table="a_table" returnUrl="foo/bar" uid="-17"/>
|
||||
*
|
||||
* Output::
|
||||
*
|
||||
* <a href="/typo3/record/edit?edit[a_table][-17]=new&returnUrl=foo/bar">
|
||||
* New record
|
||||
* </a>
|
||||
*
|
||||
* Link to create a new record of a_table on root page::
|
||||
*
|
||||
* <be:link.newRecord table="a_table" returnUrl="foo/bar""/>
|
||||
*
|
||||
* Output::
|
||||
*
|
||||
* <a href="/typo3/record/edit?edit[a_table][]=new&returnUrl=foo/bar">
|
||||
* New record
|
||||
* </a>
|
||||
*
|
||||
* Link to create a new record of a_table on page 17::
|
||||
*
|
||||
* <be:link.newRecord table="a_table" returnUrl="foo/bar" pid="17"/>
|
||||
*
|
||||
* Output::
|
||||
*
|
||||
* <a href="/typo3/record/edit?edit[a_table][17]=new&returnUrl=foo/bar">
|
||||
* New record
|
||||
* </a>
|
||||
*
|
||||
* Link to create a new record then return back to the BE module "web_MyextensionList"::
|
||||
*
|
||||
* <be:link.newRecord table="a_table" returnUrl="{f:be.uri(route: 'web_MyextensionList')}" pid="17">
|
||||
*
|
||||
* Output::
|
||||
*
|
||||
* <a href="/typo3/record/edit?edit[a_table][17]=new&returnUrl=/typo3/module/web/MyextensionList">
|
||||
* New record
|
||||
* </a>
|
||||
*
|
||||
* Link to create a new record of a_table on page 17 with a default value::
|
||||
*
|
||||
* <be:link.newRecord table="a_table" returnUrl="foo/bar" pid="17" defaultValues="{a_table: {a_field: 'value'}}">
|
||||
*
|
||||
* Output::
|
||||
*
|
||||
* <a href="/typo3/record/edit?edit[a_table][17]=new&returnUrl=foo/bar&defVals[a_table][a_field]=value">
|
||||
* New record
|
||||
* </a>
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-link-newrecord
|
||||
*/
|
||||
final class NewRecordViewHelper extends AbstractTagBasedViewHelper
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'a';
|
||||
|
||||
public function __construct(
|
||||
private readonly UriBuilder $uriBuilder
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('uid', 'int', 'uid < 0 will insert the record after the given uid');
|
||||
$this->registerArgument('pid', 'int', 'the page id where the record will be created');
|
||||
$this->registerArgument('table', 'string', 'target database table', true);
|
||||
$this->registerArgument('module', 'string', 'Set module identifier for context - marking as acitve when editing the record', false, '');
|
||||
$this->registerArgument('returnUrl', 'string', 'return to this URL after closing the new record dialog', false, '');
|
||||
$this->registerArgument('defaultValues', 'array', 'default values for fields of the new record', false, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RouteNotFoundException
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
if ($this->arguments['uid'] && $this->arguments['pid']) {
|
||||
throw new InvalidArgumentException('Can\'t handle both uid and pid for new records', 1526129969);
|
||||
}
|
||||
if (isset($this->arguments['uid']) && $this->arguments['uid'] >= 0) {
|
||||
throw new InvalidArgumentValueException('Uid must be negative integer, ' . $this->arguments['uid'] . ' given', 1526134901);
|
||||
}
|
||||
|
||||
$request = $this->renderingContext->hasAttribute(ServerRequestInterface::class)
|
||||
? $this->renderingContext->getAttribute(ServerRequestInterface::class) : null;
|
||||
if (empty($this->arguments['returnUrl']) && $request !== null) {
|
||||
$this->arguments['returnUrl'] = $request->getAttribute('normalizedParams')->getRequestUri();
|
||||
}
|
||||
|
||||
$params = [
|
||||
'edit' => [$this->arguments['table'] => [$this->arguments['uid'] ?? $this->arguments['pid'] ?? 0 => 'new']],
|
||||
// @todo add module argument to this view helper
|
||||
'module' => ($this->arguments['module'] ?? '') ?: ($request?->getAttribute('module')?->getIdentifier() ?? ''),
|
||||
'returnUrl' => $this->arguments['returnUrl'],
|
||||
];
|
||||
|
||||
if ($this->arguments['defaultValues']) {
|
||||
$params['defVals'] = $this->arguments['defaultValues'];
|
||||
}
|
||||
|
||||
$uri = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $params);
|
||||
$this->tag->addAttribute('href', $uri);
|
||||
$this->tag->setContent((string)$this->renderChildren());
|
||||
$this->tag->forceClosingTag(true);
|
||||
return $this->tag->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use TYPO3\CMS\Backend\View\AuthenticationStyleInformation;
|
||||
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
|
||||
use TYPO3\CMS\Core\Imaging\Exception\InvalidSvgException;
|
||||
use TYPO3\CMS\Core\Imaging\Svg\SvgDocumentFactory;
|
||||
use TYPO3\CMS\Core\Imaging\Svg\SvgDocumentService;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Package\Cache\PackageDependentCacheIdentifier;
|
||||
use TYPO3\CMS\Core\SystemResource\Exception\SystemResourceDoesNotExistException;
|
||||
use TYPO3\CMS\Core\SystemResource\Publishing\SystemResourcePublisherInterface;
|
||||
use TYPO3\CMS\Core\SystemResource\Type\SystemResourceInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to display the login logo.
|
||||
*
|
||||
* ```
|
||||
* <backend:loginLogo />
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-loginlogo
|
||||
* @internal
|
||||
*/
|
||||
final class LoginLogoViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function __construct(
|
||||
private readonly AuthenticationStyleInformation $authenticationStyleInformation,
|
||||
private readonly PackageDependentCacheIdentifier $packageDependentCacheIdentifier,
|
||||
#[Autowire(service: 'cache.assets')]
|
||||
private readonly FrontendInterface $cache,
|
||||
private readonly SystemResourcePublisherInterface $resourcePublisher,
|
||||
private readonly SvgDocumentFactory $svgDocumentFactory,
|
||||
private readonly SvgDocumentService $svgDocumentService,
|
||||
) {}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$languageService = $this->getLanguageService();
|
||||
$logo = $this->authenticationStyleInformation->getLogo();
|
||||
$alternativeText = $languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang_login.xlf:typo3.altText');
|
||||
if ($logo !== null) {
|
||||
$alternativeText = $this->authenticationStyleInformation->getLogoAlt() ?: $alternativeText;
|
||||
} else {
|
||||
$logo = $this->authenticationStyleInformation->getDefaultLogo();
|
||||
}
|
||||
|
||||
if ($logo instanceof SystemResourceInterface && ($renderedSvg = $this->getInlineSvg($logo)) !== null) {
|
||||
return $renderedSvg;
|
||||
}
|
||||
|
||||
$request = null;
|
||||
if ($this->renderingContext->hasAttribute(ServerRequestInterface::class)) {
|
||||
$request = $this->renderingContext->getAttribute(ServerRequestInterface::class);
|
||||
}
|
||||
$uri = (string)$this->resourcePublisher->generateUri($logo, $request);
|
||||
return $this->renderImage($uri, $alternativeText);
|
||||
}
|
||||
|
||||
private function renderImage(string $uri, string $alt): string
|
||||
{
|
||||
return sprintf('<img %s>', GeneralUtility::implodeAttributes([
|
||||
'src' => $uri,
|
||||
'alt' => $alt,
|
||||
], true));
|
||||
}
|
||||
|
||||
private function getInlineSvg(SystemResourceInterface $svg): ?string
|
||||
{
|
||||
$cacheIdentifier = $this->packageDependentCacheIdentifier
|
||||
->withPrefix('LoginLogo')
|
||||
->withAdditionalHashedIdentifier((string)$svg)
|
||||
->toString();
|
||||
if ($this->cache->has($cacheIdentifier)) {
|
||||
return $this->cache->get($cacheIdentifier);
|
||||
}
|
||||
|
||||
$svgContent = $this->parseSvg($svg);
|
||||
$this->cache->set($cacheIdentifier, $svgContent);
|
||||
return $svgContent;
|
||||
}
|
||||
|
||||
private function parseSvg(SystemResourceInterface $svg): ?string
|
||||
{
|
||||
if (!str_ends_with($svg->getName(), '.svg')) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
$svgContent = $svg->getContents();
|
||||
} catch (SystemResourceDoesNotExistException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// SVG is sanitized, because login screen needs increased security precautions.
|
||||
// Links are stripped so the rendered logo cannot contain clickable areas.
|
||||
try {
|
||||
$document = $this->svgDocumentFactory->fromStringAndSanitize($svgContent, true);
|
||||
} catch (InvalidSvgException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Logo is decorative; the login page has its own heading.
|
||||
$document->documentElement->setAttribute('aria-hidden', 'true');
|
||||
return $this->svgDocumentService->toInlineMarkup($document);
|
||||
}
|
||||
|
||||
private function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Mfa;
|
||||
|
||||
use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderManifestInterface;
|
||||
use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to check if the given provider for the current user has the requested state set.
|
||||
*
|
||||
* ```
|
||||
* <be:mfa.ifHasState state="active" provider="{provider}">
|
||||
* ...
|
||||
* </be:mfa.ifHasState>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-mfa-ifhasstate
|
||||
* @internal
|
||||
*/
|
||||
final class IfHasStateViewHelper extends AbstractConditionViewHelper
|
||||
{
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('state', 'string', 'The state to check for (e.g. active or locked)', true);
|
||||
$this->registerArgument('provider', MfaProviderManifestInterface::class, 'The provider in question', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{state: string, provider: MfaProviderManifestInterface} $arguments
|
||||
*/
|
||||
public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
|
||||
{
|
||||
$stateMethod = 'is' . ucfirst($arguments['state']);
|
||||
$provider = $arguments['provider'];
|
||||
$propertyManager = MfaProviderPropertyManager::create($provider, $GLOBALS['BE_USER']);
|
||||
return is_callable([$provider, $stateMethod]) && $provider->{$stateMethod}($propertyManager);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to create internal links within the backend.
|
||||
*
|
||||
* ```
|
||||
* <form action="{be:moduleLink(route:'pages_new', arguments:'{id:pageUid}')}" method="post">
|
||||
* <!-- form content -->
|
||||
* </form>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-modulelink
|
||||
*/
|
||||
final class ModuleLinkViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UriBuilder $uriBuilder
|
||||
) {}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('route', 'string', 'The route to link to', true);
|
||||
$this->registerArgument('arguments', 'array', 'Additional link arguments (e.g. id or returnUrl)', false, []);
|
||||
$this->registerArgument('query', 'string', 'Additional link arguments as string (e.g. id or returnUrl)');
|
||||
$this->registerArgument('currentUrlParameterName', 'string', 'Add current URL as given parameter');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render module link with arguments
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
$parameters = $this->arguments['arguments'];
|
||||
if ($this->arguments['query'] !== null) {
|
||||
ArrayUtility::mergeRecursiveWithOverrule($parameters, GeneralUtility::explodeUrl2Array($this->arguments['query']));
|
||||
}
|
||||
if (!empty($this->arguments['currentUrlParameterName'])
|
||||
&& empty($this->arguments['arguments'][$this->arguments['currentUrlParameterName']])
|
||||
&& $this->renderingContext->hasAttribute(ServerRequestInterface::class)
|
||||
) {
|
||||
// If currentUrlParameterName is given and if that argument is not hand over yet, and if there is a request, fetch it from request
|
||||
// @todo: We may want to deprecate fetching stuff from request and advise handing over a proper value as 'arguments' argument.
|
||||
$request = $this->renderingContext->getAttribute(ServerRequestInterface::class);
|
||||
$parameters[$this->arguments['currentUrlParameterName']] = $request->getAttribute('normalizedParams')->getRequestUri();
|
||||
}
|
||||
return (string)$this->uriBuilder->buildUriFromRoute($this->arguments['route'], $parameters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
|
||||
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
|
||||
use TYPO3\CMS\Core\Resource\ProcessedFile;
|
||||
use TYPO3\CMS\Extbase\Service\ImageService;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentValueException;
|
||||
|
||||
/**
|
||||
* ViewHelper for the backend which generates an `<img>` tag with the special URI to render thumbnails deferred.
|
||||
*
|
||||
* ```
|
||||
* <be:thumbnail image="{file.resource}" width="{thumbnail.width}" height="{thumbnail.height}" />
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-thumbnail
|
||||
*/
|
||||
final class ThumbnailViewHelper extends AbstractTagBasedViewHelper
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'img';
|
||||
|
||||
public function __construct(
|
||||
private readonly ImageService $imageService
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('src', 'string', 'a path to a file, a combined FAL identifier or an uid (int). If $treatIdAsReference is set, the integer is considered the uid of the sys_file_reference record. If you already got a FAL object, consider using the $image parameter instead', false, '');
|
||||
$this->registerArgument('treatIdAsReference', 'bool', 'given src argument is a sys_file_reference record', false, false);
|
||||
$this->registerArgument('image', 'object', 'a FAL object (\\TYPO3\\CMS\\Core\\Resource\\File or \\TYPO3\\CMS\\Core\\Resource\\FileReference)');
|
||||
$this->registerArgument('crop', 'string|bool', 'overrule cropping of image (setting to FALSE disables the cropping set in FileReference)');
|
||||
$this->registerArgument('cropVariant', 'string', 'select a cropping variant, in case multiple croppings have been specified or stored in FileReference', false, 'default');
|
||||
|
||||
$this->registerArgument('width', 'string', 'width of the image. This can be a numeric value representing the fixed width of the image in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.');
|
||||
$this->registerArgument('height', 'string', 'height of the image. This can be a numeric value representing the fixed height of the image in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.');
|
||||
$this->registerArgument('minWidth', 'int', 'minimum width of the image');
|
||||
$this->registerArgument('minHeight', 'int', 'minimum height of the image');
|
||||
$this->registerArgument('maxWidth', 'int', 'maximum width of the image');
|
||||
$this->registerArgument('maxHeight', 'int', 'maximum height of the image');
|
||||
$this->registerArgument('context', 'string', 'context for image rendering', false, ProcessedFile::CONTEXT_IMAGEPREVIEW);
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
if (($this->arguments['src'] === '' && $this->arguments['image'] === null) || ($this->arguments['src'] !== '' && $this->arguments['image'] !== null)) {
|
||||
throw new InvalidArgumentValueException('You must either specify a string src or a File object.', 1533290762);
|
||||
}
|
||||
|
||||
try {
|
||||
$image = $this->imageService->getImage((string)$this->arguments['src'], $this->arguments['image'], (bool)$this->arguments['treatIdAsReference']);
|
||||
|
||||
$cropString = $this->arguments['crop'];
|
||||
if ($cropString === null && $image->hasProperty('crop') && $image->getProperty('crop')) {
|
||||
$cropString = $image->getProperty('crop');
|
||||
}
|
||||
$cropVariantCollection = CropVariantCollection::create((string)$cropString);
|
||||
$cropVariant = $this->arguments['cropVariant'] ?: 'default';
|
||||
$cropArea = $cropVariantCollection->getCropArea($cropVariant);
|
||||
$processingInstructions = [];
|
||||
if (!$cropArea->isEmpty()) {
|
||||
$processingInstructions['crop'] = $cropArea->makeAbsoluteBasedOnFile($image);
|
||||
}
|
||||
foreach (['width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight'] as $argument) {
|
||||
if (!empty($this->arguments[$argument])) {
|
||||
$processingInstructions[$argument] = $this->arguments[$argument];
|
||||
}
|
||||
}
|
||||
|
||||
if (is_callable([$image, 'getOriginalFile'])) {
|
||||
// Get the original file from the file reference
|
||||
$image = $image->getOriginalFile();
|
||||
}
|
||||
|
||||
$processedFile = $image->process($this->arguments['context'], $processingInstructions);
|
||||
$imageUri = $processedFile->getPublicUrl();
|
||||
|
||||
if (!$this->tag->hasAttribute('data-focus-area')) {
|
||||
$focusArea = $cropVariantCollection->getFocusArea($cropVariant);
|
||||
if (!$focusArea->isEmpty()) {
|
||||
$this->tag->addAttribute('data-focus-area', (string)$focusArea->makeAbsoluteBasedOnFile($image));
|
||||
}
|
||||
}
|
||||
$this->tag->addAttribute('src', $imageUri);
|
||||
$this->tag->addAttribute('width', $processedFile->getProperty('width'));
|
||||
$this->tag->addAttribute('height', $processedFile->getProperty('height'));
|
||||
|
||||
$alt = $image->getProperty('alternative');
|
||||
$title = $image->getProperty('title');
|
||||
|
||||
// The alt-attribute is mandatory to have valid html-code, therefore add it even if it is empty
|
||||
if (empty($this->additionalArguments['alt'])) {
|
||||
$this->tag->addAttribute('alt', $alt);
|
||||
}
|
||||
if (empty($this->additionalArguments['title']) && $title) {
|
||||
// Set title from image if not manually given as VH argument
|
||||
$this->tag->addAttribute('title', $title);
|
||||
}
|
||||
} catch (ResourceDoesNotExistException $e) {
|
||||
// thrown if file does not exist
|
||||
throw new Exception($e->getMessage(), 1533294109, $e);
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
// thrown if a file has been replaced with a folder
|
||||
throw new Exception($e->getMessage(), 1533294113, $e);
|
||||
} catch (\RuntimeException $e) {
|
||||
// RuntimeException thrown if a file is outside of a storage
|
||||
throw new Exception($e->getMessage(), 1533294116, $e);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// thrown if file storage does not exist
|
||||
throw new Exception($e->getMessage(), 1533294120, $e);
|
||||
}
|
||||
|
||||
return $this->tag->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Toolbar;
|
||||
|
||||
use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to build a "class" attribute string for use in rendered toolbar items.
|
||||
*
|
||||
* ```
|
||||
* <be:toolbar.attributes class="{someToolbarItemInterfaceInstance}" />
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-toolbar-attributes
|
||||
* @internal
|
||||
*/
|
||||
final class AttributesViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('class', ToolbarItemInterface::class, 'Class being converted to a string for usage as id attribute', true);
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$additionalAttributes = [
|
||||
'class' => 'toolbar-item dropdown',
|
||||
];
|
||||
$toolbarItem = $this->arguments['class'] ?? null;
|
||||
if ($toolbarItem instanceof ToolbarItemInterface) {
|
||||
$additionalAttributes['class'] .= ' ' . ($toolbarItem->getAdditionalAttributes()['class'] ?? '');
|
||||
$additionalAttributes['id'] = self::convertClassNameToIdAttribute(get_class($toolbarItem));
|
||||
}
|
||||
return GeneralUtility::implodeAttributes($additionalAttributes);
|
||||
}
|
||||
|
||||
private static function convertClassNameToIdAttribute(string $fullyQualifiedClassName): string
|
||||
{
|
||||
$className = GeneralUtility::underscoredToLowerCamelCase($fullyQualifiedClassName);
|
||||
$className = GeneralUtility::camelCaseToLowerCaseUnderscored($className);
|
||||
|
||||
return str_replace(['_', '\\'], '-', $className);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Toolbar;
|
||||
|
||||
use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper condition to checks whether a toolbar item provides a dropdown menu.
|
||||
*
|
||||
* ```
|
||||
* <be:toolbar.ifHasDropdown class="{toolbarItem}">
|
||||
* <f:then>...</f:then>
|
||||
* <f:else>...</f:else>
|
||||
* </be:toolbar.ifHasDropdown>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-toolbar-ifhasdropdown
|
||||
* @internal
|
||||
*/
|
||||
class IfHasDropdownViewHelper extends AbstractConditionViewHelper
|
||||
{
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('class', ToolbarItemInterface::class, 'The toolbar item class to be checked for providing a drop down', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{class: object} $arguments
|
||||
*/
|
||||
public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
|
||||
{
|
||||
return $arguments['class'] instanceof ToolbarItemInterface && $arguments['class']->hasDropDown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Type;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to check whether the given value is an array.
|
||||
*
|
||||
* ```
|
||||
* <f:if condition="{be:type.isArray(value: myVariable)}">
|
||||
* <f:then>myVariable is an array</f:then>
|
||||
* <f:else>myVariable is not an array</f:else>
|
||||
* </f:if>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-type-isarray
|
||||
* @internal This experimental ViewHelper is not part of TYPO3 Core API and may change or vanish any time.
|
||||
*/
|
||||
final class IsArrayViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('value', 'mixed', 'The variable being checked', true);
|
||||
}
|
||||
|
||||
public function render(): bool
|
||||
{
|
||||
return is_array($this->arguments['value']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\TypoScript;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\DiffUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to runs two strings through 'FineDiff' on word level.
|
||||
*
|
||||
* ```
|
||||
* <backend:typoScript.fineDiff from="{someTextChunkBefore}" to="{someTextChunkAfter}" />
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-typoscript-finediff
|
||||
* @internal This experimental ViewHelper is not part of TYPO3 Core API and may change or vanish any time.
|
||||
*/
|
||||
final class FineDiffViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DiffUtility $diffUtility
|
||||
) {}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('from', 'string', 'Source string', true);
|
||||
$this->registerArgument('to', 'string', 'Target string', true);
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
return $this->diffUtility->diff($this->arguments['from'], $this->arguments['to']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Uri;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentValueException;
|
||||
|
||||
/**
|
||||
* ViewHelper to provide edit links (only the URI) to records. The ViewHelper will
|
||||
* pass the uid and table to FormEngine.
|
||||
*
|
||||
* The uid must be given as a positive integer.
|
||||
* For new records, use `<be:uri.newRecord>`.
|
||||
*
|
||||
* ```
|
||||
* <be:uri.editRecord uid="42" table="pages" fields="title,subtitle" returnUrl="foo/bar" />
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-uri-editrecord
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-uri-newrecord
|
||||
*/
|
||||
final class EditRecordViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UriBuilder $uriBuilder
|
||||
) {}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('uid', 'int', 'uid of record to be edited, 0 for creation', true);
|
||||
$this->registerArgument('table', 'string', 'target database table', true);
|
||||
$this->registerArgument('fields', 'string', 'Edit only these fields (comma separated list)');
|
||||
$this->registerArgument('module', 'string', 'Set module identifier for context - marking as acitve when editing the record', false, '');
|
||||
$this->registerArgument('returnUrl', 'string', 'return to this URL after closing the edit dialog', false, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentValueException
|
||||
* @throws RouteNotFoundException
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
if ($this->arguments['uid'] < 1) {
|
||||
throw new InvalidArgumentValueException('Uid must be a positive integer, ' . $this->arguments['uid'] . ' given.', 1526128259);
|
||||
}
|
||||
$request = $this->renderingContext->hasAttribute(ServerRequestInterface::class)
|
||||
? $this->renderingContext->getAttribute(ServerRequestInterface::class) : null;
|
||||
if (empty($this->arguments['returnUrl']) && $request !== null) {
|
||||
$this->arguments['returnUrl'] = $request->getAttribute('normalizedParams')->getRequestUri();
|
||||
}
|
||||
$params = [
|
||||
'edit' => [$this->arguments['table'] => [$this->arguments['uid'] => 'edit']],
|
||||
'module' => ($this->arguments['module'] ?? '') ?: ($request?->getAttribute('module')?->getIdentifier() ?? ''),
|
||||
'returnUrl' => $this->arguments['returnUrl'],
|
||||
];
|
||||
if ($this->arguments['fields'] ?? false) {
|
||||
$params['columnsOnly'] = [
|
||||
$this->arguments['table'] => GeneralUtility::trimExplode(',', $this->arguments['fields'], true),
|
||||
];
|
||||
}
|
||||
return (string)$this->uriBuilder->buildUriFromRoute('record_edit', $params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\ViewHelpers\Uri;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentException;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentValueException;
|
||||
|
||||
/**
|
||||
* ViewHelper to provide 'create new record' links.
|
||||
* The ViewHelper will pass the command to FormEngine.
|
||||
*
|
||||
* The `pid` argument will put the new record on this page, if ``0`` given it will
|
||||
* be placed to the root page.
|
||||
*
|
||||
* The `uid` argument accepts only negative values. If this is given, the new
|
||||
* record will be placed (by sorting field) behind the record with the uid.
|
||||
* It will end up on the same pid as this given record, so the pid must not
|
||||
* be given explicitly by pid argument.
|
||||
*
|
||||
* An exception will be thrown, if both uid and pid are given.
|
||||
* An exception will be thrown, if the uid argument is not a negative integer.
|
||||
*
|
||||
* ```
|
||||
* <be:uri.newRecord table="a_table" returnUrl="foo/bar" uid="-17"/>
|
||||
* <be:uri.newRecord table="a_table" returnUrl="foo/bar" pid="17"/>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-uri-newrecord
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-backend-uri-editrecord
|
||||
*/
|
||||
final class NewRecordViewHelper extends AbstractTagBasedViewHelper
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UriBuilder $uriBuilder
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('uid', 'int', 'uid < 0 will insert the record after the given uid');
|
||||
$this->registerArgument('pid', 'int', 'the page id where the record will be created');
|
||||
$this->registerArgument('table', 'string', 'target database table', true);
|
||||
$this->registerArgument('module', 'string', 'Set module identifier for context - marking as acitve when editing the record', false, '');
|
||||
$this->registerArgument('returnUrl', 'string', 'return to this URL after closing the edit dialog', false, '');
|
||||
$this->registerArgument('defaultValues', 'array', 'default values for fields of the new record', false, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RouteNotFoundException
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
if ($this->arguments['uid'] && $this->arguments['pid']) {
|
||||
throw new InvalidArgumentException('Can\'t handle both uid and pid for new records', 1526136338);
|
||||
}
|
||||
if (isset($this->arguments['uid']) && $this->arguments['uid'] >= 0) {
|
||||
throw new InvalidArgumentValueException('Uid must be negative integer, ' . $this->arguments['uid'] . ' given', 1526136362);
|
||||
}
|
||||
$request = $this->renderingContext->hasAttribute(ServerRequestInterface::class)
|
||||
? $this->renderingContext->getAttribute(ServerRequestInterface::class) : null;
|
||||
if (empty($this->arguments['returnUrl']) && $request !== null) {
|
||||
$this->arguments['returnUrl'] = $request->getAttribute('normalizedParams')->getRequestUri();
|
||||
}
|
||||
$params = [
|
||||
'edit' => [$this->arguments['table'] => [$this->arguments['uid'] ?? $this->arguments['pid'] ?? 0 => 'new']],
|
||||
'module' => ($this->arguments['module'] ?? '') ?: ($request?->getAttribute('module')?->getIdentifier() ?? ''),
|
||||
'returnUrl' => $this->arguments['returnUrl'],
|
||||
];
|
||||
if ($this->arguments['defaultValues']) {
|
||||
$params['defVals'] = $this->arguments['defaultValues'];
|
||||
}
|
||||
return (string)$this->uriBuilder->buildUriFromRoute('record_edit', $params);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user