‪TYPO3CMS  10.4
ExecuteSchedulableCommandAdditionalFieldProvider.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Symfony\Component\Console\Command\Command;
21 use Symfony\Component\Console\Exception\InvalidArgumentException;
22 use Symfony\Component\Console\Input\InputArgument;
23 use Symfony\Component\Console\Input\InputDefinition;
24 use Symfony\Component\Console\Input\InputOption;
32 use TYPO3Fluid\Fluid\Core\ViewHelper\TagBuilder;
33 
38 {
42  protected ‪$schedulableCommands = [];
43 
47  protected ‪$objectManager;
48 
52  protected ‪$reflectionService;
53 
57  protected ‪$task;
58 
59  public function ‪__construct()
60  {
61  $commandRegistry = GeneralUtility::makeInstance(CommandRegistry::class);
62  foreach ($commandRegistry->getSchedulableCommands() as $commandIdentifier => $command) {
63  $this->schedulableCommands[$commandIdentifier] = $command;
64  }
65 
66  ksort($this->schedulableCommands);
67  }
68 
78  public function ‪getAdditionalFields(array &$taskInfo, ‪$task, ‪SchedulerModuleController $schedulerModule): array
79  {
80  $this->task = ‪$task;
81  if ($this->task !== null) {
82  $this->task->‪setScheduler();
83  }
84 
85  ‪$fields = [];
86  ‪$fields['action'] = $this->‪getActionField();
87 
88  if ($this->task !== null && isset($this->schedulableCommands[$this->task->getCommandIdentifier()])) {
89  $command = $this->schedulableCommands[$this->task->getCommandIdentifier()];
90  ‪$fields['description'] = $this->‪getCommandDescriptionField($command->getDescription());
91  $argumentFields = $this->‪getCommandArgumentFields($command->getDefinition());
92  ‪$fields = array_merge(‪$fields, $argumentFields);
93  $optionFields = $this->‪getCommandOptionFields($command->getDefinition());
94  ‪$fields = array_merge(‪$fields, $optionFields);
95  $this->task->save(); // todo: this seems to be superfluous
96  }
97 
98  return ‪$fields;
99  }
100 
108  public function ‪validateAdditionalFields(array &$submittedData, SchedulerModuleController $schedulerModule): bool
109  {
110  if (!isset($this->schedulableCommands[$submittedData['task_executeschedulablecommand']['command']])) {
111  return false;
112  }
113 
114  $command = $this->schedulableCommands[$submittedData['task_executeschedulablecommand']['command']];
115 
117  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
118 
119  $hasErrors = false;
120  foreach ($command->getDefinition()->getArguments() as $argument) {
121  foreach ((array)$submittedData['task_executeschedulablecommand']['arguments'] as $argumentName => $argumentValue) {
124  if ($argument->getName() !== $argumentName) {
125  continue;
126  }
127 
128  if ($argument->isRequired() && trim($argumentValue) === '') {
129  // Argument is required and argument value is empty0
130  $flashMessageService->getMessageQueueByIdentifier()->addMessage(
131  new FlashMessage(
132  sprintf(
133  $this->‪getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:msg.mandatoryArgumentMissing'),
134  $argumentName
135  ),
136  $this->‪getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:msg.updateError'),
138  )
139  );
140  $hasErrors = true;
141  }
142  }
143  }
144 
145  foreach ($command->getDefinition()->getOptions() as $optionDefinition) {
146  $optionEnabled = $submittedData['task_executeschedulablecommand']['options'][$optionDefinition->getName()] ?? false;
147  $optionValue = $submittedData['task_executeschedulablecommand']['option_values'][$optionDefinition->getName()] ?? $optionDefinition->getDefault();
148  if ($optionEnabled && $optionDefinition->isValueRequired()) {
149  if ($optionDefinition->isArray()) {
150  $testValues = is_array($optionValue) ? $optionValue : ‪GeneralUtility::trimExplode(',', $optionValue, false);
151  } else {
152  $testValues = [$optionValue];
153  }
154 
155  foreach ($testValues as $testValue) {
156  if ($testValue === null || trim($testValue) === '') {
157  // An option that requires a value is used with an empty value
158  $flashMessageService->getMessageQueueByIdentifier()->addMessage(
159  new FlashMessage(
160  sprintf(
161  $this->‪getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:msg.mandatoryArgumentMissing'),
162  $optionDefinition->getName()
163  ),
164  $this->getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:msg.updateError'),
166  )
167  );
168  $hasErrors = true;
169  }
170  }
171  }
172  }
173 
174  return $hasErrors === false;
175  }
176 
184  public function ‪saveAdditionalFields(array $submittedData, AbstractTask ‪$task): bool
185  {
186  $command = $this->schedulableCommands[$submittedData['task_executeschedulablecommand']['command']];
187 
189  ‪$task->‪setCommandIdentifier($submittedData['task_executeschedulablecommand']['command']);
190 
191  $arguments = [];
192  foreach ((array)$submittedData['task_executeschedulablecommand']['arguments'] as $argumentName => $argumentValue) {
193  try {
194  $argumentDefinition = $command->getDefinition()->getArgument($argumentName);
195  } catch (InvalidArgumentException $e) {
196  continue;
197  }
198 
199  if ($argumentDefinition->isArray()) {
200  $argumentValue = ‪GeneralUtility::trimExplode(',', $argumentValue, true);
201  }
202 
203  $arguments[$argumentName] = $argumentValue;
204  }
205 
206  $options = [];
207  $optionValues = [];
208  foreach ($command->getDefinition()->getOptions() as $optionDefinition) {
209  $optionEnabled = $submittedData['task_executeschedulablecommand']['options'][$optionDefinition->getName()] ?? false;
210  $options[$optionDefinition->getName()] = (bool)$optionEnabled;
211 
212  if ($optionDefinition->isValueRequired() || $optionDefinition->isValueOptional() || $optionDefinition->isArray()) {
213  $optionValue = $submittedData['task_executeschedulablecommand']['option_values'][$optionDefinition->getName()] ?? $optionDefinition->getDefault();
214  if ($optionDefinition->isArray() && !is_array($optionValue)) {
215  // Do not remove empty array values.
216  // One empty array element indicates the existence of one occurrence of an array option (InputOption::VALUE_IS_ARRAY) without a value.
217  // Empty array elements are also required for command options like "-vvv" (can be entered as ",,").
218  $optionValue = ‪GeneralUtility::trimExplode(',', $optionValue, false);
219  }
220  } else {
221  // boolean flag: option value must be true if option is added or false otherwise
222  $optionValue = (bool)$optionEnabled;
223  }
224  $optionValues[$optionDefinition->getName()] = $optionValue;
225  }
226 
227  ‪$task->‪setArguments($arguments);
228  ‪$task->‪setOptions($options);
229  ‪$task->‪setOptionValues($optionValues);
230  return true;
231  }
232 
239  protected function ‪getCommandDescriptionField(string $description): array
240  {
241  return [
242  'code' => '',
243  'label' => $description
244  ];
245  }
246 
252  protected function ‪getActionField(): array
253  {
254  $currentlySelectedCommand = $this->task !== null ? $this->task->getCommandIdentifier() : '';
255  $options = [];
256  foreach ($this->schedulableCommands as $commandIdentifier => $command) {
257  $options[$commandIdentifier] = $commandIdentifier . ': ' . $command->getDescription();
258  }
259  return [
260  'code' => $this->‪renderSelectField($options, $currentlySelectedCommand),
261  'label' => $this->‪getLanguageService()->‪sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.schedulableCommandName')
262  ];
263  }
264 
273  protected function ‪getCommandArgumentFields(InputDefinition $inputDefinition): array
274  {
275  ‪$fields = [];
276  $argumentValues = $this->task->getArguments();
277  foreach ($inputDefinition->getArguments() as $argument) {
278  $name = $argument->getName();
279  $defaultValue = $argument->getDefault();
280  $this->task->addDefaultValue($name, $defaultValue);
281  $value = $argumentValues[$name] ?? $defaultValue;
282 
283  if (is_array($value) && $argument->isArray()) {
284  $value = implode(',', $value);
285  }
286 
287  ‪$fields[$name] = [
288  'code' => $this->‪renderArgumentField($argument, (string)$value),
289  'label' => $this->‪getArgumentLabel($argument)
290  ];
291  }
292 
293  return ‪$fields;
294  }
295 
304  protected function ‪getCommandOptionFields(InputDefinition $inputDefinition): array
305  {
306  ‪$fields = [];
307  $enabledOptions = $this->task->getOptions();
308  $optionValues = $this->task->getOptionValues();
309  foreach ($inputDefinition->getOptions() as $option) {
310  $name = $option->getName();
311  $defaultValue = $option->getDefault();
312  $this->task->addDefaultValue($name, $defaultValue);
313  $enabled = $enabledOptions[$name] ?? false;
314  $value = $optionValues[$name] ?? $defaultValue;
315 
316  if (is_array($value) && $option->isArray()) {
317  $value = implode(',', $value);
318  }
319 
320  ‪$fields[$name] = [
321  'code' => $this->‪renderOptionField($option, (bool)$enabled, (string)$value),
322  'label' => $this->‪getOptionLabel($option)
323  ];
324  }
325 
326  return ‪$fields;
327  }
328 
335  protected function ‪getArgumentLabel(InputArgument $argument): string
336  {
337  return 'Argument: ' . $argument->getName() . '. ' . htmlspecialchars($argument->getDescription());
338  }
339 
346  protected function ‪getOptionLabel(InputOption $option): string
347  {
348  return 'Option: ' . htmlspecialchars($option->getName()) . '. ' . htmlspecialchars($option->getDescription());
349  }
350 
356  protected function ‪renderSelectField(array $options, string $selectedOptionValue): string
357  {
358  $selectTag = new TagBuilder();
359  $selectTag->setTagName('select');
360  $selectTag->forceClosingTag(true);
361  $selectTag->addAttribute('class', 'form-control');
362  $selectTag->addAttribute('name', 'tx_scheduler[task_executeschedulablecommand][command]');
363 
364  $optionsHtml = '';
365  foreach ($options as $value => $label) {
366  $optionTag = new TagBuilder();
367  $optionTag->setTagName('option');
368  $optionTag->forceClosingTag(true);
369  $optionTag->addAttribute('title', (string)$label);
370  $optionTag->addAttribute('value', (string)$value);
371  $optionTag->setContent($label);
372 
373  if ($value === $selectedOptionValue) {
374  $optionTag->addAttribute('selected', 'selected');
375  }
376 
377  $optionsHtml .= $optionTag->render();
378  }
379 
380  $selectTag->setContent($optionsHtml);
381  return $selectTag->render();
382  }
383 
391  protected function ‪renderArgumentField(InputArgument $argument, string $currentValue): string
392  {
393  $name = $argument->getName();
394  $fieldName = 'tx_scheduler[task_executeschedulablecommand][arguments][' . $name . ']';
395 
396  $inputTag = new TagBuilder();
397  $inputTag->setTagName('input');
398  $inputTag->addAttribute('type', 'text');
399  $inputTag->addAttribute('name', $fieldName);
400  $inputTag->addAttribute('value', $currentValue);
401  $inputTag->addAttribute('class', 'form-control');
402 
403  return $inputTag->render();
404  }
405 
413  protected function ‪renderOptionField(InputOption $option, bool $enabled, string $currentValue): string
414  {
415  $name = $option->getName();
416 
417  $checkboxFieldName = 'tx_scheduler[task_executeschedulablecommand][options][' . $name . ']';
418  $checkboxId = 'tx_scheduler_task_executeschedulablecommand_options_' . $name;
419  $checkboxTag = new TagBuilder();
420  $checkboxTag->setTagName('input');
421  $checkboxTag->addAttribute('id', $checkboxId);
422  $checkboxTag->addAttribute('name', $checkboxFieldName);
423  $checkboxTag->addAttribute('type', 'checkbox');
424  if ($enabled) {
425  $checkboxTag->addAttribute('checked', 'checked');
426  }
427  $html = '<label for="' . $checkboxId . '">'
428  . $checkboxTag->render()
429  . ' ' . $this->‪getLanguageService()->‪sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.addOptionToCommand')
430  . '</label>';
431 
432  if ($option->isValueRequired() || $option->isValueOptional() || $option->isArray()) {
433  $valueFieldName = 'tx_scheduler[task_executeschedulablecommand][option_values][' . $name . ']';
434  $inputTag = new TagBuilder();
435  $inputTag->setTagName('input');
436  $inputTag->addAttribute('name', $valueFieldName);
437  $inputTag->addAttribute('type', 'text');
438  $inputTag->addAttribute('value', $currentValue);
439  $inputTag->addAttribute('class', 'form-control');
440  $html .= $inputTag->render();
441  }
442 
443  return $html;
444  }
445 
449  public function ‪getLanguageService(): ‪LanguageService
450  {
451  return ‪$GLOBALS['LANG'];
452  }
453 }
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getOptionLabel
‪string getOptionLabel(InputOption $option)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:342
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\$reflectionService
‪TYPO3 CMS Extbase Reflection ReflectionService $reflectionService
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:49
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getActionField
‪array getActionField()
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:248
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\$objectManager
‪TYPO3 CMS Extbase Object ObjectManagerInterface $objectManager
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:45
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:38
‪TYPO3\CMS\Scheduler\Task
Definition: AbstractTask.php:16
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask\setArguments
‪setArguments(array $arguments)
Definition: ExecuteSchedulableCommandTask.php:149
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getCommandArgumentFields
‪array getCommandArgumentFields(InputDefinition $inputDefinition)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:269
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask
Definition: ExecuteSchedulableCommandTask.php:32
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\renderSelectField
‪string renderSelectField(array $options, string $selectedOptionValue)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:352
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\renderOptionField
‪string renderOptionField(InputOption $option, bool $enabled, string $currentValue)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:409
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:194
‪$fields
‪$fields
Definition: pages.php:5
‪TYPO3\CMS\Core\Console\CommandRegistry
Definition: CommandRegistry.php:32
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getCommandOptionFields
‪array getCommandOptionFields(InputDefinition $inputDefinition)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:300
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\saveAdditionalFields
‪bool saveAdditionalFields(array $submittedData, AbstractTask $task)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:180
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getCommandDescriptionField
‪array getCommandDescriptionField(string $description)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:235
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getLanguageService
‪LanguageService getLanguageService()
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:445
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setScheduler
‪setScheduler()
Definition: AbstractTask.php:281
‪TYPO3\CMS\Scheduler\Task\AbstractTask
Definition: AbstractTask.php:35
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\$schedulableCommands
‪Command[] $schedulableCommands
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:41
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\__construct
‪__construct()
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:55
‪TYPO3\CMS\Scheduler\Controller\SchedulerModuleController
Definition: SchedulerModuleController.php:56
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\validateAdditionalFields
‪bool validateAdditionalFields(array &$submittedData, SchedulerModuleController $schedulerModule)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:104
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\renderArgumentField
‪string renderArgumentField(InputArgument $argument, string $currentValue)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:387
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask\setCommandIdentifier
‪setCommandIdentifier(string $commandIdentifier)
Definition: ExecuteSchedulableCommandTask.php:56
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\$task
‪ExecuteSchedulableCommandTask $task
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:53
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask\setOptions
‪setOptions(array $options)
Definition: ExecuteSchedulableCommandTask.php:159
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:24
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getAdditionalFields
‪array getAdditionalFields(array &$taskInfo, $task, SchedulerModuleController $schedulerModule)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:74
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask\setOptionValues
‪setOptionValues(array $optionValues)
Definition: ExecuteSchedulableCommandTask.php:169
‪TYPO3\CMS\Core\Messaging\FlashMessageService
Definition: FlashMessageService.php:27
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:31
‪TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface
Definition: AdditionalFieldProviderInterface.php:25
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getArgumentLabel
‪string getArgumentLabel(InputArgument $argument)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:331