Esempio n. 1
0
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;
                }
            }
        }
    }
}
Esempio n. 2
0
 /**
  * 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];
 }
Esempio n. 3
0
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);
    }
}
Esempio n. 4
0
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']);
 }