function PackageUpload() { global $txt, $scripturl, $boarddir, $context, $sourcedir; // Setup the correct template, even though I'll admit we ain't downloading ;) $context['sub_template'] = 'downloaded'; // !!! TODO: Use FTP if the Packages directory is not writable. // Check the file was even sent! if (!isset($_FILES['package']['name']) || $_FILES['package']['name'] == '' || !is_uploaded_file($_FILES['package']['tmp_name']) || @ini_get('open_basedir') == '' && !file_exists($_FILES['package']['tmp_name'])) { fatal_lang_error('package_upload_error'); } // Make sure it has a sane filename. $_FILES['package']['name'] = preg_replace(array('/\\s/', '/\\.[\\.]+/', '/[^\\w_\\.\\-]/'), array('_', '.', ''), $_FILES['package']['name']); if (strtolower(substr($_FILES['package']['name'], -4)) != '.zip' && strtolower(substr($_FILES['package']['name'], -4)) != '.tgz' && strtolower(substr($_FILES['package']['name'], -7)) != '.tar.gz') { fatal_error($txt['package_upload_error_supports'] . 'zip, tgz, tar.gz.', false); } // We only need the filename... $packageName = basename($_FILES['package']['name']); // Setup the destination and throw an error if the file is already there! $destination = $boarddir . '/Packages/' . $packageName; // !!! Maybe just roll it like we do for downloads? if (file_exists($destination)) { fatal_lang_error('package_upload_error_exists'); } // Now move the file. move_uploaded_file($_FILES['package']['tmp_name'], $destination); @chmod($destination, 0777); // If we got this far that should mean it's available. $context['package'] = getPackageInfo($packageName); $context['package_server'] = ''; // Not really a package, you lazy bum! if (empty($context['package'])) { @unlink($destination); fatal_lang_error('package_upload_error_broken', false); } if ($context['package']['type'] == 'modification') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package11'] . ' ]</a>'; } elseif ($context['package']['type'] == 'avatar') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package12'] . ' ]</a>'; } elseif ($context['package']['type'] == 'language') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package13'] . ' ]</a>'; } else { $context['package']['install']['link'] = ''; } $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['package14'] . ' ]</a>'; unset($context['package']['xml']); $context['page_title'] = $txt['package_uploaded_success']; }
if (data.type=='ok') { notify('info','Замечание!',data.text); } else { notify('error','Замечание!',data.text); } }, error: function(v1,v2,v3) { console.log(v1,v2,v3); } }); } </script> <?php $pkg_info = getPackageInfo($route->param); if (count($pkg_info) > 1) { echo '<h1 class="page-header">Группа товаров</h1>'; } else { echo '<h1 class="page-header">Информация о товаре</h1>'; } if (isset($pkg_info[0])) { foreach ($pkg_info as $k => $v) { if (count($pkg_info) > 1) { echo '<h2>Item ' . intval($k + 1) . '</h2><hr>'; } $pkg_statuses = getPackageStatuses($v->id); //debug($pkg_statuses); ?> <div class="container-fluid pkg-item">
if ($zip->open($inFile)) { // checking the last file is ad hoc and may not work $a = $zip->getNameIndex($zip->numFiles - 1); $folder = getPrefixPath($fullPath, $a); $zip->close(); return $folder; } } $libraryPath = "../../../../opus/library/"; $package = $_REQUEST["package"]; if ($package) { // // copy file to temporary location $dir = get_tempdir(".", "package") . "/"; $filename = substr($package, strrpos($package, "/") + 1); @mkdir($dir, true); $t = $dir . $filename; copy($package, $t); $package = $t; // // get info $info = getPackageInfo($package); // // unzip $extractPath = $libraryPath . getExtractDir($package, $info->name); zip_extract($package, $extractPath); // // cleanup unlink($package); rmdir($dir); }
/** * Get a listing of all the packages * * - Determines if the package is a mod, avatar, language package * - Determines if the package has been installed or not * * @param int $start * @param int $items_per_page * @param string $sort * @param string $params 'type' type of package * @param bool $installed */ public function list_packages($start, $items_per_page, $sort, $params, $installed) { global $scripturl, $context, $forum_version; static $instadds, $packages; // Start things up if (!isset($packages[$params])) { $packages[$params] = array(); } // We need the packages directory to be writable for this. if (!@is_writable(BOARDDIR . '/packages')) { create_chmod_control(array(BOARDDIR . '/packages'), array('destination_url' => $scripturl . '?action=admin;area=packages', 'crash_on_error' => true)); } list($the_brand, $the_version) = explode(' ', $forum_version, 2); // Here we have a little code to help those who class themselves as something of gods, version emulation ;) if (isset($_GET['version_emulate']) && strtr($_GET['version_emulate'], array($the_brand => '')) == $the_version) { unset($_SESSION['version_emulate']); } elseif (isset($_GET['version_emulate'])) { if (($_GET['version_emulate'] === 0 || $_GET['version_emulate'] === $forum_version) && isset($_SESSION['version_emulate'])) { unset($_SESSION['version_emulate']); } elseif ($_GET['version_emulate'] !== 0) { $_SESSION['version_emulate'] = strtr($_GET['version_emulate'], array('-' => ' ', '+' => ' ', $the_brand . ' ' => '')); } } if (!empty($_SESSION['version_emulate'])) { $context['forum_version'] = $the_brand . ' ' . $_SESSION['version_emulate']; $the_version = $_SESSION['version_emulate']; } if (isset($_SESSION['single_version_emulate'])) { unset($_SESSION['single_version_emulate']); } if (empty($instadds)) { $instadds = loadInstalledPackages(); $installed_adds = array(); // Look through the list of installed mods... foreach ($instadds as $installed_add) { $installed_adds[$installed_add['package_id']] = array('id' => $installed_add['id'], 'version' => $installed_add['version']); } // Get a list of all the ids installed, so the latest packages won't include already installed ones. $context['installed_adds'] = array_keys($installed_adds); } if ($installed) { $sort_id = 1; foreach ($instadds as $installed_add) { $context['available_modification'][$installed_add['package_id']] = array('sort_id' => $sort_id++, 'can_uninstall' => true, 'name' => $installed_add['name'], 'filename' => $installed_add['filename'], 'installed_id' => $installed_add['id'], 'version' => $installed_add['version'], 'is_installed' => true, 'is_current' => true); } } if (empty($packages)) { foreach ($context['package_types'] as $type) { $packages[$type] = array(); } } if ($dir = @opendir(BOARDDIR . '/packages')) { $dirs = array(); $sort_id = array('mod' => 1, 'modification' => 1, 'addon' => 1, 'avatar' => 1, 'language' => 1, 'smiley' => 1, 'unknown' => 1); while ($package = readdir($dir)) { if ($package == '.' || $package == '..' || $package == 'temp' || !(is_dir(BOARDDIR . '/packages/' . $package) && file_exists(BOARDDIR . '/packages/' . $package . '/package-info.xml')) && substr(strtolower($package), -7) != '.tar.gz' && substr(strtolower($package), -4) != '.tgz' && substr(strtolower($package), -4) != '.zip') { continue; } $skip = false; foreach ($context['package_types'] as $type) { if (isset($context['available_' . $type][md5($package)])) { $skip = true; } } if ($skip) { continue; } // Skip directories or files that are named the same. if (is_dir(BOARDDIR . '/packages/' . $package)) { if (in_array($package, $dirs)) { continue; } $dirs[] = $package; } elseif (substr(strtolower($package), -7) == '.tar.gz') { if (in_array(substr($package, 0, -7), $dirs)) { continue; } $dirs[] = substr($package, 0, -7); } elseif (substr(strtolower($package), -4) == '.zip' || substr(strtolower($package), -4) == '.tgz') { if (in_array(substr($package, 0, -4), $dirs)) { continue; } $dirs[] = substr($package, 0, -4); } $packageInfo = getPackageInfo($package); if (!is_array($packageInfo)) { continue; } if (!empty($packageInfo)) { $packageInfo['installed_id'] = isset($installed_adds[$packageInfo['id']]) ? $installed_adds[$packageInfo['id']]['id'] : 0; $packageInfo['sort_id'] = isset($sort_id[$packageInfo['type']]) ? $sort_id[$packageInfo['type']] : $sort_id['unknown']; $packageInfo['is_installed'] = isset($installed_adds[$packageInfo['id']]); $packageInfo['is_current'] = $packageInfo['is_installed'] && $installed_adds[$packageInfo['id']]['version'] == $packageInfo['version']; $packageInfo['is_newer'] = $packageInfo['is_installed'] && $installed_adds[$packageInfo['id']]['version'] > $packageInfo['version']; $packageInfo['can_install'] = false; $packageInfo['can_uninstall'] = false; $packageInfo['can_upgrade'] = false; $packageInfo['can_emulate_install'] = false; $packageInfo['can_emulate_uninstall'] = false; // This package is currently NOT installed. Check if it can be. if (!$packageInfo['is_installed'] && $packageInfo['xml']->exists('install')) { // Check if there's an install for *THIS* version $installs = $packageInfo['xml']->set('install'); foreach ($installs as $install) { if (!$install->exists('@for') || matchPackageVersion($the_version, $install->fetch('@for'))) { // Okay, this one is good to go. $packageInfo['can_install'] = true; break; } } // no install found for our version, lets see if one exists for another if ($packageInfo['can_install'] === false && $install->exists('@for') && empty($_SESSION['version_emulate'])) { $reset = true; // Get the highest install version that is available from the package foreach ($installs as $install) { $packageInfo['can_emulate_install'] = matchHighestPackageVersion($install->fetch('@for'), $reset, $the_version); $reset = false; } } } elseif ($packageInfo['is_installed'] && !$packageInfo['is_current'] && $packageInfo['xml']->exists('upgrade')) { $upgrades = $packageInfo['xml']->set('upgrade'); // First go through, and check against the current version of ElkArte. foreach ($upgrades as $upgrade) { // Even if it is for this ElkArte, is it for the installed version of the mod? if (!$upgrade->exists('@for') || matchPackageVersion($the_version, $upgrade->fetch('@for'))) { if (!$upgrade->exists('@from') || matchPackageVersion($installed_adds[$packageInfo['id']]['version'], $upgrade->fetch('@from'))) { $packageInfo['can_upgrade'] = true; break; } } } } elseif ($packageInfo['is_installed'] && $packageInfo['is_current'] && $packageInfo['xml']->exists('uninstall')) { $uninstalls = $packageInfo['xml']->set('uninstall'); // Can we find any uninstallation methods that work for this ElkArte version? foreach ($uninstalls as $uninstall) { if (!$uninstall->exists('@for') || matchPackageVersion($the_version, $uninstall->fetch('@for'))) { $packageInfo['can_uninstall'] = true; break; } } // No uninstall found for this version, lets see if one exists for another if ($packageInfo['can_uninstall'] === false && $uninstall->exists('@for') && empty($_SESSION['version_emulate'])) { $reset = true; // Get the highest install version that is available from the package foreach ($uninstalls as $uninstall) { $packageInfo['can_emulate_uninstall'] = matchHighestPackageVersion($uninstall->fetch('@for'), $reset, $the_version); $reset = false; } } } // Add-on / Modification if ($packageInfo['type'] == 'addon' || $packageInfo['type'] == 'modification' || $packageInfo['type'] == 'mod') { $sort_id['modification']++; $sort_id['mod']++; $sort_id['addon']++; if ($installed) { if (!empty($context['available_modification'][$packageInfo['id']])) { $packages['modification'][strtolower($packageInfo[$sort]) . '_' . $sort_id['mod']] = $packageInfo['id']; $context['available_modification'][$packageInfo['id']] = array_merge($context['available_modification'][$packageInfo['id']], $packageInfo); } } else { $packages['modification'][strtolower($packageInfo[$sort]) . '_' . $sort_id['mod']] = md5($package); $context['available_modification'][md5($package)] = $packageInfo; } } elseif ($packageInfo['type'] == 'avatar') { $sort_id[$packageInfo['type']]++; $packages['avatar'][strtolower($packageInfo[$sort])] = md5($package); $context['available_avatar'][md5($package)] = $packageInfo; } elseif ($packageInfo['type'] == 'smiley') { $sort_id[$packageInfo['type']]++; $packages['smiley'][strtolower($packageInfo[$sort])] = md5($package); $context['available_smiley'][md5($package)] = $packageInfo; } elseif ($packageInfo['type'] == 'language') { $sort_id[$packageInfo['type']]++; $packages['language'][strtolower($packageInfo[$sort])] = md5($package); $context['available_language'][md5($package)] = $packageInfo; } else { $sort_id['unknown']++; $packages['unknown'][strtolower($packageInfo[$sort])] = md5($package); $context['available_unknown'][md5($package)] = $packageInfo; } } } closedir($dir); } if (isset($_GET['type']) && $_GET['type'] == $params) { if (isset($_GET['desc'])) { krsort($packages[$params]); } else { ksort($packages[$params]); } } return $packages[$params]; }
function PackageBrowse() { global $txt, $boarddir, $scripturl, $context, $forum_version; $context['page_title'] .= ' - ' . $txt['browse_packages']; $context['sub_template'] = 'browse'; $context['forum_version'] = $forum_version; $instmods = loadInstalledPackages(); $installed_mods = array(); // Look through the list of installed mods... foreach ($instmods as $installed_mod) { $installed_mods[$installed_mod['package_id']] = array('id' => $installed_mod['id'], 'version' => $installed_mod['version']); } $the_version = strtr($forum_version, array('SMF ' => '')); // Here we have a little code to help those who class themselves as something of gods, version emulation ;) if (isset($_GET['version_emulate'])) { if ($_GET['version_emulate'] === 0 && isset($_SESSION['version_emulate'])) { unset($_SESSION['version_emulate']); } elseif ($_GET['version_emulate'] !== 0) { $_SESSION['version_emulate'] = strtr($_GET['version_emulate'], array('-' => ' ', '+' => ' ', 'SMF ' => '')); } } if (!empty($_SESSION['version_emulate'])) { $context['forum_version'] = 'SMF ' . $_SESSION['version_emulate']; $the_version = $_SESSION['version_emulate']; } // Get a list of all the ids installed, so the latest packages won't include already installed ones. $context['installed_mods'] = array_keys($installed_mods); // Empty lists for now. $context['available_mods'] = array(); $context['available_avatars'] = array(); $context['available_languages'] = array(); $context['available_other'] = array(); $context['available_all'] = array(); // We need the packages directory to be writable for this. if (!@is_writable($boarddir . '/Packages')) { create_chmod_control(array($boarddir . '/Packages'), array('destination_url' => $scripturl . '?action=admin;area=packages', 'crash_on_error' => true)); } if ($dir = @opendir($boarddir . '/Packages')) { $dirs = array(); while ($package = readdir($dir)) { if ($package == '.' || $package == '..' || $package == 'temp' || !(is_dir($boarddir . '/Packages/' . $package) && file_exists($boarddir . '/Packages/' . $package . '/package-info.xml')) && substr(strtolower($package), -7) != '.tar.gz' && substr(strtolower($package), -4) != '.tgz' && substr(strtolower($package), -4) != '.zip') { continue; } // Skip directories or files that are named the same. if (is_dir($boarddir . '/Packages/' . $package)) { if (in_array($package, $dirs)) { continue; } $dirs[] = $package; } elseif (substr(strtolower($package), -7) == '.tar.gz') { if (in_array(substr($package, 0, -7), $dirs)) { continue; } $dirs[] = substr($package, 0, -7); } elseif (substr(strtolower($package), -4) == '.zip' || substr(strtolower($package), -4) == '.tgz') { if (in_array(substr($package, 0, -4), $dirs)) { continue; } $dirs[] = substr($package, 0, -4); } $packageInfo = getPackageInfo($package); if (!is_array($packageInfo)) { continue; } $packageInfo['installed_id'] = isset($installed_mods[$packageInfo['id']]) ? $installed_mods[$packageInfo['id']]['id'] : 0; $packageInfo['is_installed'] = isset($installed_mods[$packageInfo['id']]); $packageInfo['is_current'] = $packageInfo['is_installed'] && $installed_mods[$packageInfo['id']]['version'] == $packageInfo['version']; $packageInfo['is_newer'] = $packageInfo['is_installed'] && $installed_mods[$packageInfo['id']]['version'] > $packageInfo['version']; $packageInfo['can_install'] = false; $packageInfo['can_uninstall'] = false; $packageInfo['can_upgrade'] = false; // This package is currently NOT installed. Check if it can be. if (!$packageInfo['is_installed'] && $packageInfo['xml']->exists('install')) { // Check if there's an install for *THIS* version of SMF. $installs = $packageInfo['xml']->set('install'); foreach ($installs as $install) { if (!$install->exists('@for') || matchPackageVersion($the_version, $install->fetch('@for'))) { // Okay, this one is good to go. $packageInfo['can_install'] = true; break; } } } elseif ($packageInfo['is_installed'] && !$packageInfo['is_current'] && $packageInfo['xml']->exists('upgrade')) { $upgrades = $packageInfo['xml']->set('upgrade'); // First go through, and check against the current version of SMF. foreach ($upgrades as $upgrade) { // Even if it is for this SMF, is it for the installed version of the mod? if (!$upgrade->exists('@for') || matchPackageVersion($the_version, $upgrade->fetch('@for'))) { if (!$upgrade->exists('@from') || matchPackageVersion($installed_mods[$packageInfo['id']]['version'], $upgrade->fetch('@from'))) { $packageInfo['can_upgrade'] = true; break; } } } } elseif ($packageInfo['is_installed'] && $packageInfo['is_current'] && $packageInfo['xml']->exists('uninstall')) { $uninstalls = $packageInfo['xml']->set('uninstall'); // Can we find any uninstallation methods that work for this SMF version? foreach ($uninstalls as $uninstall) { if (!$uninstall->exists('@for') || matchPackageVersion($the_version, $uninstall->fetch('@for'))) { $packageInfo['can_uninstall'] = true; break; } } } // Store a complete list. $context['available_all'][] = $packageInfo; // Modification. if ($packageInfo['type'] == 'modification' || $packageInfo['type'] == 'mod') { $context['available_mods'][] = $packageInfo; } elseif ($packageInfo['type'] == 'avatar') { $context['available_avatars'][] = $packageInfo; } elseif ($packageInfo['type'] == 'language') { $context['available_languages'][] = $packageInfo; } else { $context['available_other'][] = $packageInfo; } } closedir($dir); } }
function CleanupMods() { global $db_prefix, $modSettings, $upcontext, $boarddir, $sourcedir, $settings, $smcFunc, $command_line; // Sorry. Not supported for command line users. if ($command_line) { return true; } // Skipping first? if (!empty($_POST['skip'])) { unset($_POST['skip']); return true; } // If we get here withOUT SSI we need to redirect to ensure we get it! if (!isset($_GET['ssi']) || !function_exists('mktree')) { redirectLocation('&ssi=1'); } $upcontext['sub_template'] = 'clean_mods'; $upcontext['page_title'] = 'Cleanup Modifications'; // This can be skipped. $upcontext['skip'] = true; // If we're on the second redirect continue... if (isset($_POST['cleandone2'])) { return true; } // Do we already know about some writable files? if (isset($_POST['writable_files'])) { $writable_files = unserialize(base64_decode($_POST['writable_files'])); if (!makeFilesWritable($writable_files)) { // What have we left? $upcontext['writable_files'] = $writable_files; return false; } } // Load all theme paths.... $request = $smcFunc['db_query']('', ' SELECT id_theme, variable, value FROM {db_prefix}themes WHERE id_member = {int:id_member} AND variable IN ({string:theme_dir}, {string:images_url})', array('id_member' => 0, 'theme_dir' => 'theme_dir', 'images_url' => 'images_url', 'db_error_skip' => true)); $theme_paths = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($row['id_theme'] == 1) { $settings['default_' . $row['variable']] = $row['value']; } elseif ($row['variable'] == 'theme_dir') { $theme_paths[$row['id_theme']][$row['variable']] = $row['value']; } } $smcFunc['db_free_result']($request); // Are there are mods installed that may need uninstalling? $request = $smcFunc['db_query']('', ' SELECT id_install, filename, name, themes_installed, version FROM {db_prefix}log_packages WHERE install_state = {int:installed} ORDER BY time_installed DESC', array('installed' => 1, 'db_error_skip' => true)); $upcontext['packages'] = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { // Work out the status. if (!file_exists($boarddir . '/Packages/' . $row['filename'])) { $status = 'Missing'; $status_color = 'red'; $result = 'Removed'; } else { $status = 'Installed'; $status_color = 'green'; $result = 'No Action Needed'; } $upcontext['packages'][$row['id_install']] = array('id' => $row['id_install'], 'themes' => explode(',', $row['themes_installed']), 'name' => $row['name'], 'filename' => $row['filename'], 'missing_file' => file_exists($boarddir . '/Packages/' . $row['filename']) ? 0 : 1, 'files' => array(), 'file_count' => 0, 'status' => $status, 'result' => $result, 'color' => $status_color, 'version' => $row['version'], 'needs_removing' => false); } $smcFunc['db_free_result']($request); // Don't carry on if there are none. if (empty($upcontext['packages'])) { return true; } // Setup some basics. if (!empty($upcontext['user']['version'])) { $_SESSION['version_emulate'] = $upcontext['user']['version']; } // Before we get started, don't report notice errors. $oldErrorReporting = error_reporting(E_ALL ^ E_NOTICE); if (!mktree($boarddir . '/Packages/temp', 0755)) { deltree($boarddir . '/Packages/temp', false); if (!mktree($boarddir . '/Packages/temp', 0777)) { deltree($boarddir . '/Packages/temp', false); //!!! Error here - plus chmod! } } // Anything which reinstalled should not have its entry removed. $reinstall_worked = array(); // We're gonna be doing some removin' $test = isset($_POST['cleandone']) ? false : true; foreach ($upcontext['packages'] as $id => $package) { // Can't do anything about this.... if ($package['missing_file']) { continue; } // Not testing *and* this wasn't checked? if (!$test && (!isset($_POST['remove']) || !isset($_POST['remove'][$id]))) { continue; } // What are the themes this was installed into? $cur_theme_paths = array(); foreach ($theme_paths as $tid => $data) { if ($tid != 1 && in_array($tid, $package['themes'])) { $cur_theme_paths[$tid] = $data; } } // Get the modifications data if applicable. $filename = $package['filename']; $packageInfo = getPackageInfo($filename); if (!is_array($packageInfo)) { continue; } $info = parsePackageInfo($packageInfo['xml'], $test, 'uninstall'); // Also get the reinstall details... if (isset($_POST['remove'])) { $infoInstall = parsePackageInfo($packageInfo['xml'], true); } if (is_file($boarddir . '/Packages/' . $filename)) { read_tgz_file($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } else { copytree($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } // Work out how we uninstall... $files = array(); foreach ($info as $change) { // Work out two things: // 1) Whether it's installed at the moment - and if so whether its fully installed, and: // 2) Whether it could be installed on the new version. if ($change['type'] == 'modification') { $contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']); if ($change['boardmod']) { $results = parseBoardMod($contents, $test, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, $test, $change['reverse'], $cur_theme_paths); } foreach ($results as $action) { // Something we can remove? Probably means it existed! if (($action['type'] == 'replace' || $action['type'] == 'append' || !empty($action['filename']) && $action['type'] == 'failure') && !in_array($action['filename'], $files)) { $files[] = $action['filename']; } if ($action['type'] == 'failure') { $upcontext['packages'][$id]['needs_removing'] = true; $upcontext['packages'][$id]['status'] = 'Reinstall Required'; $upcontext['packages'][$id]['color'] = '#FD6435'; } } } } // Store this info for the template as appropriate. $upcontext['packages'][$id]['files'] = $files; $upcontext['packages'][$id]['file_count'] = count($files); // If we've done something save the changes! if (!$test) { package_flush_cache(); } // Are we attempting to reinstall this thing? if (isset($_POST['remove']) && !$test && isset($infoInstall)) { // Need to extract again I'm afraid. if (is_file($boarddir . '/Packages/' . $filename)) { read_tgz_file($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } else { copytree($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } $errors = false; $upcontext['packages'][$id]['result'] = 'Removed'; foreach ($infoInstall as $change) { if ($change['type'] == 'modification') { $contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']); if ($change['boardmod']) { $results = parseBoardMod($contents, true, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, true, $change['reverse'], $cur_theme_paths); } // Are there any errors? foreach ($results as $action) { if ($action['type'] == 'failure') { $errors = true; } } } } if (!$errors) { $reinstall_worked[] = $id; $upcontext['packages'][$id]['result'] = 'Reinstalled'; $upcontext['packages'][$id]['color'] = 'green'; foreach ($infoInstall as $change) { if ($change['type'] == 'modification') { $contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']); if ($change['boardmod']) { $results = parseBoardMod($contents, false, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, false, $change['reverse'], $cur_theme_paths); } } } // Save the changes. package_flush_cache(); } } } // Put errors back on a sec. error_reporting($oldErrorReporting); // Check everything is writable. if ($test && !empty($upcontext['packages'])) { $writable_files = array(); foreach ($upcontext['packages'] as $package) { if (!empty($package['files'])) { foreach ($package['files'] as $file) { $writable_files[] = $file; } } } if (!empty($writable_files)) { $writable_files = array_unique($writable_files); $upcontext['writable_files'] = $writable_files; if (!makeFilesWritable($writable_files)) { return false; } } } if (file_exists($boarddir . '/Packages/temp')) { deltree($boarddir . '/Packages/temp'); } // Removing/Reinstalling any packages? if (isset($_POST['remove'])) { $deletes = array(); foreach ($_POST['remove'] as $id => $dummy) { if (!in_array((int) $id, $reinstall_worked)) { $deletes[] = (int) $id; } } if (!empty($deletes)) { upgrade_query(' UPDATE ' . $db_prefix . 'log_packages SET install_state = 0 WHERE id_install IN (' . implode(',', $deletes) . ')'); } // Ensure we don't lose our changes! package_put_contents($boarddir . '/Packages/installed.list', time()); $upcontext['sub_template'] = 'cleanup_done'; return false; } else { $allgood = true; // Is there actually anything that needs our attention? foreach ($upcontext['packages'] as $package) { if ($package['color'] != 'green') { $allgood = false; } } if ($allgood) { return true; } } $_GET['substep'] = 0; return isset($_POST['cleandone']) ? true : false; }
/** * Install a smiley set. */ public function action_install() { global $modSettings, $scripturl, $context, $txt, $user_info; isAllowedTo('manage_smileys'); checkSession('request'); // One of these two may be necessary loadLanguage('Errors'); loadLanguage('Packages'); require_once SUBSDIR . '/Smileys.subs.php'; require_once SUBSDIR . '/Package.subs.php'; // Installing unless proven otherwise $testing = false; $destination = ''; $name = ''; if (isset($_REQUEST['set_gz'])) { $base_name = strtr(basename($_REQUEST['set_gz']), ':/', '-_'); $name = Util::htmlspecialchars(strtok(basename($_REQUEST['set_gz']), '.')); $name_pr = preg_replace(array('/\\s/', '/\\.[\\.]+/', '/[^\\w_\\.\\-]/'), array('_', '.', ''), $name); $context['filename'] = $base_name; // Check that the smiley is from simplemachines.org, for now... maybe add mirroring later. if (!isAuthorizedServer($_REQUEST['set_gz']) == 0) { fatal_lang_error('not_valid_server'); } $destination = BOARDDIR . '/packages/' . $base_name; if (file_exists($destination)) { fatal_lang_error('package_upload_error_exists'); } // Let's copy it to the packages directory file_put_contents($destination, fetch_web_data($_REQUEST['set_gz'])); $testing = true; } elseif (isset($_REQUEST['package'])) { $base_name = basename($_REQUEST['package']); $name = Util::htmlspecialchars(strtok(basename($_REQUEST['package']), '.')); $name_pr = preg_replace(array('/\\s/', '/\\.[\\.]+/', '/[^\\w_\\.\\-]/'), array('_', '.', ''), $name); $context['filename'] = $base_name; $destination = BOARDDIR . '/packages/' . basename($_REQUEST['package']); } if (!file_exists($destination)) { fatal_lang_error('package_no_file', false); } // Make sure temp directory exists and is empty. if (file_exists(BOARDDIR . '/packages/temp')) { deltree(BOARDDIR . '/packages/temp', false); } if (!mktree(BOARDDIR . '/packages/temp', 0755)) { deltree(BOARDDIR . '/packages/temp', false); if (!mktree(BOARDDIR . '/packages/temp', 0777)) { deltree(BOARDDIR . '/packages/temp', false); // @todo not sure about url in destination_url create_chmod_control(array(BOARDDIR . '/packages/temp/delme.tmp'), array('destination_url' => $scripturl . '?action=admin;area=smileys;sa=install;set_gz=' . $_REQUEST['set_gz'], 'crash_on_error' => true)); deltree(BOARDDIR . '/packages/temp', false); if (!mktree(BOARDDIR . '/packages/temp', 0777)) { fatal_lang_error('package_cant_download', false); } } } $extracted = read_tgz_file($destination, BOARDDIR . '/packages/temp'); // @todo needs to change the URL in the next line ;) if (!$extracted) { fatal_lang_error('packageget_unable', false, array('http://custom.elkarte.net/index.php?action=search;type=12;basic_search=' . $name)); } if ($extracted && !file_exists(BOARDDIR . '/packages/temp/package-info.xml')) { foreach ($extracted as $file) { if (basename($file['filename']) == 'package-info.xml') { $base_path = dirname($file['filename']) . '/'; break; } } } if (!isset($base_path)) { $base_path = ''; } if (!file_exists(BOARDDIR . '/packages/temp/' . $base_path . 'package-info.xml')) { fatal_lang_error('package_get_error_missing_xml', false); } $smileyInfo = getPackageInfo($context['filename']); if (!is_array($smileyInfo)) { fatal_lang_error($smileyInfo); } // See if it is installed? if (isSmileySetInstalled($smileyInfo['id'])) { fata_lang_error('package_installed_warning1'); } // Everything is fine, now it's time to do something, first we test $actions = parsePackageInfo($smileyInfo['xml'], true, 'install'); $context['post_url'] = $scripturl . '?action=admin;area=smileys;sa=install;package=' . $base_name; $context['has_failure'] = false; $context['actions'] = array(); $context['ftp_needed'] = false; foreach ($actions as $action) { if ($action['type'] == 'readme' || $action['type'] == 'license') { $type = 'package_' . $action['type']; if (file_exists(BOARDDIR . '/packages/temp/' . $base_path . $action['filename'])) { $context[$type] = htmlspecialchars(trim(file_get_contents(BOARDDIR . '/packages/temp/' . $base_path . $action['filename']), "\n\r"), ENT_COMPAT, 'UTF-8'); } elseif (file_exists($action['filename'])) { $context[$type] = htmlspecialchars(trim(file_get_contents($action['filename']), "\n\r"), ENT_COMPAT, 'UTF-8'); } if (!empty($action['parse_bbc'])) { require_once SUBSDIR . '/Post.subs.php'; preparsecode($context[$type]); $context[$type] = parse_bbc($context[$type]); } else { $context[$type] = nl2br($context[$type]); } continue; } elseif ($action['type'] == 'require-dir') { // Do this one... $thisAction = array('type' => $txt['package_extract'] . ' ' . ($action['type'] == 'require-dir' ? $txt['package_tree'] : $txt['package_file']), 'action' => Util::htmlspecialchars(strtr($action['destination'], array(BOARDDIR => '.')))); $file = BOARDDIR . '/packages/temp/' . $base_path . $action['filename']; if (isset($action['filename']) && (!file_exists($file) || !is_writable(dirname($action['destination'])))) { $context['has_failure'] = true; $thisAction += array('description' => $txt['package_action_error'], 'failed' => true); } // Show a description for the action if one is provided if (empty($thisAction['description'])) { $thisAction['description'] = isset($action['description']) ? $action['description'] : ''; } $context['actions'][] = $thisAction; } elseif ($action['type'] == 'credits') { // Time to build the billboard $credits_tag = array('url' => $action['url'], 'license' => $action['license'], 'copyright' => $action['copyright'], 'title' => $action['title']); } } if ($testing) { $context['sub_template'] = 'view_package'; $context['uninstalling'] = false; $context['is_installed'] = false; $context['package_name'] = $smileyInfo['name']; loadTemplate('Packages'); } else { $actions = parsePackageInfo($smileyInfo['xml'], false, 'install'); foreach ($context['actions'] as $action) { updateSettings(array('smiley_sets_known' => $modSettings['smiley_sets_known'] . ',' . basename($action['action']), 'smiley_sets_names' => $modSettings['smiley_sets_names'] . "\n" . $smileyInfo['name'] . (count($context['actions']) > 1 ? ' ' . (!empty($action['description']) ? Util::htmlspecialchars($action['description']) : basename($action['action'])) : ''))); } package_flush_cache(); // Time to tell pacman we have a new package installed! package_put_contents(BOARDDIR . '/packages/installed.list', time()); // Credits tag? $credits_tag = empty($credits_tag) ? '' : serialize($credits_tag); $installed = array('filename' => $smileyInfo['filename'], 'name' => $smileyInfo['name'], 'package_id' => $smileyInfo['id'], 'version' => $smileyInfo['filename'], 'id_member' => $user_info['id'], 'member_name' => $user_info['name'], 'credits_tag' => $credits_tag); logPackageInstall($installed); logAction('install_package', array('package' => Util::htmlspecialchars($smileyInfo['name']), 'version' => Util::htmlspecialchars($smileyInfo['version'])), 'admin'); cache_put_data('parsing_smileys', null, 480); cache_put_data('posting_smileys', null, 480); } if (file_exists(BOARDDIR . '/packages/temp')) { deltree(BOARDDIR . '/packages/temp'); } if (!$testing) { redirectexit('action=admin;area=smileys'); } }
/** * Upload a new package to the directory. */ function PackageUpload() { global $txt, $scripturl, $boarddir, $context, $sourcedir; // Setup the correct template, even though I'll admit we ain't downloading ;) $context['sub_template'] = 'downloaded'; // @todo Use FTP if the Packages directory is not writable. // Check the file was even sent! if (!isset($_FILES['package']['name']) || $_FILES['package']['name'] == '') { fatal_lang_error('package_upload_error_nofile'); } elseif (!is_uploaded_file($_FILES['package']['tmp_name']) || ini_get('open_basedir') == '' && !file_exists($_FILES['package']['tmp_name'])) { fatal_lang_error('package_upload_error_failed'); } // Make sure it has a sane filename. $_FILES['package']['name'] = preg_replace(array('/\\s/', '/\\.[\\.]+/', '/[^\\w_\\.\\-]/'), array('_', '.', ''), $_FILES['package']['name']); if (strtolower(substr($_FILES['package']['name'], -4)) != '.zip' && strtolower(substr($_FILES['package']['name'], -4)) != '.tgz' && strtolower(substr($_FILES['package']['name'], -7)) != '.tar.gz') { fatal_lang_error('package_upload_error_supports', false, array('zip, tgz, tar.gz')); } // We only need the filename... $packageName = basename($_FILES['package']['name']); // Setup the destination and throw an error if the file is already there! $destination = $boarddir . '/Packages/' . $packageName; // @todo Maybe just roll it like we do for downloads? if (file_exists($destination)) { fatal_lang_error('package_upload_error_exists'); } // Now move the file. move_uploaded_file($_FILES['package']['tmp_name'], $destination); @chmod($destination, 0777); // If we got this far that should mean it's available. $context['package'] = getPackageInfo($packageName); $context['package_server'] = ''; // Not really a package, you lazy bum! if (!is_array($context['package'])) { @unlink($destination); loadLanguage('Errors'); $txt[$context['package']] = str_replace('{MANAGETHEMEURL}', $scripturl . '?action=admin;area=theme;sa=admin;' . $context['session_var'] . '=' . $context['session_id'] . '#theme_install', $txt[$context['package']]); fatal_lang_error('package_upload_error_broken', false, $txt[$context['package']]); } elseif ($dir = @opendir($boarddir . '/Packages')) { while ($package = readdir($dir)) { if ($package == '.' || $package == '..' || $package == 'temp' || $package == $packageName || !(is_dir($boarddir . '/Packages/' . $package) && file_exists($boarddir . '/Packages/' . $package . '/package-info.xml')) && substr(strtolower($package), -7) != '.tar.gz' && substr(strtolower($package), -4) != '.tgz' && substr(strtolower($package), -4) != '.zip') { continue; } $packageInfo = getPackageInfo($package); if (!is_array($packageInfo)) { continue; } if ($packageInfo['id'] == $context['package']['id'] && $packageInfo['version'] == $context['package']['version']) { @unlink($destination); loadLanguage('Errors'); fatal_lang_error('package_upload_error_exists'); } } closedir($dir); } if ($context['package']['type'] == 'modification') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['install_mod'] . ' ]</a>'; } elseif ($context['package']['type'] == 'avatar') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['use_avatars'] . ' ]</a>'; } elseif ($context['package']['type'] == 'language') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['add_languages'] . ' ]</a>'; } else { $context['package']['install']['link'] = ''; } $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['list_files'] . ' ]</a>'; unset($context['package']['xml']); $context['page_title'] = $txt['package_uploaded_success']; }