diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/Labels/CshViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/Labels/CshViewHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..2d0ee8dd7a97dafea2aab893b469a4bfb12ac1ef --- /dev/null +++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/Labels/CshViewHelper.php @@ -0,0 +1,112 @@ +<?php +namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Labels; + +/* + * 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\Backend\Utility\BackendUtility; +use TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper; +use TYPO3\CMS\Lang\LanguageService; +use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; + +/** + * View helper which returns CSH (context sensitive help) label with icon hover + * Note: The CSH label will only work, if the current BE user has the "Context Sensitive Help mode" + * set to something else than "Display no help information" in the Users settings + * Note: This view helper is experimental! + * + * = Examples = + * + * <code title="Default"> + * <f:be.labels.csh /> + * </code> + * <output> + * CSH label as known from the TYPO3 backend. + * </output> + * + * <code title="Full configuration"> + * <f:be.labels.csh table="xMOD_csh_corebe" field="someCshKey" label="lang/Resources/Private/Language/locallang/header.languages" /> + * </code> + * <output> + * CSH label as known from the TYPO3 backend with some custom settings. + * </output> + */ +class CshViewHelper extends AbstractBackendViewHelper +{ + /** + * As this ViewHelper renders HTML, the output must not be escaped. + * + * @var bool + */ + protected $escapeOutput = false; + + /** + * Returns the Language Service + * @return LanguageService + */ + protected static function getLanguageService() + { + return $GLOBALS['LANG']; + } + + /** + * Initialize arguments. + * + * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception + */ + public function initializeArguments() + { + parent::initializeArguments(); + $this->registerArgument('table', 'string', 'Table name (\'_MOD_\'+module name). If not set, the current module name will be used'); + $this->registerArgument('field', 'string', 'Field name (CSH locallang main key)', false, ''); + $this->registerArgument('label', 'string', 'Language label which is wrapped with the CSH', false, ''); + } + + /** + * Render context sensitive help (CSH) for the given table + * + * @return string the rendered CSH icon + */ + public function render() + { + return static::renderStatic( + $this->arguments, + $this->buildRenderChildrenClosure(), + $this->renderingContext + ); + } + + /** + * @param array $arguments + * @param \Closure $renderChildrenClosure + * @param RenderingContextInterface $renderingContext + * @return string + */ + public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) + { + $table = $arguments['table']; + $field = $arguments['field']; + $label = $arguments['label']; + + if ($table === null) { + $currentRequest = $renderingContext->getControllerContext()->getRequest(); + $moduleName = $currentRequest->getPluginName(); + $table = '_MOD_' . $moduleName; + } + if (substr($label, 0, 4) === 'LLL:') { + $label = htmlspecialchars(self::getLanguageService()->sL($label)); + } + $label = '<label>' . $label . '</label>'; + return BackendUtility::wrapInHelp($table, $field, $label); + } +} diff --git a/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php b/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php index f64bae80314e1b60f88da64d98a3eab695dcdd5a..9c8eacb6ede262f03883550e0f8ce2e1857fdfb0 100644 --- a/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php +++ b/typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php @@ -167,7 +167,7 @@ class SchedulerModuleController // Prepare main content $content .= '<h1>' . $this->getLanguageService()->getLL('function.' . $this->MOD_SETTINGS['function']) . '</h1>'; $content .= $this->getModuleContent(); - $content .= '</form><div id="extraFieldsHidden"></div>'; + $content .= '<div id="extraFieldsSection"></div></form><div id="extraFieldsHidden"></div>'; } else { // If no access, only display the module's title $content = '<h1>' . $this->getLanguageService()->getLL('title.') . '</h1>'; @@ -628,154 +628,69 @@ class SchedulerModuleController // Start rendering the add/edit form $this->view->assign('uid', htmlspecialchars($this->submittedData['uid'])); $this->view->assign('cmd', htmlspecialchars($this->CMD)); + $this->view->assign('csh', $this->cshKey); + $this->view->assign('lang', 'LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:'); $table = []; // Disable checkbox - $label = '<label>' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:disable') . '</label>'; - $table[] = - '<div class="form-section" id="task_disable_row"><div class="form-group">' - . BackendUtility::wrapInHelp($this->cshKey, 'task_disable', $label) - . '<div class="form-control-wrap">' - . '<input type="hidden" name="tx_scheduler[disable]" value="0">' - . '<input class="checkbox" type="checkbox" name="tx_scheduler[disable]" value="1" id="task_disable" ' . ($taskInfo['disable'] ? ' checked="checked"' : '') . '>' - . '</div>' - . '</div></div>'; + $this->view->assign('task_disable', ($taskInfo['disable'] ? ' checked="checked"' : '')); + $this->view->assign('task_disable_label', 'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:disable'); // Task class selector - $label = '<label>' . $this->getLanguageService()->getLL('label.class') . '</label>'; - // On editing, don't allow changing of the task class, unless it was not valid if ($this->submittedData['uid'] > 0 && !empty($taskInfo['class'])) { - $cell = '<div>' . $registeredClasses[$taskInfo['class']]['title'] . ' (' . $registeredClasses[$taskInfo['class']]['extension'] . ')</div>'; - $cell .= '<input type="hidden" name="tx_scheduler[class]" id="task_class" value="' . htmlspecialchars($taskInfo['class']) . '">'; + $this->view->assign('task_class', $taskInfo['class']); + $this->view->assign('task_class_title', $registeredClasses[$taskInfo['class']]['title']); + $this->view->assign('task_class_extension', $registeredClasses[$taskInfo['class']]['extension']); } else { - $cell = '<select name="tx_scheduler[class]" id="task_class" class="form-control">'; // Group registered classes by classname $groupedClasses = []; foreach ($registeredClasses as $class => $classInfo) { $groupedClasses[$classInfo['extension']][$class] = $classInfo; } ksort($groupedClasses); - // Loop on all grouped classes to display a selector foreach ($groupedClasses as $extension => $class) { - $cell .= '<optgroup label="' . htmlspecialchars($extension) . '">'; foreach ($groupedClasses[$extension] as $class => $classInfo) { $selected = $class == $taskInfo['class'] ? ' selected="selected"' : ''; - $cell .= '<option value="' . htmlspecialchars($class) . '"' . ' title="' . htmlspecialchars($classInfo['description']) . '" ' . $selected . '>' . htmlspecialchars($classInfo['title']) . '</option>'; + $groupedClasses[$extension][$class]['selected'] = $selected; } - $cell .= '</optgroup>'; } - $cell .= '</select>'; + $this->view->assign('groupedClasses', $groupedClasses); } - $table[] = - '<div class="form-section" id="task_class_row"><div class="form-group">' - . BackendUtility::wrapInHelp($this->cshKey, 'task_class', $label) - . '<div class="form-control-wrap">' - . $cell - . '</div>' - . '</div></div>'; // Task type selector - $label = '<label>' . $this->getLanguageService()->getLL('label.type') . '</label>'; - $table[] = - '<div class="form-section" id="task_type_row"><div class="form-group">' - . BackendUtility::wrapInHelp($this->cshKey, 'task_type', $label) - . '<div class="form-control-wrap">' - . '<select name="tx_scheduler[type]" id="task_type" class="form-control">' - . '<option value="1" ' . ((int)$taskInfo['type'] === AbstractTask::TYPE_SINGLE ? ' selected="selected"' : '') . '>' . $this->getLanguageService()->getLL('label.type.single') . '</option>' - . '<option value="2" ' . ((int)$taskInfo['type'] === AbstractTask::TYPE_RECURRING ? ' selected="selected"' : '') . '>' . $this->getLanguageService()->getLL('label.type.recurring') . '</option>' - . '</select>' - . '</div>' - . '</div></div>'; + $this->view->assign('task_type_selected_1', ((int)$taskInfo['type'] === AbstractTask::TYPE_SINGLE ? ' selected="selected"' : '')); + $this->view->assign('task_type_selected_2', ((int)$taskInfo['type'] === AbstractTask::TYPE_RECURRING ? ' selected="selected"' : '')); // Task group selector - $label = '<label>' . $this->getLanguageService()->getLL('label.group') . '</label>'; - $cell = '<select name="tx_scheduler[task_group]" id="task_class" class="form-control">'; - - // Loop on all groups to display a selector - $cell .= '<option value="0" title=""></option>'; - foreach ($registeredTaskGroups as $taskGroup) { + foreach ($registeredTaskGroups as $key => $taskGroup) { $selected = $taskGroup['uid'] == $taskInfo['task_group'] ? ' selected="selected"' : ''; - $cell .= '<option value="' . $taskGroup['uid'] . '"' . 'title="'; - $cell .= htmlspecialchars($taskGroup['groupName']) . '"' . $selected . '>'; - $cell .= htmlspecialchars($taskGroup['groupName']) . '</option>'; + $registeredTaskGroups[$key]['selected'] = $selected; } - $cell .= '</select>'; - - $table[] = - '<div class="form-section" id="task_group_row"><div class="form-group">' - . BackendUtility::wrapInHelp($this->cshKey, 'task_group', $label) - . '<div class="form-control-wrap">' - . $cell - . '</div>' - . '</div></div>'; + $this->view->assign('registeredTaskGroups', $registeredTaskGroups); + // Start date/time field $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? '%H:%M %m-%d-%Y' : '%H:%M %d-%m-%Y'; - - $label = '<label>' . BackendUtility::wrapInHelp($this->cshKey, 'task_start', $this->getLanguageService()->getLL('label.start')) . '</label>'; - $value = ($taskInfo['start'] > 0 ? strftime($dateFormat, $taskInfo['start']) : ''); - $table[] = - '<div class="form-section"><div class="row"><div class="form-group col-sm-6" id="task_start_col">' - . $label - . '<div class="form-control-wrap">' - . '<div class="input-group" id="tceforms-datetimefield-task_start_row-wrapper">' - . '<input name="tx_scheduler[start]_hr" value="' . htmlspecialchars($value) . '" class="form-control t3js-datetimepicker t3js-clearable" data-date-type="datetime" type="text" id="tceforms-datetimefield-task_start_row">' - . '<input name="tx_scheduler[start]" value="' . htmlspecialchars($taskInfo['start']) . '" type="hidden">' - . '<span class="input-group-btn"><label class="btn btn-default" for="tceforms-datetimefield-task_start_row"><span class="fa fa-calendar"></span></label></span>' - . '</div>' - . '</div>' - . '</div>'; + $this->view->assign('start_value_hr', ($taskInfo['start'] > 0 ? strftime($dateFormat, $taskInfo['start']) : '')); + $this->view->assign('start_value', $taskInfo['start']); // End date/time field // NOTE: datetime fields need a special id naming scheme - $value = ($taskInfo['end'] > 0 ? strftime($dateFormat, $taskInfo['end']) : ''); - $label = '<label>' . $this->getLanguageService()->getLL('label.end') . '</label>'; - $table[] = - '<div class="form-group col-sm-6" id="task_end_col">' - . BackendUtility::wrapInHelp($this->cshKey, 'task_end', $label) - . '<div class="form-control-wrap">' - . '<div class="input-group" id="tceforms-datetimefield-task_end_row-wrapper">' - . '<input name="tx_scheduler[end]_hr" value="' . htmlspecialchars($value) . '" class="form-control t3js-datetimepicker t3js-clearable" data-date-type="datetime" type="text" id="tceforms-datetimefield-task_end_row">' - . '<input name="tx_scheduler[end]" value="' . htmlspecialchars($taskInfo['end']) . '" type="hidden">' - . '<span class="input-group-btn"><label class="btn btn-default" for="tceforms-datetimefield-task_end_row"><span class="fa fa-calendar"></span></label></span>' - . '</div>' - . '</div>' - . '</div></div></div>'; + $this->view->assign('end_value_hr', ($taskInfo['end'] > 0 ? strftime($dateFormat, $taskInfo['end']) : '')); + $this->view->assign('end_value', $taskInfo['end']); // Frequency input field - $label = '<label>' . $this->getLanguageService()->getLL('label.frequency.long') . '</label>'; - $table[] = - '<div class="form-section" id="task_frequency_row"><div class="form-group">' - . BackendUtility::wrapInHelp($this->cshKey, 'task_frequency', $label) - . '<div class="form-control-wrap">' - . '<input type="text" name="tx_scheduler[frequency]" class="form-control" id="task_frequency" value="' . htmlspecialchars($taskInfo['frequency']) . '">' - . '</div>' - . '</div></div>'; + $this->view->assign('frequency', $taskInfo['frequency']); // Multiple execution selector - $label = '<label>' . $this->getLanguageService()->getLL('label.parallel.long') . '</label>'; - $table[] = - '<div class="form-section" id="task_multiple_row"><div class="form-group">' - . BackendUtility::wrapInHelp($this->cshKey, 'task_multiple', $label) - . '<div class="form-control-wrap">' - . '<input type="hidden" name="tx_scheduler[multiple]" value="0">' - . '<input class="checkbox" type="checkbox" name="tx_scheduler[multiple]" value="1" id="task_multiple" ' . ($taskInfo['multiple'] ? 'checked="checked"' : '') . '>' - . '</div>' - . '</div></div>'; + $this->view->assign('multiple', ($taskInfo['multiple'] ? 'checked="checked"' : '')); // Description - $label = '<label>' . $this->getLanguageService()->getLL('label.description') . '</label>'; - $table[] = - '<div class="form-section" id="task_description_row"><div class="form-group">' - . BackendUtility::wrapInHelp($this->cshKey, 'task_description', $label) - . '<div class="form-control-wrap">' - . '<textarea class="form-control" name="tx_scheduler[description]">' . htmlspecialchars($taskInfo['description']) . '</textarea>' - . '</div>' - . '</div></div>'; + $this->view->assign('description', $taskInfo['description']); // Display additional fields - $table[] = '<div id="extraFieldsSection">'; + $additionalFieldList = []; foreach ($allAdditionalFields as $class => $fields) { if ($class == $taskInfo['class']) { $additionalFieldsStyle = ''; @@ -785,18 +700,21 @@ class SchedulerModuleController // Add each field to the display, if there are indeed any if (isset($fields) && is_array($fields)) { foreach ($fields as $fieldID => $fieldInfo) { - $label = '<label>' . $this->getLanguageService()->sL($fieldInfo['label']) . '</label>'; $htmlClassName = strtolower(str_replace('\\', '-', $class)); - $table[] = - '<div class="form-section extraFields extra_fields_' . $htmlClassName . '" ' . $additionalFieldsStyle . ' id="' . $fieldID . '_row"><div class="form-group">' - . BackendUtility::wrapInHelp($fieldInfo['cshKey'], $fieldInfo['cshLabel'], $label) - . '<div class="form-control-wrap">' . $fieldInfo['code'] . '</div>' - . $this->getBrowseButton($fieldID, $fieldInfo) - . '</div></div>'; + $field = []; + $field['htmlClassName'] = $htmlClassName; + $field['code'] = $fieldInfo['code']; + $field['cshKey'] = $fieldInfo['cshKey']; + $field['cshLabel'] = $fieldInfo['cshLabel']; + $field['langLabel'] = $fieldInfo['label']; + $field['fieldID'] = $fieldID; + $field['additionalFieldsStyle'] = $additionalFieldsStyle; + $field['browseButton'] = $this->getBrowseButton($fieldID, $fieldInfo); + $additionalFieldList[] = $field; } } } - $table[] = '</div>'; + $this->view->assign('additionalFields', $additionalFieldList); $this->view->assign('table', implode(LF, $table)); $this->view->assign('now', $this->getServerTime()); diff --git a/typo3/sysext/scheduler/Resources/Private/Templates/Backend/SchedulerModule/EditTask.html b/typo3/sysext/scheduler/Resources/Private/Templates/Backend/SchedulerModule/EditTask.html index ebc7d91949f89155fbda442c4db71072e4616b7a..9be2e642ad02decff4475848c030e78944639608 100644 --- a/typo3/sysext/scheduler/Resources/Private/Templates/Backend/SchedulerModule/EditTask.html +++ b/typo3/sysext/scheduler/Resources/Private/Templates/Backend/SchedulerModule/EditTask.html @@ -1,6 +1,132 @@ <input type="hidden" name="tx_scheduler[uid]" value="{uid}" /> <input type="hidden" name="previousCMD" value="{cmd}" /> +<div class="form-section" id="task_disable_row"> + <div class="form-group"> + <f:be.labels.csh table="{csh}" field="task_disable" label="{task_disable_label}"/> + <div class="form-control-wrap"> + <input type="hidden" name="tx_scheduler[disable]" value="0"> + <input class="checkbox" type="checkbox" name="tx_scheduler[disable]" value="1" id="task_disable" {task_disable}> + </div> + </div> +</div> +<div class="form-section" id="task_class_row"> + <div class="form-group"> + <f:be.labels.csh table="{csh}" field="task_class" label="{lang}label.class"/> + <div class="form-control-wrap"> + <f:if condition="{task_class}"> + <f:then> + <div>{task_class_title} ({task_class_extension})</div> + <input type="hidden" name="tx_scheduler[class]" id="task_class" value="{task_class}"> + </f:then> + <f:else> + <select name="tx_scheduler[class]" id="task_class" class="form-control"> + <f:for each="{groupedClasses}" as="classGroup" key="extension"> + <optgroup label="{extension}"> + <f:for each="{classGroup}" as="classInfo" key="class"> + <option value="{class}" title="{classInfo.description}" {classInfo.selected}>{classInfo.title}</option> + </f:for> + </optgroup> + </f:for> + </select> + </f:else> + </f:if> + </div> + </div> +</div> +<div class="form-section" id="task_type_row"> + <div class="form-group"> + <f:be.labels.csh table="{csh}" field="task_type" label="{lang}label.type"/> + <div class="form-control-wrap"> + <select name="tx_scheduler[type]" id="task_type" class="form-control"> + <option value="1" {task_type_selected_1}><f:translate key="{lang}label.type.single" /></option> + <option value="2" {task_type_selected_2}><f:translate key="{lang}label.type.recurring" /></option> + </select> + </div> + </div> +</div> +<div class="form-section" id="task_group_row"> + <div class="form-group"> + <f:be.labels.csh table="{csh}" field="task_group" label="{lang}label.group"/> + <div class="form-control-wrap"> + <select name="tx_scheduler[task_group]" id="task_class" class="form-control"> + <option value="0" title=""></option> + <f:for each="{registeredTaskGroups}" as="registeredTaskGroup"> + <option value="{registeredTaskGroup.uid}" title="{registeredTaskGroup.groupName}" {registeredTaskGroup.selected}> + {registeredTaskGroup.groupName} + </option> + </f:for> + </select> + </div> + </div> +</div> +<div class="form-section"> + <div class="row"> + <div class="form-group col-sm-6" id="task_start_col"> + <f:be.labels.csh table="{csh}" field="task_start" label="{lang}label.start"/> + <div class="form-control-wrap"> + <div class="input-group" id="tceforms-datetimefield-task_start_row-wrapper"> + <input name="tx_scheduler[start]_hr" value="{start_value_hr}" class="form-control t3js-datetimepicker t3js-clearable" data-date-type="datetime" data-date-offset="0" type="text" id="tceforms-datetimefield-task_start_row"> + <input name="tx_scheduler[start]" value="{start_value}" type="hidden"> + <span class="input-group-btn"><label class="btn btn-default" for="tceforms-datetimefield-task_start_row"><span class="fa fa-calendar"></span></label></span> + </div> + </div> + </div> + <div class="form-group col-sm-6" id="task_end_col"> + <f:be.labels.csh table="{csh}" field="task_end" label="{lang}label.end"/> + <div class="form-control-wrap"> + <div class="input-group" id="tceforms-datetimefield-task_end_row-wrapper"> + <input name="tx_scheduler[end]_hr" value="{end_value_hr}" class="form-control t3js-datetimepicker t3js-clearable" data-date-type="datetime" data-date-offset="0" type="text" id="tceforms-datetimefield-task_end_row"> + <input name="tx_scheduler[end]" value="{end_value}" type="hidden"> + <span class="input-group-btn"><label class="btn btn-default" for="tceforms-datetimefield-task_end_row"><span class="fa fa-calendar"></span></label></span> + </div> + </div> + </div> + </div> +</div> +<div class="form-section" id="task_frequency_row"> + <div class="form-group"> + <f:be.labels.csh table="{csh}" field="task_frequency" label="{lang}label.frequency.long"/> + <div class="form-control-wrap"> + <input type="text" name="tx_scheduler[frequency]" class="form-control" id="task_frequency" value="{frequency}"> + </div> + </div> +</div> +<div class="form-section" id="task_multiple_row"> + <div class="form-group"> + <f:be.labels.csh table="{csh}" field="task_multiple" label="{lang}label.parallel.long"/> + <div class="form-control-wrap"> + <input type="hidden" name="tx_scheduler[multiple]" value="0"> + <input class="checkbox" type="checkbox" name="tx_scheduler[multiple]" value="1" id="task_multiple" {multiple}> + </div> + </div> +</div> +<div class="form-section" id="task_description_row"> + <div class="form-group"> + <f:be.labels.csh table="{csh}" field="task_description" label="{lang}label.description"/> + <div class="form-control-wrap"> + <textarea class="form-control" name="tx_scheduler[description]">{description}</textarea> + </div> + </div> +</div> + +<f:for each="{additionalFields}" as="field"> + <f:render section="additionalField" arguments="{field: field}" /> +</f:for> + <f:format.raw>{table}</f:format.raw> + <f:render partial="ServerTime" arguments="{now: now}" /> + +<f:section name="additionalField"> + <div class="form-section extraFields extra_fields_{field.htmlClassName}" {field.additionalFieldsStyle} id="{field.fieldID}_row"> + <div class="form-group"> + <f:be.labels.csh table="{field.cshKey}" field="{field.cshLabel}" label="{field.langLabel}"/> + <div class="form-control-wrap"> + {field.code -> f:format.raw()} + </div> + {field.browseButton -> f:format.raw()} + </div> + </div> +</f:section> \ No newline at end of file diff --git a/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js b/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js index 3e364a02f10282f6527e0be59ef5d7150fdc860d..869391c3bc22b9397ae9fd7c75cf69101548ee63 100644 --- a/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js +++ b/typo3/sysext/scheduler/Resources/Public/JavaScript/Scheduler.js @@ -165,6 +165,8 @@ define(['jquery', if ($taskType.length) { Scheduler.toggleFieldsByTaskType($taskType.val()); } + var $taskClass = $('#task_class'); + Scheduler.actOnChangedTaskClass($taskClass); }; $(Scheduler.initializeEvents);