first commit
This commit is contained in:
commit
1218dd1517
12716 files changed
+989233
No files matched your search
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Extbase\Annotation;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"METHOD"})
|
||||
*/
|
||||
class IgnoreValidation
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $argumentName;
|
||||
|
||||
/**
|
||||
* @param array $values
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
if (isset($values['value'])) {
|
||||
$this->argumentName = $values['value'];
|
||||
} elseif (isset($values['argumentName'])) {
|
||||
$this->argumentName = $values['argumentName'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Extbase\Annotation;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY"})
|
||||
*/
|
||||
class Inject
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Extbase\Annotation\ORM;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY"})
|
||||
*/
|
||||
class Cascade
|
||||
{
|
||||
/**
|
||||
* @Enum({"remove"})
|
||||
*
|
||||
* Currently, Extbase does only support "remove".
|
||||
*
|
||||
* Other possible cascade operations would be: "persist", "merge", "detach", "refresh", "all"
|
||||
* @see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
if (isset($values['value'])) {
|
||||
$this->value = $values['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Extbase\Annotation\ORM;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY"})
|
||||
*/
|
||||
class Lazy
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Extbase\Annotation\ORM;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY"})
|
||||
*/
|
||||
class Transient
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Extbase\Annotation;
|
||||
|
||||
/*
|
||||
* 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 Doctrine\Common\Annotations\Annotation\Required;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY", "METHOD"})
|
||||
*/
|
||||
class Validate
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @Required
|
||||
*/
|
||||
public $validator = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $param = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $options = [];
|
||||
|
||||
/**
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
if (isset($values['value'])) {
|
||||
$this->validator = $values['value'];
|
||||
}
|
||||
|
||||
if (isset($values['validator'])) {
|
||||
$this->validator = $values['validator'];
|
||||
}
|
||||
|
||||
if (isset($values['options'])) {
|
||||
$this->options = $values['options'];
|
||||
}
|
||||
|
||||
if (isset($values['param'])) {
|
||||
$this->param = $values['param'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$strings = [];
|
||||
|
||||
if ($this->param !== '') {
|
||||
$strings[] = $this->param;
|
||||
}
|
||||
|
||||
$strings[] = $this->validator;
|
||||
|
||||
if (count($this->options) > 0) {
|
||||
$validatorOptionsStrings = [];
|
||||
foreach ($this->options as $optionKey => $optionValue) {
|
||||
$validatorOptionsStrings[] = $optionKey . '=' . $optionValue;
|
||||
}
|
||||
|
||||
$strings[] = '(' . implode(', ', $validatorOptionsStrings) . ')';
|
||||
}
|
||||
|
||||
return trim(implode(' ', $strings));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Command;
|
||||
|
||||
/*
|
||||
* 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 Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use TYPO3\CMS\Core\Package\FailsafePackageManager;
|
||||
use TYPO3\CMS\Core\Package\PackageManager;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Core\Bootstrap;
|
||||
use TYPO3\CMS\Extbase\Mvc\Cli\CommandManager;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
|
||||
/**
|
||||
* Main call to register any Extbase command from Extbase command controllers
|
||||
*
|
||||
* Fetches all registered Extbase commands and adds them to the application as custom Extbase commands
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class CoreCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @var Bootstrap
|
||||
*/
|
||||
protected $extbaseBootstrap;
|
||||
|
||||
/**
|
||||
* Configure the command, since this is a command
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setHidden(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the application instance for this command.
|
||||
* This is done in setApplication() because configure() is called too early to do it in that place.
|
||||
* The method 'setApplication()' is done right afterwards but has the application object to call.
|
||||
* Then registers additional commands that act as wrappers to the actual Extbase commands.
|
||||
*
|
||||
* @param Application $application An Application instance
|
||||
*/
|
||||
public function setApplication(Application $application = null)
|
||||
{
|
||||
parent::setApplication($application);
|
||||
|
||||
// Extbase commands can not be initialized in failsafe mode
|
||||
if (GeneralUtility::makeInstance(PackageManager::class) instanceof FailsafePackageManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find any registered Extbase commands
|
||||
$this->extbaseBootstrap = GeneralUtility::makeInstance(Bootstrap::class);
|
||||
$this->extbaseBootstrap->initialize([]);
|
||||
|
||||
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
|
||||
|
||||
/** @var CommandManager $commandManager */
|
||||
$commandManager = $objectManager->get(CommandManager::class);
|
||||
$commands = $commandManager->getAvailableCommands();
|
||||
foreach ($commands as $command) {
|
||||
$commandName = $commandManager->getShortestIdentifierForCommand($command);
|
||||
$fullCommandName = $command->getCommandIdentifier();
|
||||
if ($fullCommandName === 'extbase:help:error' || $fullCommandName === 'extbase:help:helpstub') {
|
||||
continue;
|
||||
}
|
||||
if ($commandName === 'help') {
|
||||
$commandName = 'extbase:help';
|
||||
}
|
||||
$extbaseCommand = GeneralUtility::makeInstance(ExtbaseCommand::class, $fullCommandName);
|
||||
|
||||
if ($commandName !== $fullCommandName) {
|
||||
$extbaseCommand->setAliases([$commandName]);
|
||||
}
|
||||
|
||||
$extbaseCommand->setExtbaseCommand($command);
|
||||
$this->getApplication()->add($extbaseCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Command;
|
||||
|
||||
/*
|
||||
* 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 Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Core\Bootstrap;
|
||||
|
||||
/**
|
||||
* Wrapper to wrap an Extbase command from a command controller into a Symfony Command
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class ExtbaseCommand extends Command
|
||||
{
|
||||
/**
|
||||
* Extbase's command
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Cli\Command
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* Extbase has its own validation logic, so it is disabled in this place
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->ignoreValidationErrors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the extbase command to be used for fetching the description etc.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Cli\Command $command
|
||||
*/
|
||||
public function setExtbaseCommand(\TYPO3\CMS\Extbase\Mvc\Cli\Command $command)
|
||||
{
|
||||
$this->command = $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the application instance for this command.
|
||||
* Also uses the setApplication call now, as $this->configure() is called
|
||||
* too early
|
||||
*
|
||||
* @param Application $application An Application instance
|
||||
*/
|
||||
public function setApplication(Application $application = null)
|
||||
{
|
||||
parent::setApplication($application);
|
||||
$description = $this->command->getDescription();
|
||||
$description = str_replace(LF, ' ', $description);
|
||||
$this->setDescription($description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the command to find any Extbase command
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// ugly hack because extbase only knows "help" (hardcoded, but already defined by symfony)
|
||||
// and "extbase:help:help"
|
||||
if ($_SERVER['argv'][1] === 'extbase:help') {
|
||||
$_SERVER['argv'][1] = 'extbase:help:help';
|
||||
}
|
||||
$bootstrap = GeneralUtility::makeInstance(Bootstrap::class);
|
||||
$bootstrap->run('', []);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Command;
|
||||
|
||||
/*
|
||||
* 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 Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Core\Bootstrap;
|
||||
|
||||
/**
|
||||
* Extends the help command of symfony to show the specific help for Extbase commands
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class HelpCommand extends \Symfony\Component\Console\Command\HelpCommand
|
||||
{
|
||||
/**
|
||||
* This needs to be re-set as the parent command has this property declared as "private" as well.
|
||||
*
|
||||
* @var Command
|
||||
*/
|
||||
private $command;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setAliases([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (null === $this->command) {
|
||||
$this->command = $this->getApplication()->find($input->getArgument('command_name'));
|
||||
}
|
||||
|
||||
// Extbase help was explicitly called
|
||||
if ($input->getArgument('command') === 'extbase:help' || $input->getArgument('command') === 'extbase:help:help') {
|
||||
$_SERVER['argv'][1] = 'extbase:help:help';
|
||||
$bootstrap = GeneralUtility::makeInstance(Bootstrap::class);
|
||||
$bootstrap->run('', []);
|
||||
} elseif ($this->command instanceof ExtbaseCommand) {
|
||||
// An extbase command was originally called, but is now required to show the help information
|
||||
// Ugly hack to modify 'argv' so the help command for a specific command is shown
|
||||
$args = [$_SERVER['argv'][0], 'help'];
|
||||
foreach ($_SERVER['argv'] as $k => $value) {
|
||||
if ($k === 0 || $value === '--help' || $value === '-h') {
|
||||
continue;
|
||||
}
|
||||
$args[] = $value;
|
||||
}
|
||||
$_SERVER['argv'] = $args;
|
||||
|
||||
// run Extbase bootstrap
|
||||
$bootstrap = GeneralUtility::makeInstance(Bootstrap::class);
|
||||
$bootstrap->run('', []);
|
||||
} else {
|
||||
// Any other symfony command should just show up the regular info
|
||||
parent::execute($input, $output);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Command;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Command Controller which provides help for available commands
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
class HelpCommandController extends \TYPO3\CMS\Extbase\Mvc\Controller\CommandController
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Cli\CommandManager
|
||||
*/
|
||||
protected $commandManager;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $commandsByExtensionsAndControllers = [];
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Cli\CommandManager $commandManager
|
||||
*/
|
||||
public function injectCommandManager(\TYPO3\CMS\Extbase\Mvc\Cli\CommandManager $commandManager)
|
||||
{
|
||||
$this->commandManager = $commandManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a short, general help message
|
||||
*
|
||||
* This only outputs the Extbase version number, context and some hint about how to
|
||||
* get more help about commands.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function helpStubCommand()
|
||||
{
|
||||
$this->outputLine('Extbase %s', [TYPO3_version]);
|
||||
$this->outputLine('usage: ' . $this->request->getCallingScript() . ' <command identifier>');
|
||||
$this->outputLine();
|
||||
$this->outputLine('See \'' . $this->request->getCallingScript() . ' help\' for a list of all available commands.');
|
||||
$this->outputLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display help for a command
|
||||
*
|
||||
* The help command displays help for a given command:
|
||||
* ./typo3/sysext/core/bin/typo3 extbase:help <command identifier>
|
||||
*
|
||||
* @param string $commandIdentifier Identifier of a command for more details
|
||||
*/
|
||||
public function helpCommand($commandIdentifier = null)
|
||||
{
|
||||
if ($commandIdentifier === null) {
|
||||
$this->displayHelpIndex();
|
||||
} else {
|
||||
try {
|
||||
$command = $this->commandManager->getCommandByIdentifier($commandIdentifier);
|
||||
} catch (\TYPO3\CMS\Extbase\Mvc\Exception\CommandException $exception) {
|
||||
$this->outputLine($exception->getMessage());
|
||||
return;
|
||||
}
|
||||
$this->displayHelpForCommand($command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an index of all commands that are available
|
||||
*/
|
||||
protected function displayHelpIndex()
|
||||
{
|
||||
$this->buildCommandsIndex();
|
||||
$this->outputLine('Extbase %s', [TYPO3_version]);
|
||||
$this->outputLine('usage: ' . $this->request->getCallingScript() . ' <command identifier>');
|
||||
$this->outputLine();
|
||||
$this->outputLine('The following commands are currently available:');
|
||||
foreach ($this->commandsByExtensionsAndControllers as $extensionKey => $commandControllers) {
|
||||
$this->outputLine('');
|
||||
$this->outputLine('EXTENSION "%s":', [strtoupper($extensionKey)]);
|
||||
$this->outputLine(str_repeat('-', $this->output->getMaximumLineLength()));
|
||||
foreach ($commandControllers as $commands) {
|
||||
foreach ($commands as $command) {
|
||||
$description = wordwrap($command->getShortDescription(), $this->output->getMaximumLineLength() - 43, PHP_EOL . str_repeat(' ', 43), true);
|
||||
$shortCommandIdentifier = $this->commandManager->getShortestIdentifierForCommand($command);
|
||||
$this->outputLine('%-2s%-40s %s', [' ', $shortCommandIdentifier, $description]);
|
||||
}
|
||||
$this->outputLine();
|
||||
}
|
||||
}
|
||||
$this->outputLine('See \'' . $this->request->getCallingScript() . ' help <command identifier>\' for more information about a specific command.');
|
||||
$this->outputLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render help text for a single command
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Cli\Command $command
|
||||
*/
|
||||
protected function displayHelpForCommand(\TYPO3\CMS\Extbase\Mvc\Cli\Command $command)
|
||||
{
|
||||
$this->outputLine();
|
||||
$this->outputLine($command->getShortDescription());
|
||||
$this->outputLine();
|
||||
$this->outputLine('COMMAND:');
|
||||
$this->outputLine('%-2s%s', [' ', $command->getCommandIdentifier()]);
|
||||
$commandArgumentDefinitions = $command->getArgumentDefinitions();
|
||||
$usage = '';
|
||||
$hasOptions = false;
|
||||
foreach ($commandArgumentDefinitions as $commandArgumentDefinition) {
|
||||
if (!$commandArgumentDefinition->isRequired()) {
|
||||
$hasOptions = true;
|
||||
} else {
|
||||
$usage .= sprintf(' <%s>', strtolower(preg_replace('/([A-Z])/', ' $1', $commandArgumentDefinition->getName())));
|
||||
}
|
||||
}
|
||||
$usage = $this->request->getCallingScript() . ' ' . $this->commandManager->getShortestIdentifierForCommand($command) . ($hasOptions ? ' [<options>]' : '') . $usage;
|
||||
$this->outputLine();
|
||||
$this->outputLine('USAGE:');
|
||||
$this->outputLine(' ' . $usage);
|
||||
$argumentDescriptions = [];
|
||||
$optionDescriptions = [];
|
||||
if ($command->hasArguments()) {
|
||||
foreach ($commandArgumentDefinitions as $commandArgumentDefinition) {
|
||||
$argumentDescription = $commandArgumentDefinition->getDescription();
|
||||
$argumentDescription = wordwrap($argumentDescription, $this->output->getMaximumLineLength() - 23, PHP_EOL . str_repeat(' ', 23), true);
|
||||
if ($commandArgumentDefinition->isRequired()) {
|
||||
$argumentDescriptions[] = vsprintf(' %-20s %s', [$commandArgumentDefinition->getDashedName(), $argumentDescription]);
|
||||
} else {
|
||||
$optionDescriptions[] = vsprintf(' %-20s %s', [$commandArgumentDefinition->getDashedName(), $argumentDescription]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($argumentDescriptions)) {
|
||||
$this->outputLine();
|
||||
$this->outputLine('ARGUMENTS:');
|
||||
foreach ($argumentDescriptions as $argumentDescription) {
|
||||
$this->outputLine($argumentDescription);
|
||||
}
|
||||
}
|
||||
if (!empty($optionDescriptions)) {
|
||||
$this->outputLine();
|
||||
$this->outputLine('OPTIONS:');
|
||||
foreach ($optionDescriptions as $optionDescription) {
|
||||
$this->outputLine($optionDescription);
|
||||
}
|
||||
}
|
||||
if ($command->getDescription() !== '') {
|
||||
$this->outputLine();
|
||||
$this->outputLine('DESCRIPTION:');
|
||||
$descriptionLines = explode(LF, $command->getDescription());
|
||||
foreach ($descriptionLines as $descriptionLine) {
|
||||
$this->outputLine('%-2s%s', [' ', $descriptionLine]);
|
||||
}
|
||||
}
|
||||
$relatedCommandIdentifiers = $command->getRelatedCommandIdentifiers();
|
||||
if ($relatedCommandIdentifiers !== []) {
|
||||
$this->outputLine();
|
||||
$this->outputLine('SEE ALSO:');
|
||||
foreach ($relatedCommandIdentifiers as $commandIdentifier) {
|
||||
$command = $this->commandManager->getCommandByIdentifier($commandIdentifier);
|
||||
$this->outputLine('%-2s%s (%s)', [' ', $commandIdentifier, $command->getShortDescription()]);
|
||||
}
|
||||
}
|
||||
$this->outputLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an error message
|
||||
*
|
||||
* @internal
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Exception\CommandException $exception
|
||||
*/
|
||||
public function errorCommand(\TYPO3\CMS\Extbase\Mvc\Exception\CommandException $exception)
|
||||
{
|
||||
$this->outputLine($exception->getMessage());
|
||||
if ($exception instanceof \TYPO3\CMS\Extbase\Mvc\Exception\AmbiguousCommandIdentifierException) {
|
||||
$this->outputLine('Please specify the complete command identifier. Matched commands:');
|
||||
foreach ($exception->getMatchingCommands() as $matchingCommand) {
|
||||
$this->outputLine(' %s', [$matchingCommand->getCommandIdentifier()]);
|
||||
}
|
||||
}
|
||||
$this->outputLine('');
|
||||
$this->outputLine('Enter "' . $this->request->getCallingScript() . ' help" for an overview of all available commands');
|
||||
$this->outputLine('or "' . $this->request->getCallingScript() . ' help <command identifier>" for a detailed description of the corresponding command.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an index of available commands. For each of them a Command object is
|
||||
* added to the commands array of this class.
|
||||
*/
|
||||
protected function buildCommandsIndex()
|
||||
{
|
||||
$availableCommands = $this->commandManager->getAvailableCommands();
|
||||
foreach ($availableCommands as $command) {
|
||||
if ($command->isInternal()) {
|
||||
continue;
|
||||
}
|
||||
$commandIdentifier = $command->getCommandIdentifier();
|
||||
$extensionKey = strstr($commandIdentifier, ':', true);
|
||||
$commandControllerClassName = $command->getControllerClassName();
|
||||
$commandName = $command->getControllerCommandName();
|
||||
$this->commandsByExtensionsAndControllers[$extensionKey][$commandControllerClassName][$commandName] = $command;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Configuration;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract base class for a general purpose configuration manager
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
abstract class AbstractConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface
|
||||
{
|
||||
/**
|
||||
* Default backend storage PID
|
||||
*/
|
||||
const DEFAULT_BACKEND_STORAGE_PID = 0;
|
||||
|
||||
/**
|
||||
* Storage of the raw TypoScript configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration = [];
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\TypoScript\TypoScriptService
|
||||
*/
|
||||
protected $typoScriptService;
|
||||
|
||||
/**
|
||||
* name of the extension this Configuration Manager instance belongs to
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $extensionName;
|
||||
|
||||
/**
|
||||
* name of the plugin this Configuration Manager instance belongs to
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pluginName;
|
||||
|
||||
/**
|
||||
* 1st level configuration cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $configurationCache = [];
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Service\EnvironmentService
|
||||
*/
|
||||
protected $environmentService;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Core\TypoScript\TypoScriptService $typoScriptService
|
||||
*/
|
||||
public function injectTypoScriptService(\TYPO3\CMS\Core\TypoScript\TypoScriptService $typoScriptService)
|
||||
{
|
||||
$this->typoScriptService = $typoScriptService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Service\EnvironmentService $environmentService
|
||||
*/
|
||||
public function injectEnvironmentService(\TYPO3\CMS\Extbase\Service\EnvironmentService $environmentService)
|
||||
{
|
||||
$this->environmentService = $environmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function setContentObject(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject = null)
|
||||
{
|
||||
$this->contentObject = $contentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer|null
|
||||
*/
|
||||
public function getContentObject()
|
||||
{
|
||||
if ($this->contentObject !== null) {
|
||||
return $this->contentObject;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified raw configuration coming from the outside.
|
||||
* Note that this is a low level method and only makes sense to be used by Extbase internally.
|
||||
*
|
||||
* @param array $configuration The new configuration
|
||||
*/
|
||||
public function setConfiguration(array $configuration = [])
|
||||
{
|
||||
// reset 1st level cache
|
||||
$this->configurationCache = [];
|
||||
$this->extensionName = $configuration['extensionName'] ?? null;
|
||||
$this->pluginName = $configuration['pluginName'] ?? null;
|
||||
$this->configuration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Extbase Framework configuration.
|
||||
*
|
||||
* The Extbase framework configuration HAS TO be retrieved using this method, as they are come from different places than the normal settings.
|
||||
* Framework configuration is, in contrast to normal settings, needed for the Extbase framework to operate correctly.
|
||||
*
|
||||
* @param string $extensionName if specified, the configuration for the given extension will be returned (plugin.tx_extensionname)
|
||||
* @param string $pluginName if specified, the configuration for the given plugin will be returned (plugin.tx_extensionname_pluginname)
|
||||
* @return array the Extbase framework configuration
|
||||
*/
|
||||
public function getConfiguration($extensionName = null, $pluginName = null)
|
||||
{
|
||||
// 1st level cache
|
||||
$configurationCacheKey = strtolower(($extensionName ?: $this->extensionName) . '_' . ($pluginName ?: $this->pluginName));
|
||||
if (isset($this->configurationCache[$configurationCacheKey])) {
|
||||
return $this->configurationCache[$configurationCacheKey];
|
||||
}
|
||||
$frameworkConfiguration = $this->getExtbaseConfiguration();
|
||||
if (!isset($frameworkConfiguration['persistence']['storagePid'])) {
|
||||
$frameworkConfiguration['persistence']['storagePid'] = $this->getDefaultBackendStoragePid();
|
||||
}
|
||||
// only merge $this->configuration and override switchableControllerActions when retrieving configuration of the current plugin
|
||||
if ($extensionName === null || $extensionName === $this->extensionName && $pluginName === $this->pluginName) {
|
||||
$pluginConfiguration = $this->getPluginConfiguration($this->extensionName, $this->pluginName);
|
||||
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($pluginConfiguration, $this->configuration);
|
||||
$pluginConfiguration['controllerConfiguration'] = $this->getSwitchableControllerActions($this->extensionName, $this->pluginName);
|
||||
if (isset($this->configuration['switchableControllerActions'])) {
|
||||
$this->overrideSwitchableControllerActions($pluginConfiguration, $this->configuration['switchableControllerActions']);
|
||||
}
|
||||
} else {
|
||||
$pluginConfiguration = $this->getPluginConfiguration($extensionName, $pluginName);
|
||||
$pluginConfiguration['controllerConfiguration'] = $this->getSwitchableControllerActions($extensionName, $pluginName);
|
||||
}
|
||||
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($frameworkConfiguration, $pluginConfiguration);
|
||||
// only load context specific configuration when retrieving configuration of the current plugin
|
||||
if ($extensionName === null || $extensionName === $this->extensionName && $pluginName === $this->pluginName) {
|
||||
$frameworkConfiguration = $this->getContextSpecificFrameworkConfiguration($frameworkConfiguration);
|
||||
}
|
||||
|
||||
if (!empty($frameworkConfiguration['persistence']['storagePid'])) {
|
||||
if (is_array($frameworkConfiguration['persistence']['storagePid'])) {
|
||||
// We simulate the frontend to enable the use of cObjects in
|
||||
// stdWrap. Than we convert the configuration to normal TypoScript
|
||||
// and apply the stdWrap to the storagePid
|
||||
if (!$this->environmentService->isEnvironmentInFrontendMode()) {
|
||||
\TYPO3\CMS\Extbase\Utility\FrontendSimulatorUtility::simulateFrontendEnvironment($this->getContentObject());
|
||||
}
|
||||
$conf = $this->typoScriptService->convertPlainArrayToTypoScriptArray($frameworkConfiguration['persistence']);
|
||||
$frameworkConfiguration['persistence']['storagePid'] = $GLOBALS['TSFE']->cObj->stdWrap($conf['storagePid'], $conf['storagePid.']);
|
||||
if (!$this->environmentService->isEnvironmentInFrontendMode()) {
|
||||
\TYPO3\CMS\Extbase\Utility\FrontendSimulatorUtility::resetFrontendEnvironment();
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($frameworkConfiguration['persistence']['recursive'])) {
|
||||
// All implementations of getTreeList allow to pass the ids negative to include them into the result
|
||||
// otherwise only childpages are returned
|
||||
$storagePids = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $frameworkConfiguration['persistence']['storagePid']);
|
||||
array_walk($storagePids, function (&$storagePid) {
|
||||
if ($storagePid > 0) {
|
||||
$storagePid = -$storagePid;
|
||||
}
|
||||
});
|
||||
$frameworkConfiguration['persistence']['storagePid'] = $this->getRecursiveStoragePids(
|
||||
implode(',', $storagePids),
|
||||
(int)$frameworkConfiguration['persistence']['recursive']
|
||||
);
|
||||
}
|
||||
}
|
||||
// 1st level cache
|
||||
$this->configurationCache[$configurationCacheKey] = $frameworkConfiguration;
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TypoScript configuration found in config.tx_extbase
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getExtbaseConfiguration()
|
||||
{
|
||||
$setup = $this->getTypoScriptSetup();
|
||||
$extbaseConfiguration = [];
|
||||
if (isset($setup['config.']['tx_extbase.'])) {
|
||||
$extbaseConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['config.']['tx_extbase.']);
|
||||
}
|
||||
return $extbaseConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default backend storage pid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultBackendStoragePid()
|
||||
{
|
||||
return self::DEFAULT_BACKEND_STORAGE_PID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array &$frameworkConfiguration
|
||||
* @param array $switchableControllerActions
|
||||
*/
|
||||
protected function overrideSwitchableControllerActions(array &$frameworkConfiguration, array $switchableControllerActions)
|
||||
{
|
||||
$overriddenSwitchableControllerActions = [];
|
||||
foreach ($switchableControllerActions as $controllerName => $actions) {
|
||||
if (!isset($frameworkConfiguration['controllerConfiguration'][$controllerName])) {
|
||||
continue;
|
||||
}
|
||||
$overriddenSwitchableControllerActions[$controllerName] = ['actions' => $actions];
|
||||
$nonCacheableActions = $frameworkConfiguration['controllerConfiguration'][$controllerName]['nonCacheableActions'] ?? null;
|
||||
if (!is_array($nonCacheableActions)) {
|
||||
// There are no non-cacheable actions, thus we can directly continue
|
||||
// with the next controller name.
|
||||
continue;
|
||||
}
|
||||
$overriddenNonCacheableActions = array_intersect($nonCacheableActions, $actions);
|
||||
if (!empty($overriddenNonCacheableActions)) {
|
||||
$overriddenSwitchableControllerActions[$controllerName]['nonCacheableActions'] = $overriddenNonCacheableActions;
|
||||
}
|
||||
}
|
||||
$frameworkConfiguration['controllerConfiguration'] = $overriddenSwitchableControllerActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* The context specific configuration returned by this method
|
||||
* will override the framework configuration which was
|
||||
* obtained from TypoScript. This can be used f.e. to override the storagePid
|
||||
* with the value set inside the Plugin Instance.
|
||||
*
|
||||
* WARNING: Make sure this method ALWAYS returns an array!
|
||||
*
|
||||
* @param array $frameworkConfiguration The framework configuration until now
|
||||
* @return array context specific configuration which will override the configuration obtained by TypoScript
|
||||
*/
|
||||
abstract protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration);
|
||||
|
||||
/**
|
||||
* Returns TypoScript Setup array from current Environment.
|
||||
*
|
||||
* @return array the TypoScript setup
|
||||
*/
|
||||
abstract public function getTypoScriptSetup();
|
||||
|
||||
/**
|
||||
* Returns the TypoScript configuration found in plugin.tx_yourextension_yourplugin / module.tx_yourextension_yourmodule
|
||||
* merged with the global configuration of your extension from plugin.tx_yourextension / module.tx_yourextension
|
||||
*
|
||||
* @param string $extensionName
|
||||
* @param string $pluginName in FE mode this is the specified plugin name, in BE mode this is the full module signature
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getPluginConfiguration($extensionName, $pluginName = null);
|
||||
|
||||
/**
|
||||
* Returns the configured controller/action pairs of the specified plugin/module in the format
|
||||
* array(
|
||||
* 'Controller1' => array('action1', 'action2'),
|
||||
* 'Controller2' => array('action3', 'action4')
|
||||
* )
|
||||
*
|
||||
* @param string $extensionName
|
||||
* @param string $pluginName in FE mode this is the specified plugin name, in BE mode this is the full module signature
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getSwitchableControllerActions($extensionName, $pluginName);
|
||||
|
||||
/**
|
||||
* The implementation of the methods to return a list of storagePid that are below a certain
|
||||
* storage pid.
|
||||
*
|
||||
* @param string $storagePid Storage PID to start at; multiple PIDs possible as comma-separated list
|
||||
* @param int $recursionDepth Maximum number of levels to search, 0 to disable recursive lookup
|
||||
* @return string storage PIDs
|
||||
*/
|
||||
abstract protected function getRecursiveStoragePids($storagePid, $recursionDepth = 0);
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Configuration;
|
||||
|
||||
/*
|
||||
* 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\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
|
||||
use TYPO3\CMS\Core\Database\QueryGenerator;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
||||
use TYPO3\CMS\Core\TypoScript\TemplateService;
|
||||
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\RootlineUtility;
|
||||
use TYPO3\CMS\Extbase\Mvc\Web\BackendRequestHandler;
|
||||
use TYPO3\CMS\Extbase\Mvc\Web\FrontendRequestHandler;
|
||||
|
||||
/**
|
||||
* A general purpose configuration manager used in backend mode.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class BackendConfigurationManager extends AbstractConfigurationManager
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $typoScriptSetupCache = [];
|
||||
|
||||
/**
|
||||
* stores the current page ID
|
||||
* @var int
|
||||
*/
|
||||
protected $currentPageId;
|
||||
|
||||
/**
|
||||
* Returns TypoScript Setup array from current Environment.
|
||||
*
|
||||
* @return array the raw TypoScript setup
|
||||
*/
|
||||
public function getTypoScriptSetup()
|
||||
{
|
||||
$pageId = $this->getCurrentPageId();
|
||||
|
||||
if (!array_key_exists($pageId, $this->typoScriptSetupCache)) {
|
||||
/** @var TemplateService $template */
|
||||
$template = GeneralUtility::makeInstance(TemplateService::class);
|
||||
// do not log time-performance information
|
||||
$template->tt_track = false;
|
||||
// Explicitly trigger processing of extension static files
|
||||
$template->setProcessExtensionStatics(true);
|
||||
// Get the root line
|
||||
$rootline = [];
|
||||
if ($pageId > 0) {
|
||||
try {
|
||||
$rootline = GeneralUtility::makeInstance(RootlineUtility::class, $pageId)->get();
|
||||
} catch (\RuntimeException $e) {
|
||||
$rootline = [];
|
||||
}
|
||||
}
|
||||
// This generates the constants/config + hierarchy info for the template.
|
||||
$template->runThroughTemplates($rootline, 0);
|
||||
$template->generateConfig();
|
||||
$this->typoScriptSetupCache[$pageId] = $template->setup;
|
||||
}
|
||||
return $this->typoScriptSetupCache[$pageId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TypoScript configuration found in module.tx_yourextension_yourmodule
|
||||
* merged with the global configuration of your extension from module.tx_yourextension
|
||||
*
|
||||
* @param string $extensionName
|
||||
* @param string $pluginName in BE mode this is actually the module signature. But we're using it just like the plugin name in FE
|
||||
* @return array
|
||||
*/
|
||||
protected function getPluginConfiguration($extensionName, $pluginName = null)
|
||||
{
|
||||
$setup = $this->getTypoScriptSetup();
|
||||
$pluginConfiguration = [];
|
||||
if (is_array($setup['module.']['tx_' . strtolower($extensionName) . '.'] ?? false)) {
|
||||
$pluginConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['module.']['tx_' . strtolower($extensionName) . '.']);
|
||||
}
|
||||
if ($pluginName !== null) {
|
||||
$pluginSignature = strtolower($extensionName . '_' . $pluginName);
|
||||
if (is_array($setup['module.']['tx_' . $pluginSignature . '.'] ?? false)) {
|
||||
$overruleConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['module.']['tx_' . $pluginSignature . '.']);
|
||||
ArrayUtility::mergeRecursiveWithOverrule($pluginConfiguration, $overruleConfiguration);
|
||||
}
|
||||
}
|
||||
return $pluginConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configured controller/action pairs of the specified module in the format
|
||||
* array(
|
||||
* 'Controller1' => array('action1', 'action2'),
|
||||
* 'Controller2' => array('action3', 'action4')
|
||||
* )
|
||||
*
|
||||
* @param string $extensionName
|
||||
* @param string $pluginName in BE mode this is actually the module signature. But we're using it just like the plugin name in FE
|
||||
* @return array
|
||||
*/
|
||||
protected function getSwitchableControllerActions($extensionName, $pluginName)
|
||||
{
|
||||
$switchableControllerActions = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['modules'][$pluginName]['controllers'] ?? false;
|
||||
if (!is_array($switchableControllerActions)) {
|
||||
$switchableControllerActions = [];
|
||||
}
|
||||
return $switchableControllerActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page uid of the current page.
|
||||
* If no page is selected, we'll return the uid of the first root page.
|
||||
*
|
||||
* @return int current page id. If no page is selected current root page id is returned
|
||||
*/
|
||||
protected function getCurrentPageId()
|
||||
{
|
||||
if ($this->currentPageId !== null) {
|
||||
return $this->currentPageId;
|
||||
}
|
||||
|
||||
$this->currentPageId = $this->getCurrentPageIdFromGetPostData() ?: $this->getCurrentPageIdFromCurrentSiteRoot();
|
||||
$this->currentPageId = $this->currentPageId ?: $this->getCurrentPageIdFromRootTemplate();
|
||||
$this->currentPageId = $this->currentPageId ?: self::DEFAULT_BACKEND_STORAGE_PID;
|
||||
|
||||
return $this->currentPageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current page ID from the GET/POST data.
|
||||
*
|
||||
* @return int the page UID, will be 0 if none has been set
|
||||
*/
|
||||
protected function getCurrentPageIdFromGetPostData()
|
||||
{
|
||||
return (int)GeneralUtility::_GP('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current page ID from the first site root in tree.
|
||||
*
|
||||
* @return int the page UID, will be 0 if none has been set
|
||||
*/
|
||||
protected function getCurrentPageIdFromCurrentSiteRoot()
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('pages');
|
||||
|
||||
$queryBuilder
|
||||
->getRestrictions()
|
||||
->removeAll()
|
||||
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
|
||||
->add(GeneralUtility::makeInstance(HiddenRestriction::class));
|
||||
|
||||
$rootPage = $queryBuilder
|
||||
->select('uid')
|
||||
->from('pages')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('is_siteroot', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT)),
|
||||
$queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
|
||||
)
|
||||
->orderBy('sorting')
|
||||
->execute()
|
||||
->fetch();
|
||||
|
||||
if (empty($rootPage)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int)$rootPage['uid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current page ID from the first created root template.
|
||||
*
|
||||
* @return int the page UID, will be 0 if none has been set
|
||||
*/
|
||||
protected function getCurrentPageIdFromRootTemplate()
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('sys_template');
|
||||
|
||||
$queryBuilder
|
||||
->getRestrictions()
|
||||
->removeAll()
|
||||
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
|
||||
->add(GeneralUtility::makeInstance(HiddenRestriction::class));
|
||||
|
||||
$rootTemplate = $queryBuilder
|
||||
->select('pid')
|
||||
->from('sys_template')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('root', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT))
|
||||
)
|
||||
->orderBy('crdate')
|
||||
->execute()
|
||||
->fetch();
|
||||
|
||||
if (empty($rootTemplate)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int)$rootTemplate['pid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default backend storage pid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultBackendStoragePid()
|
||||
{
|
||||
return $this->getCurrentPageId();
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to set some default request handler if the framework configuration
|
||||
* could not be loaded; to make sure Extbase also works in Backend modules
|
||||
* in all contexts.
|
||||
*
|
||||
* @param array $frameworkConfiguration
|
||||
* @return array
|
||||
*/
|
||||
protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration)
|
||||
{
|
||||
if (!isset($frameworkConfiguration['mvc']['requestHandlers'])) {
|
||||
$frameworkConfiguration['mvc']['requestHandlers'] = [
|
||||
FrontendRequestHandler::class => FrontendRequestHandler::class,
|
||||
BackendRequestHandler::class => BackendRequestHandler::class
|
||||
];
|
||||
}
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comma separated list of storagePid that are below a certain storage pid.
|
||||
*
|
||||
* @param string $storagePid Storage PID to start at; multiple PIDs possible as comma-separated list
|
||||
* @param int $recursionDepth Maximum number of levels to search, 0 to disable recursive lookup
|
||||
* @return string storage PIDs
|
||||
*/
|
||||
protected function getRecursiveStoragePids($storagePid, $recursionDepth = 0)
|
||||
{
|
||||
if ($recursionDepth <= 0) {
|
||||
return $storagePid;
|
||||
}
|
||||
|
||||
$recursiveStoragePids = '';
|
||||
$storagePids = GeneralUtility::intExplode(',', $storagePid);
|
||||
$permsClause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW);
|
||||
$queryGenerator = GeneralUtility::makeInstance(QueryGenerator::class);
|
||||
foreach ($storagePids as $startPid) {
|
||||
$pids = $queryGenerator->getTreeList($startPid, $recursionDepth, 0, $permsClause);
|
||||
if ((string)$pids !== '') {
|
||||
$recursiveStoragePids .= $pids . ',';
|
||||
}
|
||||
}
|
||||
|
||||
return rtrim($recursiveStoragePids, ',');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Configuration;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A configuration manager following the strategy pattern (GoF315). It hides the concrete
|
||||
* implementation of the configuration manager and provides an unified acccess point.
|
||||
*
|
||||
* Use the shutdown() method to drop the concrete implementation.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class ConfigurationManager implements \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Configuration\AbstractConfigurationManager
|
||||
*/
|
||||
protected $concreteConfigurationManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Service\EnvironmentService
|
||||
*/
|
||||
protected $environmentService;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Service\EnvironmentService $environmentService
|
||||
*/
|
||||
public function injectEnvironmentService(\TYPO3\CMS\Extbase\Service\EnvironmentService $environmentService)
|
||||
{
|
||||
$this->environmentService = $environmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the object
|
||||
*/
|
||||
public function initializeObject()
|
||||
{
|
||||
$this->initializeConcreteConfigurationManager();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
protected function initializeConcreteConfigurationManager()
|
||||
{
|
||||
if ($this->environmentService->isEnvironmentInFrontendMode()) {
|
||||
$this->concreteConfigurationManager = $this->objectManager->get(\TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager::class);
|
||||
} else {
|
||||
$this->concreteConfigurationManager = $this->objectManager->get(\TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function setContentObject(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject = null)
|
||||
{
|
||||
$this->concreteConfigurationManager->setContentObject($contentObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
public function getContentObject()
|
||||
{
|
||||
return $this->concreteConfigurationManager->getContentObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified raw configuration coming from the outside.
|
||||
* Note that this is a low level method and only makes sense to be used by Extbase internally.
|
||||
*
|
||||
* @param array $configuration The new configuration
|
||||
*/
|
||||
public function setConfiguration(array $configuration = [])
|
||||
{
|
||||
$this->concreteConfigurationManager->setConfiguration($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified configuration.
|
||||
* The actual configuration will be merged from different sources in a defined order.
|
||||
*
|
||||
* You can get the following types of configuration invoking:
|
||||
* CONFIGURATION_TYPE_SETTINGS: Extbase settings
|
||||
* CONFIGURATION_TYPE_FRAMEWORK: the current module/plugin settings
|
||||
* CONFIGURATION_TYPE_FULL_TYPOSCRIPT: a raw TS array
|
||||
*
|
||||
* Note that this is a low level method and only makes sense to be used by Extbase internally.
|
||||
*
|
||||
* @param string $configurationType The kind of configuration to fetch - must be one of the CONFIGURATION_TYPE_* constants
|
||||
* @param string $extensionName if specified, the configuration for the given extension will be returned.
|
||||
* @param string $pluginName if specified, the configuration for the given plugin will be returned.
|
||||
* @throws Exception\InvalidConfigurationTypeException
|
||||
* @return array The configuration
|
||||
*/
|
||||
public function getConfiguration($configurationType, $extensionName = null, $pluginName = null)
|
||||
{
|
||||
switch ($configurationType) {
|
||||
case self::CONFIGURATION_TYPE_SETTINGS:
|
||||
$configuration = $this->concreteConfigurationManager->getConfiguration($extensionName, $pluginName);
|
||||
return $configuration['settings'] ?? [];
|
||||
case self::CONFIGURATION_TYPE_FRAMEWORK:
|
||||
return $this->concreteConfigurationManager->getConfiguration($extensionName, $pluginName);
|
||||
case self::CONFIGURATION_TYPE_FULL_TYPOSCRIPT:
|
||||
return $this->concreteConfigurationManager->getTypoScriptSetup();
|
||||
default:
|
||||
throw new \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException('Invalid configuration type "' . $configurationType . '"', 1206031879);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if a certain feature, identified by $featureName
|
||||
* should be activated, FALSE for backwards-compatible behavior.
|
||||
*
|
||||
* This is an INTERNAL API used throughout Extbase and Fluid for providing backwards-compatibility.
|
||||
* Do not use it in your custom code!
|
||||
*
|
||||
* @param string $featureName
|
||||
* @return bool
|
||||
*/
|
||||
public function isFeatureEnabled($featureName)
|
||||
{
|
||||
$configuration = $this->getConfiguration(self::CONFIGURATION_TYPE_FRAMEWORK);
|
||||
return (bool)(isset($configuration['features'][$featureName]) && $configuration['features'][$featureName]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Configuration;
|
||||
|
||||
/*
|
||||
* 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 ConfigurationManagerInterface
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
interface ConfigurationManagerInterface extends \TYPO3\CMS\Core\SingletonInterface
|
||||
{
|
||||
const CONFIGURATION_TYPE_FRAMEWORK = 'Framework';
|
||||
const CONFIGURATION_TYPE_SETTINGS = 'Settings';
|
||||
const CONFIGURATION_TYPE_FULL_TYPOSCRIPT = 'FullTypoScript';
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject
|
||||
*/
|
||||
public function setContentObject(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject = null);
|
||||
|
||||
/**
|
||||
* Get the content object
|
||||
*
|
||||
* @return \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
public function getContentObject();
|
||||
|
||||
/**
|
||||
* Returns the specified configuration.
|
||||
* The actual configuration will be merged from different sources in a defined order.
|
||||
*
|
||||
* Note that this is a low level method and only makes sense to be used by Extbase internally.
|
||||
*
|
||||
* @param string $configurationType The kind of configuration to fetch - must be one of the CONFIGURATION_TYPE_* constants
|
||||
* @param string $extensionName if specified, the configuration for the given extension will be returned.
|
||||
* @param string $pluginName if specified, the configuration for the given plugin will be returned.
|
||||
* @return array The configuration
|
||||
*/
|
||||
public function getConfiguration($configurationType, $extensionName = null, $pluginName = null);
|
||||
|
||||
/**
|
||||
* Sets the specified raw configuration coming from the outside.
|
||||
* Note that this is a low level method and only makes sense to be used by Extbase internally.
|
||||
*
|
||||
* @param array $configuration The new configuration
|
||||
*/
|
||||
public function setConfiguration(array $configuration = []);
|
||||
|
||||
/**
|
||||
* Returns TRUE if a certain feature, identified by $featureName
|
||||
* should be activated, FALSE for backwards-compatible behavior.
|
||||
*
|
||||
* This is an INTERNAL API used throughout Extbase and Fluid for providing backwards-compatibility.
|
||||
* Do not use it in your custom code!
|
||||
*
|
||||
* @param string $featureName
|
||||
* @return bool
|
||||
*/
|
||||
public function isFeatureEnabled($featureName);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Configuration;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A generic Configuration Exception
|
||||
*/
|
||||
class Exception extends \TYPO3\CMS\Extbase\Exception
|
||||
{
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Configuration\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An Invalid Configuration Type Exception
|
||||
*/
|
||||
class InvalidConfigurationTypeException extends \TYPO3\CMS\Extbase\Configuration\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Configuration\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Parse Error exception
|
||||
*/
|
||||
class ParseErrorException extends \TYPO3\CMS\Extbase\Configuration\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Configuration;
|
||||
|
||||
/*
|
||||
* 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 TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* A general purpose configuration manager used in frontend mode.
|
||||
*
|
||||
* Should NOT be singleton, as a new configuration manager is needed per plugin.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class FrontendConfigurationManager extends \TYPO3\CMS\Extbase\Configuration\AbstractConfigurationManager
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Service\FlexFormService
|
||||
*/
|
||||
protected $flexFormService;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Core\Service\FlexFormService $flexFormService
|
||||
*/
|
||||
public function injectFlexFormService(\TYPO3\CMS\Core\Service\FlexFormService $flexFormService)
|
||||
{
|
||||
$this->flexFormService = $flexFormService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TypoScript Setup array from current Environment.
|
||||
*
|
||||
* @return array the raw TypoScript setup
|
||||
*/
|
||||
public function getTypoScriptSetup()
|
||||
{
|
||||
return $GLOBALS['TSFE']->tmpl->setup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TypoScript configuration found in plugin.tx_yourextension_yourplugin
|
||||
* merged with the global configuration of your extension from plugin.tx_yourextension
|
||||
*
|
||||
* @param string $extensionName
|
||||
* @param string $pluginName
|
||||
* @return array
|
||||
*/
|
||||
protected function getPluginConfiguration($extensionName, $pluginName = null)
|
||||
{
|
||||
$setup = $this->getTypoScriptSetup();
|
||||
$pluginConfiguration = [];
|
||||
if (isset($setup['plugin.']['tx_' . strtolower($extensionName) . '.']) && is_array($setup['plugin.']['tx_' . strtolower($extensionName) . '.'])) {
|
||||
$pluginConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . strtolower($extensionName) . '.']);
|
||||
}
|
||||
if ($pluginName !== null) {
|
||||
$pluginSignature = strtolower($extensionName . '_' . $pluginName);
|
||||
if (isset($setup['plugin.']['tx_' . $pluginSignature . '.']) && is_array($setup['plugin.']['tx_' . $pluginSignature . '.'])) {
|
||||
ArrayUtility::mergeRecursiveWithOverrule(
|
||||
$pluginConfiguration,
|
||||
$this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . $pluginSignature . '.'])
|
||||
);
|
||||
}
|
||||
}
|
||||
return $pluginConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configured controller/action pairs of the specified plugin in the format
|
||||
* array(
|
||||
* 'Controller1' => array('action1', 'action2'),
|
||||
* 'Controller2' => array('action3', 'action4')
|
||||
* )
|
||||
*
|
||||
* @param string $extensionName
|
||||
* @param string $pluginName
|
||||
* @return array
|
||||
*/
|
||||
protected function getSwitchableControllerActions($extensionName, $pluginName)
|
||||
{
|
||||
$switchableControllerActions = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['controllers'] ?? [];
|
||||
if (!is_array($switchableControllerActions)) {
|
||||
$switchableControllerActions = [];
|
||||
}
|
||||
return $switchableControllerActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get context specific framework configuration.
|
||||
* - Overrides storage PID with setting "Startingpoint"
|
||||
* - merge flexForm configuration, if needed
|
||||
*
|
||||
* @param array $frameworkConfiguration The framework configuration to modify
|
||||
* @return array the modified framework configuration
|
||||
*/
|
||||
protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration)
|
||||
{
|
||||
$frameworkConfiguration = $this->overrideStoragePidIfStartingPointIsSet($frameworkConfiguration);
|
||||
$frameworkConfiguration = $this->overrideConfigurationFromPlugin($frameworkConfiguration);
|
||||
$frameworkConfiguration = $this->overrideConfigurationFromFlexForm($frameworkConfiguration);
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the storage PID settings, in case the "Startingpoint" settings
|
||||
* is set in the plugin configuration.
|
||||
*
|
||||
* @param array $frameworkConfiguration the framework configurations
|
||||
* @return array the framework configuration with overridden storagePid
|
||||
*/
|
||||
protected function overrideStoragePidIfStartingPointIsSet(array $frameworkConfiguration)
|
||||
{
|
||||
$pages = $this->contentObject->data['pages'];
|
||||
if (is_string($pages) && $pages !== '') {
|
||||
$list = [];
|
||||
if ($this->contentObject->data['recursive'] > 0) {
|
||||
$explodedPages = GeneralUtility::trimExplode(',', $pages);
|
||||
foreach ($explodedPages as $pid) {
|
||||
$pids = $this->contentObject->getTreeList($pid, $this->contentObject->data['recursive']);
|
||||
if ($pids !== '') {
|
||||
$list[] = $pids;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($list)) {
|
||||
$pages = $pages . ',' . implode(',', $list);
|
||||
}
|
||||
ArrayUtility::mergeRecursiveWithOverrule($frameworkConfiguration, [
|
||||
'persistence' => [
|
||||
'storagePid' => $pages
|
||||
]
|
||||
]);
|
||||
}
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides configuration settings from the plugin typoscript (plugin.tx_myext_pi1.)
|
||||
*
|
||||
* @param array $frameworkConfiguration the framework configuration
|
||||
* @return array the framework configuration with overridden data from typoscript
|
||||
*/
|
||||
protected function overrideConfigurationFromPlugin(array $frameworkConfiguration)
|
||||
{
|
||||
$setup = $this->getTypoScriptSetup();
|
||||
$pluginSignature = strtolower($frameworkConfiguration['extensionName'] . '_' . $frameworkConfiguration['pluginName']);
|
||||
$pluginConfiguration = $setup['plugin.']['tx_' . $pluginSignature . '.'];
|
||||
if (is_array($pluginConfiguration)) {
|
||||
$pluginConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($pluginConfiguration);
|
||||
$frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'settings');
|
||||
$frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'persistence');
|
||||
$frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'view');
|
||||
}
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides configuration settings from flexForms.
|
||||
* This merges the whole flexForm data, and overrides switchable controller actions.
|
||||
*
|
||||
* @param array $frameworkConfiguration the framework configuration
|
||||
* @return array the framework configuration with overridden data from flexForm
|
||||
*/
|
||||
protected function overrideConfigurationFromFlexForm(array $frameworkConfiguration)
|
||||
{
|
||||
$flexFormConfiguration = $this->contentObject->data['pi_flexform'];
|
||||
if (is_string($flexFormConfiguration)) {
|
||||
if ($flexFormConfiguration !== '') {
|
||||
$flexFormConfiguration = $this->flexFormService->convertFlexFormContentToArray($flexFormConfiguration);
|
||||
} else {
|
||||
$flexFormConfiguration = [];
|
||||
}
|
||||
}
|
||||
if (is_array($flexFormConfiguration) && !empty($flexFormConfiguration)) {
|
||||
$frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'settings');
|
||||
$frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'persistence');
|
||||
$frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'view');
|
||||
$frameworkConfiguration = $this->overrideSwitchableControllerActionsFromFlexForm($frameworkConfiguration, $flexFormConfiguration);
|
||||
}
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a configuration into the framework configuration.
|
||||
*
|
||||
* @param array $frameworkConfiguration the framework configuration to merge the data on
|
||||
* @param array $configuration The configuration
|
||||
* @param string $configurationPartName The name of the configuration part which should be merged.
|
||||
* @return array the processed framework configuration
|
||||
*/
|
||||
protected function mergeConfigurationIntoFrameworkConfiguration(array $frameworkConfiguration, array $configuration, $configurationPartName)
|
||||
{
|
||||
if (isset($configuration[$configurationPartName]) && is_array($configuration[$configurationPartName])) {
|
||||
if (isset($frameworkConfiguration[$configurationPartName]) && is_array($frameworkConfiguration[$configurationPartName])) {
|
||||
ArrayUtility::mergeRecursiveWithOverrule($frameworkConfiguration[$configurationPartName], $configuration[$configurationPartName]);
|
||||
} else {
|
||||
$frameworkConfiguration[$configurationPartName] = $configuration[$configurationPartName];
|
||||
}
|
||||
}
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the switchable controller actions from the flexForm.
|
||||
*
|
||||
* @param array $frameworkConfiguration The original framework configuration
|
||||
* @param array $flexFormConfiguration The full flexForm configuration
|
||||
* @throws Exception\ParseErrorException
|
||||
* @return array the modified framework configuration, if needed
|
||||
*/
|
||||
protected function overrideSwitchableControllerActionsFromFlexForm(array $frameworkConfiguration, array $flexFormConfiguration)
|
||||
{
|
||||
if (!isset($flexFormConfiguration['switchableControllerActions']) || is_array($flexFormConfiguration['switchableControllerActions'])) {
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
// As "," is the flexForm field value delimiter, we need to use ";" as in-field delimiter. That's why we need to replace ; by , first.
|
||||
// The expected format is: "Controller1->action2;Controller2->action3;Controller2->action1"
|
||||
$switchableControllerActionPartsFromFlexForm = GeneralUtility::trimExplode(',', str_replace(';', ',', $flexFormConfiguration['switchableControllerActions']), true);
|
||||
$newSwitchableControllerActionsFromFlexForm = [];
|
||||
foreach ($switchableControllerActionPartsFromFlexForm as $switchableControllerActionPartFromFlexForm) {
|
||||
list($controller, $action) = GeneralUtility::trimExplode('->', $switchableControllerActionPartFromFlexForm);
|
||||
if (empty($controller) || empty($action)) {
|
||||
throw new \TYPO3\CMS\Extbase\Configuration\Exception\ParseErrorException('Controller or action were empty when overriding switchableControllerActions from flexForm.', 1257146403);
|
||||
}
|
||||
$newSwitchableControllerActionsFromFlexForm[$controller][] = $action;
|
||||
}
|
||||
if (!empty($newSwitchableControllerActionsFromFlexForm)) {
|
||||
$this->overrideSwitchableControllerActions($frameworkConfiguration, $newSwitchableControllerActionsFromFlexForm);
|
||||
}
|
||||
return $frameworkConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comma separated list of storagePid that are below a certain storage pid.
|
||||
*
|
||||
* @param string $storagePid Storage PID to start at; multiple PIDs possible as comma-separated list
|
||||
* @param int $recursionDepth Maximum number of levels to search, 0 to disable recursive lookup
|
||||
* @return string storage PIDs
|
||||
*/
|
||||
protected function getRecursiveStoragePids($storagePid, $recursionDepth = 0)
|
||||
{
|
||||
if ($recursionDepth <= 0) {
|
||||
return $storagePid;
|
||||
}
|
||||
|
||||
$recursiveStoragePids = '';
|
||||
$storagePids = GeneralUtility::intExplode(',', $storagePid);
|
||||
foreach ($storagePids as $startPid) {
|
||||
$pids = $this->getContentObject()->getTreeList($startPid, $recursionDepth, 0);
|
||||
if ((string)$pids !== '') {
|
||||
$recursiveStoragePids .= $pids . ',';
|
||||
}
|
||||
}
|
||||
return rtrim($recursiveStoragePids, ',');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Core;
|
||||
|
||||
/*
|
||||
* 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 Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Routing\Route;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Extbase\Mvc\Cli\Response as CliResponse;
|
||||
use TYPO3\CMS\Extbase\Mvc\Web\Response as WebResponse;
|
||||
|
||||
/**
|
||||
* Creates a request an dispatches it to the controller which was specified
|
||||
* by TS Setup, flexForm and returns the content.
|
||||
*
|
||||
* This class is the main entry point for extbase extensions.
|
||||
*/
|
||||
class Bootstrap implements \TYPO3\CMS\Extbase\Core\BootstrapInterface
|
||||
{
|
||||
/**
|
||||
* Back reference to the parent content object
|
||||
* This has to be public as it is set directly from TYPO3
|
||||
*
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
public $cObj;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManager
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
|
||||
*/
|
||||
protected $persistenceManager;
|
||||
|
||||
/**
|
||||
* Explicitly initializes all necessary Extbase objects by invoking the various initialize* methods.
|
||||
*
|
||||
* Usually this method is only called from unit tests or other applications which need a more fine grained control over
|
||||
* the initialization and request handling process. Most other applications just call the run() method.
|
||||
*
|
||||
* @param array $configuration The TS configuration array
|
||||
* @throws \RuntimeException
|
||||
* @see run()
|
||||
*/
|
||||
public function initialize($configuration)
|
||||
{
|
||||
if (!Environment::isCli()) {
|
||||
if (!isset($configuration['vendorName']) || $configuration['vendorName'] === '') {
|
||||
throw new \RuntimeException('Invalid configuration: "vendorName" is not set', 1526629315);
|
||||
}
|
||||
if (!isset($configuration['extensionName']) || $configuration['extensionName'] === '') {
|
||||
throw new \RuntimeException('Invalid configuration: "extensionName" is not set', 1290623020);
|
||||
}
|
||||
if (!isset($configuration['pluginName']) || $configuration['pluginName'] === '') {
|
||||
throw new \RuntimeException('Invalid configuration: "pluginName" is not set', 1290623027);
|
||||
}
|
||||
}
|
||||
$this->initializeObjectManager();
|
||||
$this->initializeConfiguration($configuration);
|
||||
$this->configureObjectManager(true);
|
||||
$this->initializePersistence();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Object framework.
|
||||
*
|
||||
* @see initialize()
|
||||
*/
|
||||
protected function initializeObjectManager()
|
||||
{
|
||||
$this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Object framework.
|
||||
*
|
||||
* @param array $configuration
|
||||
* @see initialize()
|
||||
* @internal
|
||||
*/
|
||||
public function initializeConfiguration($configuration)
|
||||
{
|
||||
$this->configurationManager = $this->objectManager->get(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::class);
|
||||
/** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject */
|
||||
$contentObject = $this->cObj ?? \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class);
|
||||
$this->configurationManager->setContentObject($contentObject);
|
||||
$this->configurationManager->setConfiguration($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the object manager object configuration from
|
||||
* config.tx_extbase.objects and plugin.tx_foo.objects
|
||||
*
|
||||
* @param bool $isInternalCall Set to true by Bootstrap, not by extensions
|
||||
* @see initialize()
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0
|
||||
*/
|
||||
public function configureObjectManager($isInternalCall = false)
|
||||
{
|
||||
if (!$isInternalCall) {
|
||||
trigger_error(self::class . '::configureObjectManager() will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
$frameworkSetup = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
|
||||
if (!isset($frameworkSetup['objects']) || !is_array($frameworkSetup['objects'])) {
|
||||
return;
|
||||
}
|
||||
trigger_error('Overriding object implementations via TypoScript settings config.tx_extbase.objects and plugin.tx_%plugin%.objects will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
|
||||
$objectContainer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\Container\Container::class);
|
||||
foreach ($frameworkSetup['objects'] as $classNameWithDot => $classConfiguration) {
|
||||
if (isset($classConfiguration['className'])) {
|
||||
$originalClassName = rtrim($classNameWithDot, '.');
|
||||
$objectContainer->registerImplementation($originalClassName, $classConfiguration['className']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the persistence framework
|
||||
*
|
||||
* @see initialize()
|
||||
* @internal
|
||||
*/
|
||||
public function initializePersistence()
|
||||
{
|
||||
$this->persistenceManager = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the the Extbase Framework by resolving an appropriate Request Handler and passing control to it.
|
||||
* If the Framework is not initialized yet, it will be initialized.
|
||||
*
|
||||
* @param string $content The content. Not used
|
||||
* @param array $configuration The TS configuration array
|
||||
* @return string $content The processed content
|
||||
*/
|
||||
public function run($content, $configuration)
|
||||
{
|
||||
$this->initialize($configuration);
|
||||
return $this->handleRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\CommandException Is thrown if the response object defined an exit code > 0
|
||||
* @return string
|
||||
*/
|
||||
protected function handleRequest()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Mvc\RequestHandlerResolver $requestHandlerResolver */
|
||||
$requestHandlerResolver = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\RequestHandlerResolver::class);
|
||||
$requestHandler = $requestHandlerResolver->resolveRequestHandler();
|
||||
|
||||
$response = $requestHandler->handleRequest();
|
||||
// If response is NULL after handling the request we need to stop
|
||||
// This happens for instance, when a USER object was converted to a USER_INT
|
||||
// @see TYPO3\CMS\Extbase\Mvc\Web\FrontendRequestHandler::handleRequest()
|
||||
if ($response === null) {
|
||||
$content = '';
|
||||
} else {
|
||||
$content = $response->shutdown();
|
||||
$this->resetSingletons();
|
||||
$this->objectManager->get(\TYPO3\CMS\Extbase\Service\CacheService::class)->clearCachesOfRegisteredPageIds();
|
||||
if ($response instanceof CliResponse && $response->getExitCode()) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\CommandException('The request has been terminated as the response defined an exit code.', $response->getExitCode());
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entrypoint for backend modules, handling PSR-7 requests/responses
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
* @internal
|
||||
*/
|
||||
public function handleBackendRequest(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
// build the configuration from the Server request / route
|
||||
/** @var Route $route */
|
||||
$route = $request->getAttribute('route');
|
||||
$moduleConfiguration = $route->getOption('moduleConfiguration');
|
||||
$configuration = [
|
||||
'extensionName' => $moduleConfiguration['extensionName'],
|
||||
'pluginName' => $route->getOption('moduleName')
|
||||
];
|
||||
if (isset($moduleConfiguration['vendorName'])) {
|
||||
$configuration['vendorName'] = $moduleConfiguration['vendorName'];
|
||||
}
|
||||
|
||||
$this->initialize($configuration);
|
||||
|
||||
/** @var \TYPO3\CMS\Extbase\Mvc\RequestHandlerResolver $requestHandlerResolver */
|
||||
$requestHandlerResolver = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\RequestHandlerResolver::class);
|
||||
$requestHandler = $requestHandlerResolver->resolveRequestHandler();
|
||||
/** @var WebResponse $extbaseResponse */
|
||||
$extbaseResponse = $requestHandler->handleRequest();
|
||||
|
||||
// Convert to PSR-7 response and hand it back to TYPO3 Core
|
||||
$response = $this->convertExtbaseResponseToPsr7Response($extbaseResponse);
|
||||
$this->resetSingletons();
|
||||
$this->objectManager->get(\TYPO3\CMS\Extbase\Service\CacheService::class)->clearCachesOfRegisteredPageIds();
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Extbase response object into a PSR-7 Response
|
||||
*
|
||||
* @param WebResponse $extbaseResponse
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
protected function convertExtbaseResponseToPsr7Response(WebResponse $extbaseResponse): ResponseInterface
|
||||
{
|
||||
$response = new \TYPO3\CMS\Core\Http\Response(
|
||||
'php://temp',
|
||||
$extbaseResponse->getStatusCode(),
|
||||
$extbaseResponse->getUnpreparedHeaders()
|
||||
);
|
||||
$content = $extbaseResponse->getContent();
|
||||
if ($content !== null) {
|
||||
$response->getBody()->write($content);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets global singletons for the next plugin
|
||||
*/
|
||||
protected function resetSingletons()
|
||||
{
|
||||
$this->persistenceManager->persistAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Core;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bootstrap Interface
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
interface BootstrapInterface
|
||||
{
|
||||
/**
|
||||
* Runs the the Extbase Framework by resolving an appropriate Request Handler and passing control to it.
|
||||
* If the Framework is not initialized yet, it will be initialized.
|
||||
*
|
||||
* @param string $content The content. Not used
|
||||
* @param array $configuration The TS configuration array
|
||||
* @return string $content The processed content
|
||||
*/
|
||||
public function run($content, $configuration);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A file object (File Abstraction Layer)
|
||||
*
|
||||
* @internal experimental! This class is experimental and subject to change!
|
||||
*/
|
||||
abstract class AbstractFileCollection extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection $object
|
||||
*/
|
||||
public function setObject(\TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection $object)
|
||||
{
|
||||
$this->object = $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection
|
||||
*/
|
||||
public function getObject()
|
||||
{
|
||||
return $this->object;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A file object (File Abstraction Layer)
|
||||
*
|
||||
* @internal experimental! This class is experimental and subject to change!
|
||||
*/
|
||||
abstract class AbstractFileFolder extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Resource\ResourceInterface
|
||||
*/
|
||||
protected $originalResource;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Core\Resource\ResourceInterface $originalResource
|
||||
*/
|
||||
public function setOriginalResource(\TYPO3\CMS\Core\Resource\ResourceInterface $originalResource)
|
||||
{
|
||||
$this->originalResource = $originalResource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Resource\ResourceInterface
|
||||
*/
|
||||
public function getOriginalResource()
|
||||
{
|
||||
return $this->originalResource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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\Annotation as Extbase;
|
||||
|
||||
/**
|
||||
* This model represents a back-end user.
|
||||
*/
|
||||
class BackendUser extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @Extbase\Validate("NotEmpty")
|
||||
*/
|
||||
protected $userName = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isAdministrator = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isDisabled = false;
|
||||
|
||||
/**
|
||||
* @var \DateTime|null
|
||||
*/
|
||||
protected $startDateAndTime;
|
||||
|
||||
/**
|
||||
* @var \DateTime|null
|
||||
*/
|
||||
protected $endDateAndTime;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $email = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $realName = '';
|
||||
|
||||
/**
|
||||
* @var \DateTime|null
|
||||
*/
|
||||
protected $lastLoginDateAndTime;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $ipLockIsDisabled = false;
|
||||
|
||||
/**
|
||||
* Gets the user name.
|
||||
*
|
||||
* @return string the user name, will not be empty
|
||||
*/
|
||||
public function getUserName()
|
||||
{
|
||||
return $this->userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user name.
|
||||
*
|
||||
* @param string $userName the user name to set, must not be empty
|
||||
*/
|
||||
public function setUserName($userName)
|
||||
{
|
||||
$this->userName = $userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this user is an administrator.
|
||||
*
|
||||
* @return bool whether this user is an administrator
|
||||
*/
|
||||
public function getIsAdministrator()
|
||||
{
|
||||
return $this->isAdministrator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this user should be an administrator.
|
||||
*
|
||||
* @param bool $isAdministrator whether this user should be an administrator
|
||||
*/
|
||||
public function setIsAdministrator($isAdministrator)
|
||||
{
|
||||
$this->isAdministrator = $isAdministrator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this user is disabled.
|
||||
*
|
||||
* @return bool whether this user is disabled
|
||||
*/
|
||||
public function getIsDisabled()
|
||||
{
|
||||
return $this->isDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this user is disabled.
|
||||
*
|
||||
* @param bool $isDisabled whether this user is disabled
|
||||
*/
|
||||
public function setIsDisabled($isDisabled)
|
||||
{
|
||||
$this->isDisabled = $isDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point in time from which this user is enabled.
|
||||
*
|
||||
* @return \DateTime|null the start date and time
|
||||
*/
|
||||
public function getStartDateAndTime()
|
||||
{
|
||||
return $this->startDateAndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the point in time from which this user is enabled.
|
||||
*
|
||||
* @param \DateTime|null $dateAndTime the start date and time
|
||||
*/
|
||||
public function setStartDateAndTime(\DateTime $dateAndTime = null)
|
||||
{
|
||||
$this->startDateAndTime = $dateAndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point in time before which this user is enabled.
|
||||
*
|
||||
* @return \DateTime|null the end date and time
|
||||
*/
|
||||
public function getEndDateAndTime()
|
||||
{
|
||||
return $this->endDateAndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the point in time before which this user is enabled.
|
||||
*
|
||||
* @param \DateTime|null $dateAndTime the end date and time
|
||||
*/
|
||||
public function setEndDateAndTime(\DateTime $dateAndTime = null)
|
||||
{
|
||||
$this->endDateAndTime = $dateAndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the e-mail address of this user.
|
||||
*
|
||||
* @return string the e-mail address, might be empty
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the e-mail address of this user.
|
||||
*
|
||||
* @param string $email the e-mail address, may be empty
|
||||
*/
|
||||
public function setEmail($email)
|
||||
{
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this user's real name.
|
||||
*
|
||||
* @return string the real name. might be empty
|
||||
*/
|
||||
public function getRealName()
|
||||
{
|
||||
return $this->realName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this user's real name.
|
||||
*
|
||||
* @param string $name the user's real name, may be empty.
|
||||
*/
|
||||
public function setRealName($name)
|
||||
{
|
||||
$this->realName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this user is currently activated.
|
||||
*
|
||||
* This function takes the "disabled" flag, the start date/time and the end date/time into account.
|
||||
*
|
||||
* @return bool whether this user is currently activated
|
||||
*/
|
||||
public function isActivated()
|
||||
{
|
||||
return !$this->getIsDisabled() && $this->isActivatedViaStartDateAndTime() && $this->isActivatedViaEndDateAndTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this user is activated as far as the start date and time is concerned.
|
||||
*
|
||||
* @return bool whether this user is activated as far as the start date and time is concerned
|
||||
*/
|
||||
protected function isActivatedViaStartDateAndTime()
|
||||
{
|
||||
if ($this->getStartDateAndTime() === null) {
|
||||
return true;
|
||||
}
|
||||
$now = new \DateTime('now');
|
||||
return $this->getStartDateAndTime() <= $now;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this user is activated as far as the end date and time is concerned.
|
||||
*
|
||||
* @return bool whether this user is activated as far as the end date and time is concerned
|
||||
*/
|
||||
protected function isActivatedViaEndDateAndTime()
|
||||
{
|
||||
if ($this->getEndDateAndTime() === null) {
|
||||
return true;
|
||||
}
|
||||
$now = new \DateTime('now');
|
||||
return $now <= $this->getEndDateAndTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the IP lock for this user is disabled.
|
||||
*
|
||||
* @param bool $disableIpLock whether the IP lock for this user is disabled
|
||||
*/
|
||||
public function setIpLockIsDisabled($disableIpLock)
|
||||
{
|
||||
$this->ipLockIsDisabled = $disableIpLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the IP lock for this user is disabled.
|
||||
*
|
||||
* @return bool whether the IP lock for this user is disabled
|
||||
*/
|
||||
public function getIpLockIsDisabled()
|
||||
{
|
||||
return $this->ipLockIsDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this user's last login date and time.
|
||||
*
|
||||
* @return \DateTime|null this user's last login date and time, will be NULL if this user has never logged in before
|
||||
*/
|
||||
public function getLastLoginDateAndTime()
|
||||
{
|
||||
return $this->lastLoginDateAndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this user's last login date and time.
|
||||
*
|
||||
* @param \DateTime|null $dateAndTime this user's last login date and time
|
||||
*/
|
||||
public function setLastLoginDateAndTime(\DateTime $dateAndTime = null)
|
||||
{
|
||||
$this->lastLoginDateAndTime = $dateAndTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,548 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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\Annotation as Extbase;
|
||||
|
||||
/**
|
||||
* This model represents a backend usergroup.
|
||||
*/
|
||||
class BackendUserGroup extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
const FILE_OPPERATIONS = 1;
|
||||
const DIRECTORY_OPPERATIONS = 4;
|
||||
const DIRECTORY_COPY = 8;
|
||||
const DIRECTORY_REMOVE_RECURSIVELY = 16;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @Extbase\Validate("NotEmpty")
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\BackendUserGroup>
|
||||
*/
|
||||
protected $subGroups;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $modules = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tablesListening = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tablesModify = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $pageTypes = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $allowedExcludeFields = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $explicitlyAllowAndDeny = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $allowedLanguages = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $workspacePermission = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $databaseMounts = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $fileOperationPermissions = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $lockToDomain = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tsConfig = '';
|
||||
|
||||
/**
|
||||
* Constructs this backend usergroup
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->subGroups = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for title
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for description
|
||||
*
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the sub groups
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $subGroups
|
||||
*/
|
||||
public function setSubGroups(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $subGroups)
|
||||
{
|
||||
$this->subGroups = $subGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sub group to this backend user group
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Domain\Model\BackendUserGroup $beGroup
|
||||
*/
|
||||
public function addSubGroup(\TYPO3\CMS\Extbase\Domain\Model\BackendUserGroup $beGroup)
|
||||
{
|
||||
$this->subGroups->attach($beGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes sub group from this backend user group
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Domain\Model\BackendUserGroup $groupToDelete
|
||||
*/
|
||||
public function removeSubGroup(\TYPO3\CMS\Extbase\Domain\Model\BackendUserGroup $groupToDelete)
|
||||
{
|
||||
$this->subGroups->detach($groupToDelete);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all sub groups from this backend user group
|
||||
*/
|
||||
public function removeAllSubGroups()
|
||||
{
|
||||
$subGroups = clone $this->subGroups;
|
||||
$this->subGroups->removeAll($subGroups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of sub groups
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
|
||||
*/
|
||||
public function getSubGroups()
|
||||
{
|
||||
return $this->subGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for modules
|
||||
*
|
||||
* @param string $modules
|
||||
*/
|
||||
public function setModules($modules)
|
||||
{
|
||||
$this->modules = $modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for modules
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getModules()
|
||||
{
|
||||
return $this->modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for tables listening
|
||||
*
|
||||
* @param string $tablesListening
|
||||
*/
|
||||
public function setTablesListening($tablesListening)
|
||||
{
|
||||
$this->tablesListening = $tablesListening;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for tables listening
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTablesListening()
|
||||
{
|
||||
return $this->tablesListening;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for tables modify
|
||||
*
|
||||
* @param string $tablesModify
|
||||
*/
|
||||
public function setTablesModify($tablesModify)
|
||||
{
|
||||
$this->tablesModify = $tablesModify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for tables modify
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTablesModify()
|
||||
{
|
||||
return $this->tablesModify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for page types
|
||||
*
|
||||
* @param string $pageTypes
|
||||
*/
|
||||
public function setPageTypes($pageTypes)
|
||||
{
|
||||
$this->pageTypes = $pageTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for page types
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPageTypes()
|
||||
{
|
||||
return $this->pageTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for allowed exclude fields
|
||||
*
|
||||
* @param string $allowedExcludeFields
|
||||
*/
|
||||
public function setAllowedExcludeFields($allowedExcludeFields)
|
||||
{
|
||||
$this->allowedExcludeFields = $allowedExcludeFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for allowed exclude fields
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAllowedExcludeFields()
|
||||
{
|
||||
return $this->allowedExcludeFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for explicitly allow and deny
|
||||
*
|
||||
* @param string $explicitlyAllowAndDeny
|
||||
*/
|
||||
public function setExplicitlyAllowAndDeny($explicitlyAllowAndDeny)
|
||||
{
|
||||
$this->explicitlyAllowAndDeny = $explicitlyAllowAndDeny;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for explicitly allow and deny
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExplicitlyAllowAndDeny()
|
||||
{
|
||||
return $this->explicitlyAllowAndDeny;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for allowed languages
|
||||
*
|
||||
* @param string $allowedLanguages
|
||||
*/
|
||||
public function setAllowedLanguages($allowedLanguages)
|
||||
{
|
||||
$this->allowedLanguages = $allowedLanguages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for allowed languages
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAllowedLanguages()
|
||||
{
|
||||
return $this->allowedLanguages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for workspace permission
|
||||
*
|
||||
* @param bool $workspacePermission
|
||||
*/
|
||||
public function setWorkspacePermissions($workspacePermission)
|
||||
{
|
||||
$this->workspacePermission = $workspacePermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for workspace permission
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getWorkspacePermission()
|
||||
{
|
||||
return $this->workspacePermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for database mounts
|
||||
*
|
||||
* @param string $databaseMounts
|
||||
*/
|
||||
public function setDatabaseMounts($databaseMounts)
|
||||
{
|
||||
$this->databaseMounts = $databaseMounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for database mounts
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabaseMounts()
|
||||
{
|
||||
return $this->databaseMounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for file operation permissions
|
||||
*
|
||||
* @param int $fileOperationPermissions
|
||||
*/
|
||||
public function setFileOperationPermissions($fileOperationPermissions)
|
||||
{
|
||||
$this->fileOperationPermissions = $fileOperationPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for file operation permissions
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFileOperationPermissions()
|
||||
{
|
||||
return $this->fileOperationPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file operations like upload, copy, move, delete, rename, new and
|
||||
* edit files is allowed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFileOperationAllowed()
|
||||
{
|
||||
return $this->isPermissionSet(self::FILE_OPPERATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the the bit for file operations are allowed.
|
||||
*
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setFileOperationAllowed($value)
|
||||
{
|
||||
$this->setPermission(self::FILE_OPPERATIONS, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if folder operations like move, delete, rename, and new are allowed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDirectoryOperationAllowed()
|
||||
{
|
||||
return $this->isPermissionSet(self::DIRECTORY_OPPERATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the the bit for directory operations are allowed.
|
||||
*
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setDirectoryOperationAllowed($value)
|
||||
{
|
||||
$this->setPermission(self::DIRECTORY_OPPERATIONS, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if it is allowed to copy folders.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDirectoryCopyAllowed()
|
||||
{
|
||||
return $this->isPermissionSet(self::DIRECTORY_COPY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the the bit for copy directories.
|
||||
*
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setDirectoryCopyAllowed($value)
|
||||
{
|
||||
$this->setPermission(self::DIRECTORY_COPY, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if it is allowed to remove folders recursively.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDirectoryRemoveRecursivelyAllowed()
|
||||
{
|
||||
return $this->isPermissionSet(self::DIRECTORY_REMOVE_RECURSIVELY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the the bit for remove directories recursively.
|
||||
*
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setDirectoryRemoveRecursivelyAllowed($value)
|
||||
{
|
||||
$this->setPermission(self::DIRECTORY_REMOVE_RECURSIVELY, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for lock to domain
|
||||
*
|
||||
* @param string $lockToDomain
|
||||
*/
|
||||
public function setLockToDomain($lockToDomain)
|
||||
{
|
||||
$this->lockToDomain = $lockToDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for lock to domain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLockToDomain()
|
||||
{
|
||||
return $this->lockToDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for ts config
|
||||
*
|
||||
* @param string $tsConfig
|
||||
*/
|
||||
public function setTsConfig($tsConfig)
|
||||
{
|
||||
$this->tsConfig = $tsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for ts config
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTsConfig()
|
||||
{
|
||||
return $this->tsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for checking the permissions bitwise.
|
||||
*
|
||||
* @param int $permission
|
||||
* @return bool
|
||||
*/
|
||||
protected function isPermissionSet($permission)
|
||||
{
|
||||
return ($this->fileOperationPermissions & $permission) == $permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for settung permissions bitwise.
|
||||
*
|
||||
* @param int $permission
|
||||
* @param bool $value
|
||||
*/
|
||||
protected function setPermission($permission, $value)
|
||||
{
|
||||
if ($value) {
|
||||
$this->fileOperationPermissions |= $permission;
|
||||
} else {
|
||||
$this->fileOperationPermissions &= ~$permission;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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\Annotation as Extbase;
|
||||
|
||||
/**
|
||||
* This model represents a category (for anything).
|
||||
*/
|
||||
class Category extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @Extbase\Validate("NotEmpty")
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Domain\Model\Category|null
|
||||
* @Extbase\ORM\Lazy
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Gets the title.
|
||||
*
|
||||
* @return string the title, might be empty
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title.
|
||||
*
|
||||
* @param string $title the title to set, may be empty
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the description.
|
||||
*
|
||||
* @return string the description, might be empty
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description.
|
||||
*
|
||||
* @param string $description the description to set, may be empty
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent category.
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Domain\Model\Category|null the parent category
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
if ($this->parent instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
|
||||
$this->parent->_loadRealInstance();
|
||||
}
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parent category.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Domain\Model\Category $parent the parent category
|
||||
*/
|
||||
public function setParent(\TYPO3\CMS\Extbase\Domain\Model\Category $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A file object (File Abstraction Layer)
|
||||
*
|
||||
* @internal experimental! This class is experimental and subject to change!
|
||||
*/
|
||||
class File extends \TYPO3\CMS\Extbase\Domain\Model\AbstractFileFolder
|
||||
{
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Resource\File
|
||||
*/
|
||||
public function getOriginalResource()
|
||||
{
|
||||
if ($this->originalResource === null) {
|
||||
$this->originalResource = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileObject($this->getUid());
|
||||
}
|
||||
|
||||
return $this->originalResource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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\Annotation as Extbase;
|
||||
|
||||
/**
|
||||
* This model represents a file mount.
|
||||
*/
|
||||
class FileMount extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
/**
|
||||
* Title of the file mount.
|
||||
*
|
||||
* @var string
|
||||
* @Extbase\Validate("NotEmpty")
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* Description of the file mount.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* Path of the file mount.
|
||||
*
|
||||
* @var string
|
||||
* @Extbase\Validate("NotEmpty")
|
||||
*/
|
||||
protected $path = '';
|
||||
|
||||
/**
|
||||
* Determines whether the value of the path field is to be recognized as an absolute
|
||||
* path on the server or a path relative to the fileadmin/ subfolder to the website.
|
||||
*
|
||||
* If the value is true the path is an absolute one, otherwise the path is relative
|
||||
* the fileadmin.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isAbsolutePath = false;
|
||||
|
||||
/**
|
||||
* Determines whether this file mount should be read only.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $readOnly = false;
|
||||
|
||||
/**
|
||||
* Getter for the title of the file mount.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the title of the file mount.
|
||||
*
|
||||
* @param string $value
|
||||
*/
|
||||
public function setTitle($value)
|
||||
{
|
||||
$this->title = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the description of the file mount.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the description of the file mount.
|
||||
*
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the path of the file mount.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the path of the file mount.
|
||||
*
|
||||
* @param string $value
|
||||
*/
|
||||
public function setPath($value)
|
||||
{
|
||||
$this->path = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the is absolute path of the file mount.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsAbsolutePath()
|
||||
{
|
||||
return $this->isAbsolutePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for is absolute path of the file mount.
|
||||
*
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setIsAbsolutePath($value)
|
||||
{
|
||||
$this->isAbsolutePath = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the readOnly property of the file mount.
|
||||
*
|
||||
* @param bool $readOnly
|
||||
*/
|
||||
public function setReadOnly($readOnly)
|
||||
{
|
||||
$this->readOnly = $readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the readOnly property of the file mount.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadOnly()
|
||||
{
|
||||
return $this->readOnly;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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\Configuration\ConfigurationManagerInterface;
|
||||
|
||||
/**
|
||||
* A file reference object (File Abstraction Layer)
|
||||
*
|
||||
* @internal experimental! This class is experimental and subject to change!
|
||||
*/
|
||||
class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\AbstractFileFolder
|
||||
{
|
||||
/**
|
||||
* Uid of the referenced sys_file. Needed for extbase to serialize the
|
||||
* reference correctly.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $uidLocal;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Core\Resource\ResourceInterface $originalResource
|
||||
*/
|
||||
public function setOriginalResource(\TYPO3\CMS\Core\Resource\ResourceInterface $originalResource)
|
||||
{
|
||||
$this->originalResource = $originalResource;
|
||||
$this->uidLocal = (int)$originalResource->getOriginalFile()->getUid();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Resource\FileReference
|
||||
*/
|
||||
public function getOriginalResource()
|
||||
{
|
||||
if ($this->originalResource === null) {
|
||||
$uid = $this->getUid();
|
||||
if ($this->configurationManager->isFeatureEnabled('consistentTranslationOverlayHandling')) {
|
||||
$uid = $this->_localizedUid;
|
||||
}
|
||||
$this->originalResource = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileReferenceObject($uid);
|
||||
}
|
||||
|
||||
return $this->originalResource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A folder object (File Abstraction Layer)
|
||||
*
|
||||
* @internal experimental! This class is experimental and subject to change!
|
||||
*/
|
||||
class Folder extends \TYPO3\CMS\Extbase\Domain\Model\AbstractFileFolder
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A file collection object (File Abstraction Layer)
|
||||
*
|
||||
* @internal experimental! This class is experimental and subject to change!
|
||||
*/
|
||||
class FolderBasedFileCollection extends \TYPO3\CMS\Extbase\Domain\Model\AbstractFileCollection
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,557 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Frontend User
|
||||
*/
|
||||
class FrontendUser extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $username = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $password = '';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup>
|
||||
*/
|
||||
protected $usergroup;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $firstName = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $middleName = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $lastName = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $address = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $telephone = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fax = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $email = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $lockToDomain = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $zip = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $city = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $country = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $www = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $company = '';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
/**
|
||||
* @var \DateTime|null
|
||||
*/
|
||||
protected $lastlogin;
|
||||
|
||||
/**
|
||||
* Constructs a new Front-End User
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
*/
|
||||
public function __construct($username = '', $password = '')
|
||||
{
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->usergroup = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
|
||||
$this->image = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username value
|
||||
*
|
||||
* @param string $username
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password value
|
||||
*
|
||||
* @param string $password
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the usergroups. Keep in mind that the property is called "usergroup"
|
||||
* although it can hold several usergroups.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $usergroup
|
||||
*/
|
||||
public function setUsergroup(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $usergroup)
|
||||
{
|
||||
$this->usergroup = $usergroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a usergroup to the frontend user
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup $usergroup
|
||||
*/
|
||||
public function addUsergroup(\TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup $usergroup)
|
||||
{
|
||||
$this->usergroup->attach($usergroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a usergroup from the frontend user
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup $usergroup
|
||||
*/
|
||||
public function removeUsergroup(\TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup $usergroup)
|
||||
{
|
||||
$this->usergroup->detach($usergroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the usergroups. Keep in mind that the property is called "usergroup"
|
||||
* although it can hold several usergroups.
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage An object storage containing the usergroup
|
||||
*/
|
||||
public function getUsergroup()
|
||||
{
|
||||
return $this->usergroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name value
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the firstName value
|
||||
*
|
||||
* @param string $firstName
|
||||
*/
|
||||
public function setFirstName($firstName)
|
||||
{
|
||||
$this->firstName = $firstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the firstName value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstName()
|
||||
{
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the middleName value
|
||||
*
|
||||
* @param string $middleName
|
||||
*/
|
||||
public function setMiddleName($middleName)
|
||||
{
|
||||
$this->middleName = $middleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the middleName value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMiddleName()
|
||||
{
|
||||
return $this->middleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lastName value
|
||||
*
|
||||
* @param string $lastName
|
||||
*/
|
||||
public function setLastName($lastName)
|
||||
{
|
||||
$this->lastName = $lastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lastName value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLastName()
|
||||
{
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the address value
|
||||
*
|
||||
* @param string $address
|
||||
*/
|
||||
public function setAddress($address)
|
||||
{
|
||||
$this->address = $address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAddress()
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the telephone value
|
||||
*
|
||||
* @param string $telephone
|
||||
*/
|
||||
public function setTelephone($telephone)
|
||||
{
|
||||
$this->telephone = $telephone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the telephone value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTelephone()
|
||||
{
|
||||
return $this->telephone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fax value
|
||||
*
|
||||
* @param string $fax
|
||||
*/
|
||||
public function setFax($fax)
|
||||
{
|
||||
$this->fax = $fax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fax value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFax()
|
||||
{
|
||||
return $this->fax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the email value
|
||||
*
|
||||
* @param string $email
|
||||
*/
|
||||
public function setEmail($email)
|
||||
{
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the email value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lockToDomain value
|
||||
*
|
||||
* @param string $lockToDomain
|
||||
*/
|
||||
public function setLockToDomain($lockToDomain)
|
||||
{
|
||||
$this->lockToDomain = $lockToDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lockToDomain value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLockToDomain()
|
||||
{
|
||||
return $this->lockToDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title value
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the zip value
|
||||
*
|
||||
* @param string $zip
|
||||
*/
|
||||
public function setZip($zip)
|
||||
{
|
||||
$this->zip = $zip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the zip value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getZip()
|
||||
{
|
||||
return $this->zip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the city value
|
||||
*
|
||||
* @param string $city
|
||||
*/
|
||||
public function setCity($city)
|
||||
{
|
||||
$this->city = $city;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the city value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCity()
|
||||
{
|
||||
return $this->city;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the country value
|
||||
*
|
||||
* @param string $country
|
||||
*/
|
||||
public function setCountry($country)
|
||||
{
|
||||
$this->country = $country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the country value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCountry()
|
||||
{
|
||||
return $this->country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the www value
|
||||
*
|
||||
* @param string $www
|
||||
*/
|
||||
public function setWww($www)
|
||||
{
|
||||
$this->www = $www;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the www value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getWww()
|
||||
{
|
||||
return $this->www;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the company value
|
||||
*
|
||||
* @param string $company
|
||||
*/
|
||||
public function setCompany($company)
|
||||
{
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the company value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCompany()
|
||||
{
|
||||
return $this->company;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the image value
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $image
|
||||
*/
|
||||
public function setImage(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $image)
|
||||
{
|
||||
$this->image = $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image value
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
|
||||
*/
|
||||
public function getImage()
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lastlogin value
|
||||
*
|
||||
* @param \DateTime $lastlogin
|
||||
*/
|
||||
public function setLastlogin(\DateTime $lastlogin)
|
||||
{
|
||||
$this->lastlogin = $lastlogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lastlogin value
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getLastlogin()
|
||||
{
|
||||
return $this->lastlogin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Frontend User Group
|
||||
*/
|
||||
class FrontendUserGroup extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $lockToDomain = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup>
|
||||
*/
|
||||
protected $subgroup;
|
||||
|
||||
/**
|
||||
* Constructs a new Frontend User Group
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function __construct($title = '')
|
||||
{
|
||||
$this->setTitle($title);
|
||||
$this->subgroup = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title value
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lockToDomain value
|
||||
*
|
||||
* @param string $lockToDomain
|
||||
*/
|
||||
public function setLockToDomain($lockToDomain)
|
||||
{
|
||||
$this->lockToDomain = $lockToDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lockToDomain value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLockToDomain()
|
||||
{
|
||||
return $this->lockToDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description value
|
||||
*
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subgroups. Keep in mind that the property is called "subgroup"
|
||||
* although it can hold several subgroups.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $subgroup An object storage containing the subgroups to add
|
||||
*/
|
||||
public function setSubgroup(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $subgroup)
|
||||
{
|
||||
$this->subgroup = $subgroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subgroup to the frontend user
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup $subgroup
|
||||
*/
|
||||
public function addSubgroup(\TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup $subgroup)
|
||||
{
|
||||
$this->subgroup->attach($subgroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a subgroup from the frontend user group
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup $subgroup
|
||||
*/
|
||||
public function removeSubgroup(\TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup $subgroup)
|
||||
{
|
||||
$this->subgroup->detach($subgroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subgroups. Keep in mind that the property is called "subgroup"
|
||||
* although it can hold several subgroups.
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage An object storage containing the subgroups
|
||||
*/
|
||||
public function getSubgroup()
|
||||
{
|
||||
return $this->subgroup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Model;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A file collection object (File Abstraction Layer)
|
||||
*
|
||||
* @internal experimental! This class is experimental and subject to change!
|
||||
*/
|
||||
class StaticFileCollection extends \TYPO3\CMS\Extbase\Domain\Model\AbstractFileCollection
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Repository;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Repository for \TYPO3\CMS\Extbase\Domain\Model\BackendUserGroup.
|
||||
*/
|
||||
class BackendUserGroupRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
|
||||
{
|
||||
/**
|
||||
* Initializes the repository.
|
||||
*/
|
||||
public function initializeObject()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings $querySettings */
|
||||
$querySettings = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class);
|
||||
$querySettings->setRespectStoragePage(false);
|
||||
$this->setDefaultQuerySettings($querySettings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Repository;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Repository for \TYPO3\CMS\Extbase\Domain\Model\BackendUser.
|
||||
*/
|
||||
class BackendUserRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
|
||||
{
|
||||
/**
|
||||
* Initializes the repository.
|
||||
*/
|
||||
public function initializeObject()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings $querySettings */
|
||||
$querySettings = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class);
|
||||
$querySettings->setRespectStoragePage(false);
|
||||
$this->setDefaultQuerySettings($querySettings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Repository;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Repository for Category models.
|
||||
*/
|
||||
class CategoryRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
|
||||
{
|
||||
/**
|
||||
* Initializes the repository.
|
||||
*/
|
||||
public function initializeObject()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings $querySettings */
|
||||
$querySettings = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class);
|
||||
$querySettings->setRespectStoragePage(false);
|
||||
$this->setDefaultQuerySettings($querySettings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Repository;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Repository for \TYPO3\CMS\Extbase\Domain\Model\FileMount.
|
||||
*/
|
||||
class FileMountRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
|
||||
{
|
||||
/**
|
||||
* Initializes the repository.
|
||||
*/
|
||||
public function initializeObject()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings $querySettings */
|
||||
$querySettings = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class);
|
||||
$querySettings->setRespectStoragePage(false);
|
||||
$this->setDefaultQuerySettings($querySettings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Repository;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Frontend User Group Repository
|
||||
*/
|
||||
class FrontendUserGroupRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Domain\Repository;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Frontend User repository
|
||||
*/
|
||||
class FrontendUserRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\DomainObject;
|
||||
|
||||
/*
|
||||
* 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\Generic\LazyLoadingProxy;
|
||||
|
||||
/**
|
||||
* A generic Domain Object.
|
||||
*
|
||||
* All Model domain objects need to inherit from either AbstractEntity or AbstractValueObject, as this provides important framework information.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
abstract class AbstractDomainObject implements DomainObjectInterface, \TYPO3\CMS\Extbase\Persistence\ObjectMonitoringInterface
|
||||
{
|
||||
/**
|
||||
* @var int The uid of the record. The uid is only unique in the context of the database table.
|
||||
*/
|
||||
protected $uid;
|
||||
|
||||
/**
|
||||
* @var int The uid of the localized record. Holds the uid of the record in default language (the translationOrigin).
|
||||
*/
|
||||
protected $_localizedUid;
|
||||
|
||||
/**
|
||||
* @var int The uid of the language of the object. This is the uid of the language record in the table sys_language.
|
||||
*/
|
||||
protected $_languageUid;
|
||||
|
||||
/**
|
||||
* @var int The uid of the versioned record.
|
||||
*/
|
||||
protected $_versionedUid;
|
||||
|
||||
/**
|
||||
* @var int The id of the page the record is "stored".
|
||||
*/
|
||||
protected $pid;
|
||||
|
||||
/**
|
||||
* TRUE if the object is a clone
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $_isClone = false;
|
||||
|
||||
/**
|
||||
* @var array An array holding the clean property values. Set right after reconstitution of the object
|
||||
*/
|
||||
private $_cleanProperties = [];
|
||||
|
||||
/**
|
||||
* Getter for uid.
|
||||
*
|
||||
* @return int the uid or NULL if none set yet.
|
||||
*/
|
||||
public function getUid()
|
||||
{
|
||||
if ($this->uid !== null) {
|
||||
return (int)$this->uid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the pid.
|
||||
*
|
||||
* @param int|null $pid
|
||||
*/
|
||||
public function setPid($pid)
|
||||
{
|
||||
if ($pid === null) {
|
||||
$this->pid = null;
|
||||
} else {
|
||||
$this->pid = (int)$pid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the pid.
|
||||
*
|
||||
* @return int The pid or NULL if none set yet.
|
||||
*/
|
||||
public function getPid()
|
||||
{
|
||||
if ($this->pid === null) {
|
||||
return null;
|
||||
}
|
||||
return (int)$this->pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitutes a property. Only for internal use.
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @param mixed $propertyValue
|
||||
* @return bool
|
||||
*/
|
||||
public function _setProperty($propertyName, $propertyValue)
|
||||
{
|
||||
if ($this->_hasProperty($propertyName)) {
|
||||
$this->{$propertyName} = $propertyValue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property value of the given property name. Only for internal use.
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @return mixed The propertyValue
|
||||
*/
|
||||
public function _getProperty($propertyName)
|
||||
{
|
||||
return $this->{$propertyName};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash map of property names and property values. Only for internal use.
|
||||
*
|
||||
* @return array The properties
|
||||
*/
|
||||
public function _getProperties()
|
||||
{
|
||||
$properties = get_object_vars($this);
|
||||
foreach ($properties as $propertyName => $propertyValue) {
|
||||
if ($propertyName[0] === '_') {
|
||||
unset($properties[$propertyName]);
|
||||
}
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property value of the given property name. Only for internal use.
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @return bool TRUE bool true if the property exists, FALSE if it doesn't exist or NULL in case of an error.
|
||||
*/
|
||||
public function _hasProperty($propertyName)
|
||||
{
|
||||
return property_exists($this, $propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the object is new (the uid was not set, yet). Only for internal use
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function _isNew()
|
||||
{
|
||||
return $this->uid === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an object's clean state, e.g. after it has been reconstituted
|
||||
* from the database.
|
||||
*
|
||||
* @param string $propertyName The name of the property to be memorized. If omitted all persistable properties are memorized.
|
||||
*/
|
||||
public function _memorizeCleanState($propertyName = null)
|
||||
{
|
||||
if ($propertyName !== null) {
|
||||
$this->_memorizePropertyCleanState($propertyName);
|
||||
} else {
|
||||
$this->_cleanProperties = [];
|
||||
$properties = get_object_vars($this);
|
||||
foreach ($properties as $propertyName => $propertyValue) {
|
||||
if ($propertyName[0] === '_') {
|
||||
continue;
|
||||
}
|
||||
// Do not memorize "internal" properties
|
||||
$this->_memorizePropertyCleanState($propertyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an properties's clean state, e.g. after it has been reconstituted
|
||||
* from the database.
|
||||
*
|
||||
* @param string $propertyName The name of the property to be memorized. If omittet all persistable properties are memorized.
|
||||
*/
|
||||
public function _memorizePropertyCleanState($propertyName)
|
||||
{
|
||||
$propertyValue = $this->{$propertyName};
|
||||
if (is_object($propertyValue)) {
|
||||
$this->_cleanProperties[$propertyName] = clone $propertyValue;
|
||||
// We need to make sure the clone and the original object
|
||||
// are identical when compared with == (see _isDirty()).
|
||||
// After the cloning, the Domain Object will have the property
|
||||
// "isClone" set to TRUE, so we manually have to set it to FALSE
|
||||
// again. Possible fix: Somehow get rid of the "isClone" property,
|
||||
// which is currently needed in Fluid.
|
||||
if ($propertyValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
|
||||
$this->_cleanProperties[$propertyName]->_setClone(false);
|
||||
}
|
||||
} else {
|
||||
$this->_cleanProperties[$propertyName] = $propertyValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash map of clean properties and $values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getCleanProperties()
|
||||
{
|
||||
return $this->_cleanProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the clean value of the given property. The returned value will be NULL if the clean state was not memorized before, or
|
||||
* if the clean value is NULL.
|
||||
*
|
||||
* @param string $propertyName The name of the property to be memorized.
|
||||
* @return mixed The clean property value or NULL
|
||||
*/
|
||||
public function _getCleanProperty($propertyName)
|
||||
{
|
||||
return $this->_cleanProperties[$propertyName] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the properties were modified after reconstitution
|
||||
*
|
||||
* @param string $propertyName An optional name of a property to be checked if its value is dirty
|
||||
* @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\TooDirtyException
|
||||
* @return bool
|
||||
*/
|
||||
public function _isDirty($propertyName = null)
|
||||
{
|
||||
if ($this->uid !== null && $this->_getCleanProperty('uid') !== null && $this->uid != $this->_getCleanProperty('uid')) {
|
||||
throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\TooDirtyException('The uid "' . $this->uid . '" has been modified, that is simply too much.', 1222871239);
|
||||
}
|
||||
|
||||
if ($propertyName === null) {
|
||||
foreach ($this->_getCleanProperties() as $propertyName => $cleanPropertyValue) {
|
||||
if ($this->isPropertyDirty($cleanPropertyValue, $this->{$propertyName}) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($this->isPropertyDirty($this->_getCleanProperty($propertyName), $this->{$propertyName}) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the $value against the $cleanState.
|
||||
*
|
||||
* @param mixed $previousValue
|
||||
* @param mixed $currentValue
|
||||
* @return bool
|
||||
*/
|
||||
protected function isPropertyDirty($previousValue, $currentValue)
|
||||
{
|
||||
// In case it is an object and it implements the ObjectMonitoringInterface, we call _isDirty() instead of a simple comparison of objects.
|
||||
// We do this, because if the object itself contains a lazy loaded property, the comparison of the objects might fail even if the object didn't change
|
||||
if (is_object($currentValue)) {
|
||||
$currentTypeString = null;
|
||||
if ($currentValue instanceof LazyLoadingProxy) {
|
||||
$currentTypeString = $currentValue->_getTypeAndUidString();
|
||||
} elseif ($currentValue instanceof DomainObjectInterface) {
|
||||
$currentTypeString = get_class($currentValue) . ':' . $currentValue->getUid();
|
||||
}
|
||||
|
||||
if ($currentTypeString !== null) {
|
||||
$previousTypeString = null;
|
||||
if ($previousValue instanceof LazyLoadingProxy) {
|
||||
$previousTypeString = $previousValue->_getTypeAndUidString();
|
||||
} elseif ($previousValue instanceof DomainObjectInterface) {
|
||||
$previousTypeString = get_class($previousValue) . ':' . $previousValue->getUid();
|
||||
}
|
||||
|
||||
$result = $currentTypeString !== $previousTypeString;
|
||||
} elseif ($currentValue instanceof \TYPO3\CMS\Extbase\Persistence\ObjectMonitoringInterface) {
|
||||
$result = !is_object($previousValue) || $currentValue->_isDirty() || get_class($previousValue) !== get_class($currentValue);
|
||||
} else {
|
||||
// For all other objects we do only a simple comparison (!=) as we want cloned objects to return the same values.
|
||||
$result = $previousValue != $currentValue;
|
||||
}
|
||||
} else {
|
||||
$result = $previousValue !== $currentValue;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the object has been clonesd, cloned, FALSE otherwise.
|
||||
*
|
||||
* @return bool TRUE if the object has been cloned
|
||||
*/
|
||||
public function _isClone()
|
||||
{
|
||||
return $this->_isClone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter whether this Domain Object is a clone of another one.
|
||||
* NEVER SET THIS PROPERTY DIRECTLY. We currently need it to make the
|
||||
* _isDirty check inside AbstractEntity work, but it is just a work-
|
||||
* around right now.
|
||||
*
|
||||
* @param bool $clone
|
||||
*/
|
||||
public function _setClone($clone)
|
||||
{
|
||||
$this->_isClone = (bool)$clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone method. Sets the _isClone property.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->_isClone = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name and the uid of the object as string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return static::class . ':' . (string)$this->uid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\DomainObject;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract Entity. An Entity is an object fundamentally defined not by its attributes,
|
||||
* but by a thread of continuity and identity (e.g. a person).
|
||||
*/
|
||||
abstract class AbstractEntity extends \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\DomainObject;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract Value Object. A Value Object is an object that describes some characteristic
|
||||
* or attribute (e.g. a color) but carries no concept of identity.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
abstract class AbstractValueObject extends \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject
|
||||
{
|
||||
/**
|
||||
* Returns the value of the Value Object. Must be overwritten by a concrete value object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->__toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\DomainObject;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Domain Object Interface. All domain objects which should be persisted need to implement the below interface.
|
||||
* Usually you will need to subclass \TYPO3\CMS\Extbase\DomainObject\AbstractEntity and \TYPO3\CMS\Extbase\DomainObject\AbstractValueObject
|
||||
* instead.
|
||||
*
|
||||
* @see \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
* @see \TYPO3\CMS\Extbase\DomainObject\AbstractValueObject
|
||||
*/
|
||||
interface DomainObjectInterface
|
||||
{
|
||||
/**
|
||||
* Getter for uid.
|
||||
*
|
||||
* @return int The uid or NULL if none set yet.
|
||||
*/
|
||||
public function getUid();
|
||||
|
||||
/**
|
||||
* Setter for the pid.
|
||||
*
|
||||
* @param int $pid
|
||||
*/
|
||||
public function setPid($pid);
|
||||
|
||||
/**
|
||||
* Getter for the pid.
|
||||
*
|
||||
* @return int The pid or NULL if none set yet.
|
||||
*/
|
||||
public function getPid();
|
||||
|
||||
/**
|
||||
* Returns TRUE if the object is new (the uid was not set, yet). Only for internal use
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function _isNew();
|
||||
|
||||
/**
|
||||
* Reconstitutes a property. Only for internal use.
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @param string $value
|
||||
*/
|
||||
public function _setProperty($propertyName, $value);
|
||||
|
||||
/**
|
||||
* Returns the property value of the given property name. Only for internal use.
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @return mixed The propertyValue
|
||||
*/
|
||||
public function _getProperty($propertyName);
|
||||
|
||||
/**
|
||||
* Returns a hash map of property names and property values
|
||||
*
|
||||
* @return array The properties
|
||||
*/
|
||||
public function _getProperties();
|
||||
|
||||
/**
|
||||
* Returns the clean value of the given property. The returned value will be NULL if the clean state was not memorized before, or
|
||||
* if the clean value is NULL.
|
||||
*
|
||||
* @param string $propertyName The name of the property to be memorized.
|
||||
* @return mixed The clean property value or NULL
|
||||
*/
|
||||
public function _getCleanProperty($propertyName);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Error;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An object representation of a generic error. Subclass this to create
|
||||
* more specific errors if necessary.
|
||||
*/
|
||||
class Error extends Message
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $message = 'Unknown error';
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Error;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An object representation of a generic message. Usually, you will use Error, Warning or Notice instead of this one.
|
||||
*/
|
||||
class Message
|
||||
{
|
||||
/**
|
||||
* The default (english) error message
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $message = 'Unknown message';
|
||||
|
||||
/**
|
||||
* The error code
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* The message arguments. Will be replaced in the message body.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* An optional title for the message (used eg. in flashMessages).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* Constructs this error
|
||||
*
|
||||
* @param string $message An english error message which is used if no other error message can be resolved
|
||||
* @param int $code A unique error code
|
||||
* @param array $arguments Array of arguments to be replaced in message
|
||||
* @param string $title optional title for the message
|
||||
*/
|
||||
public function __construct($message, $code, array $arguments = [], $title = '')
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
$this->arguments = $arguments;
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error message
|
||||
*
|
||||
* @return string The error message
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error code
|
||||
*
|
||||
* @return string The error code
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the rendered message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if (!empty($this->arguments)) {
|
||||
return vsprintf($this->message, $this->arguments);
|
||||
}
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this error into a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Error;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An object representation of a generic notice. Subclass this to create
|
||||
* more specific notices if necessary.
|
||||
*/
|
||||
class Notice extends Message
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $message = 'Unknown notice';
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Error;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
/**
|
||||
* Result object for operations dealing with objects, such as the Property Mapper or the Validators.
|
||||
*/
|
||||
class Result
|
||||
{
|
||||
/**
|
||||
* @var Error[]
|
||||
*/
|
||||
protected $errors = [];
|
||||
|
||||
/**
|
||||
* Caches the existence of errors
|
||||
* @var bool
|
||||
*/
|
||||
protected $errorsExist = false;
|
||||
|
||||
/**
|
||||
* @var Warning[]
|
||||
*/
|
||||
protected $warnings = [];
|
||||
|
||||
/**
|
||||
* Caches the existence of warning
|
||||
* @var bool
|
||||
*/
|
||||
protected $warningsExist = false;
|
||||
|
||||
/**
|
||||
* @var Notice[]
|
||||
*/
|
||||
protected $notices = [];
|
||||
|
||||
/**
|
||||
* Caches the existence of notices
|
||||
* @var bool
|
||||
*/
|
||||
protected $noticesExist = false;
|
||||
|
||||
/**
|
||||
* The result objects for the sub properties
|
||||
*
|
||||
* @var Result[]
|
||||
*/
|
||||
protected $propertyResults = [];
|
||||
|
||||
/**
|
||||
* @var Result
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Injects the parent result and propagates the
|
||||
* cached error states upwards
|
||||
*
|
||||
* @param Result $parent
|
||||
*/
|
||||
public function setParent(Result $parent)
|
||||
{
|
||||
if ($this->parent !== $parent) {
|
||||
$this->parent = $parent;
|
||||
if ($this->hasErrors()) {
|
||||
$parent->setErrorsExist();
|
||||
}
|
||||
if ($this->hasWarnings()) {
|
||||
$parent->setWarningsExist();
|
||||
}
|
||||
if ($this->hasNotices()) {
|
||||
$parent->setNoticesExist();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error to the current Result object
|
||||
*
|
||||
* @param Error $error
|
||||
*/
|
||||
public function addError(Error $error)
|
||||
{
|
||||
$this->errors[] = $error;
|
||||
$this->setErrorsExist();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a warning to the current Result object
|
||||
*
|
||||
* @param Warning $warning
|
||||
*/
|
||||
public function addWarning(Warning $warning)
|
||||
{
|
||||
$this->warnings[] = $warning;
|
||||
$this->setWarningsExist();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a notice to the current Result object
|
||||
*
|
||||
* @param Notice $notice
|
||||
*/
|
||||
public function addNotice(Notice $notice)
|
||||
{
|
||||
$this->notices[] = $notice;
|
||||
$this->setNoticesExist();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all errors in the current Result object (non-recursive)
|
||||
*
|
||||
* @return Error[]
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all warnings in the current Result object (non-recursive)
|
||||
*
|
||||
* @return Warning[]
|
||||
*/
|
||||
public function getWarnings()
|
||||
{
|
||||
return $this->warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all notices in the current Result object (non-recursive)
|
||||
*
|
||||
* @return Notice[]
|
||||
*/
|
||||
public function getNotices()
|
||||
{
|
||||
return $this->notices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first error object of the current Result object (non-recursive)
|
||||
*
|
||||
* @return Error
|
||||
*/
|
||||
public function getFirstError()
|
||||
{
|
||||
reset($this->errors);
|
||||
return current($this->errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first warning object of the current Result object (non-recursive)
|
||||
*
|
||||
* @return Warning
|
||||
*/
|
||||
public function getFirstWarning()
|
||||
{
|
||||
reset($this->warnings);
|
||||
return current($this->warnings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first notice object of the curren Result object (non-recursive)
|
||||
*
|
||||
* @return Notice
|
||||
*/
|
||||
public function getFirstNotice()
|
||||
{
|
||||
reset($this->notices);
|
||||
return current($this->notices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Result object for the given property path. This is
|
||||
* a fluent interface, so you will proboably use it like:
|
||||
* $result->forProperty('foo.bar')->getErrors() -- to get all errors
|
||||
* for property "foo.bar"
|
||||
*
|
||||
* @param string $propertyPath
|
||||
* @return Result
|
||||
*/
|
||||
public function forProperty($propertyPath)
|
||||
{
|
||||
if ($propertyPath === '' || $propertyPath === null) {
|
||||
return $this;
|
||||
}
|
||||
if (strpos($propertyPath, '.') !== false) {
|
||||
return $this->recurseThroughResult(explode('.', $propertyPath));
|
||||
}
|
||||
if (!isset($this->propertyResults[$propertyPath])) {
|
||||
$this->propertyResults[$propertyPath] = new self();
|
||||
$this->propertyResults[$propertyPath]->setParent($this);
|
||||
}
|
||||
return $this->propertyResults[$propertyPath];
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only!
|
||||
*
|
||||
* @param array $pathSegments
|
||||
* @return Result
|
||||
*/
|
||||
public function recurseThroughResult(array $pathSegments)
|
||||
{
|
||||
if (empty($pathSegments)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$propertyName = array_shift($pathSegments);
|
||||
|
||||
if (!isset($this->propertyResults[$propertyName])) {
|
||||
$this->propertyResults[$propertyName] = new self();
|
||||
$this->propertyResults[$propertyName]->setParent($this);
|
||||
}
|
||||
|
||||
return $this->propertyResults[$propertyName]->recurseThroughResult($pathSegments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the error cache to TRUE and propagates the information
|
||||
* upwards the Result-Object Tree
|
||||
*/
|
||||
protected function setErrorsExist()
|
||||
{
|
||||
$this->errorsExist = true;
|
||||
if ($this->parent !== null) {
|
||||
$this->parent->setErrorsExist();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the warning cache to TRUE and propagates the information
|
||||
* upwards the Result-Object Tree
|
||||
*/
|
||||
protected function setWarningsExist()
|
||||
{
|
||||
$this->warningsExist = true;
|
||||
if ($this->parent !== null) {
|
||||
$this->parent->setWarningsExist();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the notices cache to TRUE and propagates the information
|
||||
* upwards the Result-Object Tree
|
||||
*/
|
||||
protected function setNoticesExist()
|
||||
{
|
||||
$this->noticesExist = true;
|
||||
if ($this->parent !== null) {
|
||||
$this->parent->setNoticesExist();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the current Result object have Notices, Errors or Warnings? (Recursively)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMessages()
|
||||
{
|
||||
return $this->errorsExist || $this->noticesExist || $this->warningsExist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the result
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->errors = [];
|
||||
$this->notices = [];
|
||||
$this->warnings = [];
|
||||
|
||||
$this->warningsExist = false;
|
||||
$this->noticesExist = false;
|
||||
$this->errorsExist = false;
|
||||
|
||||
$this->propertyResults = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only!
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @param string $checkerMethodName
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasProperty($propertyName, $checkerMethodName)
|
||||
{
|
||||
if (!empty($this->{$propertyName})) {
|
||||
return true;
|
||||
}
|
||||
foreach ($this->propertyResults as $subResult) {
|
||||
if ($subResult->{$checkerMethodName}()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the current Result object have Errors? (Recursively)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasErrors()
|
||||
{
|
||||
return $this->hasProperty('errors', 'hasErrors');
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the current Result object have Warnings? (Recursively)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasWarnings()
|
||||
{
|
||||
return $this->hasProperty('warnings', 'hasWarnings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the current Result object have Notices? (Recursively)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNotices()
|
||||
{
|
||||
return $this->hasProperty('notices', 'hasNotices');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all Error objects recursively. The result is an array,
|
||||
* where the key is the property path where the error occurred, and the
|
||||
* value is a list of all errors (stored as array)
|
||||
*
|
||||
* @return Error[]
|
||||
*/
|
||||
public function getFlattenedErrors()
|
||||
{
|
||||
$result = [];
|
||||
$this->flattenTree('errors', $result, []);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all Warning objects recursively. The result is an array,
|
||||
* where the key is the property path where the warning occurred, and the
|
||||
* value is a list of all warnings (stored as array)
|
||||
*
|
||||
* @return Warning[]
|
||||
*/
|
||||
public function getFlattenedWarnings()
|
||||
{
|
||||
$result = [];
|
||||
$this->flattenTree('warnings', $result, []);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all Notice objects recursively. The result is an array,
|
||||
* where the key is the property path where the notice occurred, and the
|
||||
* value is a list of all notices (stored as array)
|
||||
*
|
||||
* @return Notice[]
|
||||
*/
|
||||
public function getFlattenedNotices()
|
||||
{
|
||||
$result = [];
|
||||
$this->flattenTree('notices', $result, []);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use internally!
|
||||
*
|
||||
* Flatten a tree of Result objects, based on a certain property.
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @param array $result
|
||||
* @param array $level
|
||||
*/
|
||||
public function flattenTree($propertyName, &$result, $level)
|
||||
{
|
||||
if (!empty($this->$propertyName)) {
|
||||
$result[implode('.', $level)] = $this->$propertyName;
|
||||
}
|
||||
foreach ($this->propertyResults as $subPropertyName => $subResult) {
|
||||
$level[] = $subPropertyName;
|
||||
$subResult->flattenTree($propertyName, $result, $level);
|
||||
array_pop($level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the given Result object into this one.
|
||||
*
|
||||
* @param Result $otherResult
|
||||
*/
|
||||
public function merge(Result $otherResult)
|
||||
{
|
||||
if ($otherResult->errorsExist) {
|
||||
$this->mergeProperty($otherResult, 'getErrors', 'addError');
|
||||
}
|
||||
if ($otherResult->warningsExist) {
|
||||
$this->mergeProperty($otherResult, 'getWarnings', 'addWarning');
|
||||
}
|
||||
if ($otherResult->noticesExist) {
|
||||
$this->mergeProperty($otherResult, 'getNotices', 'addNotice');
|
||||
}
|
||||
|
||||
foreach ($otherResult->getSubResults() as $subPropertyName => $subResult) {
|
||||
/** @var Result $subResult */
|
||||
if (array_key_exists($subPropertyName, $this->propertyResults) && $this->propertyResults[$subPropertyName]->hasMessages()) {
|
||||
$this->forProperty($subPropertyName)->merge($subResult);
|
||||
} else {
|
||||
$this->propertyResults[$subPropertyName] = $subResult;
|
||||
$subResult->setParent($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a single property from the other result object.
|
||||
*
|
||||
* @param Result $otherResult
|
||||
* @param string $getterName
|
||||
* @param string $adderName
|
||||
*/
|
||||
protected function mergeProperty(Result $otherResult, $getterName, $adderName)
|
||||
{
|
||||
foreach ($otherResult->$getterName() as $messageInOtherResult) {
|
||||
$this->$adderName($messageInOtherResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all sub Result objects available.
|
||||
*
|
||||
* @return Result[]
|
||||
*/
|
||||
public function getSubResults()
|
||||
{
|
||||
return $this->propertyResults;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Error;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An object representation of a generic warning. Subclass this to create
|
||||
* more specific warnings if necessary.
|
||||
*/
|
||||
class Warning extends Message
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $message = 'Unknown warning';
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase;
|
||||
|
||||
/*
|
||||
* 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\Exception as CoreException;
|
||||
|
||||
/**
|
||||
* A generic Extbase exception
|
||||
*/
|
||||
class Exception extends CoreException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Hook\DataHandler;
|
||||
|
||||
/*
|
||||
* 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\DataHandling\DataHandler;
|
||||
|
||||
/**
|
||||
* @internal this is not part of TYPO3 Core API as it is a concrete hook implementation.
|
||||
*/
|
||||
class CheckFlexFormValue
|
||||
{
|
||||
/**
|
||||
* Check flexform value before merge
|
||||
*
|
||||
* @param DataHandler $dataHander
|
||||
* @param array &$currentValue
|
||||
* @param array &$newValue
|
||||
*/
|
||||
public function checkFlexFormValue_beforeMerge(DataHandler $dataHander, array &$currentValue, array &$newValue)
|
||||
{
|
||||
$currentValue = $this->removeSwitchableControllerActionsRecursive($currentValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove switchable controller actions recursively
|
||||
*
|
||||
* @param array $a
|
||||
* @return array
|
||||
*/
|
||||
protected function removeSwitchableControllerActionsRecursive(array $a)
|
||||
{
|
||||
$r = [];
|
||||
|
||||
foreach ($a as $k => $v) {
|
||||
if ($k === 'switchableControllerActions') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$r[$k] = is_array($v) ? $this->removeSwitchableControllerActionsRecursive($v) : $v;
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Cli;
|
||||
|
||||
/*
|
||||
* 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\Reflection\ClassSchema;
|
||||
|
||||
/**
|
||||
* Represents a Command
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class Command
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controllerClassName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controllerCommandName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $commandIdentifier;
|
||||
|
||||
/**
|
||||
* Name of the extension to which this command belongs
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $extensionName;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
|
||||
*/
|
||||
protected $reflectionService;
|
||||
|
||||
/**
|
||||
* @var ClassSchema
|
||||
*/
|
||||
protected $classSchema;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controllerCommandMethod;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService
|
||||
*/
|
||||
public function injectReflectionService(\TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService)
|
||||
{
|
||||
$this->reflectionService = $reflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $controllerClassName Class name of the controller providing the command
|
||||
* @param string $controllerCommandName Command name, i.e. the method name of the command, without the "Command" suffix
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($controllerClassName, $controllerCommandName)
|
||||
{
|
||||
$this->controllerClassName = $controllerClassName;
|
||||
$this->controllerCommandName = $controllerCommandName;
|
||||
$this->controllerCommandMethod = $this->controllerCommandName . 'Command';
|
||||
$classNameParts = explode('\\', $controllerClassName);
|
||||
if (isset($classNameParts[0]) && $classNameParts[0] === 'TYPO3' && isset($classNameParts[1]) && $classNameParts[1] === 'CMS') {
|
||||
$classNameParts[0] .= '\\' . $classNameParts[1];
|
||||
unset($classNameParts[1]);
|
||||
$classNameParts = array_values($classNameParts);
|
||||
}
|
||||
$numberOfClassNameParts = count($classNameParts);
|
||||
if ($numberOfClassNameParts < 3) {
|
||||
throw new \InvalidArgumentException(
|
||||
'Controller class names must at least consist of three parts: vendor, extension name and path.',
|
||||
1438782187
|
||||
);
|
||||
}
|
||||
if (strpos($classNameParts[$numberOfClassNameParts - 1], 'CommandController') === false) {
|
||||
throw new \InvalidArgumentException(
|
||||
'Invalid controller class name "' . $controllerClassName . '". Class name must end with "CommandController".',
|
||||
1305100019
|
||||
);
|
||||
}
|
||||
|
||||
$this->extensionName = $classNameParts[1];
|
||||
$extensionKey = \TYPO3\CMS\Core\Utility\GeneralUtility::camelCaseToLowerCaseUnderscored($this->extensionName);
|
||||
$this->commandIdentifier = strtolower($extensionKey . ':' . substr($classNameParts[$numberOfClassNameParts - 1], 0, -17) . ':' . $controllerCommandName);
|
||||
}
|
||||
|
||||
public function initializeObject()
|
||||
{
|
||||
$this->classSchema = $this->reflectionService->getClassSchema($this->controllerClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControllerClassName()
|
||||
{
|
||||
return $this->controllerClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControllerCommandName()
|
||||
{
|
||||
return $this->controllerCommandName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command identifier for this command
|
||||
*
|
||||
* @return string The command identifier for this command, following the pattern extensionname:controllername:commandname
|
||||
*/
|
||||
public function getCommandIdentifier()
|
||||
{
|
||||
return $this->commandIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension to which this command belongs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExtensionName()
|
||||
{
|
||||
return $this->extensionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a short description of this command
|
||||
*
|
||||
* @return string A short description
|
||||
*/
|
||||
public function getShortDescription()
|
||||
{
|
||||
$lines = explode(LF, $this->classSchema->getMethod($this->controllerCommandMethod)['description']);
|
||||
return !empty($lines) ? trim($lines[0]) : '<no description available>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a longer description of this command
|
||||
* This is the complete method description except for the first line which can be retrieved via getShortDescription()
|
||||
* If The command description only consists of one line, an empty string is returned
|
||||
*
|
||||
* @return string A longer description of this command
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
$lines = explode(LF, $this->classSchema->getMethod($this->controllerCommandMethod)['description']);
|
||||
array_shift($lines);
|
||||
$descriptionLines = [];
|
||||
foreach ($lines as $line) {
|
||||
$trimmedLine = trim($line);
|
||||
if ($descriptionLines !== [] || $trimmedLine !== '') {
|
||||
$descriptionLines[] = $trimmedLine;
|
||||
}
|
||||
}
|
||||
return implode(LF, $descriptionLines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if this command expects required and/or optional arguments, otherwise FALSE
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasArguments()
|
||||
{
|
||||
return !empty($this->classSchema->getMethod($this->controllerCommandMethod)['params']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of \TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition that contains
|
||||
* information about required/optional arguments of this command.
|
||||
* If the command does not expect any arguments, an empty array is returned
|
||||
*
|
||||
* @return array<\TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition>
|
||||
*/
|
||||
public function getArgumentDefinitions()
|
||||
{
|
||||
if (!$this->hasArguments()) {
|
||||
return [];
|
||||
}
|
||||
$commandArgumentDefinitions = [];
|
||||
$commandParameters = $this->classSchema->getMethod($this->controllerCommandMethod)['params'];
|
||||
$commandParameterTags = $this->classSchema->getMethod($this->controllerCommandMethod)['tags']['param'];
|
||||
$i = 0;
|
||||
foreach ($commandParameters as $commandParameterName => $commandParameterDefinition) {
|
||||
$explodedAnnotation = preg_split('/\s+/', $commandParameterTags[$i], 3);
|
||||
$description = !empty($explodedAnnotation[2]) ? $explodedAnnotation[2] : '';
|
||||
$required = $commandParameterDefinition['optional'] !== true;
|
||||
$commandArgumentDefinitions[] = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition::class, $commandParameterName, $required, $description);
|
||||
$i++;
|
||||
}
|
||||
return $commandArgumentDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if this command is internal and thus should not be exposed through help texts, user documentation etc.
|
||||
* Internall commands are still accessible through the regular command line interface, but should not be used
|
||||
* by users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isInternal()
|
||||
{
|
||||
return isset($this->classSchema->getMethod($this->controllerCommandMethod)['tags']['internal']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if this command is meant to be used on CLI only.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCliOnly()
|
||||
{
|
||||
return isset($this->classSchema->getMethod($this->controllerCommandMethod)['tags']['cli']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if this command flushes all caches and thus needs special attention in the interactive shell.
|
||||
*
|
||||
* Note that neither this method nor the @flushesCaches annotation is currently part of the official API.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
public function isFlushingCaches()
|
||||
{
|
||||
trigger_error(
|
||||
'Method isFlushingCaches() will be removed in TYPO3 v10.0. Do not call from other extension.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
return isset($this->classSchema->getMethod($this->controllerCommandMethod)['tags']['flushesCaches']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of command identifiers which were specified in the "@see"
|
||||
* annotation of a command method.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRelatedCommandIdentifiers()
|
||||
{
|
||||
if (!isset($this->classSchema->getMethod($this->controllerCommandMethod)['tags']['see'])) {
|
||||
return [];
|
||||
}
|
||||
$relatedCommandIdentifiers = [];
|
||||
foreach ($this->classSchema->getMethod($this->controllerCommandMethod)['tags']['see'] as $tagValue) {
|
||||
if (preg_match('/^[\\w\\d\\.]+:[\\w\\d]+:[\\w\\d]+$/', $tagValue) === 1) {
|
||||
$relatedCommandIdentifiers[] = $tagValue;
|
||||
}
|
||||
}
|
||||
return $relatedCommandIdentifiers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Cli;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a CommandArgumentDefinition
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class CommandArgumentDefinition
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $required = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $name name of the command argument (= parameter name)
|
||||
* @param bool $required defines whether this argument is required or optional
|
||||
* @param string $description description of the argument
|
||||
*/
|
||||
public function __construct($name, $required, $description)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->required = $required;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lowercased name with dashes as word separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDashedName()
|
||||
{
|
||||
$dashedName = ucfirst($this->name);
|
||||
$dashedName = preg_replace('/([A-Z][a-z0-9]+)/', '$1-', $dashedName);
|
||||
return '--' . strtolower(substr($dashedName, 0, -1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function isRequired()
|
||||
{
|
||||
return $this->required;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Cli;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A helper for CLI commands
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class CommandManager implements \TYPO3\CMS\Core\SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var array<\TYPO3\CMS\Extbase\Mvc\Cli\Command>
|
||||
*/
|
||||
protected $availableCommands;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $shortCommandIdentifiers;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all commands
|
||||
*
|
||||
* @return Command[]
|
||||
*/
|
||||
public function getAvailableCommands()
|
||||
{
|
||||
if ($this->availableCommands === null) {
|
||||
$this->availableCommands = [];
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'] ?? [] as $className) {
|
||||
if (!class_exists($className)) {
|
||||
continue;
|
||||
}
|
||||
foreach (get_class_methods($className) as $methodName) {
|
||||
if (substr($methodName, -7, 7) === 'Command') {
|
||||
$this->availableCommands[] = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Cli\Command::class, $className, substr($methodName, 0, -7));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->availableCommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Command that matches the given identifier.
|
||||
* If no Command could be found a CommandNotFoundException is thrown
|
||||
* If more than one Command matches an AmbiguousCommandIdentifierException is thrown that contains the matched Commands
|
||||
*
|
||||
* @param string $commandIdentifier command identifier in the format foo:bar:baz
|
||||
* @return Command
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException if no matching command is available
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\AmbiguousCommandIdentifierException if more than one Command matches the identifier (the exception contains the matched commands)
|
||||
*/
|
||||
public function getCommandByIdentifier($commandIdentifier)
|
||||
{
|
||||
$commandIdentifier = strtolower(trim($commandIdentifier));
|
||||
if ($commandIdentifier === 'help') {
|
||||
$commandIdentifier = 'extbase:help:help';
|
||||
}
|
||||
$matchedCommands = [];
|
||||
$availableCommands = $this->getAvailableCommands();
|
||||
foreach ($availableCommands as $command) {
|
||||
if ($this->commandMatchesIdentifier($command, $commandIdentifier)) {
|
||||
$matchedCommands[] = $command;
|
||||
}
|
||||
}
|
||||
if (empty($matchedCommands)) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException('No command could be found that matches the command identifier "' . $commandIdentifier . '".', 1310556663);
|
||||
}
|
||||
if (count($matchedCommands) > 1) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\AmbiguousCommandIdentifierException('More than one command matches the command identifier "' . $commandIdentifier . '"', 1310557169, null, $matchedCommands);
|
||||
}
|
||||
return current($matchedCommands);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shortest, non-ambiguous command identifier for the given command
|
||||
*
|
||||
* @param Command $command The command
|
||||
* @return string The shortest possible command identifier
|
||||
*/
|
||||
public function getShortestIdentifierForCommand(Command $command)
|
||||
{
|
||||
if ($command->getCommandIdentifier() === 'extbase:help:help') {
|
||||
return 'help';
|
||||
}
|
||||
$shortCommandIdentifiers = $this->getShortCommandIdentifiers();
|
||||
if (!isset($shortCommandIdentifiers[$command->getCommandIdentifier()])) {
|
||||
$command->getCommandIdentifier();
|
||||
}
|
||||
return $shortCommandIdentifiers[$command->getCommandIdentifier()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array that contains all available command identifiers and their shortest non-ambiguous alias
|
||||
*
|
||||
* @return array in the format array('full.command:identifier1' => 'alias1', 'full.command:identifier2' => 'alias2')
|
||||
*/
|
||||
protected function getShortCommandIdentifiers()
|
||||
{
|
||||
if ($this->shortCommandIdentifiers === null) {
|
||||
$commandsByCommandName = [];
|
||||
foreach ($this->getAvailableCommands() as $availableCommand) {
|
||||
list($extensionKey, $controllerName, $commandName) = explode(':', $availableCommand->getCommandIdentifier());
|
||||
if (!isset($commandsByCommandName[$commandName])) {
|
||||
$commandsByCommandName[$commandName] = [];
|
||||
}
|
||||
if (!isset($commandsByCommandName[$commandName][$controllerName])) {
|
||||
$commandsByCommandName[$commandName][$controllerName] = [];
|
||||
}
|
||||
$commandsByCommandName[$commandName][$controllerName][] = $extensionKey;
|
||||
}
|
||||
foreach ($this->getAvailableCommands() as $availableCommand) {
|
||||
list($extensionKey, $controllerName, $commandName) = explode(':', $availableCommand->getCommandIdentifier());
|
||||
if (count($commandsByCommandName[$commandName][$controllerName]) > 1) {
|
||||
$this->shortCommandIdentifiers[$availableCommand->getCommandIdentifier()] = sprintf('%s:%s:%s', $extensionKey, $controllerName, $commandName);
|
||||
} else {
|
||||
$this->shortCommandIdentifiers[$availableCommand->getCommandIdentifier()] = sprintf('%s:%s', $controllerName, $commandName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->shortCommandIdentifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the specified command identifier matches the identifier of the specified command.
|
||||
* This is the case, if the identifiers are the same or if at least the last two command parts match (case sensitive).
|
||||
*
|
||||
* @param Command $command
|
||||
* @param string $commandIdentifier command identifier in the format foo:bar:baz (all lower case)
|
||||
* @return bool TRUE if the specified command identifier matches this commands identifier
|
||||
*/
|
||||
protected function commandMatchesIdentifier(Command $command, $commandIdentifier)
|
||||
{
|
||||
$commandIdentifierParts = explode(':', $command->getCommandIdentifier());
|
||||
$searchedCommandIdentifierParts = explode(':', $commandIdentifier);
|
||||
$extensionKey = array_shift($commandIdentifierParts);
|
||||
if (count($searchedCommandIdentifierParts) === 3) {
|
||||
$searchedExtensionKey = array_shift($searchedCommandIdentifierParts);
|
||||
if ($searchedExtensionKey !== $extensionKey) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (count($searchedCommandIdentifierParts) !== 2) {
|
||||
return false;
|
||||
}
|
||||
return $searchedCommandIdentifierParts === $commandIdentifierParts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Cli;
|
||||
|
||||
/*
|
||||
* 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 Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Helper\FormatterHelper;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput as SymfonyConsoleOutput;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
/**
|
||||
* A wrapper for Symfony ConsoleOutput and related helpers
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class ConsoleOutput
|
||||
{
|
||||
/**
|
||||
* @var ArgvInput
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* @var SymfonyConsoleOutput
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* @var QuestionHelper
|
||||
*/
|
||||
protected $questionHelper;
|
||||
|
||||
/**
|
||||
* @var ProgressBar
|
||||
*/
|
||||
protected $progressBar;
|
||||
|
||||
/**
|
||||
* @var Table
|
||||
*/
|
||||
protected $table;
|
||||
|
||||
/**
|
||||
* Creates and initializes the Symfony I/O instances
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->output = new SymfonyConsoleOutput();
|
||||
$this->output->getFormatter()->setStyle('b', new OutputFormatterStyle(null, null, ['bold']));
|
||||
$this->output->getFormatter()->setStyle('i', new OutputFormatterStyle('black', 'white'));
|
||||
$this->output->getFormatter()->setStyle('u', new OutputFormatterStyle(null, null, ['underscore']));
|
||||
$this->output->getFormatter()->setStyle('em', new OutputFormatterStyle(null, null, ['reverse']));
|
||||
$this->output->getFormatter()->setStyle('strike', new OutputFormatterStyle(null, null, ['conceal']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the desired maximum line length for console output.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMaximumLineLength()
|
||||
{
|
||||
return 79;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs specified text to the console window
|
||||
* You can specify arguments that will be passed to the text via sprintf
|
||||
* @see http://www.php.net/sprintf
|
||||
*
|
||||
* @param string $text Text to output
|
||||
* @param array $arguments Optional arguments to use for sprintf
|
||||
*/
|
||||
public function output($text, array $arguments = [])
|
||||
{
|
||||
if ($arguments !== []) {
|
||||
$text = vsprintf($text, $arguments);
|
||||
}
|
||||
$this->output->write($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs specified text to the console window and appends a line break
|
||||
*
|
||||
* @param string $text Text to output
|
||||
* @param array $arguments Optional arguments to use for sprintf
|
||||
* @see output()
|
||||
* @see outputLines()
|
||||
*/
|
||||
public function outputLine($text = '', array $arguments = [])
|
||||
{
|
||||
$this->output($text . PHP_EOL, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given text to fit into the maximum line length and outputs it to the
|
||||
* console window
|
||||
*
|
||||
* @param string $text Text to output
|
||||
* @param array $arguments Optional arguments to use for sprintf
|
||||
* @param int $leftPadding The number of spaces to use for indentation
|
||||
* @see outputLine()
|
||||
*/
|
||||
public function outputFormatted($text = '', array $arguments = [], $leftPadding = 0)
|
||||
{
|
||||
$lines = explode(PHP_EOL, $text);
|
||||
foreach ($lines as $line) {
|
||||
$formattedText = str_repeat(' ', $leftPadding) . wordwrap($line, $this->getMaximumLineLength() - $leftPadding, PHP_EOL . str_repeat(' ', $leftPadding), true);
|
||||
$this->outputLine($formattedText, $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a table like output of the given $rows
|
||||
*
|
||||
* @param array $rows
|
||||
* @param array $headers
|
||||
*/
|
||||
public function outputTable($rows, $headers = null)
|
||||
{
|
||||
$table = $this->getTable();
|
||||
if ($headers !== null) {
|
||||
$table->setHeaders($headers);
|
||||
}
|
||||
$table->setRows($rows);
|
||||
$table->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the user to select a value
|
||||
*
|
||||
* @param string|array $question The question to ask. If an array each array item is turned into one line of a multi-line question
|
||||
* @param array $choices List of choices to pick from
|
||||
* @param bool $default The default answer if the user enters nothing
|
||||
* @param bool $multiSelect If TRUE the result will be an array with the selected options. Multiple options can be given separated by commas
|
||||
* @param int|null $attempts Max number of times to ask before giving up (null by default, which means infinite)
|
||||
* @return int|string|array The selected value or values (the key of the choices array)
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function select($question, $choices, $default = null, $multiSelect = false, $attempts = null)
|
||||
{
|
||||
$question = (new ChoiceQuestion($question, $choices, $default))
|
||||
->setMultiselect($multiSelect)
|
||||
->setMaxAttempts($attempts)
|
||||
->setErrorMessage('Value "%s" is invalid');
|
||||
|
||||
return $this->getQuestionHelper()->ask($this->getInput(), $this->output, $question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks a question to the user
|
||||
*
|
||||
* @param string|array $question The question to ask. If an array each array item is turned into one line of a multi-line question
|
||||
* @param string $default The default answer if none is given by the user
|
||||
* @param array $autocomplete List of values to autocomplete. This only works if "stty" is installed
|
||||
* @return string The user answer
|
||||
* @throws \RuntimeException If there is no data to read in the input stream
|
||||
*/
|
||||
public function ask($question, $default = null, array $autocomplete = null)
|
||||
{
|
||||
$question = (new Question($question, $default))
|
||||
->setAutocompleterValues($autocomplete);
|
||||
|
||||
return $this->getQuestionHelper()->ask($this->getInput(), $this->output, $question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks a confirmation to the user.
|
||||
*
|
||||
* The question will be asked until the user answers by nothing, yes, or no.
|
||||
*
|
||||
* @param string|array $question The question to ask. If an array each array item is turned into one line of a multi-line question
|
||||
* @param bool $default The default answer if the user enters nothing
|
||||
* @return bool true if the user has confirmed, false otherwise
|
||||
*/
|
||||
public function askConfirmation($question, $default = true)
|
||||
{
|
||||
$question = new ConfirmationQuestion($question, $default);
|
||||
|
||||
return $this->getQuestionHelper()->ask($this->getInput(), $this->output, $question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks a question to the user, the response is hidden
|
||||
*
|
||||
* @param string|array $question The question. If an array each array item is turned into one line of a multi-line question
|
||||
* @param bool $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not
|
||||
* @return string The answer
|
||||
* @throws \RuntimeException In case the fallback is deactivated and the response can not be hidden
|
||||
*/
|
||||
public function askHiddenResponse($question, $fallback = true)
|
||||
{
|
||||
$question = (new Question($question))
|
||||
->setHidden(true)
|
||||
->setHiddenFallback($fallback);
|
||||
|
||||
return $this->getQuestionHelper()->ask($this->getInput(), $this->output, $question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks for a value and validates the response
|
||||
*
|
||||
* The validator receives the data to validate. It must return the
|
||||
* validated data when the data is valid and throw an exception
|
||||
* otherwise.
|
||||
*
|
||||
* @param string|array $question The question to ask. If an array each array item is turned into one line of a multi-line question
|
||||
* @param callable $validator A PHP callback that gets a value and is expected to return the (transformed) value or throw an exception if it wasn't valid
|
||||
* @param int|null $attempts Max number of times to ask before giving up (null by default, which means infinite)
|
||||
* @param string $default The default answer if none is given by the user
|
||||
* @param array $autocomplete List of values to autocomplete. This only works if "stty" is installed
|
||||
* @return mixed
|
||||
* @throws \Exception When any of the validators return an error
|
||||
*/
|
||||
public function askAndValidate($question, $validator, $attempts = null, $default = null, array $autocomplete = null)
|
||||
{
|
||||
$question = (new Question($question, $default))
|
||||
->setValidator($validator)
|
||||
->setMaxAttempts($attempts)
|
||||
->setAutocompleterValues($autocomplete);
|
||||
|
||||
return $this->getQuestionHelper()->ask($this->getInput(), $this->output, $question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks for a value, hide and validates the response
|
||||
*
|
||||
* The validator receives the data to validate. It must return the
|
||||
* validated data when the data is valid and throw an exception
|
||||
* otherwise.
|
||||
*
|
||||
* @param string|array $question The question to ask. If an array each array item is turned into one line of a multi-line question
|
||||
* @param callable $validator A PHP callback that gets a value and is expected to return the (transformed) value or throw an exception if it wasn't valid
|
||||
* @param int|bool $attempts Max number of times to ask before giving up (false by default, which means infinite)
|
||||
* @param bool $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not
|
||||
* @return string The response
|
||||
* @throws \Exception When any of the validators return an error
|
||||
* @throws \RuntimeException In case the fallback is deactivated and the response can not be hidden
|
||||
*/
|
||||
public function askHiddenResponseAndValidate($question, $validator, $attempts = false, $fallback = true)
|
||||
{
|
||||
$question = (new Question($question))
|
||||
->setValidator($validator)
|
||||
->setMaxAttempts($attempts)
|
||||
->setHidden(true)
|
||||
->setHiddenFallback($fallback);
|
||||
|
||||
return $this->getQuestionHelper()->ask($this->getInput(), $this->output, $question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the progress output
|
||||
*
|
||||
* @param int $max Maximum steps. If NULL an indeterminate progress bar is rendered
|
||||
*/
|
||||
public function progressStart($max = null)
|
||||
{
|
||||
$this->getProgressBar()->start($max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the progress output X steps
|
||||
*
|
||||
* @param int $step Number of steps to advance
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function progressAdvance($step = 1)
|
||||
{
|
||||
$this->getProgressBar()->advance($step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current progress
|
||||
*
|
||||
* @param int $current The current progress
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function progressSet($current)
|
||||
{
|
||||
$this->getProgressBar()->setProgress($current);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the progress output
|
||||
*/
|
||||
public function progressFinish()
|
||||
{
|
||||
$this->getProgressBar()->finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArgvInput
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getInput()
|
||||
{
|
||||
if ($this->input === null) {
|
||||
if (!isset($_SERVER['argv'])) {
|
||||
throw new \RuntimeException('Cannot initialize ArgvInput object without CLI context.', 1456914444);
|
||||
}
|
||||
$this->input = new ArgvInput();
|
||||
}
|
||||
|
||||
return $this->input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns or initializes the symfony/console QuestionHelper
|
||||
*
|
||||
* @return QuestionHelper
|
||||
*/
|
||||
protected function getQuestionHelper()
|
||||
{
|
||||
if ($this->questionHelper === null) {
|
||||
$this->questionHelper = new QuestionHelper();
|
||||
$helperSet = new HelperSet([new FormatterHelper()]);
|
||||
$this->questionHelper->setHelperSet($helperSet);
|
||||
}
|
||||
return $this->questionHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns or initializes the symfony/console ProgressBar
|
||||
*
|
||||
* @return ProgressBar
|
||||
*/
|
||||
protected function getProgressBar()
|
||||
{
|
||||
if ($this->progressBar === null) {
|
||||
$this->progressBar = new ProgressBar($this->output);
|
||||
}
|
||||
return $this->progressBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns or initializes the symfony/console Table
|
||||
*
|
||||
* @return Table
|
||||
*/
|
||||
protected function getTable()
|
||||
{
|
||||
if ($this->table === null) {
|
||||
$this->table = new Table($this->output);
|
||||
}
|
||||
return $this->table;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Cli;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a CLI request.
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class Request implements \TYPO3\CMS\Extbase\Mvc\RequestInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controllerObjectName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controllerCommandName = 'default';
|
||||
|
||||
/**
|
||||
* @var string Name of the extension which is supposed to handle this request.
|
||||
*/
|
||||
protected $controllerExtensionName;
|
||||
|
||||
/**
|
||||
* The arguments for this request
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $exceedingArguments = [];
|
||||
|
||||
/**
|
||||
* If this request has been changed and needs to be dispatched again
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $dispatched = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $commandLineArguments;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Cli\Command | NULL
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $callingScript;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $callingScript
|
||||
*/
|
||||
public function setCallingScript($callingScript)
|
||||
{
|
||||
$this->callingScript = $callingScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCallingScript()
|
||||
{
|
||||
return $this->callingScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dispatched flag
|
||||
*
|
||||
* @param bool $flag If this request has been dispatched
|
||||
*/
|
||||
public function setDispatched($flag)
|
||||
{
|
||||
$this->dispatched = (bool)$flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this request has been dispatched and addressed by the responsible
|
||||
* controller and the response is ready to be sent.
|
||||
*
|
||||
* The dispatcher will try to dispatch the request again if it has not been
|
||||
* addressed yet.
|
||||
*
|
||||
* @return bool TRUE if this request has been disptached successfully
|
||||
*/
|
||||
public function isDispatched()
|
||||
{
|
||||
return $this->dispatched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the object name of the controller
|
||||
*
|
||||
* @param string $controllerObjectName The fully qualified controller object name
|
||||
*/
|
||||
public function setControllerObjectName($controllerObjectName)
|
||||
{
|
||||
$nameParts = \TYPO3\CMS\Core\Utility\ClassNamingUtility::explodeObjectControllerName($controllerObjectName);
|
||||
|
||||
$this->controllerExtensionName = $nameParts['extensionName'];
|
||||
$this->controllerObjectName = $controllerObjectName;
|
||||
$this->command = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object name of the controller
|
||||
*
|
||||
* @return string The controller's object name
|
||||
*/
|
||||
public function getControllerObjectName()
|
||||
{
|
||||
return $this->controllerObjectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extension name of the specified controller.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
public function getControllerExtensionName()
|
||||
{
|
||||
return $this->controllerExtensionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the command contained in this request.
|
||||
*
|
||||
* Note that the command name must start with a lower case letter and is case sensitive.
|
||||
*
|
||||
* @param string $commandName Name of the command to execute by the controller
|
||||
*/
|
||||
public function setControllerCommandName($commandName)
|
||||
{
|
||||
$this->controllerCommandName = $commandName;
|
||||
$this->command = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the command the controller is supposed to execute.
|
||||
*
|
||||
* @return string Command name
|
||||
*/
|
||||
public function getControllerCommandName()
|
||||
{
|
||||
return $this->controllerCommandName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command object for this request
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Cli\Command
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
if ($this->command === null) {
|
||||
$this->command = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Cli\Command::class, $this->controllerObjectName, $this->controllerCommandName);
|
||||
}
|
||||
return $this->command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified argument
|
||||
*
|
||||
* @param string $argumentName Name of the argument to set
|
||||
* @param mixed $value The new value
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException
|
||||
*/
|
||||
public function setArgument($argumentName, $value)
|
||||
{
|
||||
if (!is_string($argumentName) || $argumentName === '') {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException('Invalid argument name.', 1300893885);
|
||||
}
|
||||
$this->arguments[$argumentName] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the whole arguments ArrayObject and therefore replaces any arguments
|
||||
* which existed before.
|
||||
*
|
||||
* @param array $arguments An array of argument names and their values
|
||||
*/
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified argument
|
||||
*
|
||||
* @param string $argumentName Name of the argument
|
||||
* @return string Value of the argument
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException if such an argument does not exist
|
||||
*/
|
||||
public function getArgument($argumentName)
|
||||
{
|
||||
if (!isset($this->arguments[$argumentName])) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException('An argument "' . $argumentName . '" does not exist for this request.', 1300893886);
|
||||
}
|
||||
return $this->arguments[$argumentName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an argument of the given name exists (is set)
|
||||
*
|
||||
* @param string $argumentName Name of the argument to check
|
||||
* @return bool TRUE if the argument is set, otherwise FALSE
|
||||
*/
|
||||
public function hasArgument($argumentName)
|
||||
{
|
||||
return isset($this->arguments[$argumentName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ArrayObject of arguments and their values
|
||||
*
|
||||
* @return array Array of arguments and their values (which may be arguments and values as well)
|
||||
*/
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the exceeding arguments
|
||||
*
|
||||
* @param array $exceedingArguments Numeric array of exceeding arguments
|
||||
*/
|
||||
public function setExceedingArguments(array $exceedingArguments)
|
||||
{
|
||||
$this->exceedingArguments = $exceedingArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns additional unnamed arguments (if any) which have been passed through the command line after all
|
||||
* required arguments (if any) have been specified.
|
||||
*
|
||||
* For a command method with the signature ($argument1, $argument2) and for the command line
|
||||
* typo3/sysext/core/bin/typo3 acme:foo --argument1 Foo --argument2 Bar baz quux
|
||||
* this method would return array(0 => 'baz', 1 => 'quux')
|
||||
*
|
||||
* @return array Numeric array of exceeding argument values
|
||||
*/
|
||||
public function getExceedingArguments()
|
||||
{
|
||||
return $this->exceedingArguments;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Cli;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Builds a CLI request object from the raw command call
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class RequestBuilder implements \TYPO3\CMS\Core\SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
|
||||
*/
|
||||
protected $reflectionService;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Cli\CommandManager
|
||||
*/
|
||||
protected $commandManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService
|
||||
*/
|
||||
public function injectReflectionService(\TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService)
|
||||
{
|
||||
$this->reflectionService = $reflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Cli\CommandManager $commandManager
|
||||
*/
|
||||
public function injectCommandManager(\TYPO3\CMS\Extbase\Mvc\Cli\CommandManager $commandManager)
|
||||
{
|
||||
$this->commandManager = $commandManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManager(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a CLI request object from a command line.
|
||||
*
|
||||
* The given command line may be a string (e.g. "myextension:foo do-that-thing --force") or
|
||||
* an array consisting of the individual parts. The array must not include the script
|
||||
* name (like in $argv) but start with command right away.
|
||||
*
|
||||
* @param mixed $commandLine The command line, either as a string or as an array
|
||||
* @param string $callingScript The calling script (usually ./typo3/sysext/core/bin/typo3)
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Cli\Request The CLI request as an object
|
||||
*/
|
||||
public function build($commandLine = '', $callingScript = './typo3/sysext/core/bin/typo3')
|
||||
{
|
||||
$request = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Cli\Request::class);
|
||||
$request->setCallingScript($callingScript);
|
||||
$request->setControllerObjectName(\TYPO3\CMS\Extbase\Command\HelpCommandController::class);
|
||||
$rawCommandLineArguments = is_array($commandLine) ? $commandLine : explode(' ', $commandLine);
|
||||
if (empty($rawCommandLineArguments)) {
|
||||
$request->setControllerCommandName('helpStub');
|
||||
return $request;
|
||||
}
|
||||
$commandIdentifier = trim(array_shift($rawCommandLineArguments));
|
||||
try {
|
||||
$command = $this->commandManager->getCommandByIdentifier($commandIdentifier);
|
||||
$this->configurationManager->setConfiguration(['extensionName' => $command->getExtensionName()]);
|
||||
} catch (\TYPO3\CMS\Extbase\Mvc\Exception\CommandException $exception) {
|
||||
$request->setArgument('exception', $exception);
|
||||
$request->setControllerCommandName('error');
|
||||
return $request;
|
||||
}
|
||||
$controllerObjectName = $command->getControllerClassName();
|
||||
$controllerCommandName = $command->getControllerCommandName();
|
||||
$request->setControllerObjectName($controllerObjectName);
|
||||
$request->setControllerCommandName($controllerCommandName);
|
||||
list($commandLineArguments, $exceedingCommandLineArguments) = $this->parseRawCommandLineArguments($rawCommandLineArguments, $controllerObjectName, $controllerCommandName);
|
||||
$request->setArguments($commandLineArguments);
|
||||
$request->setExceedingArguments($exceedingCommandLineArguments);
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an array of unparsed command line arguments and options and converts it separated
|
||||
* by named arguments, options and unnamed arguments.
|
||||
*
|
||||
* @param array $rawCommandLineArguments The unparsed command parts (such as "--foo") as an array
|
||||
* @param string $controllerObjectName Object name of the designated command controller
|
||||
* @param string $controllerCommandName Command name of the recognized command (ie. method name without "Command" suffix)
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentMixingException
|
||||
* @return array All and exceeding command line arguments
|
||||
*/
|
||||
protected function parseRawCommandLineArguments(array $rawCommandLineArguments, $controllerObjectName, $controllerCommandName)
|
||||
{
|
||||
$commandLineArguments = [];
|
||||
$exceedingArguments = [];
|
||||
$commandMethodName = $controllerCommandName . 'Command';
|
||||
$commandMethodParameters = $this->reflectionService
|
||||
->getClassSchema($controllerObjectName)
|
||||
->getMethod($commandMethodName)['params'] ?? [];
|
||||
$requiredArguments = [];
|
||||
$optionalArguments = [];
|
||||
$argumentNames = [];
|
||||
foreach ($commandMethodParameters as $parameterName => $parameterInfo) {
|
||||
$argumentNames[] = $parameterName;
|
||||
if ($parameterInfo['optional'] === false) {
|
||||
$requiredArguments[strtolower($parameterName)] = ['parameterName' => $parameterName, 'type' => $parameterInfo['type']];
|
||||
} else {
|
||||
$optionalArguments[strtolower($parameterName)] = ['parameterName' => $parameterName, 'type' => $parameterInfo['type']];
|
||||
}
|
||||
}
|
||||
$decidedToUseNamedArguments = false;
|
||||
$decidedToUseUnnamedArguments = false;
|
||||
$argumentIndex = 0;
|
||||
while (!empty($rawCommandLineArguments)) {
|
||||
$rawArgument = array_shift($rawCommandLineArguments);
|
||||
if ($rawArgument[0] === '-') {
|
||||
if ($rawArgument[1] === '-') {
|
||||
$rawArgument = substr($rawArgument, 2);
|
||||
} else {
|
||||
$rawArgument = substr($rawArgument, 1);
|
||||
}
|
||||
$argumentName = $this->extractArgumentNameFromCommandLinePart($rawArgument);
|
||||
if (isset($optionalArguments[$argumentName])) {
|
||||
$argumentValue = $this->getValueOfCurrentCommandLineOption($rawArgument, $rawCommandLineArguments, $optionalArguments[$argumentName]['type']);
|
||||
$commandLineArguments[$optionalArguments[$argumentName]['parameterName']] = $argumentValue;
|
||||
} elseif (isset($requiredArguments[$argumentName])) {
|
||||
if ($decidedToUseUnnamedArguments) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentMixingException(sprintf('Unexpected named argument "%s". If you use unnamed arguments, all required arguments must be passed without a name.', $argumentName), 1309971821);
|
||||
}
|
||||
$decidedToUseNamedArguments = true;
|
||||
$argumentValue = $this->getValueOfCurrentCommandLineOption($rawArgument, $rawCommandLineArguments, $requiredArguments[$argumentName]['type']);
|
||||
$commandLineArguments[$requiredArguments[$argumentName]['parameterName']] = $argumentValue;
|
||||
unset($requiredArguments[$argumentName]);
|
||||
}
|
||||
} else {
|
||||
if (!empty($requiredArguments)) {
|
||||
if ($decidedToUseNamedArguments) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentMixingException(sprintf('Unexpected unnamed argument "%s". If you use named arguments, all required arguments must be passed named.', $rawArgument), 1309971820);
|
||||
}
|
||||
$argument = array_shift($requiredArguments);
|
||||
$commandLineArguments[$argument['parameterName']] = $rawArgument;
|
||||
$decidedToUseUnnamedArguments = true;
|
||||
} else {
|
||||
if ($argumentIndex < count($argumentNames)) {
|
||||
$commandLineArguments[$argumentNames[$argumentIndex]] = $rawArgument;
|
||||
} else {
|
||||
$exceedingArguments[] = $rawArgument;
|
||||
}
|
||||
}
|
||||
}
|
||||
$argumentIndex++;
|
||||
}
|
||||
return [$commandLineArguments, $exceedingArguments];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the option or argument name from the name / value pair of a command line.
|
||||
*
|
||||
* @param string $commandLinePart Part of the command line, e.g. "my-important-option=SomeInterestingValue
|
||||
* @return string The lowercased argument name, e.g. "myimportantoption
|
||||
*/
|
||||
protected function extractArgumentNameFromCommandLinePart($commandLinePart)
|
||||
{
|
||||
$nameAndValue = explode('=', $commandLinePart, 2);
|
||||
return strtolower(str_replace('-', '', $nameAndValue[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the first argument of the given input array. Shifts the parsed argument off the array.
|
||||
*
|
||||
* @param string $currentArgument The current argument
|
||||
* @param array &$rawCommandLineArguments Array of the remaining command line arguments
|
||||
* @param string $expectedArgumentType The expected type of the current argument, because booleans get special attention
|
||||
* @return string The value of the first argument
|
||||
*/
|
||||
protected function getValueOfCurrentCommandLineOption($currentArgument, array &$rawCommandLineArguments, $expectedArgumentType)
|
||||
{
|
||||
if (!isset($rawCommandLineArguments[0]) && strpos($currentArgument, '=') === false || isset($rawCommandLineArguments[0]) && $rawCommandLineArguments[0][0] === '-' && strpos($currentArgument, '=') === false) {
|
||||
return true;
|
||||
}
|
||||
if (strpos($currentArgument, '=') === false) {
|
||||
$possibleValue = trim(array_shift($rawCommandLineArguments));
|
||||
if (strpos($possibleValue, '=') === false) {
|
||||
if ($expectedArgumentType !== 'boolean') {
|
||||
return $possibleValue;
|
||||
}
|
||||
if (in_array($possibleValue, ['on', '1', 'y', 'yes', 'true', 'TRUE'], true)) {
|
||||
return true;
|
||||
}
|
||||
if (in_array($possibleValue, ['off', '0', 'n', 'no', 'false', 'FALSE'], true)) {
|
||||
return false;
|
||||
}
|
||||
array_unshift($rawCommandLineArguments, $possibleValue);
|
||||
return true;
|
||||
}
|
||||
$currentArgument .= $possibleValue;
|
||||
}
|
||||
$splitArgument = explode('=', $currentArgument, 2);
|
||||
while ((!isset($splitArgument[1]) || trim($splitArgument[1]) === '') && !empty($rawCommandLineArguments)) {
|
||||
$currentArgument .= array_shift($rawCommandLineArguments);
|
||||
$splitArgument = explode('=', $currentArgument);
|
||||
}
|
||||
$value = $splitArgument[1] ?? '';
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Cli;
|
||||
|
||||
/*
|
||||
* 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\Core\Environment;
|
||||
|
||||
/**
|
||||
* The generic command line interface request handler for the MVC framework.
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class RequestHandler implements \TYPO3\CMS\Extbase\Mvc\RequestHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Dispatcher
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Cli\RequestBuilder
|
||||
*/
|
||||
protected $requestBuilder;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Dispatcher $dispatcher
|
||||
*/
|
||||
public function injectDispatcher(\TYPO3\CMS\Extbase\Mvc\Dispatcher $dispatcher)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Cli\RequestBuilder $requestBuilder
|
||||
*/
|
||||
public function injectRequestBuilder(\TYPO3\CMS\Extbase\Mvc\Cli\RequestBuilder $requestBuilder)
|
||||
{
|
||||
$this->requestBuilder = $requestBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the request
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\ResponseInterface
|
||||
*/
|
||||
public function handleRequest()
|
||||
{
|
||||
$commandLine = $_SERVER['argv'] ?? [];
|
||||
$callingScript = array_shift($commandLine);
|
||||
if ($callingScript !== $_SERVER['_']) {
|
||||
$callingScript = $_SERVER['_'] . ' ' . $callingScript;
|
||||
}
|
||||
|
||||
$request = $this->requestBuilder->build($commandLine, $callingScript);
|
||||
/** @var \TYPO3\CMS\Extbase\Mvc\Cli\Response $response */
|
||||
$response = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Cli\Response::class);
|
||||
$this->dispatcher->dispatch($request, $response);
|
||||
$response->send();
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* This request handler can handle any command line request.
|
||||
*
|
||||
* @return bool If the request is a command line request, TRUE otherwise FALSE
|
||||
*/
|
||||
public function canHandleRequest()
|
||||
{
|
||||
return Environment::isCli();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the priority - how eager the handler is to actually handle the
|
||||
* request.
|
||||
*
|
||||
* @return int The priority of the request handler.
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Cli;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A CLI specific response implementation
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class Response extends \TYPO3\CMS\Extbase\Mvc\Response
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $exitCode = 0;
|
||||
|
||||
/**
|
||||
* Sets the numerical exit code which should be returned when exiting this application.
|
||||
*
|
||||
* @param int $exitCode
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setExitCode($exitCode)
|
||||
{
|
||||
if (!is_int($exitCode)) {
|
||||
throw new \InvalidArgumentException(sprintf('Tried to set invalid exit code. The value must be integer, %s given.', gettype($exitCode)), 1312222064);
|
||||
}
|
||||
$this->exitCode = $exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rets the numerical exit code which should be returned when exiting this application.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getExitCode()
|
||||
{
|
||||
return $this->exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders and sends the whole web response
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
if ($this->content !== null) {
|
||||
echo $this->shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,418 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
|
||||
use TYPO3\CMS\Extbase\Mvc\Web\Request as WebRequest;
|
||||
|
||||
/**
|
||||
* An abstract base class for Controllers
|
||||
*/
|
||||
abstract class AbstractController implements ControllerInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
|
||||
*/
|
||||
protected $signalSlotDispatcher;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
|
||||
*/
|
||||
protected $uriBuilder;
|
||||
|
||||
/**
|
||||
* @var string Key of the extension this controller belongs to
|
||||
*/
|
||||
protected $extensionName;
|
||||
|
||||
/**
|
||||
* Contains the settings of the current extension
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* The current request.
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\RequestInterface
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* The response which will be returned by this action controller
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\ResponseInterface
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Validation\ValidatorResolver
|
||||
*/
|
||||
protected $validatorResolver;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Controller\Arguments Arguments passed to the controller
|
||||
*/
|
||||
protected $arguments;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
|
||||
*/
|
||||
public function injectSignalSlotDispatcher(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher)
|
||||
{
|
||||
$this->signalSlotDispatcher = $signalSlotDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Validation\ValidatorResolver $validatorResolver
|
||||
*/
|
||||
public function injectValidatorResolver(\TYPO3\CMS\Extbase\Validation\ValidatorResolver $validatorResolver)
|
||||
{
|
||||
$this->validatorResolver = $validatorResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* An array of supported request types. By default only web requests are supported.
|
||||
* Modify or replace this array if your specific controller supports certain
|
||||
* (additional) request types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedRequestTypes = [\TYPO3\CMS\Extbase\Mvc\Request::class];
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext
|
||||
*/
|
||||
protected $controllerContext;
|
||||
|
||||
/**
|
||||
* @return ControllerContext
|
||||
*/
|
||||
public function getControllerContext()
|
||||
{
|
||||
return $this->controllerContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* Constructs the controller.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$className = static::class;
|
||||
$classNameParts = explode('\\', $className, 4);
|
||||
// Skip vendor and product name for core classes
|
||||
if (strpos($className, 'TYPO3\\CMS\\') === 0) {
|
||||
$this->extensionName = $classNameParts[2];
|
||||
} else {
|
||||
$this->extensionName = $classNameParts[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->configurationManager = $configurationManager;
|
||||
$this->settings = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the object manager
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
$this->arguments = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Controller\Arguments::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Message object and adds it to the FlashMessageQueue.
|
||||
*
|
||||
* @param string $messageBody The message
|
||||
* @param string $messageTitle Optional message title
|
||||
* @param int $severity Optional severity, must be one of \TYPO3\CMS\Core\Messaging\FlashMessage constants
|
||||
* @param bool $storeInSession Optional, defines whether the message should be stored in the session (default) or not
|
||||
* @throws \InvalidArgumentException if the message body is no string
|
||||
* @see \TYPO3\CMS\Core\Messaging\FlashMessage
|
||||
*/
|
||||
public function addFlashMessage($messageBody, $messageTitle = '', $severity = \TYPO3\CMS\Core\Messaging\AbstractMessage::OK, $storeInSession = true)
|
||||
{
|
||||
if (!is_string($messageBody)) {
|
||||
throw new \InvalidArgumentException('The message body must be of type string, "' . gettype($messageBody) . '" given.', 1243258395);
|
||||
}
|
||||
/* @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
|
||||
$flashMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
|
||||
\TYPO3\CMS\Core\Messaging\FlashMessage::class,
|
||||
(string)$messageBody,
|
||||
(string)$messageTitle,
|
||||
$severity,
|
||||
$storeInSession
|
||||
);
|
||||
$this->controllerContext->getFlashMessageQueue()->enqueue($flashMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current request type is supported by the controller.
|
||||
*
|
||||
* If your controller only supports certain request types, either
|
||||
* replace / modify the supportedRequestTypes property or override this
|
||||
* method.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The current request
|
||||
* @return bool TRUE if this request type is supported, otherwise FALSE
|
||||
*/
|
||||
public function canProcessRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request)
|
||||
{
|
||||
foreach ($this->supportedRequestTypes as $supportedRequestType) {
|
||||
if ($request instanceof $supportedRequestType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a general request. The result can be returned by altering the given response.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request object
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, modified by this handler
|
||||
* @throws UnsupportedRequestTypeException if the controller doesn't support the current request type
|
||||
*/
|
||||
public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response)
|
||||
{
|
||||
if (!$this->canProcessRequest($request)) {
|
||||
throw new UnsupportedRequestTypeException(static::class . ' does not support requests of type "' . get_class($request) . '". Supported types are: ' . implode(' ', $this->supportedRequestTypes), 1187701132);
|
||||
}
|
||||
if ($response instanceof \TYPO3\CMS\Extbase\Mvc\Web\Response && $request instanceof WebRequest) {
|
||||
$response->setRequest($request);
|
||||
}
|
||||
$this->request = $request;
|
||||
$this->request->setDispatched(true);
|
||||
$this->response = $response;
|
||||
$this->uriBuilder = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class);
|
||||
$this->uriBuilder->setRequest($request);
|
||||
$this->initializeControllerArgumentsBaseValidators();
|
||||
$this->mapRequestArgumentsToControllerArguments();
|
||||
$this->controllerContext = $this->buildControllerContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the controller context
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext ControllerContext to be passed to the view
|
||||
*/
|
||||
protected function buildControllerContext()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext */
|
||||
$controllerContext = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext::class);
|
||||
$controllerContext->setRequest($this->request);
|
||||
$controllerContext->setResponse($this->response);
|
||||
if ($this->arguments !== null) {
|
||||
$controllerContext->setArguments($this->arguments);
|
||||
}
|
||||
$controllerContext->setUriBuilder($this->uriBuilder);
|
||||
|
||||
return $controllerContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the request to another action and / or controller.
|
||||
*
|
||||
* Request is directly transferred to the other action / controller
|
||||
* without the need for a new request.
|
||||
*
|
||||
* @param string $actionName Name of the action to forward to
|
||||
* @param string|null $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
|
||||
* @param string|null $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
|
||||
* @param array|null $arguments Arguments to pass to the target action
|
||||
* @throws StopActionException
|
||||
* @see redirect()
|
||||
*/
|
||||
public function forward($actionName, $controllerName = null, $extensionName = null, array $arguments = null)
|
||||
{
|
||||
$this->request->setDispatched(false);
|
||||
if ($this->request instanceof WebRequest) {
|
||||
$this->request->setControllerActionName($actionName);
|
||||
if ($controllerName !== null) {
|
||||
$this->request->setControllerName($controllerName);
|
||||
}
|
||||
if ($extensionName !== null) {
|
||||
$this->request->setControllerExtensionName($extensionName);
|
||||
}
|
||||
}
|
||||
if ($arguments !== null) {
|
||||
$this->request->setArguments($arguments);
|
||||
}
|
||||
throw new StopActionException('forward', 1476045801);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects the request to another action and / or controller.
|
||||
*
|
||||
* Redirect will be sent to the client which then performs another request to the new URI.
|
||||
*
|
||||
* NOTE: This method only supports web requests and will thrown an exception
|
||||
* if used with other request types.
|
||||
*
|
||||
* @param string $actionName Name of the action to forward to
|
||||
* @param string|null $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
|
||||
* @param string|null $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
|
||||
* @param array|null $arguments Arguments to pass to the target action
|
||||
* @param int|null $pageUid Target page uid. If NULL, the current page uid is used
|
||||
* @param int $delay (optional) The delay in seconds. Default is no delay.
|
||||
* @param int $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other
|
||||
* @throws UnsupportedRequestTypeException If the request is not a web request
|
||||
* @throws StopActionException
|
||||
* @see forward()
|
||||
*/
|
||||
protected function redirect($actionName, $controllerName = null, $extensionName = null, array $arguments = null, $pageUid = null, $delay = 0, $statusCode = 303)
|
||||
{
|
||||
if (!$this->request instanceof WebRequest) {
|
||||
throw new UnsupportedRequestTypeException('redirect() only supports web requests.', 1220539734);
|
||||
}
|
||||
if ($controllerName === null) {
|
||||
$controllerName = $this->request->getControllerName();
|
||||
}
|
||||
$this->uriBuilder->reset()->setTargetPageUid($pageUid)->setCreateAbsoluteUri(true);
|
||||
if (\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
|
||||
$this->uriBuilder->setAbsoluteUriScheme('https');
|
||||
}
|
||||
$uri = $this->uriBuilder->uriFor($actionName, $arguments, $controllerName, $extensionName);
|
||||
$this->redirectToUri($uri, $delay, $statusCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects the web request to another uri.
|
||||
*
|
||||
* NOTE: This method only supports web requests and will thrown an exception if used with other request types.
|
||||
*
|
||||
* @param mixed $uri A string representation of a URI
|
||||
* @param int $delay (optional) The delay in seconds. Default is no delay.
|
||||
* @param int $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other
|
||||
* @throws UnsupportedRequestTypeException If the request is not a web request
|
||||
* @throws StopActionException
|
||||
*/
|
||||
protected function redirectToUri($uri, $delay = 0, $statusCode = 303)
|
||||
{
|
||||
if (!$this->request instanceof WebRequest) {
|
||||
throw new UnsupportedRequestTypeException('redirect() only supports web requests.', 1220539735);
|
||||
}
|
||||
|
||||
$this->objectManager->get(\TYPO3\CMS\Extbase\Service\CacheService::class)->clearCachesOfRegisteredPageIds();
|
||||
|
||||
$uri = $this->addBaseUriIfNecessary($uri);
|
||||
$escapedUri = htmlentities($uri, ENT_QUOTES, 'utf-8');
|
||||
$this->response->setContent('<html><head><meta http-equiv="refresh" content="' . (int)$delay . ';url=' . $escapedUri . '"/></head></html>');
|
||||
if ($this->response instanceof \TYPO3\CMS\Extbase\Mvc\Web\Response) {
|
||||
$this->response->setStatus($statusCode);
|
||||
$this->response->setHeader('Location', (string)$uri);
|
||||
}
|
||||
// Avoid caching the plugin when we issue a redirect response
|
||||
// This means that even when an action is configured as cachable
|
||||
// we avoid the plugin to be cached, but keep the page cache untouched
|
||||
$contentObject = $this->configurationManager->getContentObject();
|
||||
if ($contentObject->getUserObjectType() === \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::OBJECTTYPE_USER) {
|
||||
$contentObject->convertToUserIntObject();
|
||||
}
|
||||
|
||||
throw new StopActionException('redirectToUri', 1476045828);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the base uri if not already in place.
|
||||
*
|
||||
* @param string $uri The URI
|
||||
* @return string
|
||||
*/
|
||||
protected function addBaseUriIfNecessary($uri)
|
||||
{
|
||||
return \TYPO3\CMS\Core\Utility\GeneralUtility::locationHeaderUrl((string)$uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the specified HTTP status immediately.
|
||||
*
|
||||
* NOTE: This method only supports web requests and will thrown an exception if used with other request types.
|
||||
*
|
||||
* @param int $statusCode The HTTP status code
|
||||
* @param string $statusMessage A custom HTTP status message
|
||||
* @param string $content Body content which further explains the status
|
||||
* @throws UnsupportedRequestTypeException If the request is not a web request
|
||||
* @throws StopActionException
|
||||
*/
|
||||
public function throwStatus($statusCode, $statusMessage = null, $content = null)
|
||||
{
|
||||
if (!$this->request instanceof WebRequest) {
|
||||
throw new UnsupportedRequestTypeException('throwStatus() only supports web requests.', 1220539739);
|
||||
}
|
||||
if ($this->response instanceof \TYPO3\CMS\Extbase\Mvc\Web\Response) {
|
||||
$this->response->setStatus($statusCode, $statusMessage);
|
||||
if ($content === null) {
|
||||
$content = $this->response->getStatus();
|
||||
}
|
||||
}
|
||||
$this->response->setContent($content);
|
||||
throw new StopActionException('throwStatus', 1476045871);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the base validators which were defined for the data type of each
|
||||
* controller argument and adds them to the argument's validator chain.
|
||||
*/
|
||||
public function initializeControllerArgumentsBaseValidators()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Mvc\Controller\Argument $argument */
|
||||
foreach ($this->arguments as $argument) {
|
||||
$validator = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
|
||||
if ($validator !== null) {
|
||||
$argument->setValidator($validator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps arguments delivered by the request object to the local controller arguments.
|
||||
*
|
||||
* @throws Exception\RequiredArgumentMissingException
|
||||
*/
|
||||
protected function mapRequestArgumentsToControllerArguments()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Mvc\Controller\Argument $argument */
|
||||
foreach ($this->arguments as $argument) {
|
||||
$argumentName = $argument->getName();
|
||||
if ($this->request->hasArgument($argumentName)) {
|
||||
$argument->setValue($this->request->getArgument($argumentName));
|
||||
} elseif ($argument->isRequired()) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Controller\Exception\RequiredArgumentMissingException('Required argument "' . $argumentName . '" is not set for ' . $this->request->getControllerObjectName() . '->' . $this->request->getControllerActionName() . '.', 1298012500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,635 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
|
||||
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\Web\Request as WebRequest;
|
||||
use TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator;
|
||||
use TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface;
|
||||
use TYPO3Fluid\Fluid\View\TemplateView;
|
||||
|
||||
/**
|
||||
* A multi action controller. This is by far the most common base class for Controllers.
|
||||
*/
|
||||
class ActionController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
|
||||
*/
|
||||
protected $reflectionService;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Service\CacheService
|
||||
*/
|
||||
protected $cacheService;
|
||||
|
||||
/**
|
||||
* The current view, as resolved by resolveView()
|
||||
*
|
||||
* @var ViewInterface
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $namespacesViewObjectNamePattern = '@vendor\@extension\View\@controller\@action@format';
|
||||
|
||||
/**
|
||||
* A list of formats and object names of the views which should render them.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* array('html' => 'Tx_MyExtension_View_MyHtmlView', 'json' => 'F3...
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $viewFormatToObjectNameMap = [];
|
||||
|
||||
/**
|
||||
* The default view object to use if none of the resolved views can render
|
||||
* a response for the current request.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $defaultViewObjectName = \TYPO3\CMS\Fluid\View\TemplateView::class;
|
||||
|
||||
/**
|
||||
* Name of the action method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $actionMethodName = 'indexAction';
|
||||
|
||||
/**
|
||||
* Name of the special error action method which is called in case of errors
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $errorMethodName = 'errorAction';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService
|
||||
*/
|
||||
protected $mvcPropertyMappingConfigurationService;
|
||||
|
||||
/**
|
||||
* The current request.
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* The response which will be returned by this action controller
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService
|
||||
*/
|
||||
public function injectReflectionService(\TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService)
|
||||
{
|
||||
$this->reflectionService = $reflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Service\CacheService $cacheService
|
||||
*/
|
||||
public function injectCacheService(\TYPO3\CMS\Extbase\Service\CacheService $cacheService)
|
||||
{
|
||||
$this->cacheService = $cacheService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService $mvcPropertyMappingConfigurationService
|
||||
*/
|
||||
public function injectMvcPropertyMappingConfigurationService(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService $mvcPropertyMappingConfigurationService)
|
||||
{
|
||||
$this->mvcPropertyMappingConfigurationService = $mvcPropertyMappingConfigurationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a request. The result output is returned by altering the given response.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request object
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, modified by this handler
|
||||
*
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
|
||||
*/
|
||||
public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response)
|
||||
{
|
||||
if (!$this->canProcessRequest($request)) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException(static::class . ' does not support requests of type "' . get_class($request) . '". Supported types are: ' . implode(' ', $this->supportedRequestTypes), 1187701131);
|
||||
}
|
||||
|
||||
if ($response instanceof \TYPO3\CMS\Extbase\Mvc\Web\Response && $request instanceof WebRequest) {
|
||||
$response->setRequest($request);
|
||||
}
|
||||
$this->request = $request;
|
||||
$this->request->setDispatched(true);
|
||||
$this->response = $response;
|
||||
$this->uriBuilder = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class);
|
||||
$this->uriBuilder->setRequest($request);
|
||||
$this->actionMethodName = $this->resolveActionMethodName();
|
||||
$this->initializeActionMethodArguments();
|
||||
$this->initializeActionMethodValidators();
|
||||
$this->mvcPropertyMappingConfigurationService->initializePropertyMappingConfigurationFromRequest($request, $this->arguments);
|
||||
$this->initializeAction();
|
||||
$actionInitializationMethodName = 'initialize' . ucfirst($this->actionMethodName);
|
||||
if (method_exists($this, $actionInitializationMethodName)) {
|
||||
call_user_func([$this, $actionInitializationMethodName]);
|
||||
}
|
||||
$this->mapRequestArgumentsToControllerArguments();
|
||||
$this->controllerContext = $this->buildControllerContext();
|
||||
$this->view = $this->resolveView();
|
||||
if ($this->view !== null) {
|
||||
$this->initializeView($this->view);
|
||||
}
|
||||
$this->callActionMethod();
|
||||
$this->renderAssetsForRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method which initializes assets that should be attached to the response
|
||||
* for the given $request, which contains parameters that an override can
|
||||
* use to determine which assets to add via PageRenderer.
|
||||
*
|
||||
* This default implementation will attempt to render the sections "HeaderAssets"
|
||||
* and "FooterAssets" from the template that is being rendered, inserting the
|
||||
* rendered content into either page header or footer, as appropriate. Both
|
||||
* sections are optional and can be used one or both in combination.
|
||||
*
|
||||
* You can add assets with this method without worrying about duplicates, if
|
||||
* for example you do this in a plugin that gets used multiple time on a page.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request
|
||||
*/
|
||||
protected function renderAssetsForRequest($request)
|
||||
{
|
||||
if (!$this->view instanceof TemplateView) {
|
||||
// Only TemplateView (from Fluid engine, so this includes all TYPO3 Views based
|
||||
// on TYPO3's AbstractTemplateView) supports renderSection(). The method is not
|
||||
// declared on ViewInterface - so we must assert a specific class. We silently skip
|
||||
// asset processing if the View doesn't match, so we don't risk breaking custom Views.
|
||||
return;
|
||||
}
|
||||
$pageRenderer = $this->objectManager->get(PageRenderer::class);
|
||||
$variables = ['request' => $request, 'arguments' => $this->arguments];
|
||||
$headerAssets = $this->view->renderSection('HeaderAssets', $variables, true);
|
||||
$footerAssets = $this->view->renderSection('FooterAssets', $variables, true);
|
||||
if (!empty(trim($headerAssets))) {
|
||||
$pageRenderer->addHeaderData($headerAssets);
|
||||
}
|
||||
if (!empty(trim($footerAssets))) {
|
||||
$pageRenderer->addFooterData($footerAssets);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the arguments initilization in the action controller:
|
||||
* Automatically registers arguments of the current action
|
||||
*
|
||||
* Don't override this method - use initializeAction() instead.
|
||||
*
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException
|
||||
* @see initializeArguments()
|
||||
*/
|
||||
protected function initializeActionMethodArguments()
|
||||
{
|
||||
$methodParameters = $this->reflectionService
|
||||
->getClassSchema(static::class)
|
||||
->getMethod($this->actionMethodName)['params'] ?? [];
|
||||
|
||||
foreach ($methodParameters as $parameterName => $parameterInfo) {
|
||||
$dataType = null;
|
||||
if (isset($parameterInfo['type'])) {
|
||||
$dataType = $parameterInfo['type'];
|
||||
} elseif ($parameterInfo['array']) {
|
||||
$dataType = 'array';
|
||||
}
|
||||
if ($dataType === null) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException('The argument type for parameter $' . $parameterName . ' of method ' . static::class . '->' . $this->actionMethodName . '() could not be detected.', 1253175643);
|
||||
}
|
||||
$defaultValue = $parameterInfo['hasDefaultValue'] === true ? $parameterInfo['defaultValue'] : null;
|
||||
$this->arguments->addNewArgument($parameterName, $dataType, $parameterInfo['optional'] === false, $defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the needed validators to the Arguments:
|
||||
*
|
||||
* - Validators checking the data type from the @param annotation
|
||||
* - Custom validators specified with validate annotations.
|
||||
* - Model-based validators (validate annotations in the model)
|
||||
* - Custom model validator classes
|
||||
*/
|
||||
protected function initializeActionMethodValidators()
|
||||
{
|
||||
if ($this->arguments->count() === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classSchema = $this->reflectionService->getClassSchema(static::class);
|
||||
|
||||
$ignoreValidationAnnotations = array_unique(array_flip(
|
||||
$classSchema->getMethod($this->actionMethodName)['tags']['ignorevalidation'] ?? []
|
||||
));
|
||||
|
||||
/** @var \TYPO3\CMS\Extbase\Mvc\Controller\Argument $argument */
|
||||
foreach ($this->arguments as $argument) {
|
||||
if (isset($ignoreValidationAnnotations[$argument->getName()])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$validator = $this->objectManager->get(ConjunctionValidator::class);
|
||||
$validatorDefinitions = $classSchema->getMethod($this->actionMethodName)['params'][$argument->getName()]['validators'] ?? [];
|
||||
|
||||
foreach ($validatorDefinitions as $validatorDefinition) {
|
||||
/** @var ValidatorInterface $validatorInstance */
|
||||
$validatorInstance = $this->objectManager->get(
|
||||
$validatorDefinition['className'],
|
||||
$validatorDefinition['options']
|
||||
);
|
||||
|
||||
$validator->addValidator(
|
||||
$validatorInstance
|
||||
);
|
||||
}
|
||||
|
||||
$baseValidatorConjunction = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
|
||||
if ($baseValidatorConjunction->count() > 0) {
|
||||
$validator->addValidator($baseValidatorConjunction);
|
||||
}
|
||||
$argument->setValidator($validator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves and checks the current action method name
|
||||
*
|
||||
* @return string Method name of the current action
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchActionException if the action specified in the request object does not exist (and if there's no default action either).
|
||||
*/
|
||||
protected function resolveActionMethodName()
|
||||
{
|
||||
$actionMethodName = $this->request->getControllerActionName() . 'Action';
|
||||
if (!method_exists($this, $actionMethodName)) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchActionException('An action "' . $actionMethodName . '" does not exist in controller "' . static::class . '".', 1186669086);
|
||||
}
|
||||
return $actionMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the specified action method and passes the arguments.
|
||||
*
|
||||
* If the action returns a string, it is appended to the content in the
|
||||
* response object. If the action doesn't return anything and a valid
|
||||
* view exists, the view is rendered automatically.
|
||||
*/
|
||||
protected function callActionMethod()
|
||||
{
|
||||
$preparedArguments = [];
|
||||
/** @var \TYPO3\CMS\Extbase\Mvc\Controller\Argument $argument */
|
||||
foreach ($this->arguments as $argument) {
|
||||
$preparedArguments[] = $argument->getValue();
|
||||
}
|
||||
$validationResult = $this->arguments->validate();
|
||||
if (!$validationResult->hasErrors()) {
|
||||
$this->emitBeforeCallActionMethodSignal($preparedArguments);
|
||||
$actionResult = $this->{$this->actionMethodName}(...$preparedArguments);
|
||||
} else {
|
||||
$actionResult = $this->{$this->errorMethodName}();
|
||||
}
|
||||
|
||||
if ($actionResult === null && $this->view instanceof ViewInterface) {
|
||||
$this->response->appendContent($this->view->render());
|
||||
} elseif (is_string($actionResult) && $actionResult !== '') {
|
||||
$this->response->appendContent($actionResult);
|
||||
} elseif (is_object($actionResult) && method_exists($actionResult, '__toString')) {
|
||||
$this->response->appendContent((string)$actionResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a signal before the current action is called
|
||||
*
|
||||
* @param array $preparedArguments
|
||||
*/
|
||||
protected function emitBeforeCallActionMethodSignal(array $preparedArguments)
|
||||
{
|
||||
$this->signalSlotDispatcher->dispatch(__CLASS__, 'beforeCallActionMethod', [static::class, $this->actionMethodName, $preparedArguments]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a view for the current action.
|
||||
* By default, this method tries to locate a view with a name matching the current action.
|
||||
*
|
||||
* @return ViewInterface
|
||||
*/
|
||||
protected function resolveView()
|
||||
{
|
||||
$viewObjectName = $this->resolveViewObjectName();
|
||||
if ($viewObjectName !== false) {
|
||||
/** @var ViewInterface $view */
|
||||
$view = $this->objectManager->get($viewObjectName);
|
||||
$this->setViewConfiguration($view);
|
||||
if ($view->canRender($this->controllerContext) === false) {
|
||||
unset($view);
|
||||
}
|
||||
}
|
||||
if (!isset($view) && $this->defaultViewObjectName != '') {
|
||||
/** @var ViewInterface $view */
|
||||
$view = $this->objectManager->get($this->defaultViewObjectName);
|
||||
$this->setViewConfiguration($view);
|
||||
if ($view->canRender($this->controllerContext) === false) {
|
||||
unset($view);
|
||||
}
|
||||
}
|
||||
if (!isset($view)) {
|
||||
$view = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\View\NotFoundView::class);
|
||||
$view->assign('errorMessage', 'No template was found. View could not be resolved for action "'
|
||||
. $this->request->getControllerActionName() . '" in class "' . $this->request->getControllerObjectName() . '"');
|
||||
}
|
||||
$view->setControllerContext($this->controllerContext);
|
||||
if (method_exists($view, 'injectSettings')) {
|
||||
$view->injectSettings($this->settings);
|
||||
}
|
||||
$view->initializeView();
|
||||
// In TYPO3.Flow, solved through Object Lifecycle methods, we need to call it explicitly
|
||||
$view->assign('settings', $this->settings);
|
||||
// same with settings injection.
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ViewInterface $view
|
||||
*/
|
||||
protected function setViewConfiguration(ViewInterface $view)
|
||||
{
|
||||
// Template Path Override
|
||||
$extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
|
||||
);
|
||||
|
||||
// set TemplateRootPaths
|
||||
$viewFunctionName = 'setTemplateRootPaths';
|
||||
if (method_exists($view, $viewFunctionName)) {
|
||||
$setting = 'templateRootPaths';
|
||||
$parameter = $this->getViewProperty($extbaseFrameworkConfiguration, $setting);
|
||||
// no need to bother if there is nothing to set
|
||||
if ($parameter) {
|
||||
$view->$viewFunctionName($parameter);
|
||||
}
|
||||
}
|
||||
|
||||
// set LayoutRootPaths
|
||||
$viewFunctionName = 'setLayoutRootPaths';
|
||||
if (method_exists($view, $viewFunctionName)) {
|
||||
$setting = 'layoutRootPaths';
|
||||
$parameter = $this->getViewProperty($extbaseFrameworkConfiguration, $setting);
|
||||
// no need to bother if there is nothing to set
|
||||
if ($parameter) {
|
||||
$view->$viewFunctionName($parameter);
|
||||
}
|
||||
}
|
||||
|
||||
// set PartialRootPaths
|
||||
$viewFunctionName = 'setPartialRootPaths';
|
||||
if (method_exists($view, $viewFunctionName)) {
|
||||
$setting = 'partialRootPaths';
|
||||
$parameter = $this->getViewProperty($extbaseFrameworkConfiguration, $setting);
|
||||
// no need to bother if there is nothing to set
|
||||
if ($parameter) {
|
||||
$view->$viewFunctionName($parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the path resolving for *rootPath(s)
|
||||
*
|
||||
* numerical arrays get ordered by key ascending
|
||||
*
|
||||
* @param array $extbaseFrameworkConfiguration
|
||||
* @param string $setting parameter name from TypoScript
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getViewProperty($extbaseFrameworkConfiguration, $setting)
|
||||
{
|
||||
$values = [];
|
||||
if (
|
||||
!empty($extbaseFrameworkConfiguration['view'][$setting])
|
||||
&& is_array($extbaseFrameworkConfiguration['view'][$setting])
|
||||
) {
|
||||
$values = $extbaseFrameworkConfiguration['view'][$setting];
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the fully qualified view object name.
|
||||
*
|
||||
* @return mixed The fully qualified view object name or FALSE if no matching view could be found.
|
||||
*/
|
||||
protected function resolveViewObjectName()
|
||||
{
|
||||
$vendorName = $this->request->getControllerVendorName();
|
||||
if ($vendorName === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$possibleViewName = str_replace(
|
||||
[
|
||||
'@vendor',
|
||||
'@extension',
|
||||
'@controller',
|
||||
'@action'
|
||||
],
|
||||
[
|
||||
$vendorName,
|
||||
$this->request->getControllerExtensionName(),
|
||||
$this->request->getControllerName(),
|
||||
ucfirst($this->request->getControllerActionName())
|
||||
],
|
||||
$this->namespacesViewObjectNamePattern
|
||||
);
|
||||
$format = $this->request->getFormat();
|
||||
$viewObjectName = str_replace('@format', ucfirst($format), $possibleViewName);
|
||||
if (class_exists($viewObjectName) === false) {
|
||||
$viewObjectName = str_replace('@format', '', $possibleViewName);
|
||||
}
|
||||
if (isset($this->viewFormatToObjectNameMap[$format]) && class_exists($viewObjectName) === false) {
|
||||
$viewObjectName = $this->viewFormatToObjectNameMap[$format];
|
||||
}
|
||||
return class_exists($viewObjectName) ? $viewObjectName : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the view before invoking an action method.
|
||||
*
|
||||
* Override this method to solve assign variables common for all actions
|
||||
* or prepare the view in another way before the action is called.
|
||||
*
|
||||
* @param ViewInterface $view The view to be initialized
|
||||
*/
|
||||
protected function initializeView(ViewInterface $view)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the controller before invoking an action method.
|
||||
*
|
||||
* Override this method to solve tasks which all actions have in
|
||||
* common.
|
||||
*/
|
||||
protected function initializeAction()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* A special action which is called if the originally intended action could
|
||||
* not be called, for example if the arguments were not valid.
|
||||
*
|
||||
* The default implementation sets a flash message, request errors and forwards back
|
||||
* to the originating action. This is suitable for most actions dealing with form input.
|
||||
*
|
||||
* We clear the page cache by default on an error as well, as we need to make sure the
|
||||
* data is re-evaluated when the user changes something.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function errorAction()
|
||||
{
|
||||
$this->clearCacheOnError();
|
||||
$this->addErrorFlashMessage();
|
||||
$this->forwardToReferringRequest();
|
||||
|
||||
return $this->getFlattenedValidationErrorMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache of current page on error. Needed because we want a re-evaluation of the data.
|
||||
* Better would be just do delete the cache for the error action, but that is not possible right now.
|
||||
*/
|
||||
protected function clearCacheOnError()
|
||||
{
|
||||
$extbaseSettings = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
|
||||
if (isset($extbaseSettings['persistence']['enableAutomaticCacheClearing']) && $extbaseSettings['persistence']['enableAutomaticCacheClearing'] === '1') {
|
||||
if (isset($GLOBALS['TSFE'])) {
|
||||
$pageUid = $GLOBALS['TSFE']->id;
|
||||
$this->cacheService->clearPageCache([$pageUid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If an error occurred during this request, this adds a flash message describing the error to the flash
|
||||
* message container.
|
||||
*/
|
||||
protected function addErrorFlashMessage()
|
||||
{
|
||||
$errorFlashMessage = $this->getErrorFlashMessage();
|
||||
if ($errorFlashMessage !== false) {
|
||||
$this->addFlashMessage($errorFlashMessage, '', FlashMessage::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A template method for displaying custom error flash messages, or to
|
||||
* display no flash message at all on errors. Override this to customize
|
||||
* the flash message in your action controller.
|
||||
*
|
||||
* @return string The flash message or FALSE if no flash message should be set
|
||||
*/
|
||||
protected function getErrorFlashMessage()
|
||||
{
|
||||
return 'An error occurred while trying to call ' . static::class . '->' . $this->actionMethodName . '()';
|
||||
}
|
||||
|
||||
/**
|
||||
* If information on the request before the current request was sent, this method forwards back
|
||||
* to the originating request. This effectively ends processing of the current request, so do not
|
||||
* call this method before you have finished the necessary business logic!
|
||||
*
|
||||
* @throws StopActionException
|
||||
*/
|
||||
protected function forwardToReferringRequest()
|
||||
{
|
||||
$referringRequest = $this->request->getReferringRequest();
|
||||
if ($referringRequest !== null) {
|
||||
$originalRequest = clone $this->request;
|
||||
$this->request->setOriginalRequest($originalRequest);
|
||||
$this->request->setOriginalRequestMappingResults($this->arguments->validate());
|
||||
$this->forward(
|
||||
$referringRequest->getControllerActionName(),
|
||||
$referringRequest->getControllerName(),
|
||||
$referringRequest->getControllerExtensionName(),
|
||||
$referringRequest->getArguments()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with a basic error message about validation failure.
|
||||
* We may add all validation error messages to a log file in the future,
|
||||
* but for security reasons (@see #54074) we do not return these here.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFlattenedValidationErrorMessage()
|
||||
{
|
||||
$outputMessage = 'Validation failed while trying to call ' . static::class . '->' . $this->actionMethodName . '().' . PHP_EOL;
|
||||
return $outputMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of action method names and their parameters.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*
|
||||
* @return array Array of method parameters by action name
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
public static function getActionMethodParameters($objectManager)
|
||||
{
|
||||
trigger_error(
|
||||
'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
$reflectionService = $objectManager->get(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class);
|
||||
|
||||
$result = [];
|
||||
|
||||
$className = get_called_class();
|
||||
$methodNames = get_class_methods($className);
|
||||
foreach ($methodNames as $methodName) {
|
||||
if (strlen($methodName) > 6 && strpos($methodName, 'Action', strlen($methodName) - 6) !== false) {
|
||||
$result[$methodName] = $reflectionService->getMethodParameters($className, $methodName);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Error\Result;
|
||||
use TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException;
|
||||
use TYPO3\CMS\Extbase\Utility\TypeHandlingUtility;
|
||||
|
||||
/**
|
||||
* A controller argument
|
||||
*/
|
||||
class Argument
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Property\PropertyMapper
|
||||
*/
|
||||
protected $propertyMapper;
|
||||
|
||||
/**
|
||||
* @var MvcPropertyMappingConfiguration
|
||||
*/
|
||||
protected $propertyMappingConfiguration;
|
||||
|
||||
/**
|
||||
* Name of this argument
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = '';
|
||||
|
||||
/**
|
||||
* Short name of this argument
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $shortName;
|
||||
|
||||
/**
|
||||
* Data type of this argument's value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $dataType;
|
||||
|
||||
/**
|
||||
* TRUE if this argument is required
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isRequired = false;
|
||||
|
||||
/**
|
||||
* Actual value of this argument
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* Default value. Used if argument is optional.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $defaultValue;
|
||||
|
||||
/**
|
||||
* A custom validator, used supplementary to the base validation
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface
|
||||
*/
|
||||
protected $validator;
|
||||
|
||||
/**
|
||||
* The validation results. This can be asked if the argument has errors.
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
protected $validationResults;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasBeenValidated = false;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper
|
||||
*/
|
||||
public function injectPropertyMapper(\TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper)
|
||||
{
|
||||
$this->propertyMapper = $propertyMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfiguration $propertyMappingConfiguration
|
||||
*/
|
||||
public function injectPropertyMappingConfiguration(MvcPropertyMappingConfiguration $propertyMappingConfiguration)
|
||||
{
|
||||
$this->propertyMappingConfiguration = $propertyMappingConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs this controller argument
|
||||
*
|
||||
* @param string $name Name of this argument
|
||||
* @param string $dataType The data type of this argument
|
||||
* @throws \InvalidArgumentException if $name is not a string or empty
|
||||
*/
|
||||
public function __construct($name, $dataType)
|
||||
{
|
||||
if (!is_string($name)) {
|
||||
throw new \InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688);
|
||||
}
|
||||
if ($name === '') {
|
||||
throw new \InvalidArgumentException('$name must be a non-empty string.', 1232551853);
|
||||
}
|
||||
$this->name = $name;
|
||||
$this->dataType = TypeHandlingUtility::normalizeType($dataType);
|
||||
|
||||
$this->validationResults = new Result();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this argument
|
||||
*
|
||||
* @return string This argument's name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the short name of this argument.
|
||||
*
|
||||
* @param string $shortName A "short name" - a single character
|
||||
* @throws \InvalidArgumentException if $shortName is not a character
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument $this
|
||||
*/
|
||||
public function setShortName($shortName)
|
||||
{
|
||||
if ($shortName !== null && (!is_string($shortName) || strlen($shortName) !== 1)) {
|
||||
throw new \InvalidArgumentException('$shortName must be a single character or NULL', 1195824959);
|
||||
}
|
||||
$this->shortName = $shortName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the short name of this argument
|
||||
*
|
||||
* @return string This argument's short name
|
||||
*/
|
||||
public function getShortName()
|
||||
{
|
||||
return $this->shortName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data type of this argument's value
|
||||
*
|
||||
* @return string The data type
|
||||
*/
|
||||
public function getDataType()
|
||||
{
|
||||
return $this->dataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this argument to be required
|
||||
*
|
||||
* @param bool $required TRUE if this argument should be required
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument $this
|
||||
*/
|
||||
public function setRequired($required)
|
||||
{
|
||||
$this->isRequired = (bool)$required;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if this argument is required
|
||||
*
|
||||
* @return bool TRUE if this argument is required
|
||||
*/
|
||||
public function isRequired()
|
||||
{
|
||||
return $this->isRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default value of the argument
|
||||
*
|
||||
* @param mixed $defaultValue Default value
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument $this
|
||||
*/
|
||||
public function setDefaultValue($defaultValue)
|
||||
{
|
||||
$this->defaultValue = $defaultValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default value of this argument
|
||||
*
|
||||
* @return mixed The default value
|
||||
*/
|
||||
public function getDefaultValue()
|
||||
{
|
||||
return $this->defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom validator which is used supplementary to the base validation
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator The actual validator object
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument Returns $this (used for fluent interface)
|
||||
*/
|
||||
public function setValidator(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set validator
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface The set validator, NULL if none was set
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this argument.
|
||||
*
|
||||
* @param mixed $rawValue The value of this argument
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument
|
||||
* @throws \TYPO3\CMS\Extbase\Property\Exception
|
||||
*/
|
||||
public function setValue($rawValue)
|
||||
{
|
||||
if ($rawValue === null) {
|
||||
$this->value = null;
|
||||
return $this;
|
||||
}
|
||||
if (is_object($rawValue) && $rawValue instanceof $this->dataType) {
|
||||
$this->value = $rawValue;
|
||||
return $this;
|
||||
}
|
||||
try {
|
||||
$this->value = $this->propertyMapper->convert($rawValue, $this->dataType, $this->propertyMappingConfiguration);
|
||||
} catch (TargetNotFoundException $e) {
|
||||
// for optional arguments no exeption is thrown.
|
||||
if ($this->isRequired()) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
$this->validationResults->merge($this->propertyMapper->getMessages());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this argument
|
||||
*
|
||||
* @return mixed The value of this argument - if none was set, NULL is returned
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
if ($this->value === null) {
|
||||
return $this->defaultValue;
|
||||
}
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Property Mapping Configuration used for this argument; can be used by the initialize*action to modify the Property Mapping.
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfiguration
|
||||
*/
|
||||
public function getPropertyMappingConfiguration()
|
||||
{
|
||||
return $this->propertyMappingConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool TRUE if the argument is valid, FALSE otherwise
|
||||
*/
|
||||
public function isValid(): bool
|
||||
{
|
||||
return !$this->validate()->hasErrors();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result Validation errors which have occurred.
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
public function getValidationResults()
|
||||
{
|
||||
trigger_error(
|
||||
'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
return $this->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this argument's value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string)$this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
public function validate(): \TYPO3\CMS\Extbase\Error\Result
|
||||
{
|
||||
if ($this->hasBeenValidated) {
|
||||
return $this->validationResults;
|
||||
}
|
||||
|
||||
if ($this->validator !== null) {
|
||||
$validationMessages = $this->validator->validate($this->value);
|
||||
$this->validationResults->merge($validationMessages);
|
||||
}
|
||||
|
||||
$this->hasBeenValidated = true;
|
||||
return $this->validationResults;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A composite of controller arguments
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class Arguments extends \ArrayObject
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var array Names of the arguments contained by this object
|
||||
*/
|
||||
protected $argumentNames = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $argumentShortNames = [];
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. If this one is removed, reflection breaks.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or replaces the argument specified by $value. The argument's name is taken from the
|
||||
* argument object itself, therefore the $offset does not have any meaning in this context.
|
||||
*
|
||||
* @param mixed $offset Offset - not used here
|
||||
* @param mixed $value The argument
|
||||
* @throws \InvalidArgumentException if the argument is not a valid Controller Argument object
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!$value instanceof Argument) {
|
||||
throw new \InvalidArgumentException('Controller arguments must be valid TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument objects.', 1187953786);
|
||||
}
|
||||
$argumentName = $value->getName();
|
||||
parent::offsetSet($argumentName, $value);
|
||||
$this->argumentNames[$argumentName] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an argument, aliased to offsetSet()
|
||||
*
|
||||
* @param mixed $value The value
|
||||
* @throws \InvalidArgumentException if the argument is not a valid Controller Argument object
|
||||
*/
|
||||
public function append($value)
|
||||
{
|
||||
if (!$value instanceof Argument) {
|
||||
throw new \InvalidArgumentException('Controller arguments must be valid TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument objects.', 1187953787);
|
||||
}
|
||||
$this->offsetSet(null, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets an argument
|
||||
*
|
||||
* @param mixed $offset Offset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$translatedOffset = $this->translateToLongArgumentName($offset);
|
||||
parent::offsetUnset($translatedOffset);
|
||||
unset($this->argumentNames[$translatedOffset]);
|
||||
if ($offset != $translatedOffset) {
|
||||
unset($this->argumentShortNames[$offset]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the requested index exists
|
||||
*
|
||||
* @param mixed $offset Offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
$translatedOffset = $this->translateToLongArgumentName($offset);
|
||||
return parent::offsetExists($translatedOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at the specified index
|
||||
*
|
||||
* @param mixed $offset Offset
|
||||
* @return Argument The requested argument object
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException if the argument does not exist
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$translatedOffset = $this->translateToLongArgumentName($offset);
|
||||
if ($translatedOffset === '') {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException('The argument "' . $offset . '" does not exist.', 1216909923);
|
||||
}
|
||||
return parent::offsetGet($translatedOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates, adds and returns a new controller argument to this composite object.
|
||||
* If an argument with the same name exists already, it will be replaced by the
|
||||
* new argument object.
|
||||
*
|
||||
* @param string $name Name of the argument
|
||||
* @param string $dataType Name of one of the built-in data types
|
||||
* @param bool $isRequired TRUE if this argument should be marked as required
|
||||
* @param mixed $defaultValue Default value of the argument. Only makes sense if $isRequired==FALSE
|
||||
* @return Argument The new argument
|
||||
*/
|
||||
public function addNewArgument($name, $dataType = 'Text', $isRequired = false, $defaultValue = null)
|
||||
{
|
||||
/** @var Argument $argument */
|
||||
$argument = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Controller\Argument::class, $name, $dataType);
|
||||
$argument->setRequired($isRequired);
|
||||
$argument->setDefaultValue($defaultValue);
|
||||
$this->addArgument($argument);
|
||||
return $argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified controller argument to this composite object.
|
||||
* If an argument with the same name exists already, it will be replaced by the
|
||||
* new argument object.
|
||||
*
|
||||
* Note that the argument will be cloned, not referenced.
|
||||
*
|
||||
* @param Argument $argument The argument to add
|
||||
*/
|
||||
public function addArgument(Argument $argument)
|
||||
{
|
||||
$this->offsetSet(null, $argument);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an argument specified by name
|
||||
*
|
||||
* @param string $argumentName Name of the argument to retrieve
|
||||
* @return Argument
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException
|
||||
*/
|
||||
public function getArgument($argumentName)
|
||||
{
|
||||
if (!$this->offsetExists($argumentName)) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException('An argument "' . $argumentName . '" does not exist.', 1195815178);
|
||||
}
|
||||
return $this->offsetGet($argumentName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an argument with the specified name exists
|
||||
*
|
||||
* @param string $argumentName Name of the argument to check for
|
||||
* @return bool TRUE if such an argument exists, otherwise FALSE
|
||||
* @see offsetExists()
|
||||
*/
|
||||
public function hasArgument($argumentName)
|
||||
{
|
||||
return $this->offsetExists($argumentName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of all arguments contained in this object
|
||||
*
|
||||
* @return array Argument names
|
||||
*/
|
||||
public function getArgumentNames()
|
||||
{
|
||||
return array_keys($this->argumentNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the short names of all arguments contained in this object that have one.
|
||||
*
|
||||
* @return array Argument short names
|
||||
*/
|
||||
public function getArgumentShortNames()
|
||||
{
|
||||
$argumentShortNames = [];
|
||||
/** @var Argument $argument */
|
||||
foreach ($this as $argument) {
|
||||
$argumentShortNames[$argument->getShortName()] = true;
|
||||
}
|
||||
return array_keys($argumentShortNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic setter method for the argument values. Each argument
|
||||
* value can be set by just calling the setArgumentName() method.
|
||||
*
|
||||
* @param string $methodName Name of the method
|
||||
* @param array $arguments Method arguments
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function __call($methodName, array $arguments)
|
||||
{
|
||||
if (strpos($methodName, 'set') !== 0) {
|
||||
throw new \LogicException('Unknown method "' . $methodName . '".', 1210858451);
|
||||
}
|
||||
$firstLowerCaseArgumentName = $this->translateToLongArgumentName(strtolower($methodName[3]) . substr($methodName, 4));
|
||||
$firstUpperCaseArgumentName = $this->translateToLongArgumentName(ucfirst(substr($methodName, 3)));
|
||||
if (in_array($firstLowerCaseArgumentName, $this->getArgumentNames())) {
|
||||
$argument = parent::offsetGet($firstLowerCaseArgumentName);
|
||||
$argument->setValue($arguments[0]);
|
||||
} elseif (in_array($firstUpperCaseArgumentName, $this->getArgumentNames())) {
|
||||
$argument = parent::offsetGet($firstUpperCaseArgumentName);
|
||||
$argument->setValue($arguments[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a short argument name to its corresponding long name. If the
|
||||
* specified argument name is a real argument name already, it will be returned again.
|
||||
*
|
||||
* If an argument with the specified name or short name does not exist, an empty
|
||||
* string is returned.
|
||||
*
|
||||
* @param string $argumentName argument name
|
||||
* @return string long argument name or empty string
|
||||
*/
|
||||
protected function translateToLongArgumentName($argumentName)
|
||||
{
|
||||
if (in_array($argumentName, $this->getArgumentNames())) {
|
||||
return $argumentName;
|
||||
}
|
||||
/** @var Argument $argument */
|
||||
foreach ($this as $argument) {
|
||||
if ($argumentName === $argument->getShortName()) {
|
||||
return $argument->getName();
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all arguments and resets this object
|
||||
*/
|
||||
public function removeAll()
|
||||
{
|
||||
foreach ($this->argumentNames as $argumentName => $booleanValue) {
|
||||
parent::offsetUnset($argumentName);
|
||||
}
|
||||
$this->argumentNames = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all property mapping / validation errors
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
public function getValidationResults()
|
||||
{
|
||||
trigger_error(
|
||||
'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
return $this->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
public function validate(): \TYPO3\CMS\Extbase\Error\Result
|
||||
{
|
||||
$results = new \TYPO3\CMS\Extbase\Error\Result();
|
||||
/** @var Argument $argument */
|
||||
foreach ($this as $argument) {
|
||||
$argumentValidationResults = $argument->validate();
|
||||
if ($argumentValidationResults === null) {
|
||||
continue;
|
||||
}
|
||||
$results->forProperty($argument->getName())->merge($argumentValidationResults);
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition;
|
||||
use TYPO3\CMS\Extbase\Mvc\Cli\ConsoleOutput;
|
||||
use TYPO3\CMS\Extbase\Mvc\Cli\Request;
|
||||
use TYPO3\CMS\Extbase\Mvc\Cli\Response;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
|
||||
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Reflection\ReflectionService;
|
||||
|
||||
/**
|
||||
* A controller which processes requests from the command line
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class CommandController implements CommandControllerInterface
|
||||
{
|
||||
/**
|
||||
* @var Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* @var Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var Arguments
|
||||
*/
|
||||
protected $arguments;
|
||||
|
||||
/**
|
||||
* Name of the command method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $commandMethodName = '';
|
||||
|
||||
/**
|
||||
* Whether the command needs admin access to perform its job
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $requestAdminPermissions = false;
|
||||
|
||||
/**
|
||||
* @var ReflectionService
|
||||
*/
|
||||
protected $reflectionService;
|
||||
|
||||
/**
|
||||
* @var ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var ConsoleOutput
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
trigger_error('Extbase Command Controllers will be removed in TYPO3 v10.0. Migrate to symfony/console commands instead.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService
|
||||
*/
|
||||
public function injectReflectionService(ReflectionService $reflectionService)
|
||||
{
|
||||
$this->reflectionService = $reflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current request type is supported by the controller.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The current request
|
||||
* @return bool TRUE if this request type is supported, otherwise FALSE
|
||||
*/
|
||||
public function canProcessRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request)
|
||||
{
|
||||
return $request instanceof Request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a command line request.
|
||||
*
|
||||
* @param RequestInterface $request The request object
|
||||
* @param ResponseInterface $response The response, modified by this handler
|
||||
* @throws UnsupportedRequestTypeException if the controller doesn't support the current request type
|
||||
*/
|
||||
public function processRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (!$this->canProcessRequest($request)) {
|
||||
throw new UnsupportedRequestTypeException(sprintf('%s only supports command line requests – requests of type "%s" given.', static::class, get_class($request)), 1300787096);
|
||||
}
|
||||
|
||||
$this->request = $request;
|
||||
$this->request->setDispatched(true);
|
||||
$this->response = $response;
|
||||
|
||||
$this->commandMethodName = $this->resolveCommandMethodName();
|
||||
$this->output = $this->objectManager->get(ConsoleOutput::class);
|
||||
$this->arguments = $this->objectManager->get(Arguments::class);
|
||||
$this->initializeCommandMethodArguments();
|
||||
$this->mapRequestArgumentsToControllerArguments();
|
||||
$this->initializeBackendAuthentication();
|
||||
$this->callCommandMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves and checks the current command method name
|
||||
*
|
||||
* Note: The resulting command method name might not have the correct case, which isn't a problem because PHP is
|
||||
* case insensitive regarding method names.
|
||||
*
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException
|
||||
* @return string Method name of the current command
|
||||
* @throws NoSuchCommandException
|
||||
*/
|
||||
protected function resolveCommandMethodName()
|
||||
{
|
||||
$commandMethodName = $this->request->getControllerCommandName() . 'Command';
|
||||
if (!is_callable([$this, $commandMethodName])) {
|
||||
throw new NoSuchCommandException(sprintf('A command method "%s()" does not exist in controller "%s".', $commandMethodName, static::class), 1300902143);
|
||||
}
|
||||
return $commandMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the arguments array of this controller by creating an empty argument object for each of the
|
||||
* method arguments found in the designated command method.
|
||||
*
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException
|
||||
* @throws InvalidArgumentTypeException
|
||||
*/
|
||||
protected function initializeCommandMethodArguments()
|
||||
{
|
||||
$methodParameters = $this->reflectionService
|
||||
->getClassSchema(static::class)
|
||||
->getMethod($this->commandMethodName)['params'] ?? [];
|
||||
|
||||
foreach ($methodParameters as $parameterName => $parameterInfo) {
|
||||
$dataType = null;
|
||||
if (isset($parameterInfo['type'])) {
|
||||
$dataType = $parameterInfo['type'];
|
||||
} elseif ($parameterInfo['array']) {
|
||||
$dataType = 'array';
|
||||
}
|
||||
if ($dataType === null) {
|
||||
throw new InvalidArgumentTypeException(sprintf('The argument type for parameter $%s of method %s->%s() could not be detected.', $parameterName, static::class, $this->commandMethodName), 1306755296);
|
||||
}
|
||||
$defaultValue = ($parameterInfo['defaultValue'] ?? null);
|
||||
$this->arguments->addNewArgument($parameterName, $dataType, $parameterInfo['optional'] === false, $defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps arguments delivered by the request object to the local controller arguments.
|
||||
*/
|
||||
protected function mapRequestArgumentsToControllerArguments()
|
||||
{
|
||||
/** @var Argument $argument */
|
||||
foreach ($this->arguments as $argument) {
|
||||
$argumentName = $argument->getName();
|
||||
if ($this->request->hasArgument($argumentName)) {
|
||||
$argument->setValue($this->request->getArgument($argumentName));
|
||||
continue;
|
||||
}
|
||||
if (!$argument->isRequired()) {
|
||||
continue;
|
||||
}
|
||||
$argumentValue = null;
|
||||
$commandArgumentDefinition = $this->objectManager->get(CommandArgumentDefinition::class, $argumentName, true, null);
|
||||
while ($argumentValue === null) {
|
||||
$argumentValue = $this->output->ask(sprintf('<comment>Please specify the required argument "%s":</comment> ', $commandArgumentDefinition->getDashedName()));
|
||||
}
|
||||
$argument->setValue($argumentValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes and ensures authenticated backend access
|
||||
*/
|
||||
protected function initializeBackendAuthentication()
|
||||
{
|
||||
$backendUserAuthentication = $this->getBackendUserAuthentication();
|
||||
if ($backendUserAuthentication !== null) {
|
||||
$backendUserAuthentication->backendCheckLogin();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the request to another command and / or CommandController.
|
||||
*
|
||||
* Request is directly transferred to the other command / controller
|
||||
* without the need for a new request.
|
||||
*
|
||||
* @param string $commandName
|
||||
* @param string $controllerObjectName
|
||||
* @param array $arguments
|
||||
* @throws StopActionException
|
||||
*/
|
||||
protected function forward($commandName, $controllerObjectName = null, array $arguments = [])
|
||||
{
|
||||
$this->request->setDispatched(false);
|
||||
$this->request->setControllerCommandName($commandName);
|
||||
if ($controllerObjectName !== null) {
|
||||
$this->request->setControllerObjectName($controllerObjectName);
|
||||
}
|
||||
$this->request->setArguments($arguments);
|
||||
|
||||
$this->arguments->removeAll();
|
||||
throw new StopActionException('forward', 1476107661);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the specified command method and passes the arguments.
|
||||
*
|
||||
* If the command returns a string, it is appended to the content in the
|
||||
* response object. If the command doesn't return anything and a valid
|
||||
* view exists, the view is rendered automatically.
|
||||
*/
|
||||
protected function callCommandMethod()
|
||||
{
|
||||
$preparedArguments = [];
|
||||
/** @var Argument $argument */
|
||||
foreach ($this->arguments as $argument) {
|
||||
$preparedArguments[] = $argument->getValue();
|
||||
}
|
||||
$commandResult = call_user_func_array([$this, $this->commandMethodName], $preparedArguments);
|
||||
if (is_string($commandResult) && $commandResult !== '') {
|
||||
$this->response->appendContent($commandResult);
|
||||
} elseif (is_object($commandResult) && method_exists($commandResult, '__toString')) {
|
||||
$this->response->appendContent((string)$commandResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs specified text to the console window
|
||||
* You can specify arguments that will be passed to the text via sprintf
|
||||
*
|
||||
* @see http://www.php.net/sprintf
|
||||
* @param string $text Text to output
|
||||
* @param array $arguments Optional arguments to use for sprintf
|
||||
*/
|
||||
protected function output($text, array $arguments = [])
|
||||
{
|
||||
$this->output->output($text, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs specified text to the console window and appends a line break
|
||||
*
|
||||
* @param string $text Text to output
|
||||
* @param array $arguments Optional arguments to use for sprintf
|
||||
* @see output()
|
||||
*/
|
||||
protected function outputLine($text = '', array $arguments = [])
|
||||
{
|
||||
$this->output->outputLine($text, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given text to fit into MAXIMUM_LINE_LENGTH and outputs it to the
|
||||
* console window
|
||||
*
|
||||
* @param string $text Text to output
|
||||
* @param array $arguments Optional arguments to use for sprintf
|
||||
* @param int $leftPadding The number of spaces to use for indentation
|
||||
* @see outputLine()
|
||||
*/
|
||||
protected function outputFormatted($text = '', array $arguments = [], $leftPadding = 0)
|
||||
{
|
||||
$this->output->outputFormatted($text, $arguments, $leftPadding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits the CLI through the dispatcher
|
||||
* An exit status code can be specified @see http://www.php.net/exit
|
||||
*
|
||||
* @param int $exitCode Exit code to return on exit
|
||||
* @throws StopActionException
|
||||
*/
|
||||
protected function quit($exitCode = 0)
|
||||
{
|
||||
$this->response->setExitCode($exitCode);
|
||||
throw new StopActionException('quit', 1476107681);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the response and exits the CLI without any further code execution
|
||||
* Should be used for commands that flush code caches.
|
||||
*
|
||||
* @param int $exitCode Exit code to return on exit
|
||||
*/
|
||||
protected function sendAndExit($exitCode = 0)
|
||||
{
|
||||
$this->response->send();
|
||||
exit($exitCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the global BackendUserAuthentication object.
|
||||
*
|
||||
* @return BackendUserAuthentication|null
|
||||
*/
|
||||
protected function getBackendUserAuthentication()
|
||||
{
|
||||
return $GLOBALS['BE_USER'] ?? null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for command controllers
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
interface CommandControllerInterface extends \TYPO3\CMS\Extbase\Mvc\Controller\ControllerInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* The controller context contains information from the controller
|
||||
*/
|
||||
class ControllerContext
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Controller\Arguments
|
||||
*/
|
||||
protected $arguments;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
|
||||
*/
|
||||
protected $uriBuilder;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $flashMessageQueueDefaultIdentifier;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Messaging\FlashMessageService
|
||||
*/
|
||||
protected $flashMessageService;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Service\ExtensionService
|
||||
*/
|
||||
protected $extensionService;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Core\Messaging\FlashMessageService $flashMessageService
|
||||
*/
|
||||
public function injectFlashMessageService(\TYPO3\CMS\Core\Messaging\FlashMessageService $flashMessageService)
|
||||
{
|
||||
$this->flashMessageService = $flashMessageService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Service\ExtensionService $extensionService
|
||||
*/
|
||||
public function injectExtensionService(\TYPO3\CMS\Extbase\Service\ExtensionService $extensionService)
|
||||
{
|
||||
$this->extensionService = $extensionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the request of the controller
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Request $request
|
||||
*/
|
||||
public function setRequest(\TYPO3\CMS\Extbase\Mvc\Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request of the controller
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Request
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the response of the controller
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Response $response
|
||||
*/
|
||||
public function setResponse(\TYPO3\CMS\Extbase\Mvc\Response $response)
|
||||
{
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response of the controller
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Response
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the arguments of the controller
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\Arguments $arguments
|
||||
*/
|
||||
public function setArguments(\TYPO3\CMS\Extbase\Mvc\Controller\Arguments $arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the arguments of the controller
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\Arguments
|
||||
*/
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder $uriBuilder
|
||||
*/
|
||||
public function setUriBuilder(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder $uriBuilder)
|
||||
{
|
||||
$this->uriBuilder = $uriBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
|
||||
*/
|
||||
public function getUriBuilder()
|
||||
{
|
||||
return $this->uriBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $identifier Queue-identifier
|
||||
* @return \TYPO3\CMS\Core\Messaging\FlashMessageQueue
|
||||
*/
|
||||
public function getFlashMessageQueue($identifier = null)
|
||||
{
|
||||
if ($identifier === null) {
|
||||
if ($this->flashMessageQueueDefaultIdentifier === null) {
|
||||
// cache the default-identifier for performance-reasons
|
||||
$this->flashMessageQueueDefaultIdentifier = 'extbase.flashmessages.' . $this->extensionService->getPluginNamespace($this->request->getControllerExtensionName(), $this->request->getPluginName());
|
||||
}
|
||||
$identifier = $this->flashMessageQueueDefaultIdentifier;
|
||||
}
|
||||
return $this->flashMessageService->getMessageQueueByIdentifier($identifier);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for controllers
|
||||
*/
|
||||
interface ControllerInterface
|
||||
{
|
||||
/**
|
||||
* Checks if the current request type is supported by the controller.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The current request
|
||||
* @return bool TRUE if this request type is supported, otherwise FALSE
|
||||
*/
|
||||
public function canProcessRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request);
|
||||
|
||||
/**
|
||||
* Processes a general request. The result can be returned by altering the given response.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request object
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, modified by the controller
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException if the controller doesn't support the current request type
|
||||
*/
|
||||
public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response);
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Controller\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Argument Name" exception
|
||||
*/
|
||||
class RequiredArgumentMissingException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* The default property mapping configuration is available
|
||||
* inside the Argument-object.
|
||||
*/
|
||||
class MvcPropertyMappingConfiguration extends \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration
|
||||
{
|
||||
/**
|
||||
* Allow creation of a certain sub property
|
||||
*
|
||||
* @param string $propertyPath
|
||||
*/
|
||||
public function allowCreationForSubProperty($propertyPath)
|
||||
{
|
||||
$this->forProperty($propertyPath)->setTypeConverterOption(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow modification for a given property path
|
||||
*
|
||||
* @param string $propertyPath
|
||||
*/
|
||||
public function allowModificationForSubProperty($propertyPath)
|
||||
{
|
||||
$this->forProperty($propertyPath)->setTypeConverterOption(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the target type for a certain property. Especially useful
|
||||
* if there is an object which has a nested object which is abstract,
|
||||
* and you want to instanciate a concrete object instead.
|
||||
*
|
||||
* @param string $propertyPath
|
||||
* @param string $targetType
|
||||
*/
|
||||
public function setTargetTypeForSubProperty($propertyPath, $targetType)
|
||||
{
|
||||
$this->forProperty($propertyPath)->setTypeConverterOption(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_TARGET_TYPE, $targetType);
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Error\Http\BadRequestException;
|
||||
use TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException;
|
||||
use TYPO3\CMS\Extbase\Security\Exception\InvalidHashException;
|
||||
|
||||
/**
|
||||
* This is a Service which can generate a request hash and check whether the currently given arguments
|
||||
* fit to the request hash.
|
||||
*
|
||||
* It is used when forms are generated and submitted:
|
||||
* After a form has been generated, the method "generateRequestHash" is called with the names of all form fields.
|
||||
* It cleans up the array of form fields and creates another representation of it, which is then serialized and hashed.
|
||||
*
|
||||
* Both serialized form field list and the added hash form the request hash, which will be sent over the wire (as an argument __hmac).
|
||||
*
|
||||
* On the validation side, the validation happens in two steps:
|
||||
* 1) Check if the request hash is consistent (the hash value fits to the serialized string)
|
||||
* 2) Check that _all_ GET/POST parameters submitted occur inside the form field list of the request hash.
|
||||
*
|
||||
* Note: It is crucially important that a private key is computed into the hash value! This is done inside the HashService.
|
||||
*
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class MvcPropertyMappingConfigurationService implements \TYPO3\CMS\Core\SingletonInterface
|
||||
{
|
||||
/**
|
||||
* The hash service class to use
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Security\Cryptography\HashService
|
||||
*/
|
||||
protected $hashService;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService
|
||||
*/
|
||||
public function injectHashService(\TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService)
|
||||
{
|
||||
$this->hashService = $hashService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a request hash for a list of form fields
|
||||
*
|
||||
* @param array $formFieldNames Array of form fields
|
||||
* @param string $fieldNamePrefix
|
||||
*
|
||||
* @return string trusted properties token
|
||||
* @throws \TYPO3\CMS\EXTBASE\Security\Exception\InvalidArgumentForHashGenerationException
|
||||
*/
|
||||
public function generateTrustedPropertiesToken($formFieldNames, $fieldNamePrefix = '')
|
||||
{
|
||||
$formFieldArray = [];
|
||||
foreach ($formFieldNames as $formField) {
|
||||
$formFieldParts = explode('[', $formField);
|
||||
$currentPosition = &$formFieldArray;
|
||||
$formFieldPartsCount = count($formFieldParts);
|
||||
for ($i = 0; $i < $formFieldPartsCount; $i++) {
|
||||
$formFieldPart = $formFieldParts[$i];
|
||||
$formFieldPart = rtrim($formFieldPart, ']');
|
||||
if (!is_array($currentPosition)) {
|
||||
throw new \TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException('The form field "' . $formField . '" is declared as array, but it collides with a previous form field of the same name which declared the field as string. This is an inconsistency you need to fix inside your Fluid form. (String overridden by Array)', 1255072196);
|
||||
}
|
||||
if ($i === $formFieldPartsCount - 1) {
|
||||
if (isset($currentPosition[$formFieldPart]) && is_array($currentPosition[$formFieldPart])) {
|
||||
throw new \TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException('The form field "' . $formField . '" is declared as string, but it collides with a previous form field of the same name which declared the field as array. This is an inconsistency you need to fix inside your Fluid form. (Array overridden by String)', 1255072587);
|
||||
}
|
||||
// Last iteration - add a string
|
||||
if ($formFieldPart === '') {
|
||||
$currentPosition[] = 1;
|
||||
} else {
|
||||
$currentPosition[$formFieldPart] = 1;
|
||||
}
|
||||
} else {
|
||||
if ($formFieldPart === '') {
|
||||
throw new \TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException('The form field "' . $formField . '" is invalid. Reason: "[]" used not as last argument, but somewhere in the middle (like foo[][bar]).', 1255072832);
|
||||
}
|
||||
if (!isset($currentPosition[$formFieldPart])) {
|
||||
$currentPosition[$formFieldPart] = [];
|
||||
}
|
||||
$currentPosition = &$currentPosition[$formFieldPart];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($fieldNamePrefix !== '') {
|
||||
$formFieldArray = ($formFieldArray[$fieldNamePrefix] ?? []);
|
||||
}
|
||||
return $this->serializeAndHashFormFieldArray($formFieldArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize and hash the form field array
|
||||
*
|
||||
* @param array $formFieldArray form field array to be serialized and hashed
|
||||
*
|
||||
* @return string Hash
|
||||
*/
|
||||
protected function serializeAndHashFormFieldArray(array $formFieldArray)
|
||||
{
|
||||
$serializedFormFieldArray = serialize($formFieldArray);
|
||||
return $this->hashService->appendHmac($serializedFormFieldArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the property mapping configuration in $controllerArguments if
|
||||
* the trusted properties are set inside the request.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Request $request
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\Arguments $controllerArguments
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function initializePropertyMappingConfigurationFromRequest(\TYPO3\CMS\Extbase\Mvc\Request $request, \TYPO3\CMS\Extbase\Mvc\Controller\Arguments $controllerArguments)
|
||||
{
|
||||
$trustedPropertiesToken = $request->getInternalArgument('__trustedProperties');
|
||||
if (!is_string($trustedPropertiesToken)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$serializedTrustedProperties = $this->hashService->validateAndStripHmac($trustedPropertiesToken);
|
||||
} catch (InvalidHashException | InvalidArgumentForHashGenerationException $e) {
|
||||
throw new BadRequestException('The HMAC of the form could not be validated.', 1581862822);
|
||||
}
|
||||
$trustedProperties = unserialize($serializedTrustedProperties, ['allowed_classes' => false]);
|
||||
foreach ($trustedProperties as $propertyName => $propertyConfiguration) {
|
||||
if (!$controllerArguments->hasArgument($propertyName)) {
|
||||
continue;
|
||||
}
|
||||
$propertyMappingConfiguration = $controllerArguments->getArgument($propertyName)->getPropertyMappingConfiguration();
|
||||
$this->modifyPropertyMappingConfiguration($propertyConfiguration, $propertyMappingConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the passed $propertyMappingConfiguration according to the $propertyConfiguration which
|
||||
* has been generated by Fluid. In detail, if the $propertyConfiguration contains
|
||||
* an __identity field, we allow modification of objects; else we allow creation.
|
||||
*
|
||||
* All other properties are specified as allowed properties.
|
||||
*
|
||||
* @param array $propertyConfiguration
|
||||
* @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration $propertyMappingConfiguration
|
||||
*/
|
||||
protected function modifyPropertyMappingConfiguration($propertyConfiguration, \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration $propertyMappingConfiguration)
|
||||
{
|
||||
if (!is_array($propertyConfiguration)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($propertyConfiguration['__identity'])) {
|
||||
$propertyMappingConfiguration->setTypeConverterOption(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED, true);
|
||||
unset($propertyConfiguration['__identity']);
|
||||
} else {
|
||||
$propertyMappingConfiguration->setTypeConverterOption(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, true);
|
||||
}
|
||||
|
||||
foreach ($propertyConfiguration as $innerKey => $innerValue) {
|
||||
if (is_array($innerValue)) {
|
||||
$this->modifyPropertyMappingConfiguration($innerValue, $propertyMappingConfiguration->forProperty($innerKey));
|
||||
}
|
||||
$propertyMappingConfiguration->allowProperties($innerKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatches requests to the controller which was specified by the request and
|
||||
* returns the response the controller generated.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class Dispatcher implements \TYPO3\CMS\Core\SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface A reference to the object manager
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
|
||||
*/
|
||||
protected $signalSlotDispatcher;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
|
||||
*/
|
||||
public function injectSignalSlotDispatcher(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher)
|
||||
{
|
||||
$this->signalSlotDispatcher = $signalSlotDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the global dispatcher
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager A reference to the object manager
|
||||
*/
|
||||
public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a request to a controller and initializes the security framework.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request to dispatch
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, to be modified by the controller
|
||||
* @throws Exception\InfiniteLoopException
|
||||
*/
|
||||
public function dispatch(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response)
|
||||
{
|
||||
$dispatchLoopCount = 0;
|
||||
while (!$request->isDispatched()) {
|
||||
if ($dispatchLoopCount++ > 99) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InfiniteLoopException('Could not ultimately dispatch the request after ' . $dispatchLoopCount . ' iterations. Most probably, a @' . \TYPO3\CMS\Extbase\Annotation\IgnoreValidation::class . ' annotation is missing on re-displaying a form with validation errors.', 1217839467);
|
||||
}
|
||||
$controller = $this->resolveController($request);
|
||||
try {
|
||||
$controller->processRequest($request, $response);
|
||||
} catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $ignoredException) {
|
||||
}
|
||||
}
|
||||
$this->emitAfterRequestDispatchSignal($request, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a signal after a request was dispatched
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*/
|
||||
protected function emitAfterRequestDispatchSignal(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response)
|
||||
{
|
||||
$this->signalSlotDispatcher->dispatch(__CLASS__, 'afterRequestDispatch', [$request, $response]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and instanciates a controller that matches the current request.
|
||||
* If no controller can be found, an instance of NotFoundControllerInterface is returned.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request to dispatch
|
||||
* @throws Exception\InvalidControllerException
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Controller\ControllerInterface
|
||||
*/
|
||||
protected function resolveController(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request)
|
||||
{
|
||||
$controllerObjectName = $request->getControllerObjectName();
|
||||
$controller = $this->objectManager->get($controllerObjectName);
|
||||
if (!$controller instanceof \TYPO3\CMS\Extbase\Mvc\Controller\ControllerInterface) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerException(
|
||||
'Invalid controller "' . $request->getControllerObjectName() . '". The controller must implement the TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ControllerInterface.',
|
||||
1476109646
|
||||
);
|
||||
}
|
||||
return $controller;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A generic MVC exception
|
||||
*/
|
||||
class Exception extends \TYPO3\CMS\Extbase\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Ambiguous command identifier" exception
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class AmbiguousCommandIdentifierException extends \TYPO3\CMS\Extbase\Mvc\Exception\CommandException
|
||||
{
|
||||
/**
|
||||
* @var array<\TYPO3\CMS\Extbase\Mvc\Cli\Command>
|
||||
*/
|
||||
protected $matchingCommands = [];
|
||||
|
||||
/**
|
||||
* Overwrites parent constructor to be able to inject matching commands.
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
* @param \Exception|null $previousException
|
||||
* @param array $matchingCommands <\TYPO3\CMS\Extbase\Mvc\Cli\Command> $matchingCommands Commands that matched the command identifier
|
||||
* @see Exception
|
||||
*/
|
||||
public function __construct($message = '', $code = 0, \Exception $previousException = null, array $matchingCommands)
|
||||
{
|
||||
$this->matchingCommands = $matchingCommands;
|
||||
parent::__construct($message, $code, $previousException);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<\TYPO3\CMS\Extbase\Mvc\Cli\Command>
|
||||
*/
|
||||
public function getMatchingCommands()
|
||||
{
|
||||
return $this->matchingCommands;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base command exception
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use symfony/console commands instead.
|
||||
*/
|
||||
class CommandException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Infinite Loop" exception
|
||||
*/
|
||||
class InfiniteLoopException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "invalid action name" exception
|
||||
*/
|
||||
class InvalidActionNameException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Argument Name" exception
|
||||
*/
|
||||
class InvalidArgumentMixingException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Argument Name" exception
|
||||
*/
|
||||
class InvalidArgumentNameException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Argument Type" exception
|
||||
*/
|
||||
class InvalidArgumentTypeException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Argument Value" exception
|
||||
*/
|
||||
class InvalidArgumentValueException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Controller" exception
|
||||
*/
|
||||
class InvalidControllerException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Controller Name" exception
|
||||
*/
|
||||
class InvalidControllerNameException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Extension Name" exception
|
||||
*/
|
||||
class InvalidExtensionNameException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid Request Method" exception
|
||||
*/
|
||||
class InvalidRequestMethodException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A "No Such Action" exception
|
||||
*/
|
||||
class NoSuchActionException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A "No Such Argument" exception
|
||||
*/
|
||||
class NoSuchArgumentException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A "No Such Command" exception
|
||||
*/
|
||||
class NoSuchCommandException extends \TYPO3\CMS\Extbase\Mvc\Exception\CommandException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A "No Such Controller" exception
|
||||
*/
|
||||
class NoSuchControllerException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* This exception is thrown by a controller to stop the execution of the current
|
||||
* action and return the control to the dispatcher. The dispatcher catches this
|
||||
* exception and - depending on the "dispatched" status of the request - either
|
||||
* continues dispatching the request or returns control to the request handler.
|
||||
*
|
||||
* See the Action Controller's forward() and redirectToUri() methods for more information.
|
||||
*/
|
||||
class StopActionException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Unsupported Request Type" exception
|
||||
*/
|
||||
class UnsupportedRequestTypeException extends \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,518 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
/*
|
||||
* 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\ClassNamingUtility;
|
||||
|
||||
/**
|
||||
* Represents a generic request.
|
||||
*/
|
||||
class Request implements RequestInterface
|
||||
{
|
||||
const PATTERN_MATCH_FORMAT = '/^[a-z0-9]{1,5}$/';
|
||||
|
||||
/**
|
||||
* Pattern after which the namespaced controller object name is built
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespacedControllerObjectNamePattern = '@vendor\@extension\@subpackage\Controller\@controllerController';
|
||||
|
||||
/**
|
||||
* @var string Key of the plugin which identifies the plugin. It must be a string containing [a-z0-9]
|
||||
*/
|
||||
protected $pluginName = '';
|
||||
|
||||
/**
|
||||
* @var string Name of the extension which is supposed to handle this request. This is the extension name converted to UpperCamelCase
|
||||
*/
|
||||
protected $controllerExtensionName;
|
||||
|
||||
/**
|
||||
* @var string vendor prefix
|
||||
*/
|
||||
protected $controllerVendorName;
|
||||
|
||||
/**
|
||||
* Subpackage key of the controller which is supposed to handle this request.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $controllerSubpackageKey;
|
||||
|
||||
/**
|
||||
* @var string Object name of the controller which is supposed to handle this request.
|
||||
*/
|
||||
protected $controllerName = 'Standard';
|
||||
|
||||
/**
|
||||
* @var string Name of the action the controller is supposed to take.
|
||||
*/
|
||||
protected $controllerActionName = 'index';
|
||||
|
||||
/**
|
||||
* @var array The arguments for this request
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* Framework-internal arguments for this request, such as __referrer.
|
||||
* All framework-internal arguments start with double underscore (__),
|
||||
* and are only used from within the framework. Not for user consumption.
|
||||
* Internal Arguments can be objects, in contrast to public arguments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $internalArguments = [];
|
||||
|
||||
/**
|
||||
* @var string The requested representation format
|
||||
*/
|
||||
protected $format = 'txt';
|
||||
|
||||
/**
|
||||
* @var bool If this request has been changed and needs to be dispatched again
|
||||
*/
|
||||
protected $dispatched = false;
|
||||
|
||||
/**
|
||||
* If this request is a forward because of an error, the original request gets filled.
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Request
|
||||
*/
|
||||
protected $originalRequest;
|
||||
|
||||
/**
|
||||
* If the request is a forward because of an error, these mapping results get filled here.
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
protected $originalRequestMappingResults;
|
||||
|
||||
/**
|
||||
* Sets the dispatched flag
|
||||
*
|
||||
* @param bool $flag If this request has been dispatched
|
||||
*/
|
||||
public function setDispatched($flag)
|
||||
{
|
||||
$this->dispatched = (bool)$flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this request has been dispatched and addressed by the responsible
|
||||
* controller and the response is ready to be sent.
|
||||
*
|
||||
* The dispatcher will try to dispatch the request again if it has not been
|
||||
* addressed yet.
|
||||
*
|
||||
* @return bool TRUE if this request has been disptached successfully
|
||||
*/
|
||||
public function isDispatched()
|
||||
{
|
||||
return $this->dispatched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object name of the controller defined by the extension name and
|
||||
* controller name
|
||||
*
|
||||
* @return string The controller's Object Name
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchControllerException if the controller does not exist
|
||||
*/
|
||||
public function getControllerObjectName()
|
||||
{
|
||||
$objectName = str_replace(
|
||||
[
|
||||
'@extension',
|
||||
'@subpackage',
|
||||
'@controller',
|
||||
'@vendor',
|
||||
'\\\\'
|
||||
],
|
||||
[
|
||||
$this->controllerExtensionName,
|
||||
$this->controllerSubpackageKey,
|
||||
$this->controllerName,
|
||||
$this->controllerVendorName,
|
||||
'\\'
|
||||
],
|
||||
$this->namespacedControllerObjectNamePattern
|
||||
);
|
||||
|
||||
// @todo implement getCaseSensitiveObjectName()
|
||||
if ($objectName === false) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchControllerException('The controller object "' . $objectName . '" does not exist.', 1220884009);
|
||||
}
|
||||
return $objectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly sets the object name of the controller
|
||||
*
|
||||
* @param string $controllerObjectName The fully qualified controller object name
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setControllerObjectName($controllerObjectName)
|
||||
{
|
||||
$nameParts = ClassNamingUtility::explodeObjectControllerName($controllerObjectName);
|
||||
$this->controllerVendorName = $nameParts['vendorName'] ?? null;
|
||||
$this->controllerExtensionName = $nameParts['extensionName'];
|
||||
$this->controllerSubpackageKey = $nameParts['subpackageKey'] ?? null;
|
||||
$this->controllerName = $nameParts['controllerName'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the plugin name.
|
||||
*
|
||||
* @param string|null $pluginName
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setPluginName($pluginName = null)
|
||||
{
|
||||
if ($pluginName !== null) {
|
||||
$this->pluginName = $pluginName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin key.
|
||||
*
|
||||
* @return string The plugin key
|
||||
*/
|
||||
public function getPluginName()
|
||||
{
|
||||
return $this->pluginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the extension name of the controller.
|
||||
*
|
||||
* @param string $controllerExtensionName The extension name.
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException if the extension name is not valid
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setControllerExtensionName($controllerExtensionName)
|
||||
{
|
||||
if ($controllerExtensionName !== null) {
|
||||
$this->controllerExtensionName = $controllerExtensionName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extension name of the specified controller.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
public function getControllerExtensionName()
|
||||
{
|
||||
return $this->controllerExtensionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extension name of the specified controller.
|
||||
*
|
||||
* @return string The extension key
|
||||
*/
|
||||
public function getControllerExtensionKey()
|
||||
{
|
||||
return \TYPO3\CMS\Core\Utility\GeneralUtility::camelCaseToLowerCaseUnderscored($this->controllerExtensionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subpackage key of the controller.
|
||||
*
|
||||
* @param string $subpackageKey The subpackage key.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setControllerSubpackageKey($subpackageKey)
|
||||
{
|
||||
$this->controllerSubpackageKey = $subpackageKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subpackage key of the specified controller.
|
||||
* If there is no subpackage key set, the method returns NULL
|
||||
*
|
||||
* @return string The subpackage key
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function getControllerSubpackageKey()
|
||||
{
|
||||
return $this->controllerSubpackageKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the controller which is supposed to handle the request.
|
||||
* Note: This is not the object name of the controller!
|
||||
*
|
||||
* @param string $controllerName Name of the controller
|
||||
* @throws Exception\InvalidControllerNameException
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setControllerName($controllerName)
|
||||
{
|
||||
if (!is_string($controllerName) && $controllerName !== null) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException('The controller name must be a valid string, ' . gettype($controllerName) . ' given.', 1187176358);
|
||||
}
|
||||
if ($controllerName !== null) {
|
||||
$this->controllerName = $controllerName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object name of the controller supposed to handle this request, if one
|
||||
* was set already (if not, the name of the default controller is returned)
|
||||
*
|
||||
* @return string Object name of the controller
|
||||
*/
|
||||
public function getControllerName()
|
||||
{
|
||||
return $this->controllerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the action contained in this request.
|
||||
*
|
||||
* Note that the action name must start with a lower case letter and is case sensitive.
|
||||
*
|
||||
* @param string $actionName Name of the action to execute by the controller
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException if the action name is not valid
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setControllerActionName($actionName)
|
||||
{
|
||||
if (!is_string($actionName) && $actionName !== null) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException('The action name must be a valid string, ' . gettype($actionName) . ' given (' . $actionName . ').', 1187176359);
|
||||
}
|
||||
if ($actionName[0] !== strtolower($actionName[0]) && $actionName !== null) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException('The action name must start with a lower case letter, "' . $actionName . '" does not match this criteria.', 1218473352);
|
||||
}
|
||||
if ($actionName !== null) {
|
||||
$this->controllerActionName = $actionName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the action the controller is supposed to execute.
|
||||
*
|
||||
* @return string Action name
|
||||
*/
|
||||
public function getControllerActionName()
|
||||
{
|
||||
$controllerObjectName = $this->getControllerObjectName();
|
||||
if ($controllerObjectName !== '' && $this->controllerActionName === strtolower($this->controllerActionName)) {
|
||||
$actionMethodName = $this->controllerActionName . 'Action';
|
||||
$classMethods = get_class_methods($controllerObjectName);
|
||||
if (is_array($classMethods)) {
|
||||
foreach ($classMethods as $existingMethodName) {
|
||||
if (strtolower($existingMethodName) === strtolower($actionMethodName)) {
|
||||
$this->controllerActionName = substr($existingMethodName, 0, -6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->controllerActionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the specified argument
|
||||
*
|
||||
* @param string $argumentName Name of the argument to set
|
||||
* @param mixed $value The new value
|
||||
* @throws Exception\InvalidArgumentNameException
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setArgument($argumentName, $value)
|
||||
{
|
||||
if (!is_string($argumentName) || $argumentName === '') {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException('Invalid argument name.', 1210858767);
|
||||
}
|
||||
if ($argumentName[0] === '_' && $argumentName[1] === '_') {
|
||||
$this->internalArguments[$argumentName] = $value;
|
||||
return;
|
||||
}
|
||||
if (!in_array($argumentName, ['@extension', '@subpackage', '@controller', '@action', '@format', '@vendor'], true)) {
|
||||
$this->arguments[$argumentName] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the VendorName
|
||||
*
|
||||
* @param string $vendorName
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setControllerVendorName($vendorName)
|
||||
{
|
||||
$this->controllerVendorName = $vendorName;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the VendorName
|
||||
*
|
||||
* @return string
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function getControllerVendorName()
|
||||
{
|
||||
return $this->controllerVendorName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the whole arguments array and therefore replaces any arguments
|
||||
* which existed before.
|
||||
*
|
||||
* @param array $arguments An array of argument names and their values
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$this->arguments = [];
|
||||
foreach ($arguments as $argumentName => $argumentValue) {
|
||||
$this->setArgument($argumentName, $argumentValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of arguments and their values
|
||||
*
|
||||
* @return array Associative array of arguments and their values (which may be arguments and values as well)
|
||||
*/
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified argument
|
||||
*
|
||||
* @param string $argumentName Name of the argument
|
||||
*
|
||||
* @return string|array Value of the argument
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException if such an argument does not exist
|
||||
*/
|
||||
public function getArgument($argumentName)
|
||||
{
|
||||
if (!isset($this->arguments[$argumentName])) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException('An argument "' . $argumentName . '" does not exist for this request.', 1176558158);
|
||||
}
|
||||
return $this->arguments[$argumentName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an argument of the given name exists (is set)
|
||||
*
|
||||
* @param string $argumentName Name of the argument to check
|
||||
*
|
||||
* @return bool TRUE if the argument is set, otherwise FALSE
|
||||
*/
|
||||
public function hasArgument($argumentName)
|
||||
{
|
||||
return isset($this->arguments[$argumentName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested representation format
|
||||
*
|
||||
* @param string $format The desired format, something like "html", "xml", "png", "json" or the like. Can even be something like "rss.xml".
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setFormat($format)
|
||||
{
|
||||
$this->format = $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested representation format
|
||||
*
|
||||
* @return string The desired format, something like "html", "xml", "png", "json" or the like.
|
||||
*/
|
||||
public function getFormat()
|
||||
{
|
||||
return $this->format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the original request. Filled only if a property mapping error occurred.
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\Request the original request.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function getOriginalRequest()
|
||||
{
|
||||
return $this->originalRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Request $originalRequest
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setOriginalRequest(\TYPO3\CMS\Extbase\Mvc\Request $originalRequest)
|
||||
{
|
||||
$this->originalRequest = $originalRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request mapping results for the original request.
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function getOriginalRequestMappingResults()
|
||||
{
|
||||
if ($this->originalRequestMappingResults === null) {
|
||||
return new \TYPO3\CMS\Extbase\Error\Result();
|
||||
}
|
||||
return $this->originalRequestMappingResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Error\Result $originalRequestMappingResults
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function setOriginalRequestMappingResults(\TYPO3\CMS\Extbase\Error\Result $originalRequestMappingResults)
|
||||
{
|
||||
$this->originalRequestMappingResults = $originalRequestMappingResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internal arguments of the request, i.e. every argument starting
|
||||
* with two underscores.
|
||||
*
|
||||
* @return array
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function getInternalArguments()
|
||||
{
|
||||
return $this->internalArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified argument
|
||||
*
|
||||
* @param string $argumentName Name of the argument
|
||||
* @return string Value of the argument, or NULL if not set.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
public function getInternalArgument($argumentName)
|
||||
{
|
||||
if (!isset($this->internalArguments[$argumentName])) {
|
||||
return null;
|
||||
}
|
||||
return $this->internalArguments[$argumentName];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* The interface for a request handler
|
||||
*/
|
||||
interface RequestHandlerInterface
|
||||
{
|
||||
/**
|
||||
* Handles a raw request and returns the respsonse.
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\ResponseInterface
|
||||
*/
|
||||
public function handleRequest();
|
||||
|
||||
/**
|
||||
* Checks if the request handler can handle the current request.
|
||||
*
|
||||
* @return bool TRUE if it can handle the request, otherwise FALSE
|
||||
*/
|
||||
public function canHandleRequest();
|
||||
|
||||
/**
|
||||
* Returns the priority - how eager the handler is to actually handle the
|
||||
* request. An integer > 0 means "I want to handle this request" where
|
||||
* "100" is default. "0" means "I am a fallback solution".
|
||||
*
|
||||
* @return int The priority of the request handler
|
||||
*/
|
||||
public function getPriority();
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Analyzes the raw request and delivers a request handler which can handle it.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class RequestHandlerResolver
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManager(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes the raw request and tries to find a request handler which can handle
|
||||
* it. If none is found, an exception is thrown.
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\RequestHandlerInterface A request handler
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception
|
||||
*/
|
||||
public function resolveRequestHandler()
|
||||
{
|
||||
$availableRequestHandlerClassNames = $this->getRegisteredRequestHandlerClassNames();
|
||||
$suitableRequestHandlers = [];
|
||||
foreach ($availableRequestHandlerClassNames as $requestHandlerClassName) {
|
||||
$requestHandler = $this->objectManager->get($requestHandlerClassName);
|
||||
if ($requestHandler->canHandleRequest()) {
|
||||
$priority = $requestHandler->getPriority();
|
||||
if (isset($suitableRequestHandlers[$priority])) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception('More than one request handler with the same priority can handle the request, but only one handler may be active at a time!', 1176475350);
|
||||
}
|
||||
$suitableRequestHandlers[$priority] = $requestHandler;
|
||||
}
|
||||
}
|
||||
if (empty($suitableRequestHandlers)) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception('No suitable request handler found.', 1205414233);
|
||||
}
|
||||
ksort($suitableRequestHandlers);
|
||||
return array_pop($suitableRequestHandlers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all registered request handlers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRegisteredRequestHandlerClassNames()
|
||||
{
|
||||
$settings = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
|
||||
return is_array($settings['mvc']['requestHandlers']) ? $settings['mvc']['requestHandlers'] : [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contract for a request.
|
||||
*/
|
||||
interface RequestInterface
|
||||
{
|
||||
/**
|
||||
* Sets the dispatched flag
|
||||
*
|
||||
* @param bool $flag If this request has been dispatched
|
||||
*/
|
||||
public function setDispatched($flag);
|
||||
|
||||
/**
|
||||
* If this request has been dispatched and addressed by the responsible
|
||||
* controller and the response is ready to be sent.
|
||||
*
|
||||
* The dispatcher will try to dispatch the request again if it has not been
|
||||
* addressed yet.
|
||||
*
|
||||
* @return bool TRUE if this request has been disptached successfully
|
||||
*/
|
||||
public function isDispatched();
|
||||
|
||||
/**
|
||||
* Returns the object name of the controller defined by the package key and
|
||||
* controller name
|
||||
*
|
||||
* @return string The controller's Object Name
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchControllerException if the controller does not exist
|
||||
*/
|
||||
public function getControllerObjectName();
|
||||
|
||||
/**
|
||||
* Sets the value of the specified argument
|
||||
*
|
||||
* @param string $argumentName Name of the argument to set
|
||||
* @param mixed $value The new value
|
||||
*/
|
||||
public function setArgument($argumentName, $value);
|
||||
|
||||
/**
|
||||
* Sets the whole arguments array and therefore replaces any arguments
|
||||
* which existed before.
|
||||
*
|
||||
* @param array $arguments An array of argument names and their values
|
||||
*/
|
||||
public function setArguments(array $arguments);
|
||||
|
||||
/**
|
||||
* Returns the value of the specified argument
|
||||
*
|
||||
* @param string $argumentName Name of the argument
|
||||
* @return string Value of the argument
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException if such an argument does not exist
|
||||
*/
|
||||
public function getArgument($argumentName);
|
||||
|
||||
/**
|
||||
* Checks if an argument of the given name exists (is set)
|
||||
*
|
||||
* @param string $argumentName Name of the argument to check
|
||||
* @return bool TRUE if the argument is set, otherwise FALSE
|
||||
*/
|
||||
public function hasArgument($argumentName);
|
||||
|
||||
/**
|
||||
* Returns an array of arguments and their values
|
||||
*
|
||||
* @return array Array of arguments and their values (which may be arguments and values as well)
|
||||
*/
|
||||
public function getArguments();
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A generic and very basic response implementation
|
||||
*/
|
||||
class Response implements \TYPO3\CMS\Extbase\Mvc\ResponseInterface
|
||||
{
|
||||
/**
|
||||
* @var string The response content
|
||||
*/
|
||||
protected $content;
|
||||
|
||||
/**
|
||||
* Overrides and sets the content of the response
|
||||
*
|
||||
* @param string $content The response content
|
||||
*/
|
||||
public function setContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends content to the already existing content.
|
||||
*
|
||||
* @param string $content More response content
|
||||
*/
|
||||
public function appendContent($content)
|
||||
{
|
||||
$this->content .= $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response content without sending it.
|
||||
*
|
||||
* @return string The response content
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the content, returns and clears it.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
$content = $this->getContent();
|
||||
$this->setContent('');
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content of the response.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getContent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A generic and very basic response implementation
|
||||
*/
|
||||
interface ResponseInterface
|
||||
{
|
||||
/**
|
||||
* Overrides and sets the content of the response
|
||||
*
|
||||
* @param string $content The response content
|
||||
*/
|
||||
public function setContent($content);
|
||||
|
||||
/**
|
||||
* Appends content to the already existing content.
|
||||
*
|
||||
* @param string $content More response content
|
||||
*/
|
||||
public function appendContent($content);
|
||||
|
||||
/**
|
||||
* Returns the response content without sending it.
|
||||
*
|
||||
* @return string The response content
|
||||
*/
|
||||
public function getContent();
|
||||
|
||||
/**
|
||||
* Returns the response content without sending it.
|
||||
*
|
||||
* @return string The response content
|
||||
*/
|
||||
public function shutdown();
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\View;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract View
|
||||
*/
|
||||
abstract class AbstractView implements \TYPO3\CMS\Extbase\Mvc\View\ViewInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext
|
||||
*/
|
||||
protected $controllerContext;
|
||||
|
||||
/**
|
||||
* View variables and their values
|
||||
*
|
||||
* @var array
|
||||
* @see assign()
|
||||
*/
|
||||
protected $variables = [];
|
||||
|
||||
/**
|
||||
* Sets the current controller context
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext
|
||||
*/
|
||||
public function setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
|
||||
{
|
||||
$this->controllerContext = $controllerContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a variable to $this->viewData.
|
||||
* Can be chained, so $this->view->assign(..., ...)->assign(..., ...); is possible
|
||||
*
|
||||
* @param string $key Key of variable
|
||||
* @param mixed $value Value of object
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\View\AbstractView an instance of $this, to enable chaining
|
||||
*/
|
||||
public function assign($key, $value)
|
||||
{
|
||||
$this->variables[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple variables to $this->viewData.
|
||||
*
|
||||
* @param array $values array in the format array(key1 => value1, key2 => value2).
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\View\AbstractView an instance of $this, to enable chaining
|
||||
*/
|
||||
public function assignMultiple(array $values)
|
||||
{
|
||||
foreach ($values as $key => $value) {
|
||||
$this->assign($key, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the view implementation can render the view for the given context.
|
||||
*
|
||||
* By default we assume that the view implementation can handle all kinds of
|
||||
* contexts. Override this method if that is not the case.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext
|
||||
* @return bool TRUE if the view has something useful to display, otherwise FALSE
|
||||
*/
|
||||
public function canRender(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this view.
|
||||
*
|
||||
* Override this method for initializing your concrete view implementation.
|
||||
*/
|
||||
public function initializeView()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\View;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An empty view - a special case.
|
||||
*/
|
||||
class EmptyView implements \TYPO3\CMS\Extbase\Mvc\View\ViewInterface
|
||||
{
|
||||
/**
|
||||
* Dummy method to satisfy the ViewInterface
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext
|
||||
* @internal
|
||||
*/
|
||||
public function setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy method to satisfy the ViewInterface
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\View\EmptyView instance of $this to allow chaining
|
||||
*/
|
||||
public function assign($key, $value)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy method to satisfy the ViewInterface
|
||||
*
|
||||
* @param array $values
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\View\EmptyView instance of $this to allow chaining
|
||||
*/
|
||||
public function assignMultiple(array $values)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This view can be used in any case.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext
|
||||
* @return bool TRUE
|
||||
*/
|
||||
public function canRender(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the empty view
|
||||
*
|
||||
* @return string An empty string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return '<!-- This is the output of the Empty View. An appropriate View was not found. -->';
|
||||
}
|
||||
|
||||
/**
|
||||
* A magic call method.
|
||||
*
|
||||
* Because this empty view is used as a Special Case in situations when no matching
|
||||
* view is available, it must be able to handle method calls which originally were
|
||||
* directed to another type of view. This magic method should prevent PHP from issuing
|
||||
* a fatal error.
|
||||
*
|
||||
* @param string $methodName
|
||||
* @param array $arguments
|
||||
*/
|
||||
public function __call($methodName, array $arguments)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this view.
|
||||
*
|
||||
* Override this method for initializing your concrete view implementation.
|
||||
*/
|
||||
public function initializeView()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Extbase\Mvc\View;
|
||||
|
||||
/*
|
||||
* 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\Mvc\Web\Response as WebResponse;
|
||||
use TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
use TYPO3\CMS\Extbase\Reflection\ReflectionService;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* A JSON view
|
||||
*/
|
||||
class JsonView extends AbstractView
|
||||
{
|
||||
/**
|
||||
* Definition for the class name exposure configuration,
|
||||
* that is, if the class name of an object should also be
|
||||
* part of the output JSON, if configured.
|
||||
*
|
||||
* Setting this value, the object's class name is fully
|
||||
* put out, including the namespace.
|
||||
*/
|
||||
const EXPOSE_CLASSNAME_FULLY_QUALIFIED = 1;
|
||||
|
||||
/**
|
||||
* Puts out only the actual class name without namespace.
|
||||
* See EXPOSE_CLASSNAME_FULL for the meaning of the constant at all.
|
||||
*/
|
||||
const EXPOSE_CLASSNAME_UNQUALIFIED = 2;
|
||||
|
||||
/**
|
||||
* @var ReflectionService
|
||||
*/
|
||||
protected $reflectionService;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext
|
||||
*/
|
||||
protected $controllerContext;
|
||||
|
||||
/**
|
||||
* Only variables whose name is contained in this array will be rendered
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $variablesToRender = ['value'];
|
||||
|
||||
/**
|
||||
* The rendering configuration for this JSON view which
|
||||
* determines which properties of each variable to render.
|
||||
*
|
||||
* The configuration array must have the following structure:
|
||||
*
|
||||
* Example 1:
|
||||
*
|
||||
* [
|
||||
* 'variable1' => [
|
||||
* '_only' => ['property1', 'property2', ...]
|
||||
* ],
|
||||
* 'variable2' => [
|
||||
* '_exclude' => ['property3', 'property4, ...]
|
||||
* ],
|
||||
* 'variable3' => [
|
||||
* '_exclude' => ['secretTitle'],
|
||||
* '_descend' => [
|
||||
* 'customer' => [
|
||||
* '_only' => [array(]'firstName', 'lastName']
|
||||
* ]
|
||||
* ]
|
||||
* ],
|
||||
* 'somearrayvalue' => [
|
||||
* '_descendAll' => [
|
||||
* '_only' => ['property1']
|
||||
* ]
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* Of variable1 only property1 and property2 will be included.
|
||||
* Of variable2 all properties except property3 and property4
|
||||
* are used.
|
||||
* Of variable3 all properties except secretTitle are included.
|
||||
*
|
||||
* If a property value is an array or object, it is not included
|
||||
* by default. If, however, such a property is listed in a "_descend"
|
||||
* section, the renderer will descend into this sub structure and
|
||||
* include all its properties (of the next level).
|
||||
*
|
||||
* The configuration of each property in "_descend" has the same syntax
|
||||
* like at the top level. Therefore - theoretically - infinitely nested
|
||||
* structures can be configured.
|
||||
*
|
||||
* To export indexed arrays the "_descendAll" section can be used to
|
||||
* include all array keys for the output. The configuration inside a
|
||||
* "_descendAll" will be applied to each array element.
|
||||
*
|
||||
*
|
||||
* Example 2: exposing object identifier
|
||||
*
|
||||
* [
|
||||
* 'variableFoo' => [
|
||||
* '_exclude' => ['secretTitle'],
|
||||
* '_descend' => [
|
||||
* 'customer' => [ // consider 'customer' being a persisted entity
|
||||
* '_only' => ['firstName'],
|
||||
* '_exposeObjectIdentifier' => TRUE,
|
||||
* '_exposedObjectIdentifierKey' => 'guid'
|
||||
* ]
|
||||
* ]
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* Note for entity objects you are able to expose the object's identifier
|
||||
* also, just add an "_exposeObjectIdentifier" directive set to TRUE and
|
||||
* an additional property '__identity' will appear keeping the persistence
|
||||
* identifier. Renaming that property name instead of '__identity' is also
|
||||
* possible with the directive "_exposedObjectIdentifierKey".
|
||||
* Example 2 above would output (summarized):
|
||||
* {"customer":{"firstName":"John","guid":"892693e4-b570-46fe-af71-1ad32918fb64"}}
|
||||
*
|
||||
*
|
||||
* Example 3: exposing object's class name
|
||||
*
|
||||
* [
|
||||
* 'variableFoo' => [
|
||||
* '_exclude' => ['secretTitle'],
|
||||
* '_descend' => [
|
||||
* 'customer' => [ // consider 'customer' being an object
|
||||
* '_only' => ['firstName'],
|
||||
* '_exposeClassName' => \TYPO3\CMS\Extbase\Mvc\View\JsonView::EXPOSE_CLASSNAME_FULLY_QUALIFIED
|
||||
* ]
|
||||
* ]
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* The ``_exposeClassName`` is similar to the objectIdentifier one, but the class name is added to the
|
||||
* JSON object output, for example (summarized):
|
||||
* {"customer":{"firstName":"John","__class":"Acme\Foo\Domain\Model\Customer"}}
|
||||
*
|
||||
* The other option is EXPOSE_CLASSNAME_UNQUALIFIED which only will give the last part of the class
|
||||
* without the namespace, for example (summarized):
|
||||
* {"customer":{"firstName":"John","__class":"Customer"}}
|
||||
* This might be of interest to not provide information about the package or domain structure behind.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration = [];
|
||||
|
||||
/**
|
||||
* @var PersistenceManagerInterface
|
||||
*/
|
||||
protected $persistenceManager;
|
||||
|
||||
/**
|
||||
* @param PersistenceManagerInterface $persistenceManager
|
||||
* @internal
|
||||
*/
|
||||
public function injectPersistenceManager(PersistenceManagerInterface $persistenceManager): void
|
||||
{
|
||||
$this->persistenceManager = $persistenceManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionService $reflectionService
|
||||
* @internal
|
||||
*/
|
||||
public function injectReflectionService(ReflectionService $reflectionService): void
|
||||
{
|
||||
$this->reflectionService = $reflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies which variables this JsonView should render
|
||||
* By default only the variable 'value' will be rendered
|
||||
*
|
||||
* @param array $variablesToRender
|
||||
*/
|
||||
public function setVariablesToRender(array $variablesToRender): void
|
||||
{
|
||||
$this->variablesToRender = $variablesToRender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $configuration The rendering configuration for this JSON view
|
||||
*/
|
||||
public function setConfiguration(array $configuration): void
|
||||
{
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the value view variable to a serializable
|
||||
* array representation using a YAML view configuration and JSON encodes
|
||||
* the result.
|
||||
*
|
||||
* @return string The JSON encoded variables
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
$response = $this->controllerContext->getResponse();
|
||||
if ($response instanceof WebResponse) {
|
||||
// @todo Ticket: #63643 This should be solved differently once request/response model is available for TSFE.
|
||||
if (!empty($GLOBALS['TSFE']) && $GLOBALS['TSFE'] instanceof TypoScriptFrontendController) {
|
||||
/** @var TypoScriptFrontendController $typoScriptFrontendController */
|
||||
$typoScriptFrontendController = $GLOBALS['TSFE'];
|
||||
if (empty($typoScriptFrontendController->config['config']['disableCharsetHeader'])) {
|
||||
// If the charset header is *not* disabled in configuration,
|
||||
// TypoScriptFrontendController will send the header later with the Content-Type which we set here.
|
||||
$typoScriptFrontendController->setContentType('application/json');
|
||||
} else {
|
||||
// Although the charset header is disabled in configuration, we *must* send a Content-Type header here.
|
||||
// Content-Type headers optionally carry charset information at the same time.
|
||||
// Since we have the information about the charset, there is no reason to not include the charset information although disabled in TypoScript.
|
||||
$response->setHeader('Content-Type', 'application/json; charset=' . trim($typoScriptFrontendController->metaCharset));
|
||||
}
|
||||
} else {
|
||||
$response->setHeader('Content-Type', 'application/json');
|
||||
}
|
||||
}
|
||||
$propertiesToRender = $this->renderArray();
|
||||
return json_encode($propertiesToRender, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration and transforms the value to a serializable
|
||||
* array.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function renderArray()
|
||||
{
|
||||
if (count($this->variablesToRender) === 1) {
|
||||
$variableName = current($this->variablesToRender);
|
||||
$valueToRender = $this->variables[$variableName] ?? null;
|
||||
$configuration = $this->configuration[$variableName] ?? [];
|
||||
} else {
|
||||
$valueToRender = [];
|
||||
foreach ($this->variablesToRender as $variableName) {
|
||||
$valueToRender[$variableName] = $this->variables[$variableName] ?? null;
|
||||
}
|
||||
$configuration = $this->configuration;
|
||||
}
|
||||
return $this->transformValue($valueToRender, $configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a value depending on type recursively using the
|
||||
* supplied configuration.
|
||||
*
|
||||
* @param mixed $value The value to transform
|
||||
* @param array $configuration Configuration for transforming the value
|
||||
* @return mixed The transformed value
|
||||
*/
|
||||
protected function transformValue($value, array $configuration)
|
||||
{
|
||||
if (is_array($value) || $value instanceof \ArrayAccess) {
|
||||
$array = [];
|
||||
foreach ($value as $key => $element) {
|
||||
if (isset($configuration['_descendAll']) && is_array($configuration['_descendAll'])) {
|
||||
$array[$key] = $this->transformValue($element, $configuration['_descendAll']);
|
||||
} else {
|
||||
if (isset($configuration['_only']) && is_array($configuration['_only']) && !in_array($key, $configuration['_only'], true)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($configuration['_exclude']) && is_array($configuration['_exclude']) && in_array($key, $configuration['_exclude'], true)) {
|
||||
continue;
|
||||
}
|
||||
$array[$key] = $this->transformValue($element, $configuration[$key] ?? []);
|
||||
}
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
if (is_object($value)) {
|
||||
return $this->transformObject($value, $configuration);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the given object structure in order to transform it into an
|
||||
* array structure.
|
||||
*
|
||||
* @param object $object Object to traverse
|
||||
* @param array $configuration Configuration for transforming the given object or NULL
|
||||
* @return array|string Object structure as an array or as a rendered string (for a DateTime instance)
|
||||
*/
|
||||
protected function transformObject(object $object, array $configuration)
|
||||
{
|
||||
if ($object instanceof \DateTime) {
|
||||
return $object->format(\DateTime::ATOM);
|
||||
}
|
||||
$propertyNames = ObjectAccess::getGettablePropertyNames($object);
|
||||
|
||||
$propertiesToRender = [];
|
||||
foreach ($propertyNames as $propertyName) {
|
||||
if (isset($configuration['_only']) && is_array($configuration['_only']) && !in_array($propertyName, $configuration['_only'], true)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($configuration['_exclude']) && is_array($configuration['_exclude']) && in_array($propertyName, $configuration['_exclude'], true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$propertyValue = ObjectAccess::getProperty($object, $propertyName);
|
||||
|
||||
if (!is_array($propertyValue) && !is_object($propertyValue)) {
|
||||
$propertiesToRender[$propertyName] = $propertyValue;
|
||||
} elseif (isset($configuration['_descend']) && array_key_exists($propertyName, $configuration['_descend'])) {
|
||||
$propertiesToRender[$propertyName] = $this->transformValue($propertyValue, $configuration['_descend'][$propertyName]);
|
||||
}
|
||||
}
|
||||
if (isset($configuration['_exposeObjectIdentifier']) && $configuration['_exposeObjectIdentifier'] === true) {
|
||||
if (isset($configuration['_exposedObjectIdentifierKey']) && strlen($configuration['_exposedObjectIdentifierKey']) > 0) {
|
||||
$identityKey = $configuration['_exposedObjectIdentifierKey'];
|
||||
} else {
|
||||
$identityKey = '__identity';
|
||||
}
|
||||
$propertiesToRender[$identityKey] = $this->persistenceManager->getIdentifierByObject($object);
|
||||
}
|
||||
if (isset($configuration['_exposeClassName']) && ($configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_FULLY_QUALIFIED || $configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_UNQUALIFIED)) {
|
||||
$className = get_class($object);
|
||||
$classNameParts = explode('\\', $className);
|
||||
$propertiesToRender['__class'] = ($configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_FULLY_QUALIFIED ? $className : array_pop($classNameParts));
|
||||
}
|
||||
|
||||
return $propertiesToRender;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\View;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* The not found view - a special case.
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class NotFoundView extends \TYPO3\CMS\Extbase\Mvc\View\AbstractView
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $variablesMarker = ['errorMessage' => 'ERROR_MESSAGE'];
|
||||
|
||||
/**
|
||||
* Renders the not found view
|
||||
*
|
||||
* @return string The rendered view
|
||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception if no request has been set
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if (!is_object($this->controllerContext->getRequest())) {
|
||||
throw new \TYPO3\CMS\Extbase\Mvc\Exception('Can\'t render view without request object.', 1192450280);
|
||||
}
|
||||
$template = file_get_contents($this->getTemplatePathAndFilename());
|
||||
if ($this->controllerContext->getRequest() instanceof \TYPO3\CMS\Extbase\Mvc\Web\Request) {
|
||||
$template = str_replace('###BASEURI###', \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), $template);
|
||||
}
|
||||
foreach ($this->variablesMarker as $variableName => $marker) {
|
||||
$variableValue = $this->variables[$variableName] ?? '';
|
||||
$template = str_replace('###' . $marker . '###', $variableValue, $template);
|
||||
}
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves path and filename of the not-found-template
|
||||
*
|
||||
* @return string path and filename of the not-found-template
|
||||
*/
|
||||
protected function getTemplatePathAndFilename()
|
||||
{
|
||||
return \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('extbase') . 'Resources/Private/MVC/NotFoundView_Template.html';
|
||||
}
|
||||
|
||||
/**
|
||||
* A magic call method.
|
||||
*
|
||||
* Because this not found view is used as a Special Case in situations when no matching
|
||||
* view is available, it must be able to handle method calls which originally were
|
||||
* directed to another type of view. This magic method should prevent PHP from issuing
|
||||
* a fatal error.
|
||||
*
|
||||
* @param string $methodName
|
||||
* @param array $arguments
|
||||
*/
|
||||
public function __call($methodName, array $arguments)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Mvc\View;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface of a view
|
||||
*/
|
||||
interface ViewInterface
|
||||
{
|
||||
/**
|
||||
* Sets the current controller context
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext
|
||||
* @internal
|
||||
*/
|
||||
public function setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext);
|
||||
|
||||
/**
|
||||
* Add a variable to the view data collection.
|
||||
* Can be chained, so $this->view->assign(..., ...)->assign(..., ...); is possible
|
||||
*
|
||||
* @param string $key Key of variable
|
||||
* @param mixed $value Value of object
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\View\ViewInterface an instance of $this, to enable chaining
|
||||
*/
|
||||
public function assign($key, $value);
|
||||
|
||||
/**
|
||||
* Add multiple variables to the view data collection
|
||||
*
|
||||
* @param array $values array in the format array(key1 => value1, key2 => value2)
|
||||
* @return \TYPO3\CMS\Extbase\Mvc\View\ViewInterface an instance of $this, to enable chaining
|
||||
*/
|
||||
public function assignMultiple(array $values);
|
||||
|
||||
/**
|
||||
* Tells if the view implementation can render the view for the given context.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext
|
||||
* @return bool TRUE if the view has something useful to display, otherwise FALSE
|
||||
*/
|
||||
public function canRender(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext);
|
||||
|
||||
/**
|
||||
* Renders the view
|
||||
*
|
||||
* @return string The rendered view
|
||||
*/
|
||||
public function render();
|
||||
|
||||
/**
|
||||
* Initializes this view.
|
||||
*/
|
||||
public function initializeView();
|
||||
}
|
||||
Loaded 100 of 12716 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user