b783ccd9cf59421ea92140124ee07493a558a505
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Scheduler / FieldProvider.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Scheduler;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Field provider for Extbase CommandController Scheduler task
19 */
20 class FieldProvider implements \TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface {
21
22 /**
23 * @var \TYPO3\CMS\Extbase\Mvc\Cli\CommandManager
24 */
25 protected $commandManager;
26
27 /**
28 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
29 */
30 protected $objectManager;
31
32 /**
33 * @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
34 */
35 protected $reflectionService;
36
37 /**
38 * @var \TYPO3\CMS\Extbase\Scheduler\Task
39 */
40 protected $task;
41
42 /**
43 * Constructor
44 *
45 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
46 * @param \TYPO3\CMS\Extbase\Mvc\Cli\CommandManager $commandManager
47 * @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService
48 */
49 public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager = NULL, \TYPO3\CMS\Extbase\Mvc\Cli\CommandManager $commandManager = NULL, \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService = NULL) {
50 $this->objectManager = $objectManager !== NULL ? $objectManager : \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
51 $this->commandManager = $commandManager !== NULL ? $commandManager : $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Cli\CommandManager::class);
52 $this->reflectionService = $reflectionService !== NULL ? $reflectionService : $this->objectManager->get(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class);
53 }
54
55 /**
56 * Render additional information fields within the scheduler backend.
57 *
58 * @param array &$taskInfo Array information of task to return
59 * @param mixed $task \TYPO3\CMS\Scheduler\Task\AbstractTask or \TYPO3\CMS\Scheduler\Execution instance
60 * @param \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule Reference to the calling object (BE module of the Scheduler)
61 * @return array Additional fields
62 * @see \TYPO3\CMS\Scheduler\AdditionalFieldProvider#getAdditionalFields($taskInfo, $task, $schedulerModule)
63 */
64 public function getAdditionalFields(array &$taskInfo, $task, \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule) {
65 $this->task = $task;
66 if ($this->task !== NULL) {
67 $this->task->setScheduler();
68 }
69 $fields = array();
70 $fields['action'] = $this->getCommandControllerActionField();
71 if ($this->task !== NULL && $this->task->getCommandIdentifier()) {
72 $command = $this->commandManager->getCommandByIdentifier($this->task->getCommandIdentifier());
73 $fields['description'] = $this->getCommandControllerActionDescriptionField();
74 $argumentFields = $this->getCommandControllerActionArgumentFields($command->getArgumentDefinitions());
75 $fields = array_merge($fields, $argumentFields);
76 $this->task->save();
77 }
78 return $fields;
79 }
80
81 /**
82 * Validates additional selected fields
83 *
84 * @param array &$submittedData
85 * @param \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule
86 * @return bool
87 */
88 public function validateAdditionalFields(array &$submittedData, \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule) {
89 return TRUE;
90 }
91
92 /**
93 * Saves additional field values
94 *
95 * @param array $submittedData
96 * @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task
97 * @return bool
98 */
99 public function saveAdditionalFields(array $submittedData, \TYPO3\CMS\Scheduler\Task\AbstractTask $task) {
100 $task->setCommandIdentifier($submittedData['task_extbase']['action']);
101 $task->setArguments((array)$submittedData['task_extbase']['arguments']);
102 return TRUE;
103 }
104
105 /**
106 * Get description of selected command
107 *
108 * @return string
109 */
110 protected function getCommandControllerActionDescriptionField() {
111 $command = $this->commandManager->getCommandByIdentifier($this->task->getCommandIdentifier());
112 return array(
113 'code' => '',
114 'label' => '<strong>' . $command->getDescription() . '</strong>'
115 );
116 }
117
118 /**
119 * Gets a select field containing all possible CommandController actions
120 *
121 * @return array
122 */
123 protected function getCommandControllerActionField() {
124 $commands = $this->commandManager->getAvailableCommands();
125 $options = array();
126 foreach ($commands as $command) {
127 if ($command->isInternal() === FALSE) {
128 $className = $command->getControllerClassName();
129 if (strpos($className, '\\')) {
130 $classNameParts = explode('\\', $className);
131 // Skip vendor and product name for core classes
132 if (strpos($className, 'TYPO3\\CMS\\') === 0) {
133 $classPartsToSkip = 2;
134 } else {
135 $classPartsToSkip = 1;
136 }
137 $classNameParts = array_slice($classNameParts, $classPartsToSkip);
138 $extensionName = $classNameParts[0];
139 $controllerName = $classNameParts[2];
140 } else {
141 $classNameParts = explode('_', $className);
142 $extensionName = $classNameParts[1];
143 $controllerName = $classNameParts[3];
144 }
145 $identifier = $command->getCommandIdentifier();
146 $options[$identifier] = $extensionName . ' ' . str_replace('CommandController', '', $controllerName) . ': ' . $command->getControllerCommandName();
147 }
148 }
149 $name = 'action';
150 $currentlySelectedCommand = $this->task !== NULL ? $this->task->getCommandIdentifier() : NULL;
151 return array(
152 'code' => $this->renderSelectField($name, $options, $currentlySelectedCommand),
153 'label' => $this->getActionLabel()
154 );
155 }
156
157 /**
158 * Gets a set of fields covering arguments which must be sent to $currentControllerAction.
159 * Also registers the default values of those fields with the Task, allowing
160 * them to be read upon execution.
161 *
162 * @param array $argumentDefinitions
163 * @return array
164 */
165 protected function getCommandControllerActionArgumentFields(array $argumentDefinitions) {
166 $fields = array();
167 $argumentValues = $this->task->getArguments();
168 foreach ($argumentDefinitions as $argument) {
169 $name = $argument->getName();
170 $defaultValue = $this->getDefaultArgumentValue($argument);
171 $this->task->addDefaultValue($name, $defaultValue);
172 $value = isset($argumentValues[$name]) ? $argumentValues[$name] : $defaultValue;
173 $fields[$name] = array(
174 'code' => $this->renderField($argument, $value),
175 'label' => $this->getArgumentLabel($argument)
176 );
177 }
178 return $fields;
179 }
180
181 /**
182 * Gets a label for $key based on either provided extension or currently
183 * selected CommandController extension,ยด
184 *
185 * @param string $localLanguageKey
186 * @param string $extensionName
187 * @return string
188 */
189 protected function getLanguageLabel($localLanguageKey, $extensionName = NULL) {
190 if (!$extensionName) {
191 list($extensionName, $commandControllerName, $commandName) = explode(':', $this->task->getCommandIdentifier());
192 }
193 $label = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate($localLanguageKey, $extensionName);
194 return $label;
195 }
196
197 /**
198 * Gets the data type required for the argument value
199 *
200 * @param \TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition $argument
201 * @return string the argument type
202 */
203 protected function getArgumentType(\TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition $argument) {
204 $command = $this->commandManager->getCommandByIdentifier($this->task->getCommandIdentifier());
205 $controllerClassName = $command->getControllerClassName();
206 $methodName = $command->getControllerCommandName() . 'Command';
207 $tags = $this->reflectionService->getMethodTagsValues($controllerClassName, $methodName);
208 foreach ($tags['param'] as $tag) {
209 list($argumentType, $argumentVariableName) = explode(' ', $tag);
210 if (substr($argumentVariableName, 1) === $argument->getName()) {
211 return $argumentType;
212 }
213 }
214 return '';
215 }
216
217 /**
218 * Get a human-readable label for a command argument
219 *
220 * @param \TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition $argument
221 * @return string
222 */
223 protected function getArgumentLabel(\TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition $argument) {
224 $argumentName = $argument->getName();
225 list($extensionName, $commandControllerName, $commandName) = explode(':', $this->task->getCommandIdentifier());
226 $path = array('command', $commandControllerName, $commandName, 'arguments', $argumentName);
227 $labelNameIndex = implode('.', $path);
228 $label = $this->getLanguageLabel($labelNameIndex);
229 if (!$label) {
230 $label = 'Argument: ' . $argumentName;
231 }
232 $descriptionIndex = $labelNameIndex . '.description';
233 $description = $this->getLanguageLabel($descriptionIndex);
234 if (strlen($description) === 0) {
235 $description = $argument->getDescription();
236 }
237 if (strlen($description) > 0) {
238 $label .= '. <em>' . htmlspecialchars($description) . '</em>';
239 }
240 return $label;
241 }
242
243 /**
244 * Gets the default value of argument
245 *
246 * @param \TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition $argument
247 * @return mixed
248 */
249 protected function getDefaultArgumentValue(\TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition $argument) {
250 $type = $this->getArgumentType($argument);
251 $argumentName = $argument->getName();
252 $command = $this->commandManager->getCommandByIdentifier($this->task->getCommandIdentifier());
253 $argumentReflection = $this->reflectionService->getMethodParameters($command->getControllerClassName(), $command->getControllerCommandName() . 'Command');
254 $defaultValue = $argumentReflection[$argumentName]['defaultValue'];
255 if ($type === 'boolean') {
256 $defaultValue = (bool)$defaultValue ? 1 : 0;
257 }
258 return $defaultValue;
259 }
260
261 /**
262 * Get a human-readable label for the action field
263 *
264 * @return string
265 */
266 protected function getActionLabel() {
267 $index = 'task.action';
268 $label = $this->getLanguageLabel($index, 'extbase');
269 if (!$label) {
270 $label = 'CommandController Command. <em>Save and reopen to define command arguments</em>';
271 }
272 return $label;
273 }
274
275 /**
276 * Render a select field with name $name and options $options
277 *
278 * @param string $name
279 * @param array $options
280 * @param string $selectedOptionValue
281 * @return string
282 */
283 protected function renderSelectField($name, array $options, $selectedOptionValue) {
284 $html = array(
285 '<select name="tx_scheduler[task_extbase][' . htmlspecialchars($name) . ']">'
286 );
287 foreach ($options as $optionValue => $optionLabel) {
288 $selected = $optionValue === $selectedOptionValue ? ' selected="selected"' : '';
289 array_push($html, '<option title="test" value="' . htmlspecialchars($optionValue) . '"' . $selected . '>' . htmlspecialchars($optionLabel) . '</option>');
290 }
291 array_push($html, '</select>');
292 return implode(LF, $html);
293 }
294
295 /**
296 * Renders a field for defining an argument's value
297 *
298 * @param \TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition $argument
299 * @param mixed $currentValue
300 * @return string
301 */
302 protected function renderField(\TYPO3\CMS\Extbase\Mvc\Cli\CommandArgumentDefinition $argument, $currentValue) {
303 $type = $this->getArgumentType($argument);
304 $name = $argument->getName();
305 $fieldName = 'tx_scheduler[task_extbase][arguments][' . htmlspecialchars($name) . ']';
306 if ($type === 'boolean') {
307 // checkbox field for boolean values.
308 $html = '<input type="hidden" name="' . $fieldName . '" value="0" />';
309 $html .= '<input type="checkbox" name="' . $fieldName . '" value="1" ' . ((bool)$currentValue ? ' checked="checked"' : '') . '/>';
310 } else {
311 // regular string, also the default field type
312 $html = '<input type="text" name="' . $fieldName . '" value="' . htmlspecialchars($currentValue) . '" /> ';
313 }
314 return $html;
315 }
316
317 }