/** * test inline settings with array get merged */ public function testAddInlineSettingArrayMerged() { $expectedReturnValue = 'TYPO3.settings = {"myApp":{"myKey1":"myValue1","myKey2":"myValue2"}};'; $this->fixture->loadExtJS(); $this->fixture->addInlineSettingArray('myApp', array('myKey1' => 'myValue1')); $this->fixture->addInlineSettingArray('myApp', array('myKey2' => 'myValue2')); $this->fixture->enableMoveJsFromHeaderToFooter(); $out = $this->fixture->render(\TYPO3\CMS\Core\Page\PageRenderer::PART_FOOTER); $this->assertContains($expectedReturnValue, $out); }
/** * Loads data in the HTML head section (e.g. JavaScript or stylesheet information). * * @return void */ protected function loadHeaderData() { // Load CSS Stylesheets: $this->pageRenderer->addCssFile($this->relativePath . 'res/css/customExtJs.css'); // Load Ext JS: $this->pageRenderer->loadExtJS(); $this->pageRenderer->enableExtJSQuickTips(); // Integrate dynamic JavaScript such as configuration or lables: $this->pageRenderer->addInlineSettingArray('Recycler', $this->getJavaScriptConfiguration()); $this->pageRenderer->addInlineLanguageLabelArray($this->getJavaScriptLabels()); // Load Recycler JavaScript: // Load Plugins $uxPath = $this->doc->backpath . 'js/extjs/ux/'; $this->pageRenderer->addJsFile($uxPath . 'Ext.grid.RowExpander.js'); $this->pageRenderer->addJsFile($uxPath . 'Ext.app.SearchField.js'); $this->pageRenderer->addJsFile($uxPath . 'Ext.ux.FitToParent.js'); // Load main script $this->pageRenderer->addJsFile($this->relativePath . 'res/js/t3_recycler.js'); }
/** * Return a form to add a new task or edit an existing one * * @return string HTML form to add or edit a task */ protected function editTask() { $registeredClasses = self::getRegisteredClasses(); $registeredTaskGroups = self::getRegisteredTaskGroups(); $content = ''; $taskInfo = array(); $task = NULL; $process = 'edit'; if ($this->submittedData['uid'] > 0) { // If editing, retrieve data for existing task try { $taskRecord = $this->scheduler->fetchTaskRecord($this->submittedData['uid']); // If there's a registered execution, the task should not be edited if (!empty($taskRecord['serialized_executions'])) { $this->addMessage($GLOBALS['LANG']->getLL('msg.maynotEditRunningTask'), \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR); throw new \LogicException('Runnings tasks cannot not be edited', 1251232849); } // Get the task object /** @var $task \TYPO3\CMS\Scheduler\Task\AbstractTask */ $task = unserialize($taskRecord['serialized_task_object']); // Set some task information $taskInfo['disable'] = $taskRecord['disable']; $taskInfo['description'] = $taskRecord['description']; $taskInfo['task_group'] = $taskRecord['task_group']; // Check that the task object is valid if ($this->scheduler->isValidTaskObject($task)) { // The task object is valid, process with fetching current data $taskInfo['class'] = get_class($task); // Get execution information $taskInfo['start'] = $task->getExecution()->getStart(); $taskInfo['end'] = $task->getExecution()->getEnd(); $taskInfo['interval'] = $task->getExecution()->getInterval(); $taskInfo['croncmd'] = $task->getExecution()->getCronCmd(); $taskInfo['multiple'] = $task->getExecution()->getMultiple(); if (!empty($taskInfo['interval']) || !empty($taskInfo['croncmd'])) { // Guess task type from the existing information // If an interval or a cron command is defined, it's a recurring task // FIXME: remove magic numbers for the type, use class constants instead $taskInfo['type'] = 2; $taskInfo['frequency'] = $taskInfo['interval'] ?: $taskInfo['croncmd']; } else { // It's not a recurring task // Make sure interval and cron command are both empty $taskInfo['type'] = 1; $taskInfo['frequency'] = ''; $taskInfo['end'] = 0; } } else { // The task object is not valid // Issue error message $this->addMessage(sprintf($GLOBALS['LANG']->getLL('msg.invalidTaskClassEdit'), get_class($task)), \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR); // Initialize empty values $taskInfo['start'] = 0; $taskInfo['end'] = 0; $taskInfo['frequency'] = ''; $taskInfo['multiple'] = FALSE; $taskInfo['type'] = 1; } } catch (\OutOfBoundsException $e) { // Add a message and continue throwing the exception $this->addMessage(sprintf($GLOBALS['LANG']->getLL('msg.taskNotFound'), $this->submittedData['uid']), \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR); throw $e; } } else { // If adding a new object, set some default values $taskInfo['class'] = key($registeredClasses); $taskInfo['type'] = 2; $taskInfo['start'] = $GLOBALS['EXEC_TIME']; $taskInfo['end'] = ''; $taskInfo['frequency'] = ''; $taskInfo['multiple'] = 0; $process = 'add'; } if (count($this->submittedData) > 0) { // If some data was already submitted, use it to override // existing data \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($taskInfo, $this->submittedData); } // Get the extra fields to display for each task that needs some $allAdditionalFields = array(); if ($process == 'add') { foreach ($registeredClasses as $class => $registrationInfo) { if (!empty($registrationInfo['provider'])) { /** @var $providerObject \TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface */ $providerObject = GeneralUtility::getUserObj($registrationInfo['provider']); if ($providerObject instanceof \TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface) { $additionalFields = $providerObject->getAdditionalFields($taskInfo, NULL, $this); $allAdditionalFields = array_merge($allAdditionalFields, array($class => $additionalFields)); } } } } else { if (!empty($registeredClasses[$taskInfo['class']]['provider'])) { $providerObject = GeneralUtility::getUserObj($registeredClasses[$taskInfo['class']]['provider']); if ($providerObject instanceof \TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface) { $allAdditionalFields[$taskInfo['class']] = $providerObject->getAdditionalFields($taskInfo, $task, $this); } } } // Load necessary JavaScript $this->pageRenderer->loadExtJS(); $this->pageRenderer->addJsFile(ExtensionManagementUtility::extRelPath('scheduler') . 'res/tx_scheduler_be.js'); $this->pageRenderer->addJsFile($this->backPath . 'sysext/backend/Resources/Public/JavaScript/tceforms.js'); $this->pageRenderer->addJsFile($this->backPath . 'js/extjs/ux/Ext.ux.DateTimePicker.js'); // Define settings for Date Picker $typo3Settings = array('datePickerUSmode' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? 1 : 0, 'dateFormat' => array('j-n-Y', 'G:i j-n-Y'), 'dateFormatUS' => array('n-j-Y', 'G:i n-j-Y')); $this->pageRenderer->addInlineSettingArray('', $typo3Settings); // Define table layout for add/edit form $tableLayout = array('table' => array('<table border="0" cellspacing="0" cellpadding="0" id="edit_form" class="typo3-usersettings">', '</table>')); // Define a style for hiding // Some fields will be hidden when the task is not recurring $style = ''; if ($taskInfo['type'] == 1) { $style = ' style="display: none"'; } // Start rendering the add/edit form $content .= '<input type="hidden" name="tx_scheduler[uid]" value="' . htmlspecialchars($this->submittedData['uid']) . '" />'; $content .= '<input type="hidden" name="previousCMD" value="' . htmlspecialchars($this->CMD) . '" />'; $table = array(); $tr = 0; $defaultCell = array('<td class="td-input">', '</td>'); // Disable checkbox $label = '<label for="task_disable">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:disable') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_disable', $label); $table[$tr][] = '<input type="hidden" name="tx_scheduler[disable]" value="0" /> <input type="checkbox" name="tx_scheduler[disable]" value="1" id="task_disable"' . ($taskInfo['disable'] == 1 ? ' checked="checked"' : '') . ' />'; $tableLayout[$tr] = array('tr' => array('<tr id="task_disable_row">', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // Task class selector $label = '<label for="task_class">' . $GLOBALS['LANG']->getLL('label.class') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_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 = $registeredClasses[$taskInfo['class']]['title'] . ' (' . $registeredClasses[$taskInfo['class']]['extension'] . ')'; $cell .= '<input type="hidden" name="tx_scheduler[class]" id="task_class" value="' . htmlspecialchars($taskInfo['class']) . '" />'; } else { $cell = '<select name="tx_scheduler[class]" id="task_class" class="wide" onchange="actOnChangedTaskClass(this)">'; // Group registered classes by classname $groupedClasses = array(); 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="' . $class . '"' . 'title="' . htmlspecialchars($classInfo['description']) . '"' . $selected . '>' . htmlspecialchars($classInfo['title']) . '</option>'; } $cell .= '</optgroup>'; } $cell .= '</select>'; } $table[$tr][] = $cell; // Make sure each row has a unique id, for manipulation with JS $tableLayout[$tr] = array('tr' => array('<tr id="task_class_row">', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // Task type selector $label = '<label for="task_type">' . $GLOBALS['LANG']->getLL('label.type') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_type', $label); $table[$tr][] = '<select name="tx_scheduler[type]" id="task_type" onchange="actOnChangedTaskType(this)">' . '<option value="1"' . ($taskInfo['type'] == 1 ? ' selected="selected"' : '') . '>' . $GLOBALS['LANG']->getLL('label.type.single') . '</option>' . '<option value="2"' . ($taskInfo['type'] == 2 ? ' selected="selected"' : '') . '>' . $GLOBALS['LANG']->getLL('label.type.recurring') . '</option>' . '</select>'; $tableLayout[$tr] = array('tr' => array('<tr id="task_type_row">', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // Task group selector $label = '<label for="task_group">' . $GLOBALS['LANG']->getLL('label.group') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_group', $label); $cell = '<select name="tx_scheduler[task_group]" id="task_class" class="wide">'; // Loop on all groups to display a selector $cell .= '<option value="0" title=""></option>'; foreach ($registeredTaskGroups as $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>'; } $cell .= '</select>'; $table[$tr][] = $cell; $tableLayout[$tr] = array('tr' => array('<tr id="task_group_row">', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // Start date/time field // NOTE: datetime fields need a special id naming scheme $label = '<label for="tceforms-datetimefield-task_start">' . $GLOBALS['LANG']->getLL('label.start') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_start', $label); $table[$tr][] = '<input name="tx_scheduler[start]" type="text" id="tceforms-datetimefield-task_start" value="' . (empty($taskInfo['start']) ? '' : strftime('%H:%M %d-%m-%Y', $taskInfo['start'])) . '" />' . IconUtility::getSpriteIcon('actions-edit-pick-date', array('style' => 'cursor:pointer;', 'id' => 'picker-tceforms-datetimefield-task_start')); $tableLayout[$tr] = array('tr' => array('<tr id="task_start_row">', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // End date/time field // NOTE: datetime fields need a special id naming scheme $label = '<label for="tceforms-datetimefield-task_end">' . $GLOBALS['LANG']->getLL('label.end') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_end', $label); $table[$tr][] = '<input name="tx_scheduler[end]" type="text" id="tceforms-datetimefield-task_end" value="' . (empty($taskInfo['end']) ? '' : strftime('%H:%M %d-%m-%Y', $taskInfo['end'])) . '" />' . IconUtility::getSpriteIcon('actions-edit-pick-date', array('style' => 'cursor:pointer;', 'id' => 'picker-tceforms-datetimefield-task_end')); $tableLayout[$tr] = array('tr' => array('<tr id="task_end_row"' . $style . '>', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // Frequency input field $label = '<label for="task_frequency">' . $GLOBALS['LANG']->getLL('label.frequency.long') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_frequency', $label); $cell = '<input type="text" name="tx_scheduler[frequency]" id="task_frequency" value="' . htmlspecialchars($taskInfo['frequency']) . '" />'; $table[$tr][] = $cell; $tableLayout[$tr] = array('tr' => array('<tr id="task_frequency_row"' . $style . '>', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // Multiple execution selector $label = '<label for="task_multiple">' . $GLOBALS['LANG']->getLL('label.parallel.long') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_multiple', $label); $table[$tr][] = '<input type="hidden" name="tx_scheduler[multiple]" value="0" /> <input type="checkbox" name="tx_scheduler[multiple]" value="1" id="task_multiple"' . ($taskInfo['multiple'] == 1 ? ' checked="checked"' : '') . ' />'; $tableLayout[$tr] = array('tr' => array('<tr id="task_multiple_row"' . $style . '>', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // Description $label = '<label for="task_description">' . $GLOBALS['LANG']->getLL('label.description') . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($this->cshKey, 'task_description', $label); $table[$tr][] = '<textarea name="tx_scheduler[description]">' . htmlspecialchars($taskInfo['description']) . '</textarea>'; $tableLayout[$tr] = array('tr' => array('<tr id="task_description_row">', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; // Display additional fields foreach ($allAdditionalFields as $class => $fields) { if ($class == $taskInfo['class']) { $additionalFieldsStyle = ''; } else { $additionalFieldsStyle = ' style="display: none"'; } // Add each field to the display, if there are indeed any if (isset($fields) && is_array($fields)) { foreach ($fields as $fieldID => $fieldInfo) { $label = '<label for="' . $fieldID . '">' . $GLOBALS['LANG']->sL($fieldInfo['label']) . '</label>'; $table[$tr][] = BackendUtility::wrapInHelp($fieldInfo['cshKey'], $fieldInfo['cshLabel'], $label); $table[$tr][] = $fieldInfo['code']; $htmlClassName = strtolower(str_replace('\\', '-', $class)); $tableLayout[$tr] = array('tr' => array('<tr id="' . $fieldID . '_row"' . $additionalFieldsStyle . ' class="extraFields extra_fields_' . $htmlClassName . '">', '</tr>'), 'defCol' => $defaultCell, '0' => array('<td class="td-label">', '</td>')); $tr++; } } } // Render the add/edit task form $content .= '<div style="float: left;"><div class="typo3-dyntabmenu-divs">'; $content .= $this->doc->table($table, $tableLayout); $content .= '</div></div>'; $content .= '<div style="padding-top: 20px; clear: both;"></div>'; // Display information about server time usage $content .= $this->displayServerTime(); return $content; }
public function render() { $this->pageRenderer = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Page\\PageRenderer'); $baseUrl = '../' . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath('extension_builder'); $this->pageRenderer->disableCompressJavascript(); // SECTION: JAVASCRIPT FILES // YUI Basis Files $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui/utilities/utilities.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui/resize/resize-min.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui/layout/layout-min.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui/container/container-min.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui/json/json-min.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui/button/button-min.js'); // YUI-RPC $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui-rpc.js'); // InputEx with wirable options $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/inputex.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/Field.js'); // extended fields for enabling unique ids $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/extended/ListField.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/extended/Group.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/util/inputex/WirableField-beta.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/Visus.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/StringField.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/Textarea.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/SelectField.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/EmailField.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/UrlField.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/CheckBox.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/InPlaceEdit.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/MenuField.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/js/fields/TypeField.js'); // WireIt $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/excanvas.js', 'text/javascript', TRUE, FALSE, '<!--[if IE]>|<![endif]-->'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/WireIt.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/CanvasElement.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/Wire.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/Terminal.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/util/DD.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/util/DDResize.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/Container.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/ImageContainer.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/Layer.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/util/inputex/FormContainer-beta.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/LayerMap.js'); $this->pageRenderer->addInlineSettingArray('extensionBuilder', array('baseUrl' => $baseUrl)); $this->setLocallangSettings(); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/js/WiringEditor.js'); // Extbase Modelling definition $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/extbaseModeling.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/layout.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/extensionProperties.js'); $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/modules/modelObject.js'); // collapsible forms in relations $this->pageRenderer->addJsFile($baseUrl . 'Resources/Public/jsDomainModeling/modules/extendedModelObject.js'); // SECTION: CSS Files // YUI CSS $this->pageRenderer->addCssFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui/reset-fonts-grids/reset-fonts-grids.css'); $this->pageRenderer->addCssFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/yui/assets/skins/sam/skin.css'); // InputEx CSS $this->pageRenderer->addCssFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/lib/inputex/css/inputEx.css'); // WireIt CSS $this->pageRenderer->addCssFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/css/WireIt.css'); $this->pageRenderer->addCssFile($baseUrl . 'Resources/Public/jsDomainModeling/wireit/css/WireItEditor.css'); // Custom CSS $this->pageRenderer->addCssFile($baseUrl . 'Resources/Public/jsDomainModeling/extbaseModeling.css'); }