/** * Constructor */ public function __construct() { // Set debug flag for BE development only $this->debug = (int) $GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] === 1; // Initializes the backend modules structure for use later. $this->moduleLoader = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Module\\ModuleLoader'); $this->moduleLoader->load($GLOBALS['TBE_MODULES']); $this->pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer(); $this->pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop'); $this->pageRenderer->loadExtJS(); $this->pageRenderer->loadJquery(NULL, NULL, \TYPO3\CMS\Core\Page\PageRenderer::JQUERY_NAMESPACE_DEFAULT_NOCONFLICT); $this->pageRenderer->enableExtJSQuickTips(); $this->pageRenderer->addJsInlineCode('consoleOverrideWithDebugPanel', '//already done', FALSE); $this->pageRenderer->addExtDirectCode(); // Add default BE javascript $this->js = ''; $this->jsFiles = array('common' => 'sysext/backend/Resources/Public/JavaScript/common.js', 'locallang' => $this->getLocalLangFileName(), 'modernizr' => 'contrib/modernizr/modernizr.min.js', 'md5' => 'sysext/backend/Resources/Public/JavaScript/md5.js', 'toolbarmanager' => 'sysext/backend/Resources/Public/JavaScript/toolbarmanager.js', 'modulemenu' => 'sysext/backend/Resources/Public/JavaScript/modulemenu.js', 'evalfield' => 'sysext/backend/Resources/Public/JavaScript/jsfunc.evalfield.js', 'flashmessages' => 'sysext/backend/Resources/Public/JavaScript/flashmessages.js', 'tabclosemenu' => 'js/extjs/ux/ext.ux.tabclosemenu.js', 'notifications' => 'sysext/backend/Resources/Public/JavaScript/notifications.js', 'backend' => 'sysext/backend/Resources/Public/JavaScript/backend.js', 'loginrefresh' => 'sysext/backend/Resources/Public/JavaScript/loginrefresh.js', 'debugPanel' => 'js/extjs/debugPanel.js', 'viewport' => 'js/extjs/viewport.js', 'iframepanel' => 'sysext/backend/Resources/Public/JavaScript/iframepanel.js', 'backendcontentiframe' => 'js/extjs/backendcontentiframe.js', 'modulepanel' => 'js/extjs/modulepanel.js', 'viewportConfiguration' => 'js/extjs/viewportConfiguration.js', 'util' => 'sysext/backend/Resources/Public/JavaScript/util.js'); if ($this->debug) { unset($this->jsFiles['loginrefresh']); } // Add default BE css $this->pageRenderer->addCssLibrary('contrib/normalize/normalize.css', 'stylesheet', 'all', '', TRUE, TRUE); $this->css = ''; $this->cssFiles = array(); $this->toolbarItems = array(); $this->initializeCoreToolbarItems(); $this->menuWidth = $this->menuWidthDefault; if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']) && (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'] != (int) $this->menuWidth) { $this->menuWidth = (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']; } $this->executeHook('constructPostProcess'); }
/** * Constructor */ public function __construct() { // Set debug flag for BE development only $this->debug = intval($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) === 1; // Initializes the backend modules structure for use later. $this->moduleLoader = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Module\\ModuleLoader'); $this->moduleLoader->load($GLOBALS['TBE_MODULES']); $this->moduleMenu = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\View\\ModuleMenuView'); $this->pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer(); $this->pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop'); $this->pageRenderer->loadExtJS(); $this->pageRenderer->enableExtJSQuickTips(); $this->pageRenderer->addJsInlineCode('consoleOverrideWithDebugPanel', '//already done', FALSE); $this->pageRenderer->addExtDirectCode(); // Add default BE javascript $this->js = ''; $this->jsFiles = array('common' => 'js/common.js', 'locallang' => $this->getLocalLangFileName(), 'modernizr' => 'contrib/modernizr/modernizr.min.js', 'swfupload' => 'contrib/swfupload/swfupload.js', 'swfupload.swfobject' => 'contrib/swfupload/plugins/swfupload.swfobject.js', 'swfupload.cookies' => 'contrib/swfupload/plugins/swfupload.cookies.js', 'swfupload.queue' => 'contrib/swfupload/plugins/swfupload.queue.js', 'md5' => 'md5.js', 'toolbarmanager' => 'js/toolbarmanager.js', 'modulemenu' => 'js/modulemenu.js', 'iecompatibility' => 'js/iecompatibility.js', 'flashupload' => 'js/flashupload.js', 'evalfield' => '../t3lib/jsfunc.evalfield.js', 'flashmessages' => '../t3lib/js/extjs/ux/flashmessages.js', 'tabclosemenu' => '../t3lib/js/extjs/ux/ext.ux.tabclosemenu.js', 'notifications' => '../t3lib/js/extjs/notifications.js', 'backend' => 'js/backend.js', 'loginrefresh' => 'js/loginrefresh.js', 'debugPanel' => 'js/extjs/debugPanel.js', 'viewport' => 'js/extjs/viewport.js', 'iframepanel' => 'js/extjs/iframepanel.js', 'backendcontentiframe' => 'js/extjs/backendcontentiframe.js', 'modulepanel' => 'js/extjs/modulepanel.js', 'viewportConfiguration' => 'js/extjs/viewportConfiguration.js', 'util' => '../t3lib/js/extjs/util.js'); if ($this->debug) { unset($this->jsFiles['loginrefresh']); } // Add default BE css $this->css = ''; $this->cssFiles = array(); $this->toolbarItems = array(); $this->initializeCoreToolbarItems(); $this->menuWidth = $this->menuWidthDefault; if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']) && (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'] != (int) $this->menuWidth) { $this->menuWidth = (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']; } $this->executeHook('constructPostProcess'); }
/** * Main function of the module. Write the content to $this->content * If you chose "web" as main module, you will need to consider the $this->id parameter which will contain the uid-number of the page clicked in the page tree */ function main() { global $BE_USER, $LANG, $BACK_PATH, $TCA_DESCR, $TCA, $CLIENT, $TYPO3_CONF_VARS; $PATH_TYPO3 = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3/'; if ($BE_USER->user["admin"]) { // Draw the header. $this->doc = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance("template"); $this->doc->backPath = $BACK_PATH; $this->pageRenderer = $this->doc->getPageRenderer(); // Include Ext JS $this->pageRenderer->loadExtJS(true, true); $this->pageRenderer->enableExtJSQuickTips(); $this->pageRenderer->enableExtJsDebug(); $this->pageRenderer->addJsFile(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('caretaker') . 'res/js/tx.caretaker.js', 'text/javascript', FALSE, FALSE); $this->pageRenderer->addJsFile(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('caretaker') . 'res/js/tx.caretaker.NodeTree.js', 'text/javascript', FALSE, FALSE); //Add caretaker css $this->pageRenderer->addCssFile(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('caretaker') . 'res/css/tx.caretaker.nodetree.css', 'stylesheet', 'all', '', FALSE); // storage Pid $confArray = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['caretaker']); $storagePid = (int) $confArray['storagePid']; $this->pageRenderer->addJsInlineCode('Caretaker_Nodetree', ' Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); Ext.ns("tx.caretaker"); Ext.onReady(function() { tx.caretaker.view = new Ext.Viewport({ layout: "fit", items: { id: "cartaker-tree", xtype: "caretaker-nodetree", autoScroll: true, dataUrl: TYPO3.settings.ajaxUrls[\'tx_caretaker::treeloader\'], addUrl: "' . $PATH_TYPO3 . 'alt_doc.php?edit[###NODE_TYPE###][' . $storagePid . ']=new", editUrl: "' . $PATH_TYPO3 . 'alt_doc.php?edit[tx_caretaker_###NODE_TYPE###][###NODE_UID###]=edit", hideUrl: "' . $PATH_TYPO3 . 'tce_db.php?&data[tx_caretaker_###NODE_TYPE###][###NODE_UID###][hidden]=1", unhideUrl: "' . $PATH_TYPO3 . 'tce_db.php?&data[tx_caretaker_###NODE_TYPE###][###NODE_UID###][hidden]=0" } }); tx_caretaker_updateTreeById = function( id ){ tx_caretaker_tree = Ext.getCmp("cartaker-tree"); tx_caretaker_tree.reloadTreePartial( id ); } }); '); $this->content .= $this->doc->startPage($LANG->getLL("title")); $this->doc->form = ''; } else { // If no access or if not admin $this->doc = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\MediumDocumentTemplate'); $this->doc->backPath = $BACK_PATH; $this->content .= $this->doc->startPage($LANG->getLL("title")); $this->content .= $this->doc->header($LANG->getLL("title")); $this->content .= $this->doc->spacer(5); $this->content .= $this->doc->spacer(10); } }
/** * 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); }
/** * @param string $table * @param array|string $data * @return string */ public function render($table = NULL, $data = NULL) { if (!$data) { $data = array(); } if ($table) { if (!$data['uid']) { $data['uid'] = "none"; } if (!$data['pid']) { $data['pid'] = "0"; } $this->pageRenderer->loadPrototype(); $this->pageRenderer->loadExtJS(); $this->tceforms = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\FormEngine'); $this->tceforms->initDefaultBEMode(); // EXTBASE FORMS $this->tceforms->prependFormFieldNames = $this->getFieldNamePrefix(); $this->tceforms->formName = $table; $this->tceforms->totalWrap = '<div class="typo3-TCEforms"> | </div>'; $this->tceforms->doSaveFieldName = 'doSave'; $this->tceforms->localizationMode = GeneralUtility::inList('text,media', $this->localizationMode) ? $this->localizationMode : ''; $this->tceforms->returnUrl = $this->R_URI; $this->tceforms->palettesCollapsed = !$this->MOD_SETTINGS['showPalettes']; $this->tceforms->disableRTE = !$GLOBALS['BE_USER']->isRTE(); $this->tceforms->enableClickMenu = TRUE; $this->tceforms->enableTabMenu = TRUE; $panel = $this->tceforms->getMainFields($table, $data); $body = $this->tceforms->printNeededJSFunctions_top(); $body .= $this->tceforms->wrapTotal($panel, $data, $table); $body .= $this->tceforms->printNeededJSFunctions(); if (count($this->tceforms->commentMessages)) { $body .= ' <!-- TCEFORM messages ' . htmlspecialchars(implode(LF, $this->tceforms->commentMessages)) . ' --> '; } } else { return "Tabelle wurde nicht angegeben."; } return $body; }
/** * Load the necessarry javascript * * This will only be done when the referenced record is available * * @return void */ protected function loadJavascript() { $compress = TRUE; $javascriptFiles = array('Initialize.js', 'Ux/Ext.ux.merge.js', 'Ux/Ext.ux.isemptyobject.js', 'Ux/Ext.ux.spinner.js', 'Ux/Ext.ux.form.spinnerfield.js', 'Ux/Ext.ux.form.textfieldsubmit.js', 'Ux/Ext.ux.grid.CheckColumn.js', 'Ux/Ext.ux.grid.SingleSelectCheckColumn.js', 'Ux/Ext.ux.grid.ItemDeleter.js', 'Helpers/History.js', 'Helpers/Element.js', 'Elements/ButtonGroup.js', 'Elements/Container.js', 'Elements/Elements.js', 'Elements/Dummy.js', 'Elements/Basic/Button.js', 'Elements/Basic/Checkbox.js', 'Elements/Basic/Fieldset.js', 'Elements/Basic/Fileupload.js', 'Elements/Basic/Form.js', 'Elements/Basic/Hidden.js', 'Elements/Basic/Password.js', 'Elements/Basic/Radio.js', 'Elements/Basic/Reset.js', 'Elements/Basic/Select.js', 'Elements/Basic/Submit.js', 'Elements/Basic/Textarea.js', 'Elements/Basic/Textline.js', 'Elements/Predefined/Email.js', 'Elements/Predefined/CheckboxGroup.js', 'Elements/Predefined/Name.js', 'Elements/Predefined/RadioGroup.js', 'Elements/Content/Header.js', 'Elements/Content/Textblock.js', 'Viewport.js', 'Viewport/Left.js', 'Viewport/Right.js', 'Viewport/Left/Elements.js', 'Viewport/Left/Elements/ButtonGroup.js', 'Viewport/Left/Elements/Basic.js', 'Viewport/Left/Elements/Predefined.js', 'Viewport/Left/Elements/Content.js', 'Viewport/Left/Options.js', 'Viewport/Left/Options/Dummy.js', 'Viewport/Left/Options/Panel.js', 'Viewport/Left/Options/Forms/Attributes.js', 'Viewport/Left/Options/Forms/Label.js', 'Viewport/Left/Options/Forms/Legend.js', 'Viewport/Left/Options/Forms/Options.js', 'Viewport/Left/Options/Forms/Various.js', 'Viewport/Left/Options/Forms/Filters.js', 'Viewport/Left/Options/Forms/Filters/Filter.js', 'Viewport/Left/Options/Forms/Filters/Dummy.js', 'Viewport/Left/Options/Forms/Filters/Alphabetic.js', 'Viewport/Left/Options/Forms/Filters/Alphanumeric.js', 'Viewport/Left/Options/Forms/Filters/Currency.js', 'Viewport/Left/Options/Forms/Filters/Digit.js', 'Viewport/Left/Options/Forms/Filters/Integer.js', 'Viewport/Left/Options/Forms/Filters/LowerCase.js', 'Viewport/Left/Options/Forms/Filters/RegExp.js', 'Viewport/Left/Options/Forms/Filters/RemoveXSS.js', 'Viewport/Left/Options/Forms/Filters/StripNewLines.js', 'Viewport/Left/Options/Forms/Filters/TitleCase.js', 'Viewport/Left/Options/Forms/Filters/Trim.js', 'Viewport/Left/Options/Forms/Filters/UpperCase.js', 'Viewport/Left/Options/Forms/Validation.js', 'Viewport/Left/Options/Forms/Validation/Rule.js', 'Viewport/Left/Options/Forms/Validation/Dummy.js', 'Viewport/Left/Options/Forms/Validation/Alphabetic.js', 'Viewport/Left/Options/Forms/Validation/Alphanumeric.js', 'Viewport/Left/Options/Forms/Validation/Between.js', 'Viewport/Left/Options/Forms/Validation/Date.js', 'Viewport/Left/Options/Forms/Validation/Digit.js', 'Viewport/Left/Options/Forms/Validation/Email.js', 'Viewport/Left/Options/Forms/Validation/Equals.js', 'Viewport/Left/Options/Forms/Validation/FileAllowedTypes.js', 'Viewport/Left/Options/Forms/Validation/FileMaximumSize.js', 'Viewport/Left/Options/Forms/Validation/FileMinimumSize.js', 'Viewport/Left/Options/Forms/Validation/Float.js', 'Viewport/Left/Options/Forms/Validation/GreaterThan.js', 'Viewport/Left/Options/Forms/Validation/InArray.js', 'Viewport/Left/Options/Forms/Validation/Integer.js', 'Viewport/Left/Options/Forms/Validation/Ip.js', 'Viewport/Left/Options/Forms/Validation/Length.js', 'Viewport/Left/Options/Forms/Validation/LessThan.js', 'Viewport/Left/Options/Forms/Validation/RegExp.js', 'Viewport/Left/Options/Forms/Validation/Required.js', 'Viewport/Left/Options/Forms/Validation/Uri.js', 'Viewport/Left/Form.js', 'Viewport/Left/Form/Behaviour.js', 'Viewport/Left/Form/Attributes.js', 'Viewport/Left/Form/Prefix.js', 'Viewport/Left/Form/PostProcessor.js', 'Viewport/Left/Form/PostProcessors/PostProcessor.js', 'Viewport/Left/Form/PostProcessors/Dummy.js', 'Viewport/Left/Form/PostProcessors/Mail.js', 'Viewport/Left/Form/PostProcessors/Redirect.js'); // Load ExtJS $this->pageRenderer->loadExtJS(); // Load the wizards javascript $baseUrl = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('form') . 'Resources/Public/JavaScript/Wizard/'; foreach ($javascriptFiles as $javascriptFile) { $this->pageRenderer->addJsFile($baseUrl . $javascriptFile, 'text/javascript', $compress, FALSE); } }
/** * Render start page with \TYPO3\CMS\Backend\Template\DocumentTemplate and pageTitle * * @param string $pageTitle title tag of the module. Not required by default, as BE modules are shown in a frame * @param bool $loadExtJs specifies whether to load ExtJS library. Defaults to FALSE * @param bool $loadExtJsTheme whether to load ExtJS "grey" theme. Defaults to FALSE * @param bool $enableExtJsDebug if TRUE, debug version of ExtJS is loaded. Use this for development only * @param bool $loadJQuery whether to load jQuery library. Defaults to FALSE * @param array $includeCssFiles List of custom CSS file to be loaded * @param array $includeJsFiles List of custom JavaScript file to be loaded * @param array $addJsInlineLabels Custom labels to add to JavaScript inline labels * @param array $includeRequireJsModules List of RequireJS modules to be loaded * @param string $jQueryNamespace Store the jQuery object in a specific namespace * @return void */ public function render($pageTitle = '', $loadExtJs = false, $loadExtJsTheme = true, $enableExtJsDebug = false, $loadJQuery = false, $includeCssFiles = null, $includeJsFiles = null, $addJsInlineLabels = null, $includeRequireJsModules = null, $jQueryNamespace = null) { if ($pageTitle) { $this->pageRenderer->setTitle($pageTitle); } if ($loadExtJs) { $this->pageRenderer->loadExtJS(true, $loadExtJsTheme); if ($enableExtJsDebug) { $this->pageRenderer->enableExtJsDebug(); } } if ($loadJQuery) { $jQueryNamespace = $jQueryNamespace ?: PageRenderer::JQUERY_NAMESPACE_DEFAULT; $this->pageRenderer->loadJquery(null, null, $jQueryNamespace); } // Include custom CSS and JS files if (is_array($includeCssFiles) && count($includeCssFiles) > 0) { foreach ($includeCssFiles as $addCssFile) { $this->pageRenderer->addCssFile($addCssFile); } } if (is_array($includeJsFiles) && count($includeJsFiles) > 0) { foreach ($includeJsFiles as $addJsFile) { $this->pageRenderer->addJsFile($addJsFile); } } if (is_array($includeRequireJsModules) && count($includeRequireJsModules) > 0) { foreach ($includeRequireJsModules as $addRequireJsFile) { $this->pageRenderer->loadRequireJsModule($addRequireJsFile); } } // Add inline language labels if (is_array($addJsInlineLabels) && count($addJsInlineLabels) > 0) { $extensionKey = $this->controllerContext->getRequest()->getControllerExtensionKey(); foreach ($addJsInlineLabels as $key) { $label = LocalizationUtility::translate($key, $extensionKey); $this->pageRenderer->addInlineLanguageLabel($key, $label); } } }
/** * Initializes the controller before invoking an action method. * * @return void */ protected function initializeAction() { $this->pageId = (int) GeneralUtility::_GP('id'); $this->pageRenderer->addInlineLanguageLabelArray(array('title' => $this->languageService->getLL('title'), 'path' => $this->languageService->sL('LLL:EXT:lang/locallang_core.xml:labels.path'), 'table' => $this->languageService->sL('LLL:EXT:lang/locallang_core.xml:labels.table'), 'depth' => $this->languageService->sL('LLL:EXT:lang/locallang_mod_web_perm.xml:Depth'), 'depth_0' => $this->languageService->sL('LLL:EXT:lang/locallang_core.xml:labels.depth_0'), 'depth_1' => $this->languageService->sL('LLL:EXT:lang/locallang_core.xml:labels.depth_1'), 'depth_2' => $this->languageService->sL('LLL:EXT:lang/locallang_core.xml:labels.depth_2'), 'depth_3' => $this->languageService->sL('LLL:EXT:lang/locallang_core.xml:labels.depth_3'), 'depth_4' => $this->languageService->sL('LLL:EXT:lang/locallang_core.xml:labels.depth_4'), 'depth_infi' => $this->languageService->sL('LLL:EXT:lang/locallang_core.xml:labels.depth_infi'))); $this->pageRenderer->addInlineLanguageLabelFile('EXT:typo3_forum/Resources/Private/Language/locallang_mod.xml'); $this->pageRenderer->loadExtJS(); $this->pageRenderer->enableExtJSQuickTips(); $this->pageRenderer->addJsFile(ExtensionManagementUtility::extRelPath('lang') . 'res/js/be/typo3lang.js'); $this->pageRenderer->addJsFile($this->backPath . 'js/extjs/ux/Ext.ux.FitToParent.js'); $this->includeJavascriptFromPath('Resources/Public/Javascript/Backend/ExtJS/'); $this->includeJavascriptFromPath('Resources/Public/Javascript/Backend/ForumIndex/'); $this->includeCssFromPath('Resources/Public/Javascript/Backend/ExtJS/'); $this->pageRenderer->addCssFile(ExtensionManagementUtility::extRelPath('typo3_forum') . 'Resources/Public/Stylesheets/typo3_forum-backend.css'); }
/** * Constructor */ public function __construct() { $this->getLanguageService()->includeLLFile('EXT:lang/locallang_misc.xlf'); $this->backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class); // Set debug flag for BE development only $this->debug = (int) $GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] === 1; // Initializes the backend modules structure for use later. $this->moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class); $this->moduleLoader->load($GLOBALS['TBE_MODULES']); $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); $this->pageRenderer->loadExtJS(); // included for the module menu JavaScript, please note that this is subject to change $this->pageRenderer->loadJquery(); $this->pageRenderer->addJsInlineCode('consoleOverrideWithDebugPanel', '//already done', false); $this->pageRenderer->addExtDirectCode(); // Add default BE javascript $backendRelPath = ExtensionManagementUtility::extRelPath('backend'); $this->jsFiles = array('locallang' => $this->getLocalLangFileName(), 'md5' => $backendRelPath . 'Resources/Public/JavaScript/md5.js', 'modulemenu' => $backendRelPath . 'Resources/Public/JavaScript/modulemenu.js', 'evalfield' => $backendRelPath . 'Resources/Public/JavaScript/jsfunc.evalfield.js', 'notifications' => $backendRelPath . 'Resources/Public/JavaScript/notifications.js', 'backend' => $backendRelPath . 'Resources/Public/JavaScript/backend.js', 'viewport' => $backendRelPath . 'Resources/Public/JavaScript/extjs/viewport.js', 'iframepanel' => $backendRelPath . 'Resources/Public/JavaScript/iframepanel.js', 'backendcontentiframe' => $backendRelPath . 'Resources/Public/JavaScript/extjs/backendcontentiframe.js', 'viewportConfiguration' => $backendRelPath . 'Resources/Public/JavaScript/extjs/viewportConfiguration.js'); $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LoginRefresh', 'function(LoginRefresh) { LoginRefresh.setLoginFramesetUrl(' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('login_frameset')) . '); LoginRefresh.setLogoutUrl(' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('logout')) . '); }'); // load Utility class $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Utility'); // load Notification functionality $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Notification'); // load Modals $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Modal'); // load Legacy CSS Support $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LegacyCssClasses'); // load the storage API and fill the UC into the PersistentStorage, so no additional AJAX call is needed $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Storage', 'function(Storage) { Storage.Persistent.load(' . json_encode($this->getBackendUser()->uc) . '); }'); // load debug console $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DebugConsole'); // Load RSA encryption $rsaEncryptionEncoder = GeneralUtility::makeInstance(RsaEncryptionEncoder::class); $rsaEncryptionEncoder->enableRsaEncryption(true); $this->pageRenderer->addInlineSetting('ShowItem', 'moduleUrl', BackendUtility::getModuleUrl('show_item')); $this->css = ''; $this->initializeToolbarItems(); if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'])) { $this->menuWidth = (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']; } $this->executeHook('constructPostProcess'); $this->includeLegacyBackendItems(); }
/** * Constructor */ public function __construct() { $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_misc.xlf'); $this->backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class); $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class); // Set debug flag for BE development only $this->debug = (int) $GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] === 1; // Initializes the backend modules structure for use later. $this->moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class); $this->moduleLoader->load($GLOBALS['TBE_MODULES']); $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); $this->pageRenderer->loadExtJS(); // included for the module menu JavaScript, please note that this is subject to change $this->pageRenderer->loadJquery(); $this->pageRenderer->addExtDirectCode(); // Add default BE javascript $this->jsFiles = ['locallang' => $this->getLocalLangFileName(), 'md5' => 'EXT:backend/Resources/Public/JavaScript/md5.js', 'evalfield' => 'EXT:backend/Resources/Public/JavaScript/jsfunc.evalfield.js', 'backend' => 'EXT:backend/Resources/Public/JavaScript/backend.js']; $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LoginRefresh', 'function(LoginRefresh) { LoginRefresh.setIntervalTime(' . MathUtility::forceIntegerInRange((int) $GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout'] - 60, 60) . '); LoginRefresh.setLoginFramesetUrl(' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('login_frameset')) . '); LoginRefresh.setLogoutUrl(' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('logout')) . '); LoginRefresh.initialize(); }'); // load module menu $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ModuleMenu'); // load Toolbar class $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar'); // load Utility class $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Utility'); // load Notification functionality $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Notification'); // load Modals $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Modal'); // load the storage API and fill the UC into the PersistentStorage, so no additional AJAX call is needed $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Storage', 'function(Storage) { Storage.Persistent.load(' . json_encode($this->getBackendUser()->uc) . '); }'); // load debug console $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DebugConsole'); // Load RSA encryption $rsaEncryptionEncoder = GeneralUtility::makeInstance(RsaEncryptionEncoder::class); $rsaEncryptionEncoder->enableRsaEncryption(true); $this->pageRenderer->addInlineSetting('ShowItem', 'moduleUrl', BackendUtility::getModuleUrl('show_item')); $this->css = ''; $this->initializeToolbarItems(); $this->executeHook('constructPostProcess'); $this->includeLegacyBackendItems(); }
/** * 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'); }
/** * Makes a collapseable section. See reports module for an example * * @param string $title * @param string $html * @param string $id * @param string $saveStatePointer * @return string * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. Use HTML bootstrap classes, localStorage etc. */ public function collapseableSection($title, $html, $id, $saveStatePointer = '') { GeneralUtility::logDeprecatedFunction(); $hasSave = (bool) $saveStatePointer; $collapsedStyle = $collapsedClass = ''; if ($hasSave) { /** @var $userSettingsController \TYPO3\CMS\Backend\Controller\UserSettingsController */ $userSettingsController = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Controller\UserSettingsController::class); $value = $userSettingsController->process('get', $saveStatePointer . '.' . $id); if ($value) { $collapsedStyle = ' style="display: none"'; $collapsedClass = ' collapsed'; } else { $collapsedStyle = ''; $collapsedClass = ' expanded'; } } $this->pageRenderer->loadExtJS(); $this->pageRenderer->addExtOnReadyCode(' Ext.select("h2.section-header").each(function(element){ element.on("click", function(event, tag) { var state = 0, el = Ext.fly(tag), div = el.next("div"), saveKey = el.getAttribute("rel"); if (el.hasClass("collapsed")) { el.removeClass("collapsed").addClass("expanded"); div.slideIn("t", { easing: "easeIn", duration: .5 }); } else { el.removeClass("expanded").addClass("collapsed"); div.slideOut("t", { easing: "easeOut", duration: .5, remove: false, useDisplay: true }); state = 1; } if (saveKey) { try { top.TYPO3.Storage.Persistent.set(saveKey + "." + tag.id, state); } catch(e) {} } }); }); '); return ' <h2 id="' . $id . '" class="section-header' . $collapsedClass . '" rel="' . $saveStatePointer . '"> ' . $title . '</h2> <div' . $collapsedStyle . '>' . $html . '</div> '; }
/** * Makes a collapseable section. See reports module for an example * * @param string $title * @param string $html * @param string $id * @param string $saveStatePointer * @return string */ public function collapseableSection($title, $html, $id, $saveStatePointer = '') { $hasSave = $saveStatePointer ? TRUE : FALSE; $collapsedStyle = $collapsedClass = ''; if ($hasSave) { /** @var $settings \TYPO3\CMS\Backend\User\ExtDirect\BackendUserSettingsDataProvider */ $settings = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\User\\ExtDirect\\BackendUserSettingsDataProvider'); $value = $settings->get($saveStatePointer . '.' . $id); if ($value) { $collapsedStyle = ' style="display: none"'; $collapsedClass = ' collapsed'; } else { $collapsedStyle = ''; $collapsedClass = ' expanded'; } } $this->pageRenderer->loadExtJS(); $this->pageRenderer->addExtOnReadyCode(' Ext.select("h2.section-header").each(function(element){ element.on("click", function(event, tag) { var state = 0, el = Ext.fly(tag), div = el.next("div"), saveKey = el.getAttribute("rel"); if (el.hasClass("collapsed")) { el.removeClass("collapsed").addClass("expanded"); div.slideIn("t", { easing: "easeIn", duration: .5 }); } else { el.removeClass("expanded").addClass("collapsed"); div.slideOut("t", { easing: "easeOut", duration: .5, remove: false, useDisplay: true }); state = 1; } if (saveKey) { try { top.TYPO3.BackendUserSettings.ExtDirect.set(saveKey + "." + tag.id, state, function(response) {}); } catch(e) {} } }); }); '); return ' <h2 id="' . $id . '" class="section-header' . $collapsedClass . '" rel="' . $saveStatePointer . '"> ' . $title . '</h2> <div' . $collapsedStyle . '>' . $html . '</div> '; }
/** * Main function of the module. Write the content to $this->content * If you chose "web" as main module, you will need to consider the $this->id parameter which will contain the uid-number of the page clicked in the page tree * * @return void */ function main() { global $BE_USER, $LANG, $BACK_PATH, $TCA_DESCR, $TCA, $CLIENT, $TYPO3_CONF_VARS; $PATH_TYPO3 = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3/'; if ($BE_USER->user["admin"]) { // find node $node_repository = tx_caretaker_NodeRepository::getInstance(); $node = $node_repository->id2node($this->node_id, true); if (!$node) { $node = $node_repository->getRootNode(); } // Draw the header. $this->doc = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate'); $this->doc->backPath = $BACK_PATH; $this->pageRenderer = $this->doc->getPageRenderer(); // Include Ext JS $this->pageRenderer->loadExtJS(); $this->pageRenderer->addJsFile($BACK_PATH . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('caretaker') . 'res/js/tx.caretaker.js'); $panels = array(); foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['caretaker']['extJsBackendPanels'] as $extJsBackendPanel) { // register JS foreach ($extJsBackendPanel['jsIncludes'] as $jsInclude) { $filename = $BACK_PATH . '../' . str_replace(PATH_site, '', \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($jsInclude)); $this->pageRenderer->addJsFile($filename); } // register CSS foreach ($extJsBackendPanel['cssIncludes'] as $cssInclude) { $filename = $BACK_PATH . '../' . str_replace(PATH_site, '', \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($cssInclude)); $this->pageRenderer->addCssFile($filename); } // add ExtJs Panel $panels[$extJsBackendPanel['id']] = $extJsBackendPanel['xtype']; } $this->pageRenderer->addJsFile($BACK_PATH . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('caretaker') . 'res/js/tx.caretaker.NodeToolbar.js'); // Enable debug mode for Ext JS $this->pageRenderer->enableExtJsDebug(); // storage Pid $confArray = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['caretaker']); $storagePid = (int) $confArray['storagePid']; //Add caretaker css $this->pageRenderer->addCssFile($BACK_PATH . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('caretaker') . 'res/css/tx.caretaker.overview.css'); $pluginItems = array(); foreach ($panels as $id => $xtype) { $pluginItems[] = '{ id: "' . $id . '", xtype: "' . $xtype . '" , back_path: back_path , node_id: node_id }'; } $this->pageRenderer->addJsInlineCode('Caretaker_Overview', ' Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); Ext.namespace("tx","tx.caretaker"); Ext.onReady( function() { var back_path = "' . $this->doc->backPath . '"; var back_url = "' . urlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL')) . '"; var path_typo3 = "' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3/"; var add_url = "' . $PATH_TYPO3 . 'alt_doc.php?edit[###NODE_TYPE###][' . $storagePid . ']=new"; var node_id = "' . $node->getCaretakerNodeId() . '"; var node_type = "' . strtolower($node->getType()) . '"; var node_hidden = "' . $node->getHidden() . '"; var node_uid = "' . $node->getUid() . '"; var node_title = "' . htmlspecialchars($node->getTitle() ? $node->getTitle() : '[no title]') . '( ' . ($node->getTypeDescription() ? htmlspecialchars($node->getTypeDescription()) : $node->getType()) . ' )" ; var node_state = "' . $node->getTestResult()->getState() . '" ; var node_state_info = "' . $node->getTestResult()->getStateInfo() . '" ; tx.caretaker.view = new Ext.Viewport({ layout: "fit", items: { xtype : "panel", id : "node", autoScroll: true, title : node_title, iconCls : "icon-caretaker-type-" + node_type, tbar : { xtype: "caretaker-nodetoolbar", back_path: back_path, path_typo3: path_typo3, back_url: back_url, add_url :add_url, node_id: node_id, node_type: node_type, node_uid: node_uid, node_hidden: node_hidden, node_state: node_state, node_state_info: node_state_info }, items : [ { xtype : "panel", padding : "10", layout : "fit", id : "caretaker-panels", items : [ ' . implode(chr(10) . ',', $pluginItems) . chr(10) . ' ] } ], } }); }); '); $this->content .= $this->doc->startPage($LANG->getLL("title")); $this->doc->form = ''; } else { // If no access or if not admin $this->doc = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\MediumDocumentTemplate'); $this->doc->backPath = $BACK_PATH; $this->content .= $this->doc->startPage($LANG->getLL("title")); $this->content .= $this->doc->header($LANG->getLL("title")); $this->content .= $this->doc->spacer(5); $this->content .= $this->doc->spacer(10); } }
/** * Assemble display of list of scheduled tasks * * @return string Table of pending tasks */ protected function listTasks() { // Define display format for dates $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] . ' ' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm']; $content = ''; // Get list of registered classes $registeredClasses = self::getRegisteredClasses(); // Get list of registered task groups $registeredTaskGroups = self::getRegisteredTaskGroups(); // add an empty entry for non-grouped tasks // add in front of list array_unshift($registeredTaskGroups, array('uid' => 0, 'groupName' => '')); // Get all registered tasks // Just to get the number of entries $query = array('SELECT' => '*', 'FROM' => 'tx_scheduler_task', 'WHERE' => '1=1', 'ORDERBY' => ''); $res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($query); $numRows = $GLOBALS['TYPO3_DB']->sql_num_rows($res); $GLOBALS['TYPO3_DB']->sql_free_result($res); // No tasks defined, display information message if ($numRows == 0) { /** @var $flashMessage \TYPO3\CMS\Core\Messaging\FlashMessage */ $flashMessage = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage', $GLOBALS['LANG']->getLL('msg.noTasks'), '', \TYPO3\CMS\Core\Messaging\FlashMessage::INFO); $content .= $flashMessage->render(); } else { // Load ExtJS framework and specific JS library $this->pageRenderer->loadExtJS(); $this->pageRenderer->addJsFile(ExtensionManagementUtility::extRelPath('scheduler') . 'res/tx_scheduler_be.js'); // Initialise table layout $tableLayout = array('table' => array('<table class="t3-table">', '</table>'), '0' => array('tr' => array('<thead><tr>', '</tr></thead>'), 'defCol' => array('<td>', '</td>'), '1' => array('<td style="width: 56px;">', '</td>'), '3' => array('<td colspan="2">', '</td>')), 'defRow' => array('tr' => array('<tr class="db_list_normal">', '</tr>'), 'defCol' => array('<td>', '</td>'), '1' => array('<td class="right">', '</td>'), '2' => array('<td class="right">', '</td>'))); $disabledTaskRow = array('tr' => array('<tr class="db_list_normal disabled">', '</tr>'), 'defCol' => array('<td>', '</td>'), '1' => array('<td class="right">', '</td>'), '2' => array('<td class="right">', '</td>')); $rowWithSpan = array('tr' => array('<tr class="db_list_normal">', '</tr>'), 'defCol' => array('<td>', '</td>'), '1' => array('<td class="right">', '</td>'), '2' => array('<td class="right">', '</td>'), '3' => array('<td colspan="6">', '</td>')); $taskGroupRow = array('tr' => array('<tr class="db_list_normal">', '</tr>'), 'defCol' => array('<td>', '</td>'), '0' => array('<td colspan="10">', '</td>')); $table = array(); $tr = 0; // Header row $table[$tr][] = '<a href="#" onclick="toggleCheckboxes();" title="' . $GLOBALS['LANG']->getLL('label.checkAll', TRUE) . '" class="icon">' . IconUtility::getSpriteIcon('actions-document-select') . '</a>'; $table[$tr][] = ' '; $table[$tr][] = $GLOBALS['LANG']->getLL('label.id'); $table[$tr][] = $GLOBALS['LANG']->getLL('task'); $table[$tr][] = $GLOBALS['LANG']->getLL('label.type'); $table[$tr][] = $GLOBALS['LANG']->getLL('label.frequency'); $table[$tr][] = $GLOBALS['LANG']->getLL('label.parallel'); $table[$tr][] = $GLOBALS['LANG']->getLL('label.lastExecution'); $table[$tr][] = $GLOBALS['LANG']->getLL('label.nextExecution'); $tr++; foreach ($registeredTaskGroups as $taskGroup) { $query = array('SELECT' => '*', 'FROM' => 'tx_scheduler_task', 'WHERE' => 'task_group=' . $taskGroup['uid'], 'ORDERBY' => 'nextexecution'); $res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($query); $numRows = $GLOBALS['TYPO3_DB']->sql_num_rows($res); if ($numRows === 0) { continue; } if ($taskGroup['groupName'] !== '') { $tableLayout[$tr] = $taskGroupRow; $groupText = '<strong>' . htmlspecialchars($taskGroup['groupName']) . '</strong>'; if (!empty($taskGroup['description'])) { $groupText .= '<br />' . nl2br(htmlspecialchars($taskGroup['description'])); } $table[$tr][] = $groupText; $tr++; } // Loop on all tasks while ($schedulerRecord = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // Define action icons $editAction = '<a href="' . $GLOBALS['MCONF']['_'] . '&CMD=edit&tx_scheduler[uid]=' . $schedulerRecord['uid'] . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:edit', TRUE) . '" class="icon">' . IconUtility::getSpriteIcon('actions-document-open') . '</a>'; $deleteAction = '<a href="' . $GLOBALS['MCONF']['_'] . '&CMD=delete&tx_scheduler[uid]=' . $schedulerRecord['uid'] . '" onclick="return confirm(\'' . $GLOBALS['LANG']->getLL('msg.delete') . '\');" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:delete', TRUE) . '" class="icon">' . IconUtility::getSpriteIcon('actions-edit-delete') . '</a>'; $stopAction = '<a href="' . $GLOBALS['MCONF']['_'] . '&CMD=stop&tx_scheduler[uid]=' . $schedulerRecord['uid'] . '" onclick="return confirm(\'' . $GLOBALS['LANG']->getLL('msg.stop') . '\');" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:stop', TRUE) . '" class="icon">' . '<img ' . IconUtility::skinImg($this->backPath, ExtensionManagementUtility::extRelPath('scheduler') . '/res/gfx/stop.png') . ' alt="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:stop') . '" /></a>'; $runAction = '<a href="' . $GLOBALS['MCONF']['_'] . '&tx_scheduler[execute][]=' . $schedulerRecord['uid'] . '" title="' . $GLOBALS['LANG']->getLL('action.run_task') . '" class="icon">' . IconUtility::getSpriteIcon('extensions-scheduler-run-task') . '</a>'; // Define some default values $lastExecution = '-'; $isRunning = FALSE; $executionStatus = 'scheduled'; $executionStatusOutput = ''; $name = ''; $nextDate = '-'; $execType = '-'; $frequency = '-'; $multiple = '-'; $startExecutionElement = ' '; // Restore the serialized task and pass it a reference to the scheduler object /** @var $task \TYPO3\CMS\Scheduler\Task\AbstractTask|\TYPO3\CMS\Scheduler\ProgressProviderInterface */ $task = unserialize($schedulerRecord['serialized_task_object']); $class = get_class($task); if ($class === '__PHP_Incomplete_Class' && preg_match('/^O:[0-9]+:"(?P<classname>.+?)"/', $schedulerRecord['serialized_task_object'], $matches) === 1) { $class = $matches['classname']; } // Assemble information about last execution $context = ''; if (!empty($schedulerRecord['lastexecution_time'])) { $lastExecution = date($dateFormat, $schedulerRecord['lastexecution_time']); if ($schedulerRecord['lastexecution_context'] == 'CLI') { $context = $GLOBALS['LANG']->getLL('label.cron'); } else { $context = $GLOBALS['LANG']->getLL('label.manual'); } $lastExecution .= ' (' . $context . ')'; } if ($this->scheduler->isValidTaskObject($task)) { // The task object is valid $name = htmlspecialchars($registeredClasses[$class]['title'] . ' (' . $registeredClasses[$class]['extension'] . ')'); $additionalInformation = $task->getAdditionalInformation(); if ($task instanceof \TYPO3\CMS\Scheduler\ProgressProviderInterface) { $progress = round(floatval($task->getProgress()), 2); $name .= '<br />' . $this->renderTaskProgressBar($progress); } if (!empty($additionalInformation)) { $name .= '<br />[' . htmlspecialchars($additionalInformation) . ']'; } // Check if task currently has a running execution if (!empty($schedulerRecord['serialized_executions'])) { $isRunning = TRUE; $executionStatus = 'running'; } // Prepare display of next execution date // If task is currently running, date is not displayed (as next hasn't been calculated yet) // Also hide the date if task is disabled (the information doesn't make sense, as it will not run anyway) if ($isRunning || $schedulerRecord['disable'] == 1) { $nextDate = '-'; } else { $nextDate = date($dateFormat, $schedulerRecord['nextexecution']); if (empty($schedulerRecord['nextexecution'])) { $nextDate = $GLOBALS['LANG']->getLL('none'); } elseif ($schedulerRecord['nextexecution'] < $GLOBALS['EXEC_TIME']) { // Next execution is overdue, highlight date $nextDate = '<span class="late" title="' . $GLOBALS['LANG']->getLL('status.legend.scheduled') . '">' . $nextDate . '</span>'; $executionStatus = 'late'; } } // Get execution type if ($task->getExecution()->getInterval() == 0 && $task->getExecution()->getCronCmd() == '') { $execType = $GLOBALS['LANG']->getLL('label.type.single'); $frequency = '-'; } else { $execType = $GLOBALS['LANG']->getLL('label.type.recurring'); if ($task->getExecution()->getCronCmd() == '') { $frequency = $task->getExecution()->getInterval(); } else { $frequency = $task->getExecution()->getCronCmd(); } } // Get multiple executions setting if ($task->getExecution()->getMultiple()) { $multiple = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:yes'); } else { $multiple = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:no'); } // Define checkbox $startExecutionElement = '<input type="checkbox" name="tx_scheduler[execute][]" value="' . $schedulerRecord['uid'] . '" id="task_' . $schedulerRecord['uid'] . '" class="checkboxes" />'; $actions = $editAction . $deleteAction; // Check the disable status // Row is shown dimmed if task is disabled, unless it is still running if ($schedulerRecord['disable'] == 1 && !$isRunning) { $tableLayout[$tr] = $disabledTaskRow; $executionStatus = 'disabled'; } // Show no action links (edit, delete) if task is running if ($isRunning) { $actions = $stopAction; } else { $actions .= $runAction; } // Check if the last run failed $failureOutput = ''; if (!empty($schedulerRecord['lastexecution_failure'])) { // Try to get the stored exception object /** @var $exception \Exception */ $exception = unserialize($schedulerRecord['lastexecution_failure']); // If the exception could not be unserialized, issue a default error message if ($exception === FALSE || $exception instanceof \__PHP_Incomplete_Class) { $failureDetail = $GLOBALS['LANG']->getLL('msg.executionFailureDefault'); } else { $failureDetail = sprintf($GLOBALS['LANG']->getLL('msg.executionFailureReport'), $exception->getCode(), $exception->getMessage()); } $failureOutput = ' <img ' . IconUtility::skinImg(ExtensionManagementUtility::extRelPath('scheduler'), 'res/gfx/status_failure.png') . ' alt="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.failure')) . '" title="' . htmlspecialchars($failureDetail) . '" />'; } // Format the execution status, // including failure feedback, if any $executionStatusOutput = '<img ' . IconUtility::skinImg(ExtensionManagementUtility::extRelPath('scheduler'), 'res/gfx/status_' . $executionStatus . '.png') . ' id="executionstatus_' . $schedulerRecord['uid'] . '" alt="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.' . $executionStatus)) . '" title="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.legend.' . $executionStatus)) . '" />' . $failureOutput; $table[$tr][] = $startExecutionElement; $table[$tr][] = $actions; $table[$tr][] = $schedulerRecord['uid']; $table[$tr][] = $executionStatusOutput; if ($schedulerRecord['description'] !== '') { if (!empty($this->scheduler->extConf['listShowTaskDescriptionAsHover'])) { $table[$tr][] = '<span title="' . htmlspecialchars($schedulerRecord['description']) . '">' . $name . '</span>'; } else { $table[$tr][] = $name . '<br />' . nl2br(htmlspecialchars($schedulerRecord['description'])) . '<br />'; } } else { $table[$tr][] = $name; } $table[$tr][] = $execType; $table[$tr][] = $frequency; $table[$tr][] = $multiple; $table[$tr][] = $lastExecution; $table[$tr][] = $nextDate; } else { // The task object is not valid // Prepare to issue an error /** @var $flashMessage \TYPO3\CMS\Core\Messaging\FlashMessage */ $flashMessage = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage', sprintf($GLOBALS['LANG']->getLL('msg.invalidTaskClass'), $class), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR); $executionStatusOutput = $flashMessage->render(); $tableLayout[$tr] = $rowWithSpan; $table[$tr][] = $startExecutionElement; $table[$tr][] = $deleteAction; $table[$tr][] = $schedulerRecord['uid']; $table[$tr][] = $executionStatusOutput; } $tr++; } $GLOBALS['TYPO3_DB']->sql_free_result($res); } // Render table $content .= $this->doc->table($table, $tableLayout); $content .= '<button name="go" id="scheduler_executeselected">' . IconUtility::getSpriteIcon('extensions-scheduler-run-task') . ' ' . $GLOBALS['LANG']->getLL('label.executeSelected') . '</button>'; } if (!count($registeredClasses) > 0) { /** @var $flashMessage \TYPO3\CMS\Core\Messaging\FlashMessage */ $flashMessage = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage', $GLOBALS['LANG']->getLL('msg.noTasksDefined'), '', \TYPO3\CMS\Core\Messaging\FlashMessage::INFO); $content .= $flashMessage->render(); } // Display legend, if there's at least one registered task // Also display information about the usage of server time if ($numRows > 0) { $content .= $this->doc->spacer(20); $content .= '<h3>' . $GLOBALS['LANG']->getLL('status.legend') . '</h3> <ul> <li><img ' . IconUtility::skinImg(ExtensionManagementUtility::extRelPath('scheduler'), 'res/gfx/status_failure.png') . ' alt="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.failure')) . '" title="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.failure')) . '" /> ' . $GLOBALS['LANG']->getLL('status.legend.failure') . '</li> <li><img ' . IconUtility::skinImg(ExtensionManagementUtility::extRelPath('scheduler'), 'res/gfx/status_late.png') . ' alt="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.late')) . '" title="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.late')) . '" /> ' . $GLOBALS['LANG']->getLL('status.legend.late') . '</li> <li><img ' . IconUtility::skinImg(ExtensionManagementUtility::extRelPath('scheduler'), 'res/gfx/status_running.png') . ' alt="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.running')) . '" title="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.running')) . '" /> ' . $GLOBALS['LANG']->getLL('status.legend.running') . '</li> <li><img ' . IconUtility::skinImg(ExtensionManagementUtility::extRelPath('scheduler'), 'res/gfx/status_scheduled.png') . ' alt="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.scheduled')) . '" title="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.scheduled')) . '" /> ' . $GLOBALS['LANG']->getLL('status.legend.scheduled') . '</li> <li><img ' . IconUtility::skinImg(ExtensionManagementUtility::extRelPath('scheduler'), 'res/gfx/status_disabled.png') . ' alt="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.disabled')) . '" title="' . htmlspecialchars($GLOBALS['LANG']->getLL('status.disabled')) . '" /> ' . $GLOBALS['LANG']->getLL('status.legend.disabled') . '</li> </ul>'; $content .= $this->displayServerTime(); } return $content; }
/** * 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'), 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)), 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']), 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->loadJquery(); $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Scheduler/Scheduler'); $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">'; // 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">' . '<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; }