/** * Render method * * @param \DateTime $lastUpdateTime The date of the last update. * @return string */ public function render($lastUpdateTime) { if (NULL === $lastUpdateTime) { return $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:extensionList.updateFromTer.never'); } return \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge(time() - $lastUpdateTime->format('U'), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')); }
/** * Render method * * @param array $arguments * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * * @return string */ public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) { $lastUpdateTime = $arguments['lastUpdateTime']; if (null === $lastUpdateTime) { return $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:extensionList.updateFromTer.never'); } return \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge(time() - $lastUpdateTime->format('U'), $GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears')); }
/** * Format field content if $config['format'] is set to date, filesize, ..., user * * @param array $config Configuration for the display * @param string $itemValue The value to display * @return string Formatted field value */ protected function formatValue($config, $itemValue) { $format = trim($config['format']); switch ($format) { case 'date': if ($itemValue) { $option = trim($config['format.']['option']); if ($option) { if ($config['format.']['strftime']) { $value = strftime($option, $itemValue); } else { $value = date($option, $itemValue); } } else { $value = date('d-m-Y', $itemValue); } } else { $value = ''; } if ($config['format.']['appendAge']) { $age = BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $itemValue, $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')); $value .= ' (' . $age . ')'; } $itemValue = $value; break; case 'datetime': // compatibility with "eval" (type "input") if ($itemValue !== '') { $itemValue = date('H:i d-m-Y', (int) $itemValue); } break; case 'time': // compatibility with "eval" (type "input") if ($itemValue !== '') { $itemValue = date('H:i', (int) $itemValue); } break; case 'timesec': // compatibility with "eval" (type "input") if ($itemValue !== '') { $itemValue = date('H:i:s', (int) $itemValue); } break; case 'year': // compatibility with "eval" (type "input") if ($itemValue !== '') { $itemValue = date('Y', (int) $itemValue); } break; case 'int': $baseArr = array('dec' => 'd', 'hex' => 'x', 'HEX' => 'X', 'oct' => 'o', 'bin' => 'b'); $base = trim($config['format.']['base']); $format = $baseArr[$base] ?: 'd'; $itemValue = sprintf('%' . $format, $itemValue); break; case 'float': $precision = MathUtility::forceIntegerInRange($config['format.']['precision'], 1, 10, 2); $itemValue = sprintf('%.' . $precision . 'f', $itemValue); break; case 'number': $format = trim($config['format.']['option']); $itemValue = sprintf('%' . $format, $itemValue); break; case 'md5': $itemValue = md5($itemValue); break; case 'filesize': // We need to cast to int here, otherwise empty values result in empty output, // but we expect zero. $value = GeneralUtility::formatSize((int) $itemValue); if ($config['format.']['appendByteSize']) { $value .= ' (' . $itemValue . ')'; } $itemValue = $value; break; case 'user': $func = trim($config['format.']['userFunc']); if ($func) { $dummyFormEngine = new FormEngine(); $params = array('value' => $itemValue, 'args' => $config['format.']['userFunc'], 'config' => $config, 'pObj' => $dummyFormEngine); $itemValue = GeneralUtility::callUserFunction($func, $params, $dummyFormEngine); } break; default: // Do nothing e.g. when $format === '' } return $itemValue; }
/** * @test * @dataProvider calcAgeDataProvider * * @param int $seconds * @param string $expectedLabel */ public function calcAgeReturnsExpectedValues($seconds, $expectedLabel) { $this->assertSame($expectedLabel, BackendUtility::calcAge($seconds)); }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @return array All available buttons as an assoc. array */ protected function getButtons() { $lang = $this->getLanguageService(); // Render SAVE type buttons: // The action of each button is decided by its name attribute. (See doProcessData()) $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); if (!$this->errorC && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly']) { $saveSplitButton = $buttonBar->makeSplitButton(); // SAVE button: $saveButton = $buttonBar->makeInputButton()->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDoc'))->setName('_savedok')->setValue('1')->setForm('EditDocumentController')->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveButton, true); // SAVE / VIEW button: if ($this->viewId && !$this->noView && $this->getNewIconMode($this->firstEl['table'], 'saveDocView')) { $pagesTSconfig = BackendUtility::getPagesTSconfig($this->pageinfo['uid']); if (isset($pagesTSconfig['TCEMAIN.']['preview.']['disableButtonForDokType'])) { $excludeDokTypes = GeneralUtility::intExplode(',', $pagesTSconfig['TCEMAIN.']['preview.']['disableButtonForDokType'], true); } else { // exclude sysfolders, spacers and recycler by default $excludeDokTypes = [PageRepository::DOKTYPE_RECYCLER, PageRepository::DOKTYPE_SYSFOLDER, PageRepository::DOKTYPE_SPACER]; } if (!in_array((int) $this->pageinfo['doktype'], $excludeDokTypes, true) || isset($pagesTSconfig['TCEMAIN.']['preview.'][$this->firstEl['table'] . '.']['previewPageId'])) { $saveAndOpenButton = $buttonBar->makeInputButton()->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDocShow'))->setName('_savedokview')->setValue('1')->setForm('EditDocumentController')->setOnClick("window.open('', 'newTYPO3frontendWindow');")->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-view', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveAndOpenButton); } } // SAVE / NEW button: if (count($this->elementsData) === 1 && $this->getNewIconMode($this->firstEl['table'])) { $saveAndNewButton = $buttonBar->makeInputButton()->setName('_savedoknew')->setClasses('t3js-editform-submitButton')->setValue('1')->setForm('EditDocumentController')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveNewDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-new', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveAndNewButton); } // SAVE / CLOSE $saveAndCloseButton = $buttonBar->makeInputButton()->setName('_saveandclosedok')->setClasses('t3js-editform-submitButton')->setValue('1')->setForm('EditDocumentController')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveCloseDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveAndCloseButton); // FINISH TRANSLATION / SAVE / CLOSE if ($GLOBALS['TYPO3_CONF_VARS']['BE']['explicitConfirmationOfTranslation']) { $saveTranslationButton = $buttonBar->makeInputButton()->setName('_translation_savedok')->setValue('1')->setForm('EditDocumentController')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.translationSaveDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-cleartranslationcache', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveTranslationButton); $saveAndClearTranslationButton = $buttonBar->makeInputButton()->setName('_translation_savedokclear')->setValue('1')->setForm('EditDocumentController')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.translationSaveDocClear'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-cleartranslationcache', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveAndClearTranslationButton); } $buttonBar->addButton($saveSplitButton, ButtonBar::BUTTON_POSITION_LEFT, 2); } // CLOSE button: $closeButton = $buttonBar->makeLinkButton()->setHref('#')->setClasses('t3js-editform-close')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL)); $buttonBar->addButton($closeButton); // DELETE + UNDO buttons: if (!$this->errorC && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly'] && count($this->elementsData) === 1) { if ($this->firstEl['cmd'] !== 'new' && MathUtility::canBeInterpretedAsInteger($this->firstEl['uid'])) { // Delete: if ($this->firstEl['deleteAccess'] && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly'] && !$this->getNewIconMode($this->firstEl['table'], 'disableDelete')) { $returnUrl = $this->retUrl; if ($this->firstEl['table'] === 'pages') { parse_str((string) parse_url($returnUrl, PHP_URL_QUERY), $queryParams); if (isset($queryParams['M']) && isset($queryParams['id']) && (string) $this->firstEl['uid'] === (string) $queryParams['id']) { // TODO: Use the page's pid instead of 0, this requires a clean API to manipulate the page // tree from the outside to be able to mark the pid as active $returnUrl = BackendUtility::getModuleUrl($queryParams['M'], ['id' => 0]); } } $deleteButton = $buttonBar->makeLinkButton()->setHref('#')->setClasses('t3js-editform-delete-record')->setTitle($lang->getLL('deleteItem'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-edit-delete', Icon::SIZE_SMALL))->setDataAttributes(['return-url' => $returnUrl, 'uid' => $this->firstEl['uid'], 'table' => $this->firstEl['table']]); $buttonBar->addButton($deleteButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } // Undo: $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_history'); $undoButtonR = $queryBuilder->select('tstamp')->from('sys_history')->where($queryBuilder->expr()->eq('tablename', $queryBuilder->createNamedParameter($this->firstEl['table'], \PDO::PARAM_STR)), $queryBuilder->expr()->eq('recuid', $queryBuilder->createNamedParameter($this->firstEl['uid'], \PDO::PARAM_INT)))->orderBy('tstamp', 'DESC')->setMaxResults(1)->execute()->fetch(); if ($undoButtonR !== false) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', ['element' => $this->firstEl['table'] . ':' . $this->firstEl['uid'], 'revert' => 'ALL_FIELDS', 'returnUrl' => $this->R_URI])) . '; return false;'; $undoButton = $buttonBar->makeLinkButton()->setHref('#')->setOnClick($aOnClick)->setTitle(sprintf($lang->getLL('undoLastChange'), BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears'))))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-history-open', Icon::SIZE_SMALL)); $buttonBar->addButton($undoButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } if ($this->getNewIconMode($this->firstEl['table'], 'showHistory')) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', ['element' => $this->firstEl['table'] . ':' . $this->firstEl['uid'], 'returnUrl' => $this->R_URI])) . '; return false;'; $historyButton = $buttonBar->makeLinkButton()->setHref('#')->setOnClick($aOnClick)->setTitle('Open history of this record')->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-history-open', Icon::SIZE_SMALL)); $buttonBar->addButton($historyButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } // If only SOME fields are shown in the form, this will link the user to the FULL form: if ($this->columnsOnly) { $columnsOnlyButton = $buttonBar->makeLinkButton()->setHref($this->R_URI . '&columnsOnly=')->setTitle($lang->getLL('editWholeRecord'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-open', Icon::SIZE_SMALL)); $buttonBar->addButton($columnsOnlyButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } } } $cshButton = $buttonBar->makeHelpButton()->setModuleName('xMOD_csh_corebe')->setFieldName('TCEforms'); $buttonBar->addButton($cshButton); $this->shortCutLink(); $this->openInNewWindowLink(); }
/** * This creates the buttons for die modules * * @param string $function Identifier for function of module * @return void */ protected function makeButtons($function = '') { $lang = $this->getLanguageService(); // View page if (!VersionState::cast($this->pageinfo['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) { $viewButton = $this->buttonBar->makeLinkButton()->setOnClick(htmlspecialchars(BackendUtility::viewOnClick($this->pageinfo['uid'], '', BackendUtility::BEgetRootLine($this->pageinfo['uid']))))->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', true))->setIcon($this->iconFactory->getIcon('actions-document-view', Icon::SIZE_SMALL))->setHref('#'); $this->buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } // Shortcut $shortcutButton = $this->buttonBar->makeShortcutButton()->setModuleName($this->moduleName)->setGetVariables(['id', 'M', 'edit_record', 'pointer', 'new_unique_uid', 'search_field', 'search_levels', 'showLimit'])->setSetVariables(array_keys($this->MOD_MENU)); $this->buttonBar->addButton($shortcutButton); // Cache if (!$this->modTSconfig['properties']['disableAdvanced']) { $clearCacheButton = $this->buttonBar->makeLinkButton()->setHref(BackendUtility::getModuleUrl($this->moduleName, ['id' => $this->pageinfo['uid'], 'clear_cache' => '1']))->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.clear_cache', true))->setIcon($this->iconFactory->getIcon('actions-system-cache-clear', Icon::SIZE_SMALL)); $this->buttonBar->addButton($clearCacheButton, ButtonBar::BUTTON_POSITION_RIGHT, 1); } if (!$this->modTSconfig['properties']['disableIconToolbar']) { // Move record if (MathUtility::canBeInterpretedAsInteger($this->eRParts[1])) { $urlParameters = ['table' => $this->eRParts[0], 'uid' => $this->eRParts[1], 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]; $moveButton = $this->buttonBar->makeLinkButton()->setHref(BackendUtility::getModuleUrl('move_element', $urlParameters))->setTitle($lang->getLL('move_' . ($this->eRParts[0] == 'tt_content' ? 'record' : 'page'), true))->setIcon($this->iconFactory->getIcon('actions-' . ($this->eRParts[0] == 'tt_content' ? 'document' : 'page') . '-move', Icon::SIZE_SMALL)); $this->buttonBar->addButton($moveButton, ButtonBar::BUTTON_POSITION_LEFT, 2); } // Edit page properties and page language overlay icons if ($this->pageIsNotLockedForEditors() && $this->getBackendUser()->checkLanguageAccess(0)) { // Edit localized page_language_overlay only when one specific language is selected if ($this->MOD_SETTINGS['function'] == 1 && $this->current_sys_language > 0) { $overlayRecord = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid', 'pages_language_overlay', 'pid = ' . (int) $this->id . ' ' . 'AND sys_language_uid = ' . (int) $this->current_sys_language . BackendUtility::deleteClause('pages_language_overlay') . BackendUtility::versioningPlaceholderClause('pages_language_overlay'), '', '', ''); $editLanguageButton = $this->buttonBar->makeLinkButton()->setHref('#')->setTitle($lang->getLL('editPageLanguageOverlayProperties', true))->setOnClick(htmlspecialchars(BackendUtility::editOnClick('&edit[pages_language_overlay][' . $overlayRecord['uid'] . ']=edit')))->setIcon($this->iconFactory->getIcon('mimetypes-x-content-page-language-overlay', Icon::SIZE_SMALL)); $this->buttonBar->addButton($editLanguageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } $editPageButton = $this->buttonBar->makeLinkButton()->setHref('#')->setTitle($lang->getLL('editPageProperties', true))->setOnClick(htmlspecialchars(BackendUtility::editOnClick('&edit[pages][' . $this->id . ']=edit')))->setIcon($this->iconFactory->getIcon('actions-page-open', Icon::SIZE_SMALL)); $this->buttonBar->addButton($editPageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } // Add CSH (Context Sensitive Help) icon to tool bar $contextSensitiveHelpButton = $this->buttonBar->makeHelpButton()->setModuleName($this->descrTable)->setFieldName($function === 'quickEdit' ? 'quickEdit' : 'columns_' . $this->MOD_SETTINGS['function']); $this->buttonBar->addButton($contextSensitiveHelpButton); // QuickEdit if ($function == 'quickEdit') { // Close Record $closeButton = $this->buttonBar->makeLinkButton()->setHref('#')->setOnClick(htmlspecialchars('jumpToUrl(' . GeneralUtility::quoteJSvalue($this->closeUrl) . '); return false;'))->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', true))->setIcon($this->iconFactory->getIcon('actions-document-close', Icon::SIZE_SMALL)); $this->buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 0); // Save Record $saveButtonDropdown = $this->buttonBar->makeSplitButton(); $saveButton = $this->buttonBar->makeInputButton()->setName('_savedok')->setValue('1')->setForm('PageLayoutController')->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', true))->setIcon($this->iconFactory->getIcon('actions-document-save', Icon::SIZE_SMALL)); $saveButtonDropdown->addItem($saveButton); $saveAndCloseButton = $this->buttonBar->makeInputButton()->setName('_saveandclosedok')->setValue('1')->setForm('PageLayoutController')->setOnClick('document.editform.redirect.value=\'' . $this->closeUrl . '\';')->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', true))->setIcon($this->iconFactory->getIcon('actions-document-save-close', Icon::SIZE_SMALL)); $saveButtonDropdown->addItem($saveAndCloseButton); $saveAndShowPageButton = $this->buttonBar->makeInputButton()->setName('_savedokview')->setValue('1')->setForm('PageLayoutController')->setOnClick('document.editform.redirect.value+=\'&popView=1\';')->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDocShow', true))->setIcon($this->iconFactory->getIcon('actions-document-save-view', Icon::SIZE_SMALL)); $saveButtonDropdown->addItem($saveAndShowPageButton); $this->buttonBar->addButton($saveButtonDropdown, ButtonBar::BUTTON_POSITION_LEFT, 1); // Delete record if ($this->deleteButton) { $deleteButton = $this->buttonBar->makeLinkButton()->setHref('#')->setOnClick(htmlspecialchars('return deleteRecord(' . GeneralUtility::quoteJSvalue($this->eRParts[0]) . ',' . GeneralUtility::quoteJSvalue($this->eRParts[1]) . ',' . GeneralUtility::quoteJSvalue(GeneralUtility::getIndpEnv('SCRIPT_NAME') . '?id=' . $this->id) . ');'))->setTitle($lang->getLL('deleteItem', true))->setIcon($this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)); $this->buttonBar->addButton($deleteButton, ButtonBar::BUTTON_POSITION_LEFT, 4); } // History if ($this->undoButton) { $undoButton = $this->buttonBar->makeLinkButton()->setHref('#')->setOnClick(htmlspecialchars('window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', array('element' => $this->eRParts[0] . ':' . $this->eRParts[1], 'revert' => 'ALL_FIELDS', 'sumUp' => -1, 'returnUrl' => $this->R_URI))) . '; return false;'))->setTitle(htmlspecialchars(sprintf($lang->getLL('undoLastChange'), BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $this->undoButtonR['tstamp'], $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))))->setIcon($this->iconFactory->getIcon('actions-edit-undo', Icon::SIZE_SMALL)); $this->buttonBar->addButton($undoButton, ButtonBar::BUTTON_POSITION_LEFT, 5); $historyButton = $this->buttonBar->makeLinkButton()->setHref('#')->setOnClick(htmlspecialchars('jumpToUrl(' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', array('element' => $this->eRParts[0] . ':' . $this->eRParts[1], 'returnUrl' => $this->R_URI)) . '#latest') . ');return false;'))->setTitle($lang->getLL('recordHistory', true))->setIcon($this->iconFactory->getIcon('actions-document-history-open', Icon::SIZE_SMALL)); $this->buttonBar->addButton($historyButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } } } }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @return array All available buttons as an assoc. array */ protected function getButtons() { $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); if ($this->P['table'] && $this->P['field'] && $this->P['uid'] && $this->checkEditAccess($this->P['table'], $this->P['uid'])) { $closeUrl = GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']); // Getting settings for the undo button: $undoButton = 0; $databaseConnection = $this->getDatabaseConnection(); $undoRes = $databaseConnection->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $databaseConnection->fullQuoteStr($this->P['table'], 'sys_history') . ' AND recuid=' . (int) $this->P['uid'], '', 'tstamp DESC', '1'); if ($undoButtonR = $databaseConnection->sql_fetch_assoc($undoRes)) { $undoButton = 1; } // Close $closeButton = $buttonBar->makeLinkButton()->setHref($closeUrl)->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL)); $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 10); // Save $saveButton = $buttonBar->makeInputButton()->setName('_savedok_x')->setValue('1')->setForm('RteController')->setOnClick('TBE_EDITOR.checkAndDoSubmit(1); return false;')->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL)); // Save & View $saveAndViewButton = $buttonBar->makeInputButton()->setName('_savedokview_x')->setValue('1')->setForm('RteController')->setOnClick('document.editform.redirect.value+= ' . GeneralUtility::quoteJSvalue('&popView=1') . '; ' . ' TBE_EDITOR.checkAndDoSubmit(1); return false;')->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDocShow'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-view', Icon::SIZE_SMALL)); // Save & Close $saveAndCloseButton = $buttonBar->makeInputButton()->setName('_saveandclosedok_x')->setValue('1')->setForm('RteController')->setOnClick('document.editform.redirect.value=' . GeneralUtility::quoteJSvalue($closeUrl) . '; TBE_EDITOR.checkAndDoSubmit(1); return false;')->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL)); // Save SplitButton $saveSplitButton = $buttonBar->makeSplitButton()->addItem($saveButton)->addItem($saveAndViewButton)->addItem($saveAndCloseButton); $buttonBar->addButton($saveSplitButton, ButtonBar::BUTTON_POSITION_LEFT, 20); // Undo/Revert: if ($undoButton) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', array('element' => $this->P['table'] . ':' . $this->P['uid'], 'revert' => 'field:' . $this->P['field'], 'sumUp' => -1, 'returnUrl' => $this->R_URI))) . '; return false;'; $undoText = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_wizards.xlf:rte_undoLastChange'); $lastChangeLabel = sprintf($undoText, BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears'))); $undoRevertButton = $buttonBar->makeLinkButton()->setHref('#')->setOnClick($aOnClick)->setTitle($lastChangeLabel)->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-edit-undo', Icon::SIZE_SMALL)); $buttonBar->addButton($undoRevertButton, ButtonBar::BUTTON_POSITION_LEFT, 30); } // Shortcut $shortButton = $buttonBar->makeShortcutButton()->setModuleName($this->MCONF['name'])->setGetVariables(['P']); $buttonBar->addButton($shortButton); } }
/** * Shows the full change log * * @return string HTML for list, wrapped in a table. */ public function displayHistory() { if (empty($this->changeLog)) { return ''; } $languageService = $this->getLanguageService(); $lines = array(); $beUserArray = BackendUtility::getUserNames(); $i = 0; // Traverse changeLog array: foreach ($this->changeLog as $sysLogUid => $entry) { // stop after maxSteps if ($this->maxSteps && $i > $this->maxSteps) { break; } // Show only marked states if (!$entry['snapshot'] && $this->showMarked) { continue; } $i++; // Build up single line $singleLine = array(); // Get user names $userName = $entry['user'] ? $beUserArray[$entry['user']]['username'] : $languageService->getLL('externalChange'); // Executed by switch-user if (!empty($entry['originalUser'])) { $userName .= ' (' . $languageService->getLL('viaUser') . ' ' . $beUserArray[$entry['originalUser']]['username'] . ')'; } $singleLine['backendUserName'] = htmlspecialchars($userName); $singleLine['backendUserUid'] = $entry['user']; // add user name // Diff link $image = $this->iconFactory->getIcon('actions-document-history-open', Icon::SIZE_SMALL)->render(); $singleLine['rollbackLink'] = $this->linkPage($image, array('diff' => $sysLogUid)); // remove first link $singleLine['time'] = htmlspecialchars(BackendUtility::datetime($entry['tstamp'])); // add time $singleLine['age'] = htmlspecialchars(BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $entry['tstamp'], $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears'))); // add age $singleLine['tableUid'] = $this->linkPage($this->generateTitle($entry['tablename'], $entry['recuid']), array('element' => $entry['tablename'] . ':' . $entry['recuid']), '', $languageService->getLL('linkRecordHistory', true)); // add record UID // Show insert/delete/diff/changed field names if ($entry['action']) { // insert or delete of element $singleLine['action'] = htmlspecialchars($languageService->getLL($entry['action'], true)); } else { // Display field names instead of full diff if (!$this->showDiff) { // Re-write field names with labels $tmpFieldList = explode(',', $entry['fieldlist']); foreach ($tmpFieldList as $key => $value) { $tmp = str_replace(':', '', $languageService->sL(BackendUtility::getItemLabel($entry['tablename'], $value), true)); if ($tmp) { $tmpFieldList[$key] = $tmp; } else { // remove fields if no label available unset($tmpFieldList[$key]); } } $singleLine['fieldNames'] = htmlspecialchars(implode(',', $tmpFieldList)); } else { // Display diff $diff = $this->renderDiff($entry, $entry['tablename']); $singleLine['differences'] = $diff; } } // Show link to mark/unmark state if (!$entry['action']) { if ($entry['snapshot']) { $title = $languageService->getLL('unmarkState', true); $image = $this->iconFactory->getIcon('actions-unmarkstate', Icon::SIZE_SMALL)->render(); } else { $title = $languageService->getLL('markState', true); $image = $this->iconFactory->getIcon('actions-markstate', Icon::SIZE_SMALL)->render(); } $singleLine['markState'] = $this->linkPage($image, array('highlight' => $entry['uid']), '', $title); } else { $singleLine['markState'] = ''; } // put line together $lines[] = $singleLine; } $this->view->assign('history', $lines); if ($this->lastSyslogId) { $this->view->assign('fullViewLink', $this->linkPage($languageService->getLL('fullView', true), array('diff' => ''))); } }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @return array All available buttons as an assoc. array */ protected function getButtons() { $buttons = array('close' => '', 'save' => '', 'save_view' => '', 'save_close' => '', 'shortcut' => '', 'undo' => ''); if ($this->P['table'] && $this->P['field'] && $this->P['uid'] && $this->checkEditAccess($this->P['table'], $this->P['uid'])) { $closeUrl = GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']); // Getting settings for the undo button: $undoButton = 0; $databaseConnection = $this->getDatabaseConnection(); $undoRes = $databaseConnection->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $databaseConnection->fullQuoteStr($this->P['table'], 'sys_history') . ' AND recuid=' . (int) $this->P['uid'], '', 'tstamp DESC', '1'); if ($undoButtonR = $databaseConnection->sql_fetch_assoc($undoRes)) { $undoButton = 1; } // Close $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(' . GeneralUtility::quoteJSvalue($closeUrl) . '); return false;') . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-close') . '</a>'; // Save $buttons['save'] = IconUtility::getSpriteIcon('actions-document-save', array('html' => '<input type="image" name="_savedok" class="c-inputButton" src="clear.gif" onclick="TBE_EDITOR.checkAndDoSubmit(1); return false;" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', TRUE) . '" />')); // Save & View $buttons['save_view'] = IconUtility::getSpriteIcon('actions-document-save-view', array('html' => '<input type="image" class="c-inputButton" name="_savedokview" src="clear.gif" onclick="' . htmlspecialchars('document.editform.redirect.value+=\'&popView=1\'; TBE_EDITOR.checkAndDoSubmit(1); return false;') . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDocShow', TRUE) . '" />')); // Save & Close $buttons['save_close'] = IconUtility::getSpriteIcon('actions-document-save-close', array('html' => '<input type="image" class="c-inputButton" name="_saveandclosedok" src="clear.gif" onclick="' . htmlspecialchars('document.editform.redirect.value=' . GeneralUtility::quoteJSvalue($closeUrl) . '; TBE_EDITOR.checkAndDoSubmit(1); return false;') . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', TRUE) . '" />')); // Undo/Revert: if ($undoButton) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', array('element' => $this->P['table'] . ':' . $this->P['uid'], 'revert' => 'field:' . $this->P['field'], 'sumUp' => -1, 'returnUrl' => $this->R_URI))) . '; return false;'; $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"' . ' title="' . htmlspecialchars(sprintf($this->getLanguageService()->getLL('undoLastChange'), BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))) . '">' . IconUtility::getSpriteIcon('actions-edit-undo') . '</a>'; } // Shortcut if ($this->getBackendUserAuthentication()->mayMakeShortcut()) { $buttons['shortcut'] = $this->doc->makeShortcutIcon('P', '', $this->MCONF['name'], 1); } } return $buttons; }
/** * This creates the buttons for die modules * * @param string $function Identifier for function of module * @return void */ protected function makeButtons($function = '') { $lang = $this->getLanguageService(); // View page if (!VersionState::cast($this->pageinfo['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) { $viewButton = $this->buttonBar->makeLinkButton()->setOnClick(BackendUtility::viewOnClick($this->pageinfo['uid'], '', BackendUtility::BEgetRootLine($this->pageinfo['uid'])))->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.showPage'))->setIcon($this->iconFactory->getIcon('actions-document-view', Icon::SIZE_SMALL))->setHref('#'); $this->buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } // Shortcut $shortcutButton = $this->buttonBar->makeShortcutButton()->setModuleName($this->moduleName)->setGetVariables(['id', 'M', 'edit_record', 'pointer', 'new_unique_uid', 'search_field', 'search_levels', 'showLimit'])->setSetVariables(array_keys($this->MOD_MENU)); $this->buttonBar->addButton($shortcutButton); // Cache if (!$this->modTSconfig['properties']['disableAdvanced']) { $clearCacheButton = $this->buttonBar->makeLinkButton()->setHref(BackendUtility::getModuleUrl($this->moduleName, ['id' => $this->pageinfo['uid'], 'clear_cache' => '1']))->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.clear_cache'))->setIcon($this->iconFactory->getIcon('actions-system-cache-clear', Icon::SIZE_SMALL)); $this->buttonBar->addButton($clearCacheButton, ButtonBar::BUTTON_POSITION_RIGHT, 1); } if (!$this->modTSconfig['properties']['disableIconToolbar']) { // Move record if (MathUtility::canBeInterpretedAsInteger($this->eRParts[1])) { $urlParameters = ['table' => $this->eRParts[0], 'uid' => $this->eRParts[1], 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]; $moveButton = $this->buttonBar->makeLinkButton()->setHref(BackendUtility::getModuleUrl('move_element', $urlParameters))->setTitle($lang->getLL('move_' . ($this->eRParts[0] == 'tt_content' ? 'record' : 'page')))->setIcon($this->iconFactory->getIcon('actions-' . ($this->eRParts[0] == 'tt_content' ? 'document' : 'page') . '-move', Icon::SIZE_SMALL)); $this->buttonBar->addButton($moveButton, ButtonBar::BUTTON_POSITION_LEFT, 2); } // Edit page properties and page language overlay icons if ($this->pageIsNotLockedForEditors() && $this->getBackendUser()->checkLanguageAccess(0)) { // Edit localized page_language_overlay only when one specific language is selected if ($this->MOD_SETTINGS['function'] == 1 && $this->current_sys_language > 0) { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages_language_overlay'); $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class))->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class)); $overlayRecord = $queryBuilder->select('uid')->from('pages_language_overlay')->where($queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)), $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($this->current_sys_language, \PDO::PARAM_INT)))->setMaxResults(1)->execute()->fetch(); // Edit button $urlParameters = ['edit' => ['pages_language_overlay' => [$overlayRecord['uid'] => 'edit']], 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]; $url = BackendUtility::getModuleUrl('record_edit', $urlParameters); $editLanguageButton = $this->buttonBar->makeLinkButton()->setHref($url)->setTitle($lang->getLL('editPageLanguageOverlayProperties'))->setIcon($this->iconFactory->getIcon('mimetypes-x-content-page-language-overlay', Icon::SIZE_SMALL)); $this->buttonBar->addButton($editLanguageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } $urlParameters = ['edit' => ['pages' => [$this->id => 'edit']], 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]; $url = BackendUtility::getModuleUrl('record_edit', $urlParameters); $editPageButton = $this->buttonBar->makeLinkButton()->setHref($url)->setTitle($lang->getLL('editPageProperties'))->setIcon($this->iconFactory->getIcon('actions-page-open', Icon::SIZE_SMALL)); $this->buttonBar->addButton($editPageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } // Add CSH (Context Sensitive Help) icon to tool bar $contextSensitiveHelpButton = $this->buttonBar->makeHelpButton()->setModuleName($this->descrTable)->setFieldName($function === 'quickEdit' ? 'quickEdit' : 'columns_' . $this->MOD_SETTINGS['function']); $this->buttonBar->addButton($contextSensitiveHelpButton); // QuickEdit if ($function == 'quickEdit') { // Close Record $closeButton = $this->buttonBar->makeLinkButton()->setHref('#')->setOnClick('jumpToUrl(' . GeneralUtility::quoteJSvalue($this->closeUrl) . '); return false;')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))->setIcon($this->iconFactory->getIcon('actions-document-close', Icon::SIZE_SMALL)); $this->buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 0); // Save Record $saveButtonDropdown = $this->buttonBar->makeSplitButton(); $saveButton = $this->buttonBar->makeInputButton()->setName('_savedok')->setValue('1')->setForm('PageLayoutController')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDoc'))->setIcon($this->iconFactory->getIcon('actions-document-save', Icon::SIZE_SMALL)); $saveButtonDropdown->addItem($saveButton); $saveAndCloseButton = $this->buttonBar->makeInputButton()->setName('_saveandclosedok')->setValue('1')->setForm('PageLayoutController')->setOnClick('document.editform.redirect.value=\'' . $this->closeUrl . '\';')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveCloseDoc'))->setIcon($this->iconFactory->getIcon('actions-document-save-close', Icon::SIZE_SMALL)); $saveButtonDropdown->addItem($saveAndCloseButton); $saveAndShowPageButton = $this->buttonBar->makeInputButton()->setName('_savedokview')->setValue('1')->setForm('PageLayoutController')->setOnClick('document.editform.redirect.value+=\'&popView=1\';')->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDocShow'))->setIcon($this->iconFactory->getIcon('actions-document-save-view', Icon::SIZE_SMALL)); $saveButtonDropdown->addItem($saveAndShowPageButton); $this->buttonBar->addButton($saveButtonDropdown, ButtonBar::BUTTON_POSITION_LEFT, 1); // Delete record if ($this->deleteButton) { $dataAttributes = []; $dataAttributes['table'] = $this->eRParts[0]; $dataAttributes['uid'] = $this->eRParts[1]; $dataAttributes['return-url'] = BackendUtility::getModuleUrl($this->moduleName) . '&id=' . $this->id; $deleteButton = $this->buttonBar->makeLinkButton()->setHref('#')->setClasses('t3js-editform-delete-record')->setDataAttributes($dataAttributes)->setTitle($lang->getLL('deleteItem'))->setIcon($this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)); $this->buttonBar->addButton($deleteButton, ButtonBar::BUTTON_POSITION_LEFT, 4); } // History if ($this->undoButton) { $undoButton = $this->buttonBar->makeLinkButton()->setHref('#')->setOnClick('window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', ['element' => $this->eRParts[0] . ':' . $this->eRParts[1], 'revert' => 'ALL_FIELDS', 'returnUrl' => $this->R_URI])) . '; return false;')->setTitle(sprintf($lang->getLL('undoLastChange'), BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $this->undoButtonR['tstamp'], $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears'))))->setIcon($this->iconFactory->getIcon('actions-edit-undo', Icon::SIZE_SMALL)); $this->buttonBar->addButton($undoButton, ButtonBar::BUTTON_POSITION_LEFT, 5); $historyButton = $this->buttonBar->makeLinkButton()->setHref('#')->setOnClick('jumpToUrl(' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', ['element' => $this->eRParts[0] . ':' . $this->eRParts[1], 'returnUrl' => $this->R_URI]) . '#latest') . ');return false;')->setTitle($lang->getLL('recordHistory'))->setIcon($this->iconFactory->getIcon('actions-document-history-open', Icon::SIZE_SMALL)); $this->buttonBar->addButton($historyButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } } } }
/** * Creates an info-box for the current page (identified by input record). * * @param array $rec Page record * @param boolean $edit If set, there will be shown an edit icon, linking to editing of the page properties. * @return string HTML for the box. * @deprecated and unused since 6.0, will be removed two versions later * @todo Define visibility */ public function getPageInfoBox($rec, $edit = 0) { \TYPO3\CMS\Core\Utility\GeneralUtility::logDeprecatedFunction(); // If editing of the page properties is allowed: if ($edit) { $params = '&edit[pages][' . $rec['uid'] . ']=edit'; $editIcon = '<a href="#" onclick="' . htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::editOnClick($params, $this->backPath)) . '" title="' . $GLOBALS['LANG']->getLL('edit', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-open') . '</a>'; } else { $editIcon = $this->noEditIcon('noEditPage'); } // Setting page icon, link, title: $outPutContent = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord('pages', $rec, array('title' => \TYPO3\CMS\Backend\Utility\BackendUtility::titleAttribForPages($rec))) . $editIcon . ' ' . htmlspecialchars($rec['title']); // Init array where infomation is accumulated as label/value pairs. $lines = array(); // Owner user/group: if ($this->pI_showUser) { // User: $users = \TYPO3\CMS\Backend\Utility\BackendUtility::getUserNames('username,usergroup,usergroup_cached_list,uid,realName'); $groupArray = explode(',', $GLOBALS['BE_USER']->user['usergroup_cached_list']); $users = \TYPO3\CMS\Backend\Utility\BackendUtility::blindUserNames($users, $groupArray); $lines[] = array($GLOBALS['LANG']->getLL('pI_crUser') . ':', htmlspecialchars($users[$rec['cruser_id']]['username']) . ' (' . $users[$rec['cruser_id']]['realName'] . ')'); } // Created: $lines[] = array($GLOBALS['LANG']->getLL('pI_crDate') . ':', \TYPO3\CMS\Backend\Utility\BackendUtility::datetime($rec['crdate']) . ' (' . \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $rec['crdate'], $this->agePrefixes) . ')'); // Last change: $lines[] = array($GLOBALS['LANG']->getLL('pI_lastChange') . ':', \TYPO3\CMS\Backend\Utility\BackendUtility::datetime($rec['tstamp']) . ' (' . \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $rec['tstamp'], $this->agePrefixes) . ')'); // Last change of content: if ($rec['SYS_LASTCHANGED']) { $lines[] = array($GLOBALS['LANG']->getLL('pI_lastChangeContent') . ':', \TYPO3\CMS\Backend\Utility\BackendUtility::datetime($rec['SYS_LASTCHANGED']) . ' (' . \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $rec['SYS_LASTCHANGED'], $this->agePrefixes) . ')'); } // Spacer: $lines[] = ''; // Display contents of certain page fields, if any value: $dfields = explode(',', 'alias,target,hidden,starttime,endtime,fe_group,no_cache,cache_timeout,newUntil,lastUpdated,subtitle,keywords,description,abstract,author,author_email'); foreach ($dfields as $fV) { if ($rec[$fV]) { $lines[] = array($GLOBALS['LANG']->sL(\TYPO3\CMS\Backend\Utility\BackendUtility::getItemLabel('pages', $fV)), \TYPO3\CMS\Backend\Utility\BackendUtility::getProcessedValue('pages', $fV, $rec[$fV])); } } // Finally, wrap the elements in the $lines array in table cells/rows foreach ($lines as $fV) { if (is_array($fV)) { if (!$fV[2]) { $fV[1] = htmlspecialchars($fV[1]); } $out .= ' <tr> <td class="bgColor4" nowrap="nowrap"><strong>' . htmlspecialchars($fV[0]) . ' </strong></td> <td class="bgColor4">' . $fV[1] . '</td> </tr>'; } else { $out .= ' <tr> <td colspan="2"><img src="clear.gif" width="1" height="3" alt="" /></td> </tr>'; } } // Wrap table tags around... $outPutContent .= ' <!-- Page info box: --> <table border="0" cellpadding="0" cellspacing="1" id="typo3-page-info"> ' . $out . ' </table>'; // ... and return it. return $outPutContent; }
/** * Shows the full change log * * @return string HTML for list, wrapped in a table. */ public function displayHistory() { if (empty($this->changeLog)) { return ''; } $languageService = $this->getLanguageService(); $lines = array(); // Initialize: $lines[] = '<thead><tr> <th>' . $languageService->getLL('rollback', true) . '</th> <th>' . $languageService->getLL('time', true) . '</th> <th>' . $languageService->getLL('age', true) . '</th> <th>' . $languageService->getLL('user', true) . '</th> <th>' . $languageService->getLL('tableUid', true) . '</th> <th>' . $languageService->getLL('differences', true) . '</th> <th> </th> </tr></thead>'; $beUserArray = BackendUtility::getUserNames(); $i = 0; /** @var Avatar $avatar */ $avatar = GeneralUtility::makeInstance(Avatar::class); // Traverse changeLog array: foreach ($this->changeLog as $sysLogUid => $entry) { // stop after maxSteps if ($this->maxSteps && $i > $this->maxSteps) { break; } // Show only marked states if (!$entry['snapshot'] && $this->showMarked) { continue; } $i++; // Get user names $userName = $entry['user'] ? $beUserArray[$entry['user']]['username'] : $languageService->getLL('externalChange', true); // Build up single line $singleLine = array(); // Diff link $image = '<span title="' . $languageService->getLL('sumUpChanges', true) . '">' . $this->iconFactory->getIcon('actions-document-history-open', Icon::SIZE_SMALL)->render() . '</span>'; $singleLine[] = '<span>' . $this->linkPage($image, array('diff' => $sysLogUid)) . '</span>'; // remove first link $singleLine[] = htmlspecialchars(BackendUtility::datetime($entry['tstamp'])); // add time $singleLine[] = htmlspecialchars(BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $entry['tstamp'], $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears'))); // add age $userEntry = is_array($beUserArray[$entry['user']]) ? $beUserArray[$entry['user']] : null; $singleLine[] = $avatar->render($userEntry) . ' ' . htmlspecialchars($userName); // add user name $singleLine[] = $this->linkPage($this->generateTitle($entry['tablename'], $entry['recuid']), array('element' => $entry['tablename'] . ':' . $entry['recuid']), '', $languageService->getLL('linkRecordHistory', true)); // add record UID // Show insert/delete/diff/changed field names if ($entry['action']) { // insert or delete of element $singleLine[] = '<strong>' . htmlspecialchars($languageService->getLL($entry['action'], true)) . '</strong>'; } else { // Display field names instead of full diff if (!$this->showDiff) { // Re-write field names with labels $tmpFieldList = explode(',', $entry['fieldlist']); foreach ($tmpFieldList as $key => $value) { $tmp = str_replace(':', '', $languageService->sl(BackendUtility::getItemLabel($entry['tablename'], $value), true)); if ($tmp) { $tmpFieldList[$key] = $tmp; } else { // remove fields if no label available unset($tmpFieldList[$key]); } } $singleLine[] = htmlspecialchars(implode(',', $tmpFieldList)); } else { // Display diff $diff = $this->renderDiff($entry, $entry['tablename']); $singleLine[] = $diff; } } // Show link to mark/unmark state if (!$entry['action']) { if ($entry['snapshot']) { $title = $languageService->getLL('unmarkState', true); $image = $this->iconFactory->getIcon('actions-unmarkstate', Icon::SIZE_SMALL)->render(); } else { $title = $languageService->getLL('markState', true); $image = $this->iconFactory->getIcon('actions-markstate', Icon::SIZE_SMALL)->render(); } $singleLine[] = $this->linkPage($image, array('highlight' => $entry['uid']), '', $title); } else { $singleLine[] = ''; } // put line together $lines[] = ' <tr> <td>' . implode('</td><td>', $singleLine) . '</td> </tr>'; } // @TODO: introduce Fluid Standalone view and use callout viewHelper $theCode = '<div class="callout callout-info">' . '<div class="media"><div class="media-left"><span class="fa-stack fa-lg callout-icon"><i class="fa fa-circle fa-stack-2x"></i><i class="fa fa-info fa-stack-1x"></i></span></div>' . '<div class="media-body">' . '<p>' . $languageService->getLL('differenceMsg') . '</p>' . ' <div class="callout-body">' . ' </div></div></div></div>'; // Finally, put it all together: $theCode .= ' <!-- History (list): --> <table class="table table-striped table-hover table-vertical-top" id="typo3-history"> ' . implode('', $lines) . ' </table>'; if ($this->lastSyslogId) { $theCode .= '<br />' . $this->linkPage('<span class="btn btn-default">' . $languageService->getLL('fullView', true) . '</span>', array('diff' => '')); } $theCode .= '<br /><br />'; // Add the whole content as a module section: return '<h2>' . $languageService->getLL('changes', true) . '</h2><div>' . $theCode . '</div>'; }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @return array All available buttons as an assoc. array */ protected function getButtons() { $buttons = array('save' => '', 'save_view' => '', 'save_new' => '', 'save_close' => '', 'close' => '', 'delete' => '', 'undo' => '', 'history' => '', 'columns_only' => '', 'csh' => '', 'translation_save' => '', 'translation_saveclear' => ''); // Render SAVE type buttons: // The action of each button is decided by its name attribute. (See doProcessData()) if (!$this->errorC && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly']) { // SAVE button: $buttons['save'] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-save', array('html' => '<input type="image" name="_savedok" class="c-inputButton" src="clear.gif" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc', 1) . '" />')); // SAVE / VIEW button: if ($this->viewId && !$this->noView && \TYPO3\CMS\Core\Extension\ExtensionManager::isLoaded('cms') && $this->getNewIconMode($this->firstEl['table'], 'saveDocView')) { $buttons['save_view'] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-save-view', array('html' => '<input type="image" class="c-inputButton" name="_savedokview" src="clear.gif" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDocShow', 1) . '" />')); } // SAVE / NEW button: if (count($this->elementsData) == 1 && $this->getNewIconMode($this->firstEl['table'])) { $buttons['save_new'] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-save-new', array('html' => '<input type="image" class="c-inputButton" name="_savedoknew" src="clear.gif" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveNewDoc', 1) . '" />')); } // SAVE / CLOSE $buttons['save_close'] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-save-close', array('html' => '<input type="image" class="c-inputButton" name="_saveandclosedok" src="clear.gif" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc', 1) . '" />')); // FINISH TRANSLATION / SAVE / CLOSE if ($GLOBALS['TYPO3_CONF_VARS']['BE']['explicitConfirmationOfTranslation']) { $buttons['translation_save'] = '<input type="image" class="c-inputButton" name="_translation_savedok" src="' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->doc->backPath, 'gfx/translationsavedok.gif', '', 1) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.translationSaveDoc', 1) . '" />'; $buttons['translation_saveclear'] = '<input type="image" class="c-inputButton" name="_translation_savedokclear" src="' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->doc->backPath, 'gfx/translationsavedok_clear.gif', '', 1) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.translationSaveDocClear', 1) . '" />'; } } // CLOSE button: $buttons['close'] = '<a href="#" onclick="document.editform.closeDoc.value=1; document.editform.submit(); return false;" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-close') . '</a>'; // DELETE + UNDO buttons: if (!$this->errorC && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly'] && count($this->elementsData) == 1) { if ($this->firstEl['cmd'] != 'new' && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->firstEl['uid'])) { // Delete: if ($this->firstEl['deleteAccess'] && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly'] && !$this->getNewIconMode($this->firstEl['table'], 'disableDelete')) { $aOnClick = 'return deleteRecord(\'' . $this->firstEl['table'] . '\',\'' . $this->firstEl['uid'] . '\', unescape(\'' . rawurlencode($this->retUrl) . '\'));'; $buttons['delete'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '" title="' . $GLOBALS['LANG']->getLL('deleteItem', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-delete') . '</a>'; } // Undo: $undoRes = $GLOBALS['TYPO3_DB']->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->firstEl['table'], 'sys_history') . ' AND recuid=' . intval($this->firstEl['uid']), '', 'tstamp DESC', '1'); if ($undoButtonR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($undoRes)) { $aOnClick = 'window.location.href=\'show_rechis.php?element=' . rawurlencode($this->firstEl['table'] . ':' . $this->firstEl['uid']) . '&revert=ALL_FIELDS&sumUp=-1&returnUrl=' . rawurlencode($this->R_URI) . '\'; return false;'; $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"' . ' title="' . htmlspecialchars(sprintf($GLOBALS['LANG']->getLL('undoLastChange'), \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')))) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-undo') . '</a>'; } if ($this->getNewIconMode($this->firstEl['table'], 'showHistory')) { $aOnClick = 'window.location.href=\'show_rechis.php?element=' . rawurlencode($this->firstEl['table'] . ':' . $this->firstEl['uid']) . '&returnUrl=' . rawurlencode($this->R_URI) . '\'; return false;'; $buttons['history'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-history-open') . '</a>'; } // If only SOME fields are shown in the form, this will link the user to the FULL form: if ($this->columnsOnly) { $buttons['columns_only'] = '<a href="' . htmlspecialchars($this->R_URI . '&columnsOnly=') . '" title="' . $GLOBALS['LANG']->getLL('editWholeRecord', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-open') . '</a>'; } } } // add the CSH icon $buttons['csh'] = \TYPO3\CMS\Backend\Utility\BackendUtility::cshItem('xMOD_csh_corebe', 'TCEforms', $GLOBALS['BACK_PATH'], '', TRUE); $buttons['shortcut'] = $this->shortCutLink(); $buttons['open_in_new_window'] = $this->openInNewWindowLink(); return $buttons; }
/** * Update extension list from TER * * @param bool $forceUpdateCheck * @return void */ public function updateExtensionListFromTerAction($forceUpdateCheck = false) { $updated = false; $errorMessage = ''; if ($this->extensionRepository->countAll() === 0 || $forceUpdateCheck) { try { $updated = $this->repositoryHelper->updateExtList(); } catch (\TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException $e) { $errorMessage = $e->getMessage(); } } /** @var $repository \TYPO3\CMS\Extensionmanager\Domain\Model\Repository */ $repository = $this->repositoryRepository->findByUid((int) $this->settings['repositoryUid']); $timeFormat = $this->getLanguageService()->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:extensionList.updateFromTer.lastUpdate.fullTimeFormat'); $lastUpdateTime = $repository->getLastUpdate(); if (null === $lastUpdateTime) { $lastUpdatedSince = $this->getLanguageService()->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:extensionList.updateFromTer.never'); $lastUpdateTime = date($timeFormat); } else { $lastUpdatedSince = \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge(time() - $lastUpdateTime->format('U'), $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears')); $lastUpdateTime = $lastUpdateTime->format($timeFormat); } $this->view->assign('value', ['updated' => $updated, 'lastUpdateTime' => $lastUpdateTime, 'timeSinceLastUpdate' => $lastUpdatedSince, 'errorMessage' => $errorMessage]); }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @return array All available buttons as an assoc. array */ protected function getButtons() { $lang = $this->getLanguageService(); // Render SAVE type buttons: // The action of each button is decided by its name attribute. (See doProcessData()) $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); if (!$this->errorC && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly']) { $saveSplitButton = $buttonBar->makeSplitButton(); // SAVE button: $saveButton = $buttonBar->makeInputButton()->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', true))->setName('_savedok')->setValue('1')->setForm('EditDocumentController')->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveButton, true); // SAVE / VIEW button: if ($this->viewId && !$this->noView && $this->getNewIconMode($this->firstEl['table'], 'saveDocView')) { $pagesTSconfig = BackendUtility::getPagesTSconfig($this->pageinfo['uid']); if (isset($pagesTSconfig['TCEMAIN.']['preview.']['disableButtonForDokType'])) { $excludeDokTypes = GeneralUtility::intExplode(',', $pagesTSconfig['TCEMAIN.']['preview.']['disableButtonForDokType'], true); } else { // exclude sysfolders, spacers and recycler by default $excludeDokTypes = array(PageRepository::DOKTYPE_RECYCLER, PageRepository::DOKTYPE_SYSFOLDER, PageRepository::DOKTYPE_SPACER); } if (!in_array((int) $this->pageinfo['doktype'], $excludeDokTypes, true) || isset($pagesTSconfig['TCEMAIN.']['preview.'][$this->firstEl['table'] . '.']['previewPageId'])) { $saveAndOpenButton = $buttonBar->makeInputButton()->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDocShow', true))->setName('_savedokview')->setValue('1')->setForm('EditDocumentController')->setOnClick("window.open('', 'newTYPO3frontendWindow');")->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-view', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveAndOpenButton); } } // SAVE / NEW button: if (count($this->elementsData) === 1 && $this->getNewIconMode($this->firstEl['table'])) { $saveAndNewButton = $buttonBar->makeInputButton()->setName('_savedoknew')->setClasses('t3js-editform-submitButton')->setValue('1')->setForm('EditDocumentController')->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveNewDoc', true))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-new', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveAndNewButton); } // SAVE / CLOSE $saveAndCloseButton = $buttonBar->makeInputButton()->setName('_saveandclosedok')->setClasses('t3js-editform-submitButton')->setValue('1')->setForm('EditDocumentController')->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', true))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveAndCloseButton); // FINISH TRANSLATION / SAVE / CLOSE if ($GLOBALS['TYPO3_CONF_VARS']['BE']['explicitConfirmationOfTranslation']) { $saveTranslationButton = $buttonBar->makeInputButton()->setName('_translation_savedok')->setValue('1')->setForm('EditDocumentController')->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.translationSaveDoc', true))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-cleartranslationcache', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveTranslationButton); $saveAndClearTranslationButton = $buttonBar->makeInputButton()->setName('_translation_savedokclear')->setValue('1')->setForm('EditDocumentController')->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.translationSaveDocClear', true))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-cleartranslationcache', Icon::SIZE_SMALL)); $saveSplitButton->addItem($saveAndClearTranslationButton); } $buttonBar->addButton($saveSplitButton, ButtonBar::BUTTON_POSITION_LEFT, 2); } // CLOSE button: $closeButton = $buttonBar->makeLinkButton()->setHref('#')->setClasses('t3js-editform-close')->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', true))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL)); $buttonBar->addButton($closeButton); // DELETE + UNDO buttons: if (!$this->errorC && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly'] && count($this->elementsData) === 1) { if ($this->firstEl['cmd'] != 'new' && MathUtility::canBeInterpretedAsInteger($this->firstEl['uid'])) { // Delete: if ($this->firstEl['deleteAccess'] && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly'] && !$this->getNewIconMode($this->firstEl['table'], 'disableDelete')) { $deleteButton = $buttonBar->makeLinkButton()->setHref('#')->setClasses('t3js-editform-delete-record')->setTitle($lang->getLL('deleteItem', true))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-edit-delete', Icon::SIZE_SMALL))->setDataAttributes(['return-url' => BackendUtility::getModuleUrl('web_layout', array('id' => $this->pageinfo['pid'])), 'uid' => $this->firstEl['uid'], 'table' => $this->firstEl['table']]); $buttonBar->addButton($deleteButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } // Undo: $undoRes = $this->getDatabaseConnection()->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $this->getDatabaseConnection()->fullQuoteStr($this->firstEl['table'], 'sys_history') . ' AND recuid=' . (int) $this->firstEl['uid'], '', 'tstamp DESC', '1'); if ($undoButtonR = $this->getDatabaseConnection()->sql_fetch_assoc($undoRes)) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', array('element' => $this->firstEl['table'] . ':' . $this->firstEl['uid'], 'revert' => 'ALL_FIELDS', 'sumUp' => -1, 'returnUrl' => $this->R_URI))) . '; return false;'; $undoButton = $buttonBar->makeLinkButton()->setHref('#')->setOnClick(htmlspecialchars($aOnClick))->setTitle(sprintf($lang->getLL('undoLastChange'), BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears'))))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-edit-undo', Icon::SIZE_SMALL)); $buttonBar->addButton($undoButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } if ($this->getNewIconMode($this->firstEl['table'], 'showHistory')) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', array('element' => $this->firstEl['table'] . ':' . $this->firstEl['uid'], 'returnUrl' => $this->R_URI))) . '; return false;'; $historyButton = $buttonBar->makeLinkButton()->setHref('#')->setOnClick($aOnClick)->setTitle('Open history of this record')->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-history-open', Icon::SIZE_SMALL)); $buttonBar->addButton($historyButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } // If only SOME fields are shown in the form, this will link the user to the FULL form: if ($this->columnsOnly) { $columnsOnlyButton = $buttonBar->makeLinkButton()->setHref(htmlspecialchars($this->R_URI . '&columnsOnly='))->setTitle($lang->getLL('editWholeRecord', true))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-open', Icon::SIZE_SMALL)); $buttonBar->addButton($columnsOnlyButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } } } $cshButton = $buttonBar->makeHelpButton()->setModuleName('xMOD_csh_corebe')->setFieldName('TCEforms'); $buttonBar->addButton($cshButton); $this->shortCutLink(); $this->openInNewWindowLink(); }
/** * Format field content of various types if $config['format'] is set to date, filesize, ..., user * This is primarily for the field type none but can be used for user field types for example * * @param array $config Configuration for the display * @param string $itemValue The value to display * @return string Formatted Field content * @todo Define visibility */ public function formatValue($config, $itemValue) { $format = trim($config['format']); switch ($format) { case 'date': if ($itemValue) { $option = trim($config['format.']['option']); if ($option) { if ($config['format.']['strftime']) { $value = strftime($option, $itemValue); } else { $value = date($option, $itemValue); } } else { $value = date('d-m-Y', $itemValue); } } else { $value = ''; } if ($config['format.']['appendAge']) { $value .= ' (' . \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $itemValue, $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')) . ')'; } $itemValue = $value; break; case 'datetime': // compatibility with "eval" (type "input") $itemValue = date('H:i d-m-Y', $itemValue); break; case 'time': // compatibility with "eval" (type "input") $itemValue = date('H:i', $itemValue); break; case 'timesec': // compatibility with "eval" (type "input") $itemValue = date('H:i:s', $itemValue); break; case 'year': // compatibility with "eval" (type "input") $itemValue = date('Y', $itemValue); break; case 'int': $baseArr = array('dec' => 'd', 'hex' => 'x', 'HEX' => 'X', 'oct' => 'o', 'bin' => 'b'); $base = trim($config['format.']['base']); $format = $baseArr[$base] ? $baseArr[$base] : 'd'; $itemValue = sprintf('%' . $format, $itemValue); break; case 'float': $precision = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($config['format.']['precision'], 1, 10, 2); $itemValue = sprintf('%.' . $precision . 'f', $itemValue); break; case 'number': $format = trim($config['format.']['option']); $itemValue = sprintf('%' . $format, $itemValue); break; case 'md5': $itemValue = md5($itemValue); break; case 'filesize': $value = \TYPO3\CMS\Core\Utility\GeneralUtility::formatSize(intval($itemValue)); if ($config['format.']['appendByteSize']) { $value .= ' (' . $itemValue . ')'; } $itemValue = $value; break; case 'user': $func = trim($config['format.']['userFunc']); if ($func) { $params = array('value' => $itemValue, 'args' => $config['format.']['userFunc'], 'config' => $config, 'pObj' => &$this); $itemValue = \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($func, $params, $this); } break; default: break; } return $itemValue; }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @param string $function Identifier for function of module * @return array all available buttons as an assoc. array */ protected function getButtons($function = '') { $lang = $this->getLanguageService(); $buttons = array('view' => '', 'history_page' => '', 'new_content' => '', 'move_page' => '', 'move_record' => '', 'new_page' => '', 'edit_page' => '', 'edit_language' => '', 'csh' => '', 'shortcut' => '', 'cache' => '', 'savedok' => '', 'save_close' => '', 'savedokshow' => '', 'closedok' => '', 'deletedok' => '', 'undo' => '', 'history_record' => ''); // View page $buttons['view'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($this->pageinfo['uid'], $GLOBALS['BACK_PATH'], BackendUtility::BEgetRootLine($this->pageinfo['uid']))) . '" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-view') . '</a>'; // Shortcut if ($this->getBackendUser()->mayMakeShortcut()) { $buttons['shortcut'] = $this->doc->makeShortcutIcon('id, edit_record, pointer, new_unique_uid, search_field, search_levels, showLimit', implode(',', array_keys($this->MOD_MENU)), $this->MCONF['name']); } // Cache if (!$this->modTSconfig['properties']['disableAdvanced']) { $buttons['cache'] = '<a href="' . htmlspecialchars(BackendUtility::getModuleUrl('web_layout', array('id' => $this->pageinfo['uid'], 'clear_cache' => '1'))) . '" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.clear_cache', TRUE) . '">' . IconUtility::getSpriteIcon('actions-system-cache-clear') . '</a>'; } if (!$this->modTSconfig['properties']['disableIconToolbar']) { // Move record if (MathUtility::canBeInterpretedAsInteger($this->eRParts[1])) { $urlParameters = ['table' => $this->eRParts[0], 'uid' => $this->eRParts[1], 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]; $buttons['move_record'] = '<a href="' . htmlspecialchars(BackendUtility::getModuleUrl('move_element', $urlParameters)) . '">' . IconUtility::getSpriteIcon('actions-' . ($this->eRParts[0] == 'tt_content' ? 'document' : 'page') . '-move', array('class' => 'c-inputButton', 'title' => $lang->getLL('move_' . ($this->eRParts[0] == 'tt_content' ? 'record' : 'page'), TRUE))) . '</a>'; } // Edit page properties and page language overlay icons if ($this->CALC_PERMS & Permission::PAGE_EDIT) { // Edit localized page_language_overlay only when one specific language is selected if ($this->MOD_SETTINGS['function'] == 1 && $this->current_sys_language > 0) { $overlayRecord = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid', 'pages_language_overlay', 'pid = ' . (int) $this->id . ' ' . 'AND sys_language_uid = ' . (int) $this->current_sys_language . BackendUtility::deleteClause('pages_language_overlay') . BackendUtility::versioningPlaceholderClause('pages_language_overlay'), '', '', '', 'sys_language_uid'); $editLanguageOnClick = htmlspecialchars(BackendUtility::editOnClick('&edit[pages_language_overlay][' . $overlayRecord['uid'] . ']=edit')); $buttons['edit_language'] = '<a href="#" ' . 'onclick="' . $editLanguageOnClick . '"' . 'title="' . $lang->getLL('editPageLanguageOverlayProperties', TRUE) . '">' . IconUtility::getSpriteIcon('mimetypes-x-content-page-language-overlay') . '</a>'; } // Edit page properties $editPageOnClick = htmlspecialchars(BackendUtility::editOnClick('&edit[pages][' . $this->id . ']=edit')); $buttons['edit_page'] = '<a href="#" ' . 'onclick="' . $editPageOnClick . '"' . 'title="' . $lang->getLL('editPageProperties', TRUE) . '">' . IconUtility::getSpriteIcon('actions-page-open') . '</a>'; } // Add CSH (Context Sensitive Help) icon to tool bar if ($function == 'quickEdit') { $buttons['csh'] = BackendUtility::cshItem($this->descrTable, 'quickEdit'); } else { $buttons['csh'] = BackendUtility::cshItem($this->descrTable, 'columns_' . $this->MOD_SETTINGS['function']); } if ($function == 'quickEdit') { // Save record $buttons['savedok'] = IconUtility::getSpriteIcon('actions-document-save', array('html' => '<input type="image" name="_savedok" class="c-inputButton" src="clear.gif" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', TRUE) . '" />')); // Save and close $buttons['save_close'] = IconUtility::getSpriteIcon('actions-document-save-close', array('html' => '<input type="image" class="c-inputButton" name="_saveandclosedok" src="clear.gif" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', TRUE) . '" />')); // Save record and show page $buttons['savedokshow'] = '<a href="#" onclick="' . htmlspecialchars('document.editform.redirect.value+=\'&popView=1\'; TBE_EDITOR.checkAndDoSubmit(1); return false;') . '" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDocShow', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-save-view') . '</a>'; // Close record $buttons['closedok'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(' . GeneralUtility::quoteJSvalue($this->closeUrl) . '); return false;') . '" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-close') . '</a>'; // Delete record if ($this->deleteButton) { $buttons['deletedok'] = '<a href="#" onclick="' . htmlspecialchars('return deleteRecord(' . GeneralUtility::quoteJSvalue($this->eRParts[0]) . ',' . GeneralUtility::quoteJSvalue($this->eRParts[1]) . ',' . GeneralUtility::quoteJSvalue(GeneralUtility::getIndpEnv('SCRIPT_NAME') . '?id=' . $this->id) . ');') . '" title="' . $lang->getLL('deleteItem', TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-delete') . '</a>'; } if ($this->undoButton) { // Undo button $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars('window.location.href=' . GeneralUtility::quoteJSvalue($GLOBALS['BACK_PATH'] . BackendUtility::getModuleUrl('record_history', array('element' => $this->eRParts[0] . ':' . $this->eRParts[1], 'revert' => 'ALL_FIELDS', 'sumUp' => -1, 'returnUrl' => $this->R_URI))) . '; return false;') . '" title="' . htmlspecialchars(sprintf($lang->getLL('undoLastChange'), BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $this->undoButtonR['tstamp'], $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))) . '">' . IconUtility::getSpriteIcon('actions-edit-undo') . '</a>'; // History button $buttons['history_record'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(' . GeneralUtility::quoteJSvalue($GLOBALS['BACK_PATH'] . BackendUtility::getModuleUrl('record_history', array('element' => $this->eRParts[0] . ':' . $this->eRParts[1], 'returnUrl' => $this->R_URI)) . '#latest') . ');return false;') . '" title="' . $lang->getLL('recordHistory', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-history-open') . '</a>'; } } } return $buttons; }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @return array All available buttons as an assoc. array */ protected function getButtons() { $lang = $this->getLanguageService(); $buttons = array('save' => '', 'save_view' => '', 'save_new' => '', 'save_close' => '', 'close' => '', 'delete' => '', 'undo' => '', 'history' => '', 'columns_only' => '', 'csh' => '', 'translation_save' => '', 'translation_saveclear' => ''); // Render SAVE type buttons: // The action of each button is decided by its name attribute. (See doProcessData()) if (!$this->errorC && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly']) { // SAVE button: $buttons['save'] = IconUtility::getSpriteIcon('actions-document-save', array('html' => '<input type="image" name="_savedok" class="c-inputButton" src="clear.gif" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', TRUE) . '" />')); // SAVE / VIEW button: if ($this->viewId && !$this->noView && $this->getNewIconMode($this->firstEl['table'], 'saveDocView')) { $buttons['save_view'] = IconUtility::getSpriteIcon('actions-document-save-view', array('html' => '<input onclick="window.open(\'\', \'newTYPO3frontendWindow\');" type="image" class="c-inputButton" name="_savedokview" src="clear.gif" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDocShow', TRUE) . '" />')); } // SAVE / NEW button: if (count($this->elementsData) === 1 && $this->getNewIconMode($this->firstEl['table'])) { $buttons['save_new'] = IconUtility::getSpriteIcon('actions-document-save-new', array('html' => '<input type="image" class="c-inputButton" name="_savedoknew" src="clear.gif" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveNewDoc', TRUE) . '" />')); } // SAVE / CLOSE $buttons['save_close'] = IconUtility::getSpriteIcon('actions-document-save-close', array('html' => '<input type="image" class="c-inputButton" name="_saveandclosedok" src="clear.gif" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', TRUE) . '" />')); // FINISH TRANSLATION / SAVE / CLOSE if ($GLOBALS['TYPO3_CONF_VARS']['BE']['explicitConfirmationOfTranslation']) { $buttons['translation_save'] = '<input type="image" class="c-inputButton" name="_translation_savedok" src="' . IconUtility::skinImg($this->doc->backPath, 'sysext/t3skin/images/icons/actions/document-save-translation.png', '', 1) . '" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.translationSaveDoc', TRUE) . '" /> '; $buttons['translation_saveclear'] = '<input type="image" class="c-inputButton" name="_translation_savedokclear" src="' . IconUtility::skinImg($this->doc->backPath, 'sysext/t3skin/images/icons/actions/document-save-cleartranslationcache.png', '', 1) . '" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.translationSaveDocClear', TRUE) . '" />'; } } // CLOSE button: $buttons['close'] = '<a href="#" class="t3js-editform-close" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-close') . '</a>'; // DELETE + UNDO buttons: if (!$this->errorC && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly'] && count($this->elementsData) === 1) { if ($this->firstEl['cmd'] != 'new' && MathUtility::canBeInterpretedAsInteger($this->firstEl['uid'])) { // Delete: if ($this->firstEl['deleteAccess'] && !$GLOBALS['TCA'][$this->firstEl['table']]['ctrl']['readOnly'] && !$this->getNewIconMode($this->firstEl['table'], 'disableDelete')) { $aOnClick = 'return deleteRecord(' . GeneralUtility::quoteJSvalue($this->firstEl['table']) . ',' . GeneralUtility::quoteJSvalue($this->firstEl['uid']) . ', ' . GeneralUtility::quoteJSvalue($this->retUrl) . ');'; $buttons['delete'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '" title="' . $lang->getLL('deleteItem', TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-delete') . '</a>'; } // Undo: $undoRes = $this->getDatabaseConnection()->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $this->getDatabaseConnection()->fullQuoteStr($this->firstEl['table'], 'sys_history') . ' AND recuid=' . (int) $this->firstEl['uid'], '', 'tstamp DESC', '1'); if ($undoButtonR = $this->getDatabaseConnection()->sql_fetch_assoc($undoRes)) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', array('element' => $this->firstEl['table'] . ':' . $this->firstEl['uid'], 'revert' => 'ALL_FIELDS', 'sumUp' => -1, 'returnUrl' => $this->R_URI))) . '; return false;'; $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"' . ' title="' . htmlspecialchars(sprintf($lang->getLL('undoLastChange'), BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))) . '">' . IconUtility::getSpriteIcon('actions-edit-undo') . '</a>'; } if ($this->getNewIconMode($this->firstEl['table'], 'showHistory')) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', array('element' => $this->firstEl['table'] . ':' . $this->firstEl['uid'], 'returnUrl' => $this->R_URI))) . '; return false;'; $buttons['history'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . IconUtility::getSpriteIcon('actions-document-history-open') . '</a>'; } // If only SOME fields are shown in the form, this will link the user to the FULL form: if ($this->columnsOnly) { $buttons['columns_only'] = '<a href="' . htmlspecialchars($this->R_URI . '&columnsOnly=') . '" title="' . $lang->getLL('editWholeRecord', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-open') . '</a>'; } } } // add the CSH icon $buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'TCEforms'); $buttons['shortcut'] = $this->shortCutLink(); $buttons['open_in_new_window'] = $this->openInNewWindowLink(); return $buttons; }
/** * Rendering the encode-cache content * * @param array The Page tree data * @return string HTML for the information table. */ public function encodeView(\TYPO3\CMS\Backend\Tree\View\PageTreeView $tree) { // Delete entries: $cmd = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('cmd'); $subcmd = ''; if ($cmd === 'deleteEC') { $subcmd = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('entry'); $this->clearDEncodeCache($subcmd); } // Traverse tree: $cc = 0; $countDisplayed = 0; $output = ''; $duplicates = array(); foreach ($tree->tree as $row) { // Select rows: $displayRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'tx_realurl_urlencodecache', 'page_id=' . intval($row['row']['uid']), '', 'content'); // Row title: $rowTitle = $row['HTML'] . \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordTitle('pages', $row['row'], true); // Add at least one empty element: if (!count($displayRows) || $subcmd === 'displayed') { // Add title: $tCells = array(); $tCells[] = '<td nowrap="nowrap">' . $rowTitle . '</td>'; $tCells[] = '<td nowrap="nowrap"> </td>'; // Empty row: $tCells[] = '<td colspan="7" align="center"> </td>'; // Compile Row: $output .= ' <tr class="bgColor' . ($cc % 2 ? '-20' : '-10') . '"> ' . implode(' ', $tCells) . ' </tr>'; $cc++; if ($subcmd === 'displayed') { foreach ($displayRows as $c => $inf) { $this->clearDEncodeCache('urlhash_' . $inf['url_hash']); } } } else { foreach ($displayRows as $c => $inf) { // Add icon/title and ID: $tCells = array(); if (!$c) { $tCells[] = '<td nowrap="nowrap" rowspan="' . count($displayRows) . '">' . $rowTitle . '</td>'; $tCells[] = '<td nowrap="nowrap" rowspan="' . count($displayRows) . '">' . $row['row']['uid'] . '</td>'; $tCells[] = '<td rowspan="' . count($displayRows) . '">' . '<a href="' . $this->linkSelf('&cmd=deleteEC&entry=page_' . intval($row['row']['uid'])) . '">' . $this->getIcon('gfx/garbage.gif', 'width="11" height="12"', $this->pObj->doc->backPath, 'Delete entries for page') . '</a>' . '</td>'; } // Get vars: $tCells[] = '<td>' . htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs($inf['origparams'], 100)) . '</td>'; // Internal Extras: $tCells[] = '<td>' . ($inf['internalExtras'] ? \TYPO3\CMS\Core\Utility\GeneralUtility::arrayToLogString(unserialize($inf['internalExtras'])) : ' ') . '</td>'; // Path: $tCells[] = '<td>' . htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs($inf['content'], 100)) . '</td>'; // Delete: $tCells[] = '<td>' . '<a href="' . $this->linkSelf('&cmd=deleteEC&entry=urlhash_' . rawurlencode($inf['url_hash'])) . '">' . $this->getIcon('gfx/garbage.gif', 'width="11" height="12"', $this->pObj->doc->backPath, 'Delete entry!') . '</a>' . '</td>'; // Error: $eMsg = $duplicates[$inf['content']] && $duplicates[$inf['content']] !== $row['row']['uid'] ? $this->pObj->doc->icons(2) . 'Already used on page ID ' . $duplicates[$inf['content']] . '<br/>' : ''; if (count($GLOBALS['TYPO3_DB']->exec_SELECTgetRows('url_hash', 'tx_realurl_redirects', 'url_hash=' . intval(\TYPO3\CMS\Core\Utility\GeneralUtility::md5int($inf['content']))))) { $eMsg .= $this->pObj->doc->icons(3) . 'Also a redirect!'; } $tCells[] = '<td>' . $eMsg . '</td>'; // Timestamp: $tCells[] = '<td>' . htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::datetime($inf['tstamp'])) . ' / ' . htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::calcAge(time() - $inf['tstamp'])) . '</td>'; // Compile Row: $output .= ' <tr class="bgColor' . ($cc % 2 ? '-20' : '-10') . '"> ' . implode(' ', $tCells) . ' </tr>'; $cc++; $countDisplayed++; if (!isset($duplicates[$inf['content']])) { $duplicates[$inf['content']] = $row['row']['uid']; } } } } list($count_allInTable) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('count(*) AS count', 'tx_realurl_urlencodecache', ''); // Create header: $tCells = array(); $tCells[] = '<td>Title:</td>'; $tCells[] = '<td>ID:</td>'; $tCells[] = '<td> </td>'; $tCells[] = '<td>Host | GET variables:</td>'; $tCells[] = '<td>Internal Extras:</td>'; $tCells[] = '<td>Path:</td>'; $tCells[] = '<td> </td>'; $tCells[] = '<td>Errors:</td>'; $tCells[] = '<td>Timestamp:</td>'; $output = ' <tr class="bgColor5 tableheader"> ' . implode(' ', $tCells) . ' </tr>' . $output; // Compile final table and return: $output = ' <br/> <br/> Displayed entries: <b>' . $countDisplayed . '</b> ' . '<a href="' . $this->linkSelf('&cmd=deleteEC&entry=displayed') . '">' . $this->getIcon('gfx/garbage.gif', 'width="11" height="12"', $this->pObj->doc->backPath, 'Delete displayed entries') . '</a>' . '<br/> Total entries in encode cache: <b>' . $count_allInTable['count'] . '</b> ' . '<a href="' . $this->linkSelf('&cmd=deleteEC&entry=all') . '">' . $this->getIcon('gfx/garbage.gif', 'width="11" height="12"', $this->pObj->doc->backPath, 'Delete WHOLE encode cache!') . '</a>' . '<br/> <table border="0" cellspacing="1" cellpadding="0" id="tx-realurl-pathcacheTable" class="lrPadding c-list">' . $output . ' </table>'; return $output; }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @param string $function Identifier for function of module * @return array all available buttons as an assoc. array */ protected function getButtons($function = '') { $buttons = array('view' => '', 'history_page' => '', 'new_content' => '', 'move_page' => '', 'move_record' => '', 'new_page' => '', 'edit_page' => '', 'csh' => '', 'shortcut' => '', 'cache' => '', 'savedok' => '', 'save_close' => '', 'savedokshow' => '', 'closedok' => '', 'deletedok' => '', 'undo' => '', 'history_record' => ''); // View page $buttons['view'] = '<a href="#" onclick="' . htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::viewOnClick($this->pageinfo['uid'], $GLOBALS['BACK_PATH'], \TYPO3\CMS\Backend\Utility\BackendUtility::BEgetRootLine($this->pageinfo['uid']))) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showPage', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-view') . '</a>'; // Shortcut if ($GLOBALS['BE_USER']->mayMakeShortcut()) { $buttons['shortcut'] = $this->doc->makeShortcutIcon('id, edit_record, pointer, new_unique_uid, search_field, search_levels, showLimit', implode(',', array_keys($this->MOD_MENU)), $this->MCONF['name']); } // Cache if (!$this->modTSconfig['properties']['disableAdvanced']) { $buttons['cache'] = '<a href="' . htmlspecialchars('db_layout.php?id=' . $this->pageinfo['uid'] . '&clear_cache=1') . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.clear_cache', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-system-cache-clear') . '</a>'; } if (!$this->modTSconfig['properties']['disableIconToolbar']) { // Move record if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->eRParts[1])) { $buttons['move_record'] = '<a href="' . htmlspecialchars($GLOBALS['BACK_PATH'] . 'move_el.php?table=' . $this->eRParts[0] . '&uid=' . $this->eRParts[1] . '&returnUrl=' . rawurlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REQUEST_URI'))) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-' . ($this->eRParts[0] == 'tt_content' ? 'document' : 'page') . '-move', array('class' => 'c-inputButton', 'title' => $GLOBALS['LANG']->getLL('move_' . ($this->eRParts[0] == 'tt_content' ? 'record' : 'page'), 1))) . '</a>'; } // Edit page properties if ($this->CALC_PERMS & 2) { $params = '&edit[pages][' . $this->id . ']=edit'; $buttons['edit_page'] = '<a href="#" onclick="' . htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::editOnClick($params, $GLOBALS['BACK_PATH'])) . '" title="' . $GLOBALS['LANG']->getLL('editPageProperties', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-page-open') . '</a>'; } // Add CSH (Context Sensitive Help) icon to tool bar if ($function == 'quickEdit') { $buttons['csh'] = \TYPO3\CMS\Backend\Utility\BackendUtility::cshItem($this->descrTable, 'quickEdit', $GLOBALS['BACK_PATH'], '', TRUE, 'margin-top: 0px; margin-bottom: 0px;'); } else { $buttons['csh'] = \TYPO3\CMS\Backend\Utility\BackendUtility::cshItem($this->descrTable, 'columns_' . $this->MOD_SETTINGS['function'], $GLOBALS['BACK_PATH'], '', TRUE, 'margin-top: 0px; margin-bottom: 0px;'); } if ($function == 'quickEdit') { // Save record $buttons['savedok'] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-save', array('html' => '<input type="image" name="_savedok" class="c-inputButton" src="clear.gif" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc', TRUE) . '" />')); // Save and close $buttons['save_close'] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-save-close', array('html' => '<input type="image" class="c-inputButton" name="_saveandclosedok" src="clear.gif" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc', 1) . '" />')); // Save record and show page $buttons['savedokshow'] = '<a href="#" onclick="' . htmlspecialchars('document.editform.redirect.value+=\'&popView=1\'; TBE_EDITOR.checkAndDoSubmit(1); return false;') . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDocShow', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-save-view') . '</a>'; // Close record $buttons['closedok'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(unescape(\'' . rawurlencode($this->closeUrl) . '\')); return false;') . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-close') . '</a>'; // Delete record if ($this->deleteButton) { $buttons['deletedok'] = '<a href="#" onclick="' . htmlspecialchars('return deleteRecord(\'' . $this->eRParts[0] . '\',\'' . $this->eRParts[1] . '\',\'' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('SCRIPT_NAME') . '?id=' . $this->id . '\');') . '" title="' . $GLOBALS['LANG']->getLL('deleteItem', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-delete') . '</a>'; } if ($this->undoButton) { // Undo button $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars('window.location.href=\'' . $GLOBALS['BACK_PATH'] . 'show_rechis.php?element=' . rawurlencode($this->eRParts[0] . ':' . $this->eRParts[1]) . '&revert=ALL_FIELDS&sumUp=-1&returnUrl=' . rawurlencode($this->R_URI) . '\'; return false;') . '" title="' . htmlspecialchars(sprintf($GLOBALS['LANG']->getLL('undoLastChange'), \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $this->undoButtonR['tstamp'], $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')))) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-undo') . '</a>'; // History button $buttons['history_record'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(\'' . $GLOBALS['BACK_PATH'] . 'show_rechis.php?element=' . rawurlencode($this->eRParts[0] . ':' . $this->eRParts[1]) . '&returnUrl=' . rawurlencode($this->R_URI) . '#latest\');return false;') . '" title="' . $GLOBALS['LANG']->getLL('recordHistory', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-history-open') . '</a>'; } } } return $buttons; }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @return array All available buttons as an assoc. array */ protected function getButtons() { $buttons = array('close' => '', 'save' => '', 'save_view' => '', 'save_close' => '', 'shortcut' => '', 'undo' => ''); if ($this->P['table'] && $this->P['field'] && $this->P['uid'] && $this->checkEditAccess($this->P['table'], $this->P['uid'])) { $closeUrl = \TYPO3\CMS\Core\Utility\GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']); // Getting settings for the undo button: $undoButton = 0; $undoRes = $GLOBALS['TYPO3_DB']->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->P['table'], 'sys_history') . ' AND recuid=' . intval($this->P['uid']), '', 'tstamp DESC', '1'); if ($undoButtonR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($undoRes)) { $undoButton = 1; } // Close $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(unescape(\'' . rawurlencode($closeUrl) . '\')); return false;') . '">' . '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->doc->backPath, 'gfx/closedok.gif') . ' class="c-inputButton" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc', 1) . '" alt="" />' . '</a>'; // Save $buttons['save'] = '<a href="#" onclick="TBE_EDITOR.checkAndDoSubmit(1); return false;">' . '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->doc->backPath, 'gfx/savedok.gif') . ' class="c-inputButton" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc', 1) . '" alt="" />' . '</a>'; // Save & View if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('cms')) { $buttons['save_view'] = '<a href="#" onclick="' . htmlspecialchars('document.editform.redirect.value+=\'&popView=1\'; TBE_EDITOR.checkAndDoSubmit(1); return false;') . '">' . '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->doc->backPath, 'gfx/savedokshow.gif') . ' class="c-inputButton" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDocShow', 1) . '" alt="" />' . '</a>'; } // Save & Close $buttons['save_close'] = '<input type="image" class="c-inputButton" onclick="' . htmlspecialchars('document.editform.redirect.value=\'' . $closeUrl . '\'; TBE_EDITOR.checkAndDoSubmit(1); return false;') . '" name="_saveandclosedok"' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->doc->backPath, 'gfx/saveandclosedok.gif', '') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc', 1) . '" />'; // Undo/Revert: if ($undoButton) { $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars('window.location.href=\'show_rechis.php?element=' . rawurlencode($this->P['table'] . ':' . $this->P['uid']) . '&revert=' . rawurlencode('field:' . $this->P['field']) . '&sumUp=-1&returnUrl=' . rawurlencode($this->R_URI) . '\'; return false;') . '">' . '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->doc->backPath, 'gfx/undo.gif') . ' class="c-inputButton" title="' . htmlspecialchars(sprintf($GLOBALS['LANG']->getLL('rte_undoLastChange'), \TYPO3\CMS\Backend\Utility\BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')))) . '" alt="" />' . '</a>'; } // Shortcut if ($GLOBALS['BE_USER']->mayMakeShortcut()) { $buttons['shortcut'] = $this->doc->makeShortcutIcon('P', '', $this->MCONF['name'], 1); } } return $buttons; }
/** * Returns the record title for input fields * * @param mixed $value Current database value of this field * @param array $fieldConfig TCA field configuration * @return string */ protected function getRecordTitleForInputType($value, $fieldConfig) { if (!isset($value)) { return ''; } $title = $value; if (GeneralUtility::inList($fieldConfig['eval'], 'date')) { if (isset($fieldConfig['dbType']) && $fieldConfig['dbType'] === 'date') { $value = $value === '0000-00-00' ? 0 : (int) strtotime($value); } else { $value = (int) $value; } if (!empty($value)) { $ageSuffix = ''; // Generate age suffix as long as not explicitly suppressed if (!isset($fieldConfig['disableAgeDisplay']) || (bool) $fieldConfig['disableAgeDisplay'] === false) { $ageDelta = $GLOBALS['EXEC_TIME'] - $value; $calculatedAge = BackendUtility::calcAge(abs($ageDelta), $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')); $ageSuffix = ' (' . ($ageDelta > 0 ? '-' : '') . $calculatedAge . ')'; } $title = BackendUtility::date($value) . $ageSuffix; } } elseif (GeneralUtility::inList($fieldConfig['eval'], 'time')) { if (!empty($value)) { $title = BackendUtility::time((int) $value, false); } } elseif (GeneralUtility::inList($fieldConfig['eval'], 'timesec')) { if (!empty($value)) { $title = BackendUtility::time((int) $value); } } elseif (GeneralUtility::inList($fieldConfig['eval'], 'datetime')) { // Handle native date/time field if (isset($fieldConfig['dbType']) && $fieldConfig['dbType'] === 'datetime') { $value = $value === '0000-00-00 00:00:00' ? 0 : (int) strtotime($value); } else { $value = (int) $value; } if (!empty($value)) { $title = BackendUtility::datetime($value); } } return $title; }
/** * Shows the full change log * * @return string HTML for list, wrapped in a table. * @todo Define visibility */ public function displayHistory() { $lines = array(); // Initialize: $lines[] = '<thead><tr> <th> </th> <th>' . $GLOBALS['LANG']->getLL('time', 1) . '</th> <th>' . $GLOBALS['LANG']->getLL('age', 1) . '</th> <th>' . $GLOBALS['LANG']->getLL('user', 1) . '</th> <th>' . $GLOBALS['LANG']->getLL('tableUid', 1) . '</th> <th>' . $GLOBALS['LANG']->getLL('differences', 1) . '</th> <th> </th> </tr></thead>'; $be_user_array = BackendUtility::getUserNames(); // Traverse changelog array: if (!$this->changeLog) { return 0; } $i = 0; foreach ($this->changeLog as $sysLogUid => $entry) { // stop after maxSteps if ($i > $this->maxSteps && $this->maxSteps) { break; } // Show only marked states if (!$entry['snapshot'] && $this->showMarked) { continue; } $i++; // Get user names $userName = $entry['user'] ? $be_user_array[$entry['user']]['username'] : $GLOBALS['LANG']->getLL('externalChange', 1); // Build up single line $singleLine = array(); // Diff link $image = IconUtility::getSpriteIcon('actions-view-go-forward', array('title' => $GLOBALS['LANG']->getLL('sumUpChanges', TRUE))); $singleLine[] = '<span>' . $this->linkPage($image, array('diff' => $sysLogUid)) . '</span>'; // remove first link $singleLine[] = htmlspecialchars(BackendUtility::datetime($entry['tstamp'])); // add time $singleLine[] = htmlspecialchars(BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $entry['tstamp'], $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears'))); // add age $singleLine[] = htmlspecialchars($userName); // add user name $singleLine[] = $this->linkPage($this->generateTitle($entry['tablename'], $entry['recuid']), array('element' => $entry['tablename'] . ':' . $entry['recuid']), '', $GLOBALS['LANG']->getLL('linkRecordHistory', 1)); // add record UID // Show insert/delete/diff/changed field names if ($entry['action']) { // insert or delete of element $singleLine[] = '<strong>' . htmlspecialchars($GLOBALS['LANG']->getLL($entry['action'], 1)) . '</strong>'; } else { // Display field names instead of full diff if (!$this->showDiff) { // Re-write field names with labels $tmpFieldList = explode(',', $entry['fieldlist']); foreach ($tmpFieldList as $key => $value) { $tmp = str_replace(':', '', $GLOBALS['LANG']->sl(BackendUtility::getItemLabel($entry['tablename'], $value), 1)); if ($tmp) { $tmpFieldList[$key] = $tmp; } else { // remove fields if no label available unset($tmpFieldList[$key]); } } $singleLine[] = htmlspecialchars(implode(',', $tmpFieldList)); } else { // Display diff $diff = $this->renderDiff($entry, $entry['tablename']); $singleLine[] = $diff; } } // Show link to mark/unmark state if (!$entry['action']) { if ($entry['snapshot']) { $image = IconUtility::getSpriteIcon('actions-unmarkstate', array('title' => $GLOBALS['LANG']->getLL('unmarkState', TRUE)), array()); } else { $image = IconUtility::getSpriteIcon('actions-markstate', array('title' => $GLOBALS['LANG']->getLL('markState', TRUE)), array()); } $singleLine[] = $this->linkPage($image, array('highlight' => $entry['uid'])); } else { $singleLine[] = ''; } // put line together $lines[] = ' <tr> <td>' . implode('</td><td>', $singleLine) . '</td> </tr>'; } // Finally, put it all together: $theCode = ' <!-- History (list): --> <table class="t3-table" id="typo3-history"> ' . implode('', $lines) . ' </table>'; if ($this->lastSyslogId) { $theCode .= '<br />' . $this->linkPage(IconUtility::getSpriteIcon('actions-move-to-bottom', array('title' => $GLOBALS['LANG']->getLL('fullView', TRUE))), array('diff' => '')); } // Add message about the difference view. $flashMessage = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage', $GLOBALS['LANG']->getLL('differenceMsg'), '', \TYPO3\CMS\Core\Messaging\FlashMessage::INFO); $theCode .= '<br /><br />' . $flashMessage->render() . '<br />'; // Add the whole content as a module section: return $GLOBALS['SOBE']->doc->section($GLOBALS['LANG']->getLL('changes'), $theCode, FALSE, TRUE); }
/** * Create the panel of buttons for submitting the form or otherwise perform operations. * * @return array All available buttons as an assoc. array */ protected function getButtons() { $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); if ($this->P['table'] && $this->P['field'] && $this->P['uid'] && $this->checkEditAccess($this->P['table'], $this->P['uid'])) { $closeUrl = GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']); // Getting settings for the undo button: $undoButton = false; $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_history'); $undoButtonR = $queryBuilder->select('tstamp')->from('sys_history')->where($queryBuilder->expr()->eq('tablename', $queryBuilder->createNamedParameter($this->P['table'], \PDO::PARAM_STR)), $queryBuilder->expr()->eq('recuid', $queryBuilder->createNamedParameter($this->P['uid'], \PDO::PARAM_INT)))->orderBy('tstamp', 'desc')->setMaxResults(1)->execute()->fetchColumn(); if ($undoButtonR !== false) { $undoButton = true; } // Close $closeButton = $buttonBar->makeLinkButton()->setHref($closeUrl)->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL)); $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 10); // Save $saveButton = $buttonBar->makeInputButton()->setName('_savedok_x')->setValue('1')->setForm('RteController')->setOnClick('TBE_EDITOR.checkAndDoSubmit(1); return false;')->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL)); // Save & View $saveAndViewButton = $buttonBar->makeInputButton()->setName('_savedokview_x')->setValue('1')->setForm('RteController')->setOnClick('document.editform.redirect.value+= ' . GeneralUtility::quoteJSvalue('&popView=1') . '; ' . ' TBE_EDITOR.checkAndDoSubmit(1); return false;')->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDocShow'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-view', Icon::SIZE_SMALL)); // Save & Close $saveAndCloseButton = $buttonBar->makeInputButton()->setName('_saveandclosedok_x')->setValue('1')->setForm('RteController')->setOnClick('document.editform.redirect.value=' . GeneralUtility::quoteJSvalue($closeUrl) . '; TBE_EDITOR.checkAndDoSubmit(1); return false;')->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveCloseDoc'))->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL)); // Save SplitButton $saveSplitButton = $buttonBar->makeSplitButton()->addItem($saveButton)->addItem($saveAndViewButton)->addItem($saveAndCloseButton); $buttonBar->addButton($saveSplitButton, ButtonBar::BUTTON_POSITION_LEFT, 20); // Undo/Revert: if ($undoButton) { $aOnClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('record_history', ['element' => $this->P['table'] . ':' . $this->P['uid'], 'revert' => 'field:' . $this->P['field'], 'returnUrl' => $this->R_URI])) . '; return false;'; $undoText = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_wizards.xlf:rte_undoLastChange'); $lastChangeLabel = sprintf($undoText, BackendUtility::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears'))); $undoRevertButton = $buttonBar->makeLinkButton()->setHref('#')->setOnClick($aOnClick)->setTitle($lastChangeLabel)->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-edit-undo', Icon::SIZE_SMALL)); $buttonBar->addButton($undoRevertButton, ButtonBar::BUTTON_POSITION_LEFT, 30); } // Shortcut $shortButton = $buttonBar->makeShortcutButton()->setModuleName($this->MCONF['name'])->setGetVariables(['P']); $buttonBar->addButton($shortButton); } }