/** * Returns true, if ext_update class says it wants to run. * * @param string $extensionKey extension key * @return mixed NULL, if update is not available, else update script return */ public function executeUpdateIfNeeded($extensionKey) { $this->requireUpdateScript($extensionKey); $scriptObject = new \ext_update(); // old em always assumed the method exist, we do so too. // @TODO: Make this smart, let scripts implement interfaces // @TODO: Enforce different update class script names per extension // @TODO: With different class names it would be easily possible to check for updates in list view. $accessReturnValue = $scriptObject->access(); $result = NULL; if ($accessReturnValue === TRUE) { // @TODO: With current ext_update construct it is impossible // @TODO: to enforce some type of return $result = $scriptObject->main(); } return $result; }
/** * Display extensions details. * * @param string Extension key * @return void Writes content to $this->content */ function showExtDetails($extKey) { global $TYPO3_LOADED_EXT; list($list, ) = $this->extensionList->getInstalledExtensions(); $absPath = tx_em_Tools::getExtPath($extKey, $list[$extKey]['type']); // Check updateModule: if (isset($list[$extKey]) && @is_file($absPath . 'class.ext_update.php')) { require_once $absPath . 'class.ext_update.php'; $updateObj = new ext_update(); if (!$updateObj->access()) { unset($this->MOD_MENU['singleDetails']['updateModule']); } } else { unset($this->MOD_MENU['singleDetails']['updateModule']); } if ($this->CMD['doDelete']) { $this->MOD_MENU['singleDetails'] = array(); } // Function menu here: if (!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone')) { $content = $GLOBALS['LANG']->getLL('ext_details_ext') . ' <strong>' . $this->extensionTitleIconHeader($extKey, $list[$extKey]) . '</strong> (' . htmlspecialchars($extKey) . ')'; $this->content .= $this->doc->section('', $content); } // Show extension details: if ($list[$extKey]) { // Checking if a command for install/uninstall is executed: if (($this->CMD['remove'] || $this->CMD['load']) && !in_array($extKey, $this->requiredExt)) { // Install / Uninstall extension here: if (t3lib_extMgm::isLocalconfWritable()) { // Check dependencies: $depStatus = $this->install->checkDependencies($extKey, $list[$extKey]['EM_CONF'], $list); if (!$this->CMD['remove'] && !$depStatus['returnCode']) { $this->content .= $depStatus['html']; $newExtList = -1; } elseif ($this->CMD['remove']) { $newExtList = $this->extensionList->removeExtFromList($extKey, $list); } else { $newExtList = $this->extensionList->addExtToList($extKey, $list); } // Successful installation: if ($newExtList != -1) { $updates = ''; if ($this->CMD['load']) { if ($_SERVER['REQUEST_METHOD'] == 'POST') { $script = t3lib_div::linkThisScript(array('CMD[showExt]' => $extKey, 'CMD[load]' => 1, 'CMD[clrCmd]' => $this->CMD['clrCmd'], 'SET[singleDetails]' => 'info')); } else { $script = ''; } $standaloneUpdates = ''; if ($this->CMD['standAlone']) { $standaloneUpdates .= '<input type="hidden" name="standAlone" value="1" />'; } if ($this->CMD['silendMode']) { $standaloneUpdates .= '<input type="hidden" name="silendMode" value="1" />'; } $depsolver = t3lib_div::_POST('depsolver'); if (is_array($depsolver['ignore'])) { foreach ($depsolver['ignore'] as $depK => $depV) { $dependencyUpdates .= '<input type="hidden" name="depsolver[ignore][' . $depK . ']" value="1" />'; } } $updatesForm = $this->install->updatesForm($extKey, $list[$extKey], 1, $script, $dependencyUpdates . $standaloneUpdates . '<input type="hidden" name="_do_install" value="1" /><input type="hidden" name="_clrCmd" value="' . $this->CMD['clrCmd'] . '" />', TRUE); if ($updatesForm) { $updates = $GLOBALS['LANG']->getLL('ext_details_new_tables_fields') . '<br />' . $GLOBALS['LANG']->getLL('ext_details_new_tables_fields_select') . $updatesForm; $labelDBUpdate = $GLOBALS['LANG']->csConvObj->conv_case($GLOBALS['LANG']->charSet, $GLOBALS['LANG']->getLL('ext_details_db_needs_update'), 'toUpper'); $this->content .= $this->doc->section(sprintf($GLOBALS['LANG']->getLL('ext_details_installing') . ' ', $this->extensionTitleIconHeader($extKey, $list[$extKey])) . ' ' . $labelDBUpdate, $updates, 1, 1, 1, 1); } } elseif ($this->CMD['remove']) { $updates .= $this->install->checkClearCache($list[$extKey]); if ($updates) { $updates = ' <form action="' . $this->script . '" method="post">' . $updates . ' <br /><input type="submit" name="write" value="' . $GLOBALS['LANG']->getLL('ext_details_remove_ext') . '" /> <input type="hidden" name="_do_install" value="1" /> <input type="hidden" name="_clrCmd" value="' . $this->CMD['clrCmd'] . '" /> <input type="hidden" name="CMD[showExt]" value="' . $this->CMD['showExt'] . '" /> <input type="hidden" name="CMD[remove]" value="' . $this->CMD['remove'] . '" /> <input type="hidden" name="standAlone" value="' . $this->CMD['standAlone'] . '" /> <input type="hidden" name="silentMode" value="' . $this->CMD['silentMode'] . '" /> ' . ($this->noDocHeader ? '<input type="hidden" name="nodoc" value="1" />' : '') . ' </form>'; $labelDBUpdate = $GLOBALS['LANG']->csConvObj->conv_case($GLOBALS['LANG']->charSet, $GLOBALS['LANG']->getLL('ext_details_db_needs_update'), 'toUpper'); $this->content .= $this->doc->section(sprintf($GLOBALS['LANG']->getLL('ext_details_removing') . ' ', $this->extensionTitleIconHeader($extKey, $list[$extKey])) . ' ' . $labelDBUpdate, $updates, 1, 1, 1, 1); } } if (!$updates || t3lib_div::_GP('_do_install') || $this->noDocHeader && $this->CMD['remove']) { $this->install->writeNewExtensionList($newExtList); $action = $this->CMD['load'] ? 'installed' : 'removed'; $GLOBALS['BE_USER']->writelog(5, 1, 0, 0, 'Extension list has been changed, extension %s has been %s', array($extKey, $action)); if (!t3lib_div::_GP('silentMode') && !$this->CMD['standAlone']) { $messageLabel = 'ext_details_ext_' . $action . '_with_key'; $flashMessage = t3lib_div::makeInstance('t3lib_FlashMessage', sprintf($GLOBALS['LANG']->getLL($messageLabel), $extKey), '', t3lib_FlashMessage::OK, TRUE); t3lib_FlashMessageQueue::addMessage($flashMessage); } if ($this->CMD['clrCmd'] || t3lib_div::_GP('_clrCmd')) { if ($this->CMD['load'] && @is_file($absPath . 'ext_conf_template.txt')) { $vA = array('CMD' => array('showExt' => $extKey)); } else { $vA = array('CMD' => ''); } } else { $vA = array('CMD' => array('showExt' => $extKey)); } if ($this->CMD['standAlone'] || t3lib_div::_GP('standAlone')) { $this->content .= sprintf($GLOBALS['LANG']->getLL('ext_details_ext_installed_removed'), $this->CMD['load'] ? $GLOBALS['LANG']->getLL('ext_details_installed') : $GLOBALS['LANG']->getLL('ext_details_removed')) . '<br /><br />' . $this->getSubmitAndOpenerCloseLink(); } else { // Determine if new modules were installed: $techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $list[$extKey]); if (($this->CMD['load'] || $this->CMD['remove']) && is_array($techInfo['flags']) && in_array('Module', $techInfo['flags'], true)) { $vA['CMD']['refreshMenu'] = 1; } t3lib_utility_Http::redirect(t3lib_div::linkThisScript($vA)); exit; } } } } else { $writeAccessError = $GLOBALS['LANG']->csConvObj->conv_case($GLOBALS['LANG']->charSet, $GLOBALS['LANG']->getLL('ext_details_write_access_error'), 'toUpper'); $this->content .= $this->doc->section(sprintf($GLOBALS['LANG']->getLL('ext_details_installing') . ' ', $this->extensionTitleIconHeader($extKey, $list[$extKey])) . ' ' . $writeAccessError, $GLOBALS['LANG']->getLL('ext_details_write_error_localconf'), 1, 1, 2, 1); } } elseif ($this->CMD['downloadFile'] && !in_array($extKey, $this->requiredExt)) { // Link for downloading extension has been clicked - deliver content stream: $dlFile = $this->CMD['downloadFile']; if (t3lib_div::isAllowedAbsPath($dlFile) && t3lib_div::isFirstPartOfStr($dlFile, PATH_site) && t3lib_div::isFirstPartOfStr($dlFile, $absPath) && @is_file($dlFile)) { $mimeType = 'application/octet-stream'; Header('Content-Type: ' . $mimeType); Header('Content-Disposition: attachment; filename=' . basename($dlFile)); echo t3lib_div::getUrl($dlFile); exit; } else { throw new RuntimeException('TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('ext_details_error_downloading'), 1270853980); } } elseif ($this->CMD['editFile'] && !in_array($extKey, $this->requiredExt)) { // Editing extension file: $editFile = rawurldecode($this->CMD['editFile']); if (t3lib_div::isAllowedAbsPath($editFile) && t3lib_div::isFirstPartOfStr($editFile, $absPath)) { $fI = t3lib_div::split_fileref($editFile); if (@is_file($editFile) && t3lib_div::inList($this->editTextExtensions, $fI['fileext'] ? $fI['fileext'] : $fI['filebody'])) { if (filesize($editFile) < $this->kbMax * 1024) { $outCode = '<form action="' . $this->script . ' method="post" name="editfileform">'; $info = ''; $submittedContent = t3lib_div::_POST('edit'); $saveFlag = 0; if (isset($submittedContent['file']) && !$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) { // Check referer here? $oldFileContent = t3lib_div::getUrl($editFile); if ($oldFileContent != $submittedContent['file']) { $oldMD5 = md5(str_replace(CR, '', $oldFileContent)); $info .= sprintf($GLOBALS['LANG']->getLL('ext_details_md5_previous'), '<strong>' . $oldMD5 . '</strong>') . '<br />'; t3lib_div::writeFile($editFile, $submittedContent['file']); $saveFlag = 1; } else { $info .= $GLOBALS['LANG']->getLL('ext_details_no_changes') . '<br />'; } } $fileContent = t3lib_div::getUrl($editFile); $outCode .= sprintf($GLOBALS['LANG']->getLL('ext_details_file'), '<strong>' . substr($editFile, strlen($absPath)) . '</strong> (' . t3lib_div::formatSize(filesize($editFile)) . ')<br />'); $fileMD5 = md5(str_replace(CR, '', $fileContent)); $info .= sprintf($GLOBALS['LANG']->getLL('ext_details_md5_current'), '<strong>' . $fileMD5 . '</strong>') . '<br />'; if ($saveFlag) { $saveMD5 = md5(str_replace(CR, '', $submittedContent['file'])); $info .= sprintf($GLOBALS['LANG']->getLL('ext_details_md5_submitted'), '<strong>' . $saveMD5 . '</strong>') . '<br />'; if ($fileMD5 != $saveMD5) { $info .= tx_em_Tools::rfw('<br /><strong>' . $GLOBALS['LANG']->getLL('ext_details_saving_failed_changes_lost') . '</strong>') . '<br />'; } else { $info .= tx_em_Tools::rfw('<br /><strong>' . $GLOBALS['LANG']->getLL('ext_details_file_saved') . '</strong>') . '<br />'; } } $outCode .= '<textarea name="edit[file]" rows="35" wrap="off"' . $this->doc->formWidthText(48, 'width:98%;height:70%', 'off') . ' class="fixed-font enable-tab">' . t3lib_div::formatForTextarea($fileContent) . '</textarea>'; $outCode .= '<input type="hidden" name="edit[filename]" value="' . $editFile . '" />'; $outCode .= '<input type="hidden" name="CMD[editFile]" value="' . htmlspecialchars($editFile) . '" />'; $outCode .= '<input type="hidden" name="CMD[showExt]" value="' . $extKey . '" />'; $outCode .= $info; if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) { $outCode .= '<br /><input type="submit" name="save_file" value="' . $GLOBALS['LANG']->getLL('ext_details_file_save_button') . '" />'; } else { $outCode .= tx_em_Tools::rfw('<br />' . $GLOBALS['LANG']->getLL('ext_details_saving_disabled') . ' '); } $onClick = 'window.location.href="' . t3lib_div::linkThisScript(array('CMD[showExt]' => $extKey)) . '";return false;'; $outCode .= '<input type="submit" name="cancel" value="' . $GLOBALS['LANG']->getLL('ext_details_cancel_button') . '" onclick="' . htmlspecialchars($onClick) . '" /></form>'; $theOutput .= $this->doc->spacer(15); $theOutput .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_edit_file'), '', 0, 1); $theOutput .= $this->doc->sectionEnd() . $outCode; $this->content .= $theOutput; } else { $theOutput .= $this->doc->spacer(15); $theOutput .= $this->doc->section(sprintf($GLOBALS['LANG']->getLL('ext_details_filesize_exceeded_kb'), $this->kbMax), sprintf($GLOBALS['LANG']->getLL('ext_details_file_too_large'), $this->kbMax)); } } } else { die(sprintf($GLOBALS['LANG']->getLL('ext_details_fatal_edit_error'), htmlspecialchars($editFile))); } } else { // MAIN: switch ((string) $this->MOD_SETTINGS['singleDetails']) { case 'info': // Loaded / Not loaded: if (!in_array($extKey, $this->requiredExt)) { if ($TYPO3_LOADED_EXT[$extKey]) { $content = '<strong>' . $GLOBALS['LANG']->getLL('ext_details_loaded_and_running') . '</strong><br />' . '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array('CMD[showExt]' => $extKey, 'CMD[remove]' => 1))) . '">' . $GLOBALS['LANG']->getLL('ext_details_remove_button') . ' ' . tx_em_Tools::removeButton() . '</a>'; } else { $content = $GLOBALS['LANG']->getLL('ext_details_not_loaded') . '<br />' . '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array('CMD[showExt]' => $extKey, 'CMD[load]' => 1))) . '">' . $GLOBALS['LANG']->getLL('ext_details_install_button') . ' ' . tx_em_Tools::installButton() . '</a>'; } } else { $content = $GLOBALS['LANG']->getLL('ext_details_always_loaded'); } $this->content .= $this->doc->spacer(10); $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_current_status'), $content, 0, 1); if (t3lib_extMgm::isLoaded($extKey)) { $updates = $this->install->updatesForm($extKey, $list[$extKey]); if ($updates) { $this->content .= $this->doc->spacer(10); $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_update_needed'), $updates . '<br /><br />' . $GLOBALS['LANG']->getLL('ext_details_notice_static_data'), 0, 1); } } // Config: if (@is_file($absPath . 'ext_conf_template.txt')) { $this->content .= $this->doc->spacer(10); $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_configuration'), $GLOBALS['LANG']->getLL('ext_details_notice_clear_cache') . '<br /><br />', 0, 1); $this->content .= $this->install->tsStyleConfigForm($extKey, $list[$extKey]); } // Show details: $headline = $GLOBALS['LANG']->getLL('ext_details_details'); $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'info', $headline); $content = $this->extensionDetails->extInformationarray($extKey, $list[$extKey]); $this->content .= $this->doc->spacer(10); $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE); break; case 'upload': $em = t3lib_div::_POST('em'); if ($em['action'] == 'doUpload') { $em['extKey'] = $extKey; $em['extInfo'] = $list[$extKey]; $content = $this->extensionDetails->uploadExtensionToTER($em); $content .= $this->doc->spacer(10); // Must reload this, because EM_CONF information has been updated! list($list, ) = $this->extensionList->getInstalledExtensions(); } else { // headline and CSH $headline = $GLOBALS['LANG']->getLL('ext_details_upload_to_ter'); $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'upload', $headline); // Upload: if (substr($extKey, 0, 5) != 'user_') { $content = $this->getRepositoryUploadForm($extKey, $list[$extKey]); $eC = 0; } else { $content = $GLOBALS['LANG']->getLL('ext_details_no_unique_ext'); $eC = 2; } if (!$this->fe_user['username']) { $flashMessage = t3lib_div::makeInstance('t3lib_FlashMessage', sprintf($GLOBALS['LANG']->getLL('ext_details_no_username'), '<a href="' . t3lib_div::linkThisScript(array('SET[function]' => 3)) . '">', '</a>'), '', t3lib_FlashMessage::INFO); $content .= '<br />' . $flashMessage->render(); } } $this->content .= $this->doc->section($headline, $content, 0, 1, $eC, TRUE); break; case 'backup': if ($this->CMD['doDelete']) { $content = $this->install->extDelete($extKey, $list[$extKey], $this->CMD); $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_delete'), $GLOBALS['LANG']->getLL('ext_details_delete'), $content, 0, 1); } else { // headline and CSH $headline = $GLOBALS['LANG']->getLL('ext_details_backup'); $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'backup_delete', $headline); $content = $this->extBackup($extKey, $list[$extKey]); $this->content .= $this->doc->section($headline, $content, 0, 1, 0, 1); $content = $this->install->extDelete($extKey, $list[$extKey], $this->CMD); $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_delete'), $content, 0, 1); $content = $this->extUpdateEMCONF($extKey, $list[$extKey]); $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_update_em_conf'), $content, 0, 1); } break; case 'dump': $this->extDumpTables($extKey, $list[$extKey]); break; case 'edit': // headline and CSH $headline = $GLOBALS['LANG']->getLL('ext_details_ext_files'); $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'editfiles', $headline); $content = $this->getFileListOfExtension($extKey, $list[$extKey]); $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE); break; case 'updateModule': $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_update'), is_object($updateObj) ? $updateObj->main() : $GLOBALS['LANG']->getLL('ext_details_no_update_object'), 0, 1); break; default: $this->extObjContent(); break; } } } }
/** * Execute update script * * @param $extkey * @return array */ public function getExtensionUpdateScript($extkey) { $updateScript = t3lib_extMgm::extPath($extkey) . 'class.ext_update.php'; require_once $updateScript; $updateObj = new ext_update(); $access = FALSE; if ($updateObj->access()) { $access = TRUE; } return array('success' => $access); }