1<?php 2 3/* 4 * This file is part of the TYPO3 CMS project. 5 * 6 * It is free software; you can redistribute it and/or modify it under 7 * the terms of the GNU General Public License, either version 2 8 * of the License, or any later version. 9 * 10 * For the full copyright and license information, please read the 11 * LICENSE.txt file that was distributed with this source code. 12 * 13 * The TYPO3 project - inspiring people to share! 14 */ 15 16namespace TYPO3\CMS\Linkvalidator\Task; 17 18use TYPO3\CMS\Backend\Utility\BackendUtility; 19use TYPO3\CMS\Core\Localization\LanguageService; 20use TYPO3\CMS\Core\Messaging\FlashMessage; 21use TYPO3\CMS\Core\Utility\GeneralUtility; 22use TYPO3\CMS\Scheduler\AbstractAdditionalFieldProvider; 23use TYPO3\CMS\Scheduler\Controller\SchedulerModuleController; 24use TYPO3\CMS\Scheduler\Task\AbstractTask; 25use TYPO3\CMS\Scheduler\Task\Enumeration\Action; 26 27/** 28 * This class provides Scheduler Additional Field plugin implementation 29 * @internal This class is a specific Scheduler task implementation and is not part of the TYPO3's Core API. 30 */ 31class ValidatorTaskAdditionalFieldProvider extends AbstractAdditionalFieldProvider 32{ 33 /** 34 * Default language file of the extension linkvalidator 35 * 36 * @var string 37 */ 38 protected $languageFile = 'LLL:EXT:linkvalidator/Resources/Private/Language/locallang.xlf'; 39 40 /** 41 * Render additional information fields within the scheduler backend. 42 * 43 * @param array $taskInfo Array information of task to return 44 * @param ValidatorTask|null $task The task object being edited. Null when adding a task! 45 * @param SchedulerModuleController $schedulerModule Reference to the BE module of the Scheduler 46 * @return array Additional fields 47 * @see AdditionalFieldProviderInterface::getAdditionalFields 48 */ 49 public function getAdditionalFields(array &$taskInfo, $task, SchedulerModuleController $schedulerModule) 50 { 51 $additionalFields = []; 52 $currentSchedulerModuleAction = $schedulerModule->getCurrentAction(); 53 54 if (empty($taskInfo['configuration'])) { 55 if ($currentSchedulerModuleAction->equals(Action::ADD)) { 56 $taskInfo['configuration'] = $taskInfo['linkvalidator']['configuration']; 57 } elseif ($currentSchedulerModuleAction->equals(Action::EDIT)) { 58 $taskInfo['configuration'] = $task->getConfiguration(); 59 } else { 60 $taskInfo['configuration'] = $task->getConfiguration(); 61 } 62 } 63 64 if (empty($taskInfo['depth'])) { 65 if ($currentSchedulerModuleAction->equals(Action::ADD)) { 66 $taskInfo['depth'] = $taskInfo['linkvalidator']['depth']; 67 } elseif ($currentSchedulerModuleAction->equals(Action::EDIT)) { 68 $taskInfo['depth'] = $task->getDepth(); 69 } else { 70 $taskInfo['depth'] = $task->getDepth(); 71 } 72 } 73 74 if (empty($taskInfo['page'])) { 75 if ($currentSchedulerModuleAction->equals(Action::ADD)) { 76 $taskInfo['page'] = $taskInfo['linkvalidator']['page']; 77 } elseif ($currentSchedulerModuleAction->equals(Action::EDIT)) { 78 $taskInfo['page'] = $task->getPage(); 79 } else { 80 $taskInfo['page'] = $task->getPage(); 81 } 82 } 83 if (empty($taskInfo['email'])) { 84 if ($currentSchedulerModuleAction->equals(Action::ADD)) { 85 $taskInfo['email'] = $taskInfo['linkvalidator']['email']; 86 } elseif ($currentSchedulerModuleAction->equals(Action::EDIT)) { 87 $taskInfo['email'] = $task->getEmail(); 88 } else { 89 $taskInfo['email'] = $task->getEmail(); 90 } 91 } 92 if (empty($taskInfo['emailOnBrokenLinkOnly'])) { 93 if ($currentSchedulerModuleAction->equals(Action::ADD)) { 94 $taskInfo['emailOnBrokenLinkOnly'] = $taskInfo['linkvalidator']['emailOnBrokenLinkOnly'] ?: 1; 95 } elseif ($currentSchedulerModuleAction->equals(Action::EDIT)) { 96 $taskInfo['emailOnBrokenLinkOnly'] = $task->getEmailOnBrokenLinkOnly(); 97 } else { 98 $taskInfo['emailOnBrokenLinkOnly'] = $task->getEmailOnBrokenLinkOnly(); 99 } 100 } 101 if (empty($taskInfo['emailTemplateFile'])) { 102 if ($currentSchedulerModuleAction->equals(Action::ADD)) { 103 $taskInfo['emailTemplateFile'] = $taskInfo['linkvalidator']['emailTemplateFile'] ?: 'EXT:linkvalidator/Resources/Private/Templates/mailtemplate.html'; 104 } elseif ($currentSchedulerModuleAction->equals(Action::EDIT)) { 105 $taskInfo['emailTemplateFile'] = $task->getEmailTemplateFile(); 106 } else { 107 $taskInfo['emailTemplateFile'] = $task->getEmailTemplateFile(); 108 } 109 } 110 $fieldId = 'task_page'; 111 $fieldCode = '<input type="number" min="0" class="form-control" name="tx_scheduler[linkvalidator][page]" id="' 112 . $fieldId 113 . '" value="' 114 . htmlspecialchars($taskInfo['page']) 115 . '">'; 116 $lang = $this->getLanguageService(); 117 $label = $lang->sL($this->languageFile . ':tasks.validate.page'); 118 $pageTitle = ''; 119 if (!empty($taskInfo['page'])) { 120 $pageTitle = $this->getPageTitle((int)$taskInfo['page']); 121 } 122 $additionalFields[$fieldId] = [ 123 'browser' => 'page', 124 'pageTitle' => $pageTitle, 125 'code' => $fieldCode, 126 'cshTable' => 'linkvalidator', 127 'cshLabel' => $fieldId, 128 'label' => $label 129 ]; 130 // input for depth 131 $fieldId = 'task_depth'; 132 $fieldValueArray = [ 133 '0' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'), 134 '1' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'), 135 '2' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'), 136 '3' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'), 137 '4' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'), 138 '999' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi') 139 ]; 140 /** @var array<string, string> $fieldValueArray */ 141 $fieldCode = '<select class="form-control" name="tx_scheduler[linkvalidator][depth]" id="' . $fieldId . '">'; 142 foreach ($fieldValueArray as $depth => $label) { 143 $fieldCode .= "\t" . '<option value="' . htmlspecialchars($depth) . '"' 144 . (($depth == $taskInfo['depth']) ? ' selected="selected"' : '') . '>' 145 . $label 146 . '</option>'; 147 } 148 $fieldCode .= '</select>'; 149 $label = $lang->sL($this->languageFile . ':tasks.validate.depth'); 150 $additionalFields[$fieldId] = [ 151 'code' => $fieldCode, 152 'cshKey' => 'linkvalidator', 153 'cshLabel' => $fieldId, 154 'label' => $label 155 ]; 156 $fieldId = 'task_configuration'; 157 $fieldCode = '<textarea class="form-control" name="tx_scheduler[linkvalidator][configuration]" id="' 158 . $fieldId 159 . '" >' 160 . htmlspecialchars($taskInfo['configuration']) 161 . '</textarea>'; 162 $label = $lang->sL($this->languageFile . ':tasks.validate.conf'); 163 $additionalFields[$fieldId] = [ 164 'code' => $fieldCode, 165 'cshKey' => 'linkvalidator', 166 'cshLabel' => $fieldId, 167 'label' => $label 168 ]; 169 $fieldId = 'task_email'; 170 $fieldCode = '<textarea class="form-control" rows="5" cols="50" name="tx_scheduler[linkvalidator][email]" id="' 171 . $fieldId 172 . '">' 173 . htmlspecialchars($taskInfo['email']) 174 . '</textarea>'; 175 $label = $lang->sL($this->languageFile . ':tasks.validate.email'); 176 $additionalFields[$fieldId] = [ 177 'code' => $fieldCode, 178 'cshKey' => 'linkvalidator', 179 'cshLabel' => $fieldId, 180 'label' => $label 181 ]; 182 $fieldId = 'task_emailOnBrokenLinkOnly'; 183 $fieldCode = '<div class="checkbox"><label>' 184 . '<input type="checkbox" name="tx_scheduler[linkvalidator][emailOnBrokenLinkOnly]" id="' . $fieldId . '" ' 185 . (htmlspecialchars($taskInfo['emailOnBrokenLinkOnly']) ? 'checked="checked"' : '') 186 . '></label></div>'; 187 $label = $lang->sL($this->languageFile . ':tasks.validate.emailOnBrokenLinkOnly'); 188 $additionalFields[$fieldId] = [ 189 'code' => $fieldCode, 190 'cshKey' => 'linkvalidator', 191 'cshLabel' => $fieldId, 192 'label' => $label 193 ]; 194 $fieldId = 'task_emailTemplateFile'; 195 $fieldCode = '<input class="form-control" type="text" name="tx_scheduler[linkvalidator][emailTemplateFile]" ' 196 . 'id="' 197 . $fieldId 198 . '" value="' 199 . htmlspecialchars($taskInfo['emailTemplateFile']) 200 . '">'; 201 $label = $lang->sL($this->languageFile . ':tasks.validate.emailTemplateFile'); 202 $additionalFields[$fieldId] = [ 203 'code' => $fieldCode, 204 'cshKey' => 'linkvalidator', 205 'cshLabel' => $fieldId, 206 'label' => $label 207 ]; 208 return $additionalFields; 209 } 210 211 /** 212 * Mark current value as selected by returning the "selected" attribute 213 * 214 * @param array $configurationArray Array of configuration 215 * @param string $currentValue Value of selector object 216 * @return string Html fragment for a selected option or empty 217 */ 218 protected function getSelectedState(array $configurationArray, $currentValue) 219 { 220 $selected = ''; 221 if (in_array($currentValue, $configurationArray, true)) { 222 $selected = 'selected="selected" '; 223 } 224 return $selected; 225 } 226 227 /** 228 * This method checks any additional data that is relevant to the specific task. 229 * If the task class is not relevant, the method is expected to return TRUE. 230 * 231 * @param array $submittedData Reference to the array containing the data submitted by the user 232 * @param SchedulerModuleController $schedulerModule Reference to the BE module of the Scheduler 233 * @return bool TRUE if validation was ok (or selected class is not relevant), FALSE otherwise 234 */ 235 public function validateAdditionalFields(array &$submittedData, SchedulerModuleController $schedulerModule) 236 { 237 $isValid = true; 238 // @todo add validation to validate the $submittedData['configuration'] 239 // @todo which is normally a comma separated string 240 $lang = $this->getLanguageService(); 241 if (!empty($submittedData['linkvalidator']['email'])) { 242 if (strpos($submittedData['linkvalidator']['email'], ',') !== false) { 243 $emailList = GeneralUtility::trimExplode(',', $submittedData['linkvalidator']['email']); 244 } else { 245 $emailList = GeneralUtility::trimExplode(LF, $submittedData['linkvalidator']['email']); 246 } 247 foreach ($emailList as $emailAdd) { 248 if (!GeneralUtility::validEmail($emailAdd)) { 249 $isValid = false; 250 $this->addMessage( 251 $lang->sL($this->languageFile . ':tasks.validate.invalidEmail'), 252 FlashMessage::ERROR 253 ); 254 } 255 } 256 } 257 258 $row = BackendUtility::getRecord('pages', (int)$submittedData['linkvalidator']['page'], '*', '', false); 259 if (empty($row)) { 260 $isValid = false; 261 $this->addMessage( 262 $lang->sL($this->languageFile . ':tasks.validate.invalidPage'), 263 FlashMessage::ERROR 264 ); 265 } 266 if ($submittedData['linkvalidator']['depth'] < 0) { 267 $isValid = false; 268 $this->addMessage( 269 $lang->sL($this->languageFile . ':tasks.validate.invalidDepth'), 270 FlashMessage::ERROR 271 ); 272 } 273 return $isValid; 274 } 275 276 /** 277 * This method is used to save any additional input into the current task object 278 * if the task class matches. 279 * 280 * @param array $submittedData Array containing the data submitted by the user 281 * @param AbstractTask $task Reference to the current task object 282 */ 283 public function saveAdditionalFields(array $submittedData, AbstractTask $task) 284 { 285 /** @var ValidatorTask $task */ 286 $task->setDepth($submittedData['linkvalidator']['depth']); 287 $task->setPage($submittedData['linkvalidator']['page']); 288 $task->setEmail($submittedData['linkvalidator']['email']); 289 if ($submittedData['linkvalidator']['emailOnBrokenLinkOnly']) { 290 $task->setEmailOnBrokenLinkOnly(1); 291 } else { 292 $task->setEmailOnBrokenLinkOnly(0); 293 } 294 $task->setConfiguration($submittedData['linkvalidator']['configuration']); 295 $task->setEmailTemplateFile($submittedData['linkvalidator']['emailTemplateFile']); 296 } 297 298 /** 299 * Get the title of the selected page 300 * 301 * @param int $pageId 302 * @return string Page title or empty string 303 */ 304 private function getPageTitle($pageId) 305 { 306 $page = BackendUtility::getRecord('pages', $pageId, 'title', '', false); 307 if ($page === null) { 308 return ''; 309 } 310 return $page['title']; 311 } 312 313 /** 314 * @return LanguageService 315 */ 316 protected function getLanguageService() 317 { 318 return $GLOBALS['LANG']; 319 } 320} 321