function PackageGBrowse() { global $txt, $boardurl, $context, $scripturl, $boarddir, $sourcedir, $forum_version, $context, $db_prefix; if (isset($_GET['server'])) { if ($_GET['server'] == '') { redirectexit('action=packageget'); } $server = (int) $_GET['server']; // Query the server list to find the current server. $request = db_query("\n\t\t\tSELECT name, url\n\t\t\tFROM {$db_prefix}package_servers\n\t\t\tWHERE ID_SERVER = {$server}\n\t\t\tLIMIT 1", __FILE__, __LINE__); list($name, $url) = mysql_fetch_row($request); mysql_free_result($request); // If the server does not exist, dump out. if (empty($url)) { fatal_lang_error('smf191', false); } // If there is a relative link, append to the stored server url. if (isset($_GET['relative'])) { $url = $url . (substr($url, -1) == '/' ? '' : '/') . $_GET['relative']; } // Clear any "absolute" URL. Since "server" is present, "absolute" is garbage. unset($_GET['absolute']); } elseif (isset($_GET['absolute']) && $_GET['absolute'] != '') { // Initialize the requried variables. $server = ''; $url = $_GET['absolute']; $name = ''; $_GET['package'] = $url . '/packages.xml?language=' . $context['user']['language']; // Clear any "relative" URL. Since "server" is not present, "relative" is garbage. unset($_GET['relative']); $token = checkConfirm('get_absolute_url'); if ($token !== true) { $context['sub_template'] = 'package_confirm'; $context['page_title'] = $txt['smf183']; $context['confirm_message'] = sprintf($txt['package_confirm_view_package_content'], htmlspecialchars($_GET['absolute'])); $context['proceed_href'] = $scripturl . '?action=packageget;sa=browse;absolute=' . urlencode($_GET['absolute']) . ';confirm=' . $token; return; } } else { fatal_lang_error('smf191', false); } // In safe mode or on lycos? Try this URL. (includes package-list for informational purposes ;).) //if (@ini_get('safe_mode')) // redirectexit($url . '/index.php?package-list&language=' . $context['user']['language'] . '&ref=' . $boardurl); // Attempt to connect. If unsuccessful... try the URL. if (!isset($_GET['package']) || file_exists($_GET['package'])) { $_GET['package'] = $url . '/packages.xml?language=' . $context['user']['language']; } // Check to be sure the packages.xml file actually exists where it is should be... or dump out. if ((isset($_GET['absolute']) || isset($_GET['relative'])) && !url_exists($_GET['package'])) { fatal_lang_error('packageget_unable', false, array($url . '/index.php')); } // Read packages.xml and parse into xmlArray. (the true tells it to trim things ;).) $listing = new xmlArray(fetch_web_data($_GET['package']), true); // Errm.... empty file? Try the URL.... if (!$listing->exists('package-list')) { fatal_lang_error('packageget_unable', false, array($url . '/index.php')); } // List out the packages... $context['package_list'] = array(); $listing = $listing->path('package-list[0]'); // Use the package list's name if it exists. if ($listing->exists('list-title')) { $name = $listing->fetch('list-title'); } // Pick the correct template. $context['sub_template'] = 'package_list'; $context['page_title'] = $txt['smf183'] . ($name != '' ? ' - ' . $name : ''); $context['package_server'] = $server; $instmods = loadInstalledPackages(); // Look through the list of installed mods... foreach ($instmods as $installed_mod) { $installed_mods[$installed_mod['id']] = $installed_mod['version']; } // Get default author and email if they exist. if ($listing->exists('default-author')) { $default_author = htmlspecialchars($listing->fetch('default-author')); if ($listing->exists('default-author/@email')) { $default_email = $listing->fetch('default-author/@email'); } } // Get default web site if it exists. if ($listing->exists('default-website')) { $default_website = $listing->fetch('default-website'); if ($listing->exists('default-website/@title')) { $default_title = htmlspecialchars($listing->fetch('default-website/@title')); } } $the_version = strtr($forum_version, array('SMF ' => '')); if (!empty($_SESSION['version_emulate'])) { $the_version = $_SESSION['version_emulate']; } $packageNum = 0; $sections = $listing->set('section'); foreach ($sections as $i => $section) { $packages = $section->set('title|heading|text|remote|rule|modification|language|avatar-pack|theme|smiley-set'); foreach ($packages as $thisPackage) { $package =& $context['package_list'][]; $package['type'] = $thisPackage->name(); // It's a Title, Heading, Rule or Text. if (in_array($package['type'], array('title', 'heading', 'text', 'rule'))) { $package['name'] = htmlspecialchars($thisPackage->fetch('.')); } elseif ($package['type'] == 'remote') { $remote_type = $thisPackage->exists('@type') ? $thisPackage->fetch('@type') : 'relative'; if ($remote_type == 'relative' && substr($thisPackage->fetch('@href'), 0, 7) != 'http://') { if (isset($_GET['absolute'])) { $current_url = $_GET['absolute'] . '/'; } elseif (isset($_GET['relative'])) { $current_url = $_GET['relative'] . '/'; } else { $current_url = ''; } $current_url .= $thisPackage->fetch('@href'); if (isset($_GET['absolute'])) { $package['href'] = $scripturl . '?action=packageget;sa=browse;absolute=' . $current_url; } else { $package['href'] = $scripturl . '?action=packageget;sa=browse;server=' . $context['package_server'] . ';relative=' . $current_url; } } else { $current_url = $thisPackage->fetch('@href'); $package['href'] = $scripturl . '?action=packageget;sa=browse;absolute=' . $current_url; } $package['name'] = htmlspecialchars($thisPackage->fetch('.')); $package['link'] = '<a href="' . $package['href'] . '">' . $package['name'] . '</a>'; } else { if (isset($_GET['absolute'])) { $current_url = $_GET['absolute'] . '/'; } elseif (isset($_GET['relative'])) { $current_url = $_GET['relative'] . '/'; } else { $current_url = ''; } $server_att = $server != '' ? ';server=' . $server : ''; $package += $thisPackage->to_array(); if (isset($package['website'])) { unset($package['website']); } $package['author'] = array(); if ($package['description'] == '') { $package['description'] = $txt['pacman8']; } else { $package['description'] = parse_bbc(preg_replace('~\\[[/]?html\\]~i', '', htmlspecialchars($package['description']))); } $package['is_installed'] = isset($installed_mods[$package['id']]); $package['is_current'] = $package['is_installed'] && $installed_mods[$package['id']] == $package['version']; $package['is_newer'] = $package['is_installed'] && $installed_mods[$package['id']] > $package['version']; // This package is either not installed, or installed but old. Is it supported on this version of SMF? if (!$package['is_installed'] || !$package['is_current'] && !$package['is_newer']) { if ($thisPackage->exists('version/@for')) { $package['can_install'] = matchPackageVersion($the_version, $thisPackage->fetch('version/@for')); } } else { $package['can_install'] = false; } $already_exists = getPackageInfo(basename($package['filename'])); $package['download_conflict'] = !empty($already_exists) && $already_exists['id'] == $package['id'] && $already_exists['version'] != $package['version']; $package['href'] = $url . '/' . $package['filename']; $package['name'] = htmlspecialchars($package['name']); $package['link'] = '<a href="' . $package['href'] . '">' . $package['name'] . '</a>'; $package['download']['href'] = $scripturl . '?action=packageget;sa=download' . $server_att . ';package=' . $current_url . $package['filename'] . ($package['download_conflict'] ? ';conflict' : '') . ';sesc=' . $context['session_id']; $package['download']['link'] = '<a href="' . $package['download']['href'] . '">' . $package['name'] . '</a>'; if ($thisPackage->exists('author') || isset($default_author)) { if ($thisPackage->exists('author/@email')) { $package['author']['email'] = htmlspecialchars($thisPackage->fetch('author/@email')); } elseif (isset($default_email)) { $package['author']['email'] = $default_email; } if ($thisPackage->exists('author') && $thisPackage->fetch('author') != '') { $package['author']['name'] = htmlspecialchars($thisPackage->fetch('author')); } else { $package['author']['name'] = $default_author; } if (!empty($package['author']['email'])) { // Only put the "mailto:" if it looks like a valid email address. Some may wish to put a link to an SMF IM Form or other web mail form. $package['author']['href'] = preg_match('~^[\\w\\.\\-]+@[\\w][\\w\\-\\.]+[\\w]$~', $package['author']['email']) != 0 ? 'mailto:' . $package['author']['email'] : $package['author']['email']; $package['author']['link'] = '<a href="' . $package['author']['href'] . '">' . $package['author']['name'] . '</a>'; } } if ($thisPackage->exists('website') || isset($default_website)) { if ($thisPackage->exists('website') && $thisPackage->exists('website/@title')) { $package['author']['website']['name'] = htmlspecialchars($thisPackage->fetch('website/@title')); } elseif (isset($default_title)) { $package['author']['website']['name'] = $default_title; } elseif ($thisPackage->exists('website')) { $package['author']['website']['name'] = htmlspecialchars($thisPackage->fetch('website')); } else { $package['author']['website']['name'] = $default_website; } if ($thisPackage->exists('website') && $thisPackage->fetch('website') != '') { $authorhompage = $thisPackage->fetch('website'); } else { $authorhompage = $default_website; } if (strpos(strtolower($authorhompage), 'a href') === false) { $package['author']['website']['href'] = $authorhompage; $package['author']['website']['link'] = '<a href="' . $authorhompage . '">' . $package['author']['website']['name'] . '</a>'; } else { if (preg_match('/a href="(.+?)"/', $authorhompage, $match) == 1) { $package['author']['website']['href'] = $match[1]; } else { $package['author']['website']['href'] = ''; } $package['author']['website']['link'] = $authorhompage; } } else { $package['author']['website']['href'] = ''; $package['author']['website']['link'] = ''; } } $package['is_remote'] = $package['type'] == 'remote'; $package['is_title'] = $package['type'] == 'title'; $package['is_heading'] = $package['type'] == 'heading'; $package['is_text'] = $package['type'] == 'text'; $package['is_line'] = $package['type'] == 'rule'; $packageNum = in_array($package['type'], array('title', 'heading', 'text', 'remote', 'rule')) ? 0 : $packageNum + 1; $package['count'] = $packageNum; } } // Lets make sure we get a nice new spiffy clean $package to work with. Otherwise we get PAIN! unset($package); foreach ($context['package_list'] as $i => $package) { if ($package['count'] == 0 || isset($package['can_install'])) { continue; } $context['package_list'][$i]['can_install'] = false; $packageInfo = getPackageInfo($url . '/' . $package['filename']); if (!empty($packageInfo) && $packageInfo['xml']->exists('install')) { $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. $context['package_list'][$i]['can_install'] = true; break; } } } } }
/** * 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 show_mods() { global $txt; echo ' <div class="tab-page" id="mods_installed"><h2 class="tab">', $txt['mods_installed'], '</h2> <script type="text/javascript">addSection("mods_installed", "', $txt['mods_installed'], '");</script> <table border="0" width="50%" align="center"> <tr> <td width="200px"><strong>', $txt['package_name'], '</strong></td> <td><strong>', $txt['package_id'], '</strong></td> <td width="150px"><strong>', $txt['package_version'], '</strong></td> </tr>'; foreach (loadInstalledPackages() as $package) { echo ' <tr> <td>', $package['name'], '</td> <td>', !empty($package['package_id']) ? $package['package_id'] : $package['id'], '</td> <td>', $package['version'], '</td> </tr>'; } echo ' </table> </div>'; }
/** * Browse a server's list of packages. * * - Accessed by action=admin;area=packageservers;sa=browse */ public function action_browse() { global $txt, $scripturl, $forum_version, $context; // Load our subs worker. require_once SUBSDIR . '/PackageServers.subs.php'; // Browsing the packages from a server if (isset($_GET['server'])) { if ($_GET['server'] == '') { redirectexit('action=admin;area=packageservers'); } $server = (int) $_GET['server']; // Query the server list to find the current server. $packageserver = fetchPackageServers($server); $url = $packageserver[0]['url']; $name = $packageserver[0]['name']; // If the server does not exist, dump out. if (empty($url)) { fatal_lang_error('couldnt_connect', false); } // If there is a relative link, append to the stored server url. if (isset($_GET['relative'])) { $url = $url . (substr($url, -1) == '/' ? '' : '/') . $_GET['relative']; } // Clear any "absolute" URL. Since "server" is present, "absolute" is garbage. unset($_GET['absolute']); } elseif (isset($_GET['absolute']) && $_GET['absolute'] != '') { // Initialize the required variables. $server = ''; $url = $_GET['absolute']; $name = ''; $_GET['package'] = $url . '/packages.xml?language=' . $context['user']['language']; // Clear any "relative" URL. Since "server" is not present, "relative" is garbage. unset($_GET['relative']); $token = checkConfirm('get_absolute_url'); if ($token !== true) { $context['sub_template'] = 'package_confirm'; $context['page_title'] = $txt['package_servers']; $context['confirm_message'] = sprintf($txt['package_confirm_view_package_content'], htmlspecialchars($_GET['absolute'], ENT_COMPAT, 'UTF-8')); $context['proceed_href'] = $scripturl . '?action=admin;area=packageservers;sa=browse;absolute=' . urlencode($_GET['absolute']) . ';confirm=' . $token; return; } } else { fatal_lang_error('couldnt_connect', false); } // Attempt to connect. If unsuccessful... try the URL. if (!isset($_GET['package']) || file_exists($_GET['package'])) { $_GET['package'] = $url . '/packages.xml?language=' . $context['user']['language']; } // Check to be sure the packages.xml file actually exists where it is should be... or dump out. if ((isset($_GET['absolute']) || isset($_GET['relative'])) && !url_exists($_GET['package'])) { fatal_lang_error('packageget_unable', false, array($url . '/index.php')); } // Might take some time. @set_time_limit(600); // Read packages.xml and parse into Xml_Array. (the true tells it to trim things ;).) require_once SUBSDIR . '/XmlArray.class.php'; $listing = new Xml_Array(fetch_web_data($_GET['package']), true); // Errm.... empty file? Try the URL.... if (!$listing->exists('package-list')) { fatal_lang_error('packageget_unable', false, array($url . '/index.php')); } // List out the packages... $context['package_list'] = array(); $listing = $listing->path('package-list[0]'); // Use the package list's name if it exists. if ($listing->exists('list-title')) { $name = Util::htmlspecialchars($listing->fetch('list-title')); } // Pick the correct template. $context['sub_template'] = 'package_list'; $context['page_title'] = $txt['package_servers'] . ($name != '' ? ' - ' . $name : ''); $context['package_server'] = $server; // By default we use an unordered list, unless there are no lists with more than one package. $context['list_type'] = 'ul'; // Load the installed packages // We'll figure out if what they select a package they already have installed. $instadds = loadInstalledPackages(); // Look through the list of installed mods... $installed_adds = array(); foreach ($instadds as $installed_add) { $installed_adds[$installed_add['package_id']] = $installed_add['version']; } // Get default author and email if they exist. if ($listing->exists('default-author')) { $default_author = Util::htmlspecialchars($listing->fetch('default-author')); if ($listing->exists('default-author/@email')) { $default_email = Util::htmlspecialchars($listing->fetch('default-author/@email')); } } // Get default web site if it exists. if ($listing->exists('default-website')) { $default_website = Util::htmlspecialchars($listing->fetch('default-website')); if ($listing->exists('default-website/@title')) { $default_title = Util::htmlspecialchars($listing->fetch('default-website/@title')); } } $the_version = strtr($forum_version, array('ElkArte ' => '')); if (!empty($_SESSION['version_emulate'])) { $the_version = $_SESSION['version_emulate']; } $packageNum = 0; $packageSection = 0; $sections = $listing->set('section'); foreach ($sections as $i => $section) { $context['package_list'][$packageSection] = array('title' => '', 'text' => '', 'items' => array()); $packages = $section->set('title|heading|text|remote|rule|modification|language|avatar-pack|theme|smiley-set'); foreach ($packages as $thisPackage) { $package = array('type' => $thisPackage->name()); if (in_array($package['type'], array('title', 'text'))) { $context['package_list'][$packageSection][$package['type']] = Util::htmlspecialchars($thisPackage->fetch('.')); } elseif (in_array($package['type'], array('heading', 'rule'))) { $package['name'] = Util::htmlspecialchars($thisPackage->fetch('.')); } elseif ($package['type'] == 'remote') { $remote_type = $thisPackage->exists('@type') ? $thisPackage->fetch('@type') : 'relative'; if ($remote_type == 'relative' && (substr($thisPackage->fetch('@href'), 0, 7) !== 'http://' || substr($thisPackage->fetch('@href'), 0, 8) !== 'https://')) { if (isset($_GET['absolute'])) { $current_url = $_GET['absolute'] . '/'; } elseif (isset($_GET['relative'])) { $current_url = $_GET['relative'] . '/'; } else { $current_url = ''; } $current_url .= $thisPackage->fetch('@href'); if (isset($_GET['absolute'])) { $package['href'] = $scripturl . '?action=admin;area=packageservers;sa=browse;absolute=' . $current_url; } else { $package['href'] = $scripturl . '?action=admin;area=packageservers;sa=browse;server=' . $context['package_server'] . ';relative=' . $current_url; } } else { $current_url = $thisPackage->fetch('@href'); $package['href'] = $scripturl . '?action=admin;area=packageservers;sa=browse;absolute=' . $current_url; } $package['name'] = Util::htmlspecialchars($thisPackage->fetch('.')); $package['link'] = '<a href="' . $package['href'] . '">' . $package['name'] . '</a>'; } else { if (isset($_GET['absolute'])) { $current_url = $_GET['absolute'] . '/'; } elseif (isset($_GET['relative'])) { $current_url = $_GET['relative'] . '/'; } else { $current_url = ''; } $server_att = $server != '' ? ';server=' . $server : ''; $package += $thisPackage->to_array(); if (isset($package['website'])) { unset($package['website']); } $package['author'] = array(); if ($package['description'] == '') { $package['description'] = $txt['package_no_description']; } else { $package['description'] = parse_bbc(preg_replace('~\\[[/]?html\\]~i', '', Util::htmlspecialchars($package['description']))); } $package['is_installed'] = isset($installed_adds[$package['id']]); $package['is_current'] = $package['is_installed'] && $installed_adds[$package['id']] == $package['version']; $package['is_newer'] = $package['is_installed'] && $installed_adds[$package['id']] > $package['version']; // This package is either not installed, or installed but old. Is it supported on this version? if (!$package['is_installed'] || !$package['is_current'] && !$package['is_newer']) { if ($thisPackage->exists('version/@for')) { $package['can_install'] = matchPackageVersion($the_version, $thisPackage->fetch('version/@for')); } } else { $package['can_install'] = false; } $already_exists = getPackageInfo(basename($package['filename'])); $package['download_conflict'] = is_array($already_exists) && $already_exists['id'] == $package['id'] && $already_exists['version'] != $package['version']; $package['href'] = $url . '/' . $package['filename']; $package['name'] = Util::htmlspecialchars($package['name']); $package['link'] = '<a href="' . $package['href'] . '">' . $package['name'] . '</a>'; $package['download']['href'] = $scripturl . '?action=admin;area=packageservers;sa=download' . $server_att . ';package=' . $current_url . $package['filename'] . ($package['download_conflict'] ? ';conflict' : '') . ';' . $context['session_var'] . '=' . $context['session_id']; $package['download']['link'] = '<a href="' . $package['download']['href'] . '">' . $package['name'] . '</a>'; // Author name, email if ($thisPackage->exists('author') || isset($default_author)) { if ($thisPackage->exists('author/@email')) { $package['author']['email'] = $thisPackage->fetch('author/@email'); } elseif (isset($default_email)) { $package['author']['email'] = $default_email; } if ($thisPackage->exists('author') && $thisPackage->fetch('author') != '') { $package['author']['name'] = Util::htmlspecialchars($thisPackage->fetch('author')); } else { $package['author']['name'] = $default_author; } if (!empty($package['author']['email'])) { // Only put the "mailto:" if it looks like a valid email address. Some may wish to put a link to an IM Form or other web mail form. $package['author']['href'] = preg_match('~^[\\w\\.\\-]+@[\\w][\\w\\-\\.]+[\\w]$~', $package['author']['email']) != 0 ? 'mailto:' . $package['author']['email'] : $package['author']['email']; $package['author']['link'] = '<a href="' . $package['author']['href'] . '">' . $package['author']['name'] . '</a>'; } } // Author website if ($thisPackage->exists('website') || isset($default_website)) { if ($thisPackage->exists('website') && $thisPackage->exists('website/@title')) { $package['author']['website']['name'] = Util::htmlspecialchars($thisPackage->fetch('website/@title')); } elseif (isset($default_title)) { $package['author']['website']['name'] = $default_title; } elseif ($thisPackage->exists('website')) { $package['author']['website']['name'] = Util::htmlspecialchars($thisPackage->fetch('website')); } else { $package['author']['website']['name'] = $default_website; } if ($thisPackage->exists('website') && $thisPackage->fetch('website') != '') { $authorhomepage = Util::htmlspecialchars($thisPackage->fetch('website')); } else { $authorhomepage = $default_website; } if (stripos($authorhomepage, 'a href') === false) { $package['author']['website']['href'] = $authorhomepage; $package['author']['website']['link'] = '<a href="' . $authorhomepage . '">' . $package['author']['website']['name'] . '</a>'; } else { if (preg_match('/a href="(.+?)"/', $authorhomepage, $match) == 1) { $package['author']['website']['href'] = $match[1]; } else { $package['author']['website']['href'] = ''; } $package['author']['website']['link'] = $authorhomepage; } } else { $package['author']['website']['href'] = ''; $package['author']['website']['link'] = ''; } } $package['is_remote'] = $package['type'] == 'remote'; $package['is_title'] = $package['type'] == 'title'; $package['is_heading'] = $package['type'] == 'heading'; $package['is_text'] = $package['type'] == 'text'; $package['is_line'] = $package['type'] == 'rule'; $packageNum = in_array($package['type'], array('title', 'heading', 'text', 'remote', 'rule')) ? 0 : $packageNum + 1; $package['count'] = $packageNum; if (!in_array($package['type'], array('title', 'text'))) { $context['package_list'][$packageSection]['items'][] = $package; } if ($package['count'] > 1) { $context['list_type'] = 'ol'; } } $packageSection++; } // Lets make sure we get a nice new spiffy clean $package to work with. Otherwise we get PAIN! unset($package); foreach ($context['package_list'] as $ps_id => $packageSection) { foreach ($packageSection['items'] as $i => $package) { if ($package['count'] == 0 || isset($package['can_install'])) { continue; } $context['package_list'][$ps_id]['items'][$i]['can_install'] = false; $packageInfo = getPackageInfo($url . '/' . $package['filename']); if (is_array($packageInfo) && $packageInfo['xml']->exists('install')) { $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. $context['package_list'][$ps_id]['items'][$i]['can_install'] = true; break; } } } } } }
/** * Browse a server's list of packages. * * - Accessed by action=admin;area=packageservers;sa=browse */ public function action_browse() { global $txt, $scripturl, $forum_version, $context; // Load our subs worker. require_once SUBSDIR . '/PackageServers.subs.php'; $server = ''; $url = ''; $name = ''; // Browsing the packages from a server if (isset($_GET['server'])) { list($name, $url, $server) = $this->_package_server(); } else { fatal_lang_error('couldnt_connect', false); } // Might take some time. @set_time_limit(60); // Fetch the package listing from the server and json decode $listing = json_decode(fetch_web_data($url)); // List out the packages... $context['package_list'] = array(); // Pick the correct template. $context['sub_template'] = 'package_list'; $context['page_title'] = $txt['package_servers'] . ($name != '' ? ' - ' . $name : ''); $context['package_server'] = $server; // If we received data if (!empty($listing)) { // Load the installed packages $instadds = loadInstalledPackages(); // Look through the list of installed mods and get version information for the compare $installed_adds = array(); foreach ($instadds as $installed_add) { $installed_adds[$installed_add['package_id']] = $installed_add['version']; } $the_version = strtr($forum_version, array('ElkArte ' => '')); if (!empty($_SESSION['version_emulate'])) { $the_version = $_SESSION['version_emulate']; } // Parse the json file, each section contains a category of addons $packageNum = 0; foreach ($listing as $packageSection => $section_items) { // Section title / header for the category $context['package_list'][$packageSection] = array('title' => Util::htmlspecialchars(ucwords($packageSection)), 'text' => '', 'items' => array()); // Load each package array as an item $section_count = 0; foreach ($section_items as $thisPackage) { // Read in the package info from the fetched data $package = $this->_load_package_json($thisPackage, $packageSection); // Check the install status $package['can_install'] = false; $is_installed = array_intersect(array_keys($installed_adds), $package['id']); $package['is_installed'] = !empty($is_installed); // Set the ID from our potential list should the ID not be provided in the package .yaml $package['id'] = $package['is_installed'] ? array_shift($is_installed) : $package['id'][0]; // Version installed vs version available $package['is_current'] = !empty($package['is_installed']) && $installed_adds[$package['id']] == $package['version']; $package['is_newer'] = !empty($package['is_installed']) && $installed_adds[$package['id']] > $package['version']; // Set the package filename for downloading and pre-existence checking $base_name = $this->_rename_master($package['server']['download']); $package['filename'] = basename($package['server']['download']); // This package is either not installed, or installed but old. if (!$package['is_installed'] || !$package['is_current'] && !$package['is_newer']) { // Does it claim to install on this version of ElkArte? $path_parts = pathinfo($base_name); if (!empty($thisPackage->elkversion) && isset($path_parts['extension']) && in_array($path_parts['extension'], array('zip', 'tar', 'gz', 'tar.gz'))) { // No install range given, then set one, it will all work out in the end. $for = strpos($thisPackage->elkversion, '-') === false ? $thisPackage->elkversion . '-' . $the_version : $thisPackage->elkversion; $package['can_install'] = matchPackageVersion($the_version, $for); } } // See if this filename already exists on the server $already_exists = getPackageInfo($base_name); $package['download_conflict'] = is_array($already_exists) && $already_exists['id'] == $package['id'] && $already_exists['version'] != $package['version']; $package['count'] = ++$packageNum; // Build the download to server link $server_att = $server != '' ? ';server=' . $server : ''; $current_url = ';section=' . $packageSection . ';num=' . $section_count; $package['download']['href'] = $scripturl . '?action=admin;area=packageservers;sa=download' . $server_att . $current_url . ';package=' . $package['filename'] . ($package['download_conflict'] ? ';conflict' : '') . ';' . $context['session_var'] . '=' . $context['session_id']; $package['download']['link'] = '<a href="' . $package['download']['href'] . '">' . $package['name'] . '</a>'; // Add this package to the list $context['package_list'][$packageSection]['items'][$packageNum] = $package; $section_count++; } $context['package_list'][$packageSection]['text'] = sprintf($txt['mod_section_count'], $section_count); } } // Good time to sort the categories, the packages inside each category will be by last modification date. asort($context['package_list']); }