/** * The function that gets extension metadata manager for Upload Extensions. */ public static function get_manager() { objects::$md_manager = new \phpbb\extension\metadata_manager(objects::$upload_ext_name, objects::$config, objects::$phpbb_extension_manager, objects::$template, objects::$user, objects::$phpbb_root_path); try { $metadata = objects::$md_manager->get_metadata('all'); } catch (\phpbb\extension\exception $e) { files::catch_errors($e); } $upload_extensions_download = false; try { $updates_available = extensions::version_check(objects::$md_manager, objects::$request->variable('versioncheck_force', false)); objects::$template->assign_vars(array('UPLOAD_EXT_NEW_UPDATE' => !empty($updates_available), 'S_UPLOAD_UP_TO_DATE' => empty($updates_available), 'S_UPLOAD_VERSIONCHECK' => true, 'UPLOAD_UP_TO_DATE_MSG' => objects::$user->lang(empty($updates_available) ? 'UP_TO_DATE' : 'NOT_UP_TO_DATE', objects::$md_manager->get_metadata('display-name')))); foreach ($updates_available as $branch => $version_data) { objects::$template->assign_block_vars('upload_updates_available', $version_data); $upload_extensions_download = $version_data['download']; } } catch (\RuntimeException $e) { objects::$template->assign_vars(array('S_UPLOAD_VERSIONCHECK_STATUS' => $e->getCode(), 'UPLOAD_VERSIONCHECK_FAIL_REASON' => $e->getMessage() !== objects::$user->lang('VERSIONCHECK_FAIL') ? $e->getMessage() : '')); } objects::$self_update = $upload_extensions_download; }
/** * Gets missing language directories for an extension from a specified zip file. * @param string $ext_name The name of the extension. * @param string $zip_file The name of zip file. * @return null|bool */ public static function restore_languages($ext_name, $zip_file) { $ext_tmp = objects::$phpbb_root_path . 'ext/' . objects::$upload_ext_name . '/tmp/' . (int) objects::$user->data['user_id']; // Ensure that we don't have any previous files in the working directory. if (is_dir($ext_tmp)) { if (!files::catch_errors(files::rrmdir($ext_tmp))) { files::catch_errors(objects::$user->lang['ERROR_DIRECTORIES_NOT_RESTORED']); return false; } } if (!class_exists('\\compress_zip')) { include objects::$phpbb_root_path . 'includes/functions_compress.' . objects::$phpEx; } $zip = new \compress_zip('r', objects::$zip_dir . '/' . $zip_file); $zip->extract($ext_tmp . '/'); $zip->close(); $composery = files::getComposer($ext_tmp); if (!$composery) { files::catch_errors(files::rrmdir($ext_tmp)); files::catch_errors(objects::$user->lang['ERROR_ZIP_NO_COMPOSER']); files::catch_errors(objects::$user->lang['ERROR_DIRECTORIES_NOT_RESTORED']); return false; } $source = substr($composery, 0, -14); // Check languages missing in the new version. $ext_path = objects::$phpbb_root_path . 'ext/' . $ext_name; $old_langs = files::get_languages($source . '/language'); $new_langs = files::get_languages($ext_path . '/language'); $old_langs = array_diff($old_langs, $new_langs); if (sizeof($old_langs)) { foreach ($old_langs as $lang) { files::catch_errors(files::rcopy($source . '/language/' . $lang, $ext_path . '/language/' . $lang)); } objects::$template->assign_var('EXT_LANGUAGES_RESTORED', true); } files::catch_errors(files::rrmdir($ext_tmp)); }
/** * The function that uploads the specified language package for the extension. * * @param string $action Requested action. * @param string $ext_name The name of the extension. * @param string $lang_name The ISO code of the language. * @return bool */ public function upload_lang($action, $ext_name, $lang_name) { global $phpbb_root_path, $phpEx, $user; if (empty($ext_name)) { files::catch_errors(objects::$user->lang('ERROR_LANGUAGE_NO_EXTENSION')); return false; } if (empty($lang_name)) { files::catch_errors(objects::$user->lang('ERROR_LANGUAGE_NOT_DEFINED')); return false; } $file = $this->proceed_upload($action); if (!$file) { return false; } $dest_file = $this->get_dest_file($action, $file, objects::$zip_dir); if (!$dest_file) { return false; } // We need to use the user ID and the time to escape from problems with simultaneous uploads. // We suppose that one user can upload only one extension per session. $ext_tmp = $phpbb_root_path . 'ext/' . objects::$upload_ext_name . '/tmp/' . (int) $user->data['user_id']; // Ensure that we don't have any previous files in the working directory. if (is_dir($ext_tmp)) { if (!files::catch_errors(files::rrmdir($ext_tmp))) { if ($action != 'upload_local') { $file->remove(); } return false; } } if (!class_exists('\\compress_zip')) { include $phpbb_root_path . 'includes/functions_compress.' . $phpEx; } $zip = new \compress_zip('r', $dest_file); $zip->extract($ext_tmp . '/'); $zip->close(); if ($action != 'upload_local') { $file->remove(); } // The files can be stored inside the $ext_tmp directory or up to two levels lower in the file tree. $lang_dir = ''; // First level (the highest one). $files = @scandir($ext_tmp); if ($files === false) { files::catch_errors(objects::$user->lang('ERROR_LANGUAGE_UNKNOWN_STRUCTURE')); return false; } $files = array_diff($files, array('.', '..')); $last_file = array_pop($files); // Continue searching if we have a single directory. if (!sizeof($files) && !is_null($last_file) && @is_dir($ext_tmp . $lang_dir . '/' . $last_file)) { $lang_dir .= '/' . $last_file; // Second level. $files = @scandir($ext_tmp . $lang_dir); if ($files === false) { files::catch_errors(objects::$user->lang('ERROR_LANGUAGE_UNKNOWN_STRUCTURE')); return false; } $files = array_diff($files, array('.', '..')); // Search for a directory with language ISO code (to escape from problems with unnecessary readme files). if (array_search($lang_name, $files) !== false && @is_dir($ext_tmp . $lang_dir . '/' . $lang_name)) { $lang_dir .= '/' . $lang_name; } } $source = $ext_tmp . $lang_dir; if (!files::catch_errors(files::rcopy($source, $phpbb_root_path . 'ext/' . $ext_name . '/language/' . $lang_name))) { files::catch_errors(files::rrmdir($ext_tmp)); return false; } if (!files::catch_errors(files::rrmdir($ext_tmp))) { return false; } if (objects::$is_ajax && $ext_name === objects::$upload_ext_name && $lang_name === objects::$user->lang_name) { /* * Refresh the page if the uploaded language package * is currently used by the user of Upload Extensions. * Only for Ajax requests. */ $response_object = new \phpbb\json_response(); $response_object->send(array("LANGUAGE" => urlencode($lang_name), "REFRESH" => true)); } objects::$template->assign_var('EXT_LANGUAGE_UPLOADED', objects::$user->lang('EXT_LANGUAGE_UPLOADED', $lang_name)); return true; }
/** * The function that displays the details page. * @param string $ext_name The name of the extension. * @param string $ext_show The section that we need to display. */ public static function details($ext_name, $ext_show) { if (!$ext_name) { redirect(objects::$u_action . '&action=list'); } $show_lang_page = false; $load_full_page = objects::$request->variable('ajax', 0) === 1; // If they've specified an extension, let's load the metadata manager and validate it. if ($ext_name !== objects::$upload_ext_name) { $ext_md_manager = new \phpbb\extension\metadata_manager($ext_name, objects::$config, objects::$phpbb_extension_manager, objects::$template, objects::$user, objects::$phpbb_root_path); try { $ext_md_manager->get_metadata('all'); $ext_name = $ext_md_manager->get_metadata('name'); // Just to be sure of the name. $display_name = $ext_md_manager->get_metadata('display-name'); // Output it to the template $ext_md_manager->output_template_data(); try { $updates_available = extensions::version_check($ext_md_manager, objects::$request->variable('versioncheck_force', false)); objects::$template->assign_vars(array('S_UP_TO_DATE' => empty($updates_available), 'S_VERSIONCHECK' => true, 'UP_TO_DATE_MSG' => objects::$user->lang(empty($updates_available) ? 'UP_TO_DATE' : 'NOT_UP_TO_DATE', $ext_md_manager->get_metadata('display-name')))); foreach ($updates_available as $branch => $version_data) { objects::$template->assign_block_vars('updates_available', $version_data); } } catch (\RuntimeException $e) { objects::$template->assign_vars(array('S_VERSIONCHECK_STATUS' => $e->getCode(), 'VERSIONCHECK_FAIL_REASON' => $e->getMessage() !== objects::$user->lang('VERSIONCHECK_FAIL') ? $e->getMessage() : '')); } } catch (\phpbb\extension\exception $e) { // Display errors in the details tab. objects::$template->assign_vars(array('META_NAME' => $ext_name, 'NOT_AVAILABLE' => $e)); $display_name = $ext_name; } objects::$template->assign_vars(array('S_IS_ENABLED' => objects::$phpbb_extension_manager->is_enabled($ext_name), 'S_IS_DISABLED' => objects::$phpbb_extension_manager->is_disabled($ext_name))); if (!objects::$is_ajax) { objects::$template->assign_var('S_DETAILS', true); // We output everything if required. if ($load_full_page) { $ext_show = 'readme'; } } } else { $display_name = objects::$md_manager->get_metadata('display-name'); objects::$md_manager->output_template_data(); // Output update link to the template if Upload Extensions Updater is installed and updates are available. updater::set_update_link(); // We output everything if this is an ajax request or if we load languages page for Upload Extensions. if ($ext_show == 'languages' && $load_full_page) { objects::$template->assign_var('S_EXT_DETAILS_SHOW_LANGUAGES', "true"); // "true" is the specially handled text $show_lang_page = true; $ext_show = 'readme'; } if (objects::$is_ajax || $ext_show == 'faq' || $load_full_page) { objects::$user->add_lang_ext('boardtools/upload', 'upload', false, true); $faq_sections = 0; foreach (objects::$user->help as $help_ary) { if ($help_ary[0] == '--') { $faq_sections++; objects::$template->assign_block_vars('upload_ext_faq_block', array('BLOCK_TITLE' => $help_ary[1], 'SECTION_NUMBER' => $faq_sections)); continue; } objects::$template->assign_block_vars('upload_ext_faq_block.faq_row', array('FAQ_QUESTION' => $help_ary[0], 'FAQ_ANSWER' => $help_ary[1])); } if (!objects::$is_ajax && !$show_lang_page) { objects::$template->assign_vars(array('SHOW_DETAILS_TAB' => 'faq')); } if ($ext_show == 'faq') { objects::$template->assign_var('S_EXT_DETAILS_SHOW_FAQ', "true"); // "true" is the specially handled text } } if (!objects::$is_ajax) { objects::$template->assign_var('S_UPLOAD_DETAILS', true); // We output everything if required. if ($load_full_page) { $ext_show = 'readme'; } } else { objects::$tpl_name = 'acp_ext_details'; } } if (file_exists(objects::$phpbb_root_path . 'ext/' . $ext_name . '/README.md') && !objects::$request->is_ajax()) { objects::$template->assign_var('EXT_DETAILS_README', true); } if (file_exists(objects::$phpbb_root_path . 'ext/' . $ext_name . '/CHANGELOG.md') && !objects::$request->is_ajax()) { objects::$template->assign_var('EXT_DETAILS_CHANGELOG', true); } switch ($ext_show) { case 'uploaded': objects::$template->assign_var('EXT_UPLOADED', true); break; case 'updated': objects::$template->assign_var('EXT_UPDATED', true); break; case 'enabled': objects::$template->assign_var('EXT_ENABLE_STATUS', objects::$user->lang['EXT_ENABLED']); break; case 'disabled': objects::$template->assign_var('EXT_ENABLE_STATUS', objects::$user->lang['EXT_DISABLED']); break; case 'purged': objects::$template->assign_var('EXT_ENABLE_STATUS', objects::$user->lang['EXT_PURGED']); break; case 'update': objects::$template->assign_vars(array('EXT_DETAILS_UPDATE' => true, 'SHOW_DETAILS_TAB' => 'update')); break; } // We output everything if this is an ajax request or if we load languages page for Upload Extensions. if (objects::$is_ajax) { if ($ext_show == 'languages') { objects::$template->assign_var('S_EXT_DETAILS_SHOW_LANGUAGES', "true"); // "true" is the specially handled text } $ext_show = 'readme'; } switch ($ext_show) { case 'faq': case 'update': break; case 'readme': $string = @file_get_contents(objects::$phpbb_root_path . 'ext/' . $ext_name . '/README.md'); if ($string !== false) { $readme = \Michelf\MarkdownExtra::defaultTransform($string); if (!objects::$is_ajax && !$load_full_page) { objects::$template->assign_vars(array('SHOW_DETAILS_TAB' => 'readme', 'EXT_DETAILS_MARKDOWN' => $readme)); } else { objects::$template->assign_var('EXT_DETAILS_README', $readme); } } if (!objects::$is_ajax && !$load_full_page) { break; } case 'changelog': $string = @file_get_contents(objects::$phpbb_root_path . 'ext/' . $ext_name . '/CHANGELOG.md'); if ($string !== false) { $changelog = \Michelf\MarkdownExtra::defaultTransform($string); if (!objects::$is_ajax && !$load_full_page) { objects::$template->assign_vars(array('SHOW_DETAILS_TAB' => 'changelog', 'EXT_DETAILS_MARKDOWN' => $changelog)); } else { objects::$template->assign_var('EXT_DETAILS_CHANGELOG', $changelog); } } if (!objects::$is_ajax && !$load_full_page) { break; } case 'languages': if (($result = objects::$request->variable('result', '')) == 'deleted' || $result == 'deleted1') { objects::$template->assign_var('EXT_LANGUAGE_UPLOADED', objects::$user->lang('EXT_LANGUAGE' . ($result == 'deleted' ? 'S' : '') . '_DELETE_SUCCESS')); } else { if ($result == 'language_uploaded') { $load_lang = objects::$request->variable('lang', ''); objects::$template->assign_vars(array('EXT_LOAD_LANG' => $load_lang, 'EXT_LANGUAGE_UPLOADED' => objects::$user->lang('EXT_LANGUAGE_UPLOADED', $load_lang))); } } $language_directory = objects::$phpbb_root_path . 'ext/' . $ext_name . '/language'; $langs = files::get_languages($language_directory); $default_lang = in_array(objects::$config['default_lang'], $langs) ? objects::$config['default_lang'] : 'en'; foreach ($langs as $lang) { $lang_info = languages::details($language_directory, $lang); objects::$template->assign_block_vars('ext_languages', array('NAME' => $lang_info['name'] . ($lang === $default_lang ? ' (' . objects::$user->lang('DEFAULT') . ')' : ''))); } objects::$template->assign_vars(array('EXT_DETAILS_LANGUAGES' => true)); if (!objects::$is_ajax && (!$load_full_page || $show_lang_page)) { objects::$template->assign_var('SHOW_DETAILS_TAB', 'languages'); if (!$load_full_page) { break; } } case 'filetree': filetree::$ext_name = $ext_name; $ext_file = objects::$request->variable('ext_file', '/composer.json'); objects::$template->assign_vars(array('EXT_DETAILS_FILETREE' => true, 'FILETREE' => filetree::php_file_tree(objects::$phpbb_root_path . 'ext/' . $ext_name, objects::$user->lang('ACP_UPLOAD_EXT_CONT', $display_name), objects::$u_action), 'FILENAME' => substr($ext_file, strrpos($ext_file, '/') + 1), 'CONTENT' => highlight_string(@file_get_contents(objects::$phpbb_root_path . 'ext/' . $ext_name . $ext_file), true))); if (!objects::$is_ajax && !$load_full_page) { objects::$template->assign_var('SHOW_DETAILS_TAB', 'filetree'); break; } case 'tools': objects::$template->assign_vars(array('EXT_DETAILS_TOOLS' => true)); if (!objects::$is_ajax && !$load_full_page) { objects::$template->assign_var('SHOW_DETAILS_TAB', 'tools'); break; } default: if (!$show_lang_page) { objects::$template->assign_vars(array('SHOW_DETAILS_TAB' => 'details')); } break; } objects::$template->assign_vars(array('U_ACTION_LIST' => objects::$u_action . '&action=list', 'U_UPLOAD' => objects::$u_action . '&action=upload_language', 'U_DELETE_ACTION' => objects::$u_action . '&action=delete_language&ext_name=' . urlencode($ext_name), 'U_BACK' => objects::$u_action . '&action=list', 'U_EXT_DETAILS' => objects::$u_action . '&action=details&ext_name=' . urlencode($ext_name), 'U_VERSIONCHECK_FORCE' => objects::$u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($ext_name), 'UPDATE_EXT_PURGE_DATA' => objects::$user->lang('EXTENSION_DELETE_DATA_CONFIRM', $display_name), 'S_FORM_ENCTYPE' => ' enctype="multipart/form-data"', 'S_LOAD_FULL_PAGE' => $load_full_page)); }