‪TYPO3CMS  9.5
ExecuteSchedulableCommandAdditionalFieldProvider.php
Go to the documentation of this file.
1 <?php
2 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 
18 use Symfony\Component\Console\Command\Command;
19 use Symfony\Component\Console\Exception\InvalidArgumentException;
20 use Symfony\Component\Console\Input\InputArgument;
21 use Symfony\Component\Console\Input\InputDefinition;
22 use Symfony\Component\Console\Input\InputOption;
30 use TYPO3Fluid\Fluid\Core\ViewHelper\TagBuilder;
31 
36 {
40  protected ‪$schedulableCommands = [];
41 
45  protected ‪$objectManager;
46 
50  protected ‪$reflectionService;
51 
55  protected ‪$task;
56 
57  public function ‪__construct()
58  {
59  $commandRegistry = GeneralUtility::makeInstance(CommandRegistry::class);
60  foreach ($commandRegistry->getSchedulableCommands() as $commandIdentifier => $command) {
61  $this->schedulableCommands[$commandIdentifier] = $command;
62  }
63 
64  ksort($this->schedulableCommands);
65  }
66 
76  public function ‪getAdditionalFields(array &$taskInfo, ‪$task, ‪SchedulerModuleController $schedulerModule): array
77  {
78  $this->task = ‪$task;
79  if ($this->task !== null) {
80  $this->task->‪setScheduler();
81  }
82 
83  ‪$fields = [];
84  ‪$fields['action'] = $this->‪getActionField();
85 
86  if ($this->task !== null && isset($this->schedulableCommands[$this->task->getCommandIdentifier()])) {
87  $command = $this->schedulableCommands[$this->task->getCommandIdentifier()];
88  ‪$fields['description'] = $this->‪getCommandDescriptionField($command->getDescription());
89  $argumentFields = $this->‪getCommandArgumentFields($command->getDefinition());
90  ‪$fields = array_merge(‪$fields, $argumentFields);
91  $optionFields = $this->‪getCommandOptionFields($command->getDefinition());
92  ‪$fields = array_merge(‪$fields, $optionFields);
93  $this->task->save(); // todo: this seems to be superfluous
94  }
95 
96  return ‪$fields;
97  }
98 
106  public function ‪validateAdditionalFields(array &$submittedData, SchedulerModuleController $schedulerModule): bool
107  {
108  if (!isset($this->schedulableCommands[$submittedData['task_executeschedulablecommand']['command']])) {
109  return false;
110  }
111 
112  $command = $this->schedulableCommands[$submittedData['task_executeschedulablecommand']['command']];
113 
115  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
116 
117  $hasErrors = false;
118  foreach ($command->getDefinition()->getArguments() as $argument) {
119  foreach ((array)$submittedData['task_executeschedulablecommand']['arguments'] as $argumentName => $argumentValue) {
122  if ($argument->getName() !== $argumentName) {
123  continue;
124  }
125 
126  if ($argument->isRequired() && trim($argumentValue) === '') {
127  // Argument is required and argument value is empty0
128  $flashMessageService->getMessageQueueByIdentifier()->addMessage(
129  new FlashMessage(
130  sprintf(
131  $this->‪getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:msg.mandatoryArgumentMissing'),
132  $argumentName
133  ),
134  $this->‪getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:msg.updateError'),
136  )
137  );
138  $hasErrors = true;
139  }
140  }
141  }
142 
143  foreach ($command->getDefinition()->getOptions() as $optionDefinition) {
144  $optionEnabled = $submittedData['task_executeschedulablecommand']['options'][$optionDefinition->getName()] ?? false;
145  $optionValue = $submittedData['task_executeschedulablecommand']['option_values'][$optionDefinition->getName()] ?? $optionDefinition->getDefault();
146  if ($optionEnabled && $optionDefinition->isValueRequired()) {
147  if ($optionDefinition->isArray()) {
148  $testValues = is_array($optionValue) ? $optionValue : GeneralUtility::trimExplode(',', $optionValue, false);
149  } else {
150  $testValues = [$optionValue];
151  }
152 
153  foreach ($testValues as $testValue) {
154  if ($testValue === null || trim($testValue) === '') {
155  // An option that requires a value is used with an empty value
156  $flashMessageService->getMessageQueueByIdentifier()->addMessage(
157  new FlashMessage(
158  sprintf(
159  $this->‪getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:msg.mandatoryArgumentMissing'),
160  $optionDefinition->getName()
161  ),
162  $this->getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:msg.updateError'),
164  )
165  );
166  $hasErrors = true;
167  }
168  }
169  }
170  }
171 
172  return $hasErrors === false;
173  }
174 
182  public function ‪saveAdditionalFields(array $submittedData, AbstractTask ‪$task): bool
183  {
184  $command = $this->schedulableCommands[$submittedData['task_executeschedulablecommand']['command']];
185 
187  ‪$task->‪setCommandIdentifier($submittedData['task_executeschedulablecommand']['command']);
188 
189  $arguments = [];
190  foreach ((array)$submittedData['task_executeschedulablecommand']['arguments'] as $argumentName => $argumentValue) {
191  try {
192  $argumentDefinition = $command->getDefinition()->getArgument($argumentName);
193  } catch (InvalidArgumentException $e) {
194  continue;
195  }
196 
197  if ($argumentDefinition->isArray()) {
198  $argumentValue = GeneralUtility::trimExplode(',', $argumentValue, true);
199  }
200 
201  $arguments[$argumentName] = $argumentValue;
202  }
203 
204  $options = [];
205  $optionValues = [];
206  foreach ($command->getDefinition()->getOptions() as $optionDefinition) {
207  $optionEnabled = $submittedData['task_executeschedulablecommand']['options'][$optionDefinition->getName()] ?? false;
208  $options[$optionDefinition->getName()] = (bool)$optionEnabled;
209 
210  if ($optionDefinition->isValueRequired() || $optionDefinition->isValueOptional() || $optionDefinition->isArray()) {
211  $optionValue = $submittedData['task_executeschedulablecommand']['option_values'][$optionDefinition->getName()] ?? $optionDefinition->getDefault();
212  if ($optionDefinition->isArray() && !is_array($optionValue)) {
213  // Do not remove empty array values.
214  // One empty array element indicates the existence of one occurence of an array option (InputOption::VALUE_IS_ARRAY) without a value.
215  // Empty array elements are also required for command options like "-vvv" (can be entered as ",,").
216  $optionValue = GeneralUtility::trimExplode(',', $optionValue, false);
217  }
218  } else {
219  // boolean flag: option value must be true if option is added or false otherwise
220  $optionValue = (bool)$optionEnabled;
221  }
222  $optionValues[$optionDefinition->getName()] = $optionValue;
223  }
224 
225  ‪$task->‪setArguments($arguments);
226  ‪$task->‪setOptions($options);
227  ‪$task->‪setOptionValues($optionValues);
228  return true;
229  }
230 
237  protected function ‪getCommandDescriptionField(string $description): array
238  {
239  return [
240  'code' => '',
241  'label' => '<strong>' . $description . '</strong>'
242  ];
243  }
244 
250  protected function ‪getActionField(): array
251  {
252  $currentlySelectedCommand = $this->task !== null ? $this->task->getCommandIdentifier() : '';
253  $options = [];
254  foreach ($this->schedulableCommands as $commandIdentifier => $command) {
255  $options[$commandIdentifier] = $commandIdentifier . ': ' . $command->getDescription();
256  }
257  return [
258  'code' => $this->‪renderSelectField($options, $currentlySelectedCommand),
259  'label' => $this->‪getLanguageService()->‪sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.schedulableCommandName')
260  ];
261  }
262 
271  protected function ‪getCommandArgumentFields(InputDefinition $inputDefinition): array
272  {
273  ‪$fields = [];
274  $argumentValues = $this->task->getArguments();
275  foreach ($inputDefinition->getArguments() as $argument) {
276  $name = $argument->getName();
277  $defaultValue = $argument->getDefault();
278  $this->task->addDefaultValue($name, $defaultValue);
279  $value = $argumentValues[$name] ?? $defaultValue;
280 
281  if (is_array($value) && $argument->isArray()) {
282  $value = implode(',', $value);
283  }
284 
285  ‪$fields[$name] = [
286  'code' => $this->‪renderArgumentField($argument, (string)$value),
287  'label' => $this->‪getArgumentLabel($argument)
288  ];
289  }
290 
291  return ‪$fields;
292  }
293 
302  protected function ‪getCommandOptionFields(InputDefinition $inputDefinition): array
303  {
304  ‪$fields = [];
305  $enabledOptions = $this->task->getOptions();
306  $optionValues = $this->task->getOptionValues();
307  foreach ($inputDefinition->getOptions() as $option) {
308  $name = $option->getName();
309  $defaultValue = $option->getDefault();
310  $this->task->addDefaultValue($name, $defaultValue);
311  $enabled = $enabledOptions[$name] ?? false;
312  $value = $optionValues[$name] ?? $defaultValue;
313 
314  if (is_array($value) && $option->isArray()) {
315  $value = implode(',', $value);
316  }
317 
318  ‪$fields[$name] = [
319  'code' => $this->‪renderOptionField($option, (bool)$enabled, (string)$value),
320  'label' => $this->‪getOptionLabel($option)
321  ];
322  }
323 
324  return ‪$fields;
325  }
326 
333  protected function ‪getArgumentLabel(InputArgument $argument): string
334  {
335  return 'Argument: ' . $argument->getName() . '. <em>' . htmlspecialchars($argument->getDescription()) . '</em>';
336  }
337 
344  protected function ‪getOptionLabel(InputOption $option): string
345  {
346  return 'Option: ' . htmlspecialchars($option->getName()) . '. <em>' . htmlspecialchars($option->getDescription()) . '</em>';
347  }
348 
354  protected function ‪renderSelectField(array $options, string $selectedOptionValue): string
355  {
356  $selectTag = new TagBuilder();
357  $selectTag->setTagName('select');
358  $selectTag->forceClosingTag(true);
359  $selectTag->addAttribute('class', 'form-control');
360  $selectTag->addAttribute('name', 'tx_scheduler[task_executeschedulablecommand][command]');
361 
362  $optionsHtml = '';
363  foreach ($options as $value => $label) {
364  $optionTag = new TagBuilder();
365  $optionTag->setTagName('option');
366  $optionTag->forceClosingTag(true);
367  $optionTag->addAttribute('title', (string)$label);
368  $optionTag->addAttribute('value', (string)$value);
369  $optionTag->setContent($label);
370 
371  if ($value === $selectedOptionValue) {
372  $optionTag->addAttribute('selected', 'selected');
373  }
374 
375  $optionsHtml .= $optionTag->render();
376  }
377 
378  $selectTag->setContent($optionsHtml);
379  return $selectTag->render();
380  }
381 
389  protected function ‪renderArgumentField(InputArgument $argument, string $currentValue): string
390  {
391  $name = $argument->getName();
392  $fieldName = 'tx_scheduler[task_executeschedulablecommand][arguments][' . $name . ']';
393 
394  $inputTag = new TagBuilder();
395  $inputTag->setTagName('input');
396  $inputTag->addAttribute('type', 'text');
397  $inputTag->addAttribute('name', $fieldName);
398  $inputTag->addAttribute('value', $currentValue);
399  $inputTag->addAttribute('class', 'form-control');
400 
401  return $inputTag->render();
402  }
403 
411  protected function ‪renderOptionField(InputOption $option, bool $enabled, string $currentValue): string
412  {
413  $name = $option->getName();
414 
415  $checkboxFieldName = 'tx_scheduler[task_executeschedulablecommand][options][' . $name . ']';
416  $checkboxId = 'tx_scheduler_task_executeschedulablecommand_options_' . $name;
417  $checkboxTag = new TagBuilder();
418  $checkboxTag->setTagName('input');
419  $checkboxTag->addAttribute('id', $checkboxId);
420  $checkboxTag->addAttribute('name', $checkboxFieldName);
421  $checkboxTag->addAttribute('type', 'checkbox');
422  if ($enabled) {
423  $checkboxTag->addAttribute('checked', 'checked');
424  }
425  $html = '<label for="' . $checkboxId . '">'
426  . $checkboxTag->render()
427  . ' ' . $this->‪getLanguageService()->‪sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.addOptionToCommand')
428  . '</label>';
429 
430  if ($option->isValueRequired() || $option->isValueOptional() || $option->isArray()) {
431  $valueFieldName = 'tx_scheduler[task_executeschedulablecommand][option_values][' . $name . ']';
432  $inputTag = new TagBuilder();
433  $inputTag->setTagName('input');
434  $inputTag->addAttribute('name', $valueFieldName);
435  $inputTag->addAttribute('type', 'text');
436  $inputTag->addAttribute('value', $currentValue);
437  $inputTag->addAttribute('class', 'form-control');
438  $html .= $inputTag->render();
439  }
440 
441  return $html;
442  }
443 
447  public function ‪getLanguageService(): ‪LanguageService
448  {
449  return ‪$GLOBALS['LANG'];
450  }
451 }
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getOptionLabel
‪string getOptionLabel(InputOption $option)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:340
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\$reflectionService
‪TYPO3 CMS Extbase Reflection ReflectionService $reflectionService
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:47
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getActionField
‪array getActionField()
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:246
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\$objectManager
‪TYPO3 CMS Extbase Object ObjectManagerInterface $objectManager
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:43
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:36
‪TYPO3\CMS\Scheduler\Task
Definition: AbstractTask.php:2
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask\setArguments
‪setArguments(array $arguments)
Definition: ExecuteSchedulableCommandTask.php:147
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getCommandArgumentFields
‪array getCommandArgumentFields(InputDefinition $inputDefinition)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:267
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask
Definition: ExecuteSchedulableCommandTask.php:30
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\renderSelectField
‪string renderSelectField(array $options, string $selectedOptionValue)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:350
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\renderOptionField
‪string renderOptionField(InputOption $option, bool $enabled, string $currentValue)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:407
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:158
‪$fields
‪$fields
Definition: pages.php:4
‪TYPO3\CMS\Core\Console\CommandRegistry
Definition: CommandRegistry.php:27
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getCommandOptionFields
‪array getCommandOptionFields(InputDefinition $inputDefinition)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:298
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\saveAdditionalFields
‪bool saveAdditionalFields(array $submittedData, AbstractTask $task)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:178
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getCommandDescriptionField
‪array getCommandDescriptionField(string $description)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:233
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getLanguageService
‪LanguageService getLanguageService()
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:443
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setScheduler
‪setScheduler()
Definition: AbstractTask.php:278
‪TYPO3\CMS\Scheduler\Task\AbstractTask
Definition: AbstractTask.php:32
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\$schedulableCommands
‪Command[] $schedulableCommands
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:39
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\__construct
‪__construct()
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:53
‪TYPO3\CMS\Scheduler\Controller\SchedulerModuleController
Definition: SchedulerModuleController.php:53
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\validateAdditionalFields
‪bool validateAdditionalFields(array &$submittedData, SchedulerModuleController $schedulerModule)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:102
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\renderArgumentField
‪string renderArgumentField(InputArgument $argument, string $currentValue)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:385
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask\setCommandIdentifier
‪setCommandIdentifier(string $commandIdentifier)
Definition: ExecuteSchedulableCommandTask.php:54
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\$task
‪ExecuteSchedulableCommandTask $task
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:51
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask\setOptions
‪setOptions(array $options)
Definition: ExecuteSchedulableCommandTask.php:157
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getAdditionalFields
‪array getAdditionalFields(array &$taskInfo, $task, SchedulerModuleController $schedulerModule)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:72
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandTask\setOptionValues
‪setOptionValues(array $optionValues)
Definition: ExecuteSchedulableCommandTask.php:167
‪TYPO3\CMS\Core\Messaging\FlashMessageService
Definition: FlashMessageService.php:25
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:29
‪TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface
Definition: AdditionalFieldProviderInterface.php:21
‪TYPO3\CMS\Scheduler\Task\ExecuteSchedulableCommandAdditionalFieldProvider\getArgumentLabel
‪string getArgumentLabel(InputArgument $argument)
Definition: ExecuteSchedulableCommandAdditionalFieldProvider.php:329