Ejemplo n.º 1
0
function DownloadLanguage()
{
    global $context, $sourcedir, $forum_version, $boarddir, $txt, $smcFunc, $scripturl, $modSettings;
    loadLanguage('ManageSettings');
    require_once $sourcedir . '/Subs-Package.php';
    // Clearly we need to know what to request.
    if (!isset($_GET['did'])) {
        fatal_lang_error('no_access', false);
    }
    // Some lovely context.
    $context['download_id'] = $_GET['did'];
    $context['sub_template'] = 'download_language';
    $context['menu_data_' . $context['admin_menu_id']]['current_subsection'] = 'add';
    // Can we actually do the installation - and do they want to?
    if (!empty($_POST['do_install']) && !empty($_POST['copy_file'])) {
        checkSession('get');
        $chmod_files = array();
        $install_files = array();
        // Check writable status.
        foreach ($_POST['copy_file'] as $file) {
            // Check it's not very bad.
            if (strpos($file, '..') !== false || substr($file, 0, 6) != 'Themes' && !preg_match('~agreement\\.[A-Za-z-_0-9]+\\.txt$~', $file)) {
                fatal_error($txt['languages_download_illegal_paths']);
            }
            $chmod_files[] = $boarddir . '/' . $file;
            $install_files[] = $file;
        }
        // Call this in case we have work to do.
        $file_status = create_chmod_control($chmod_files);
        $files_left = $file_status['files']['notwritable'];
        // Something not writable?
        if (!empty($files_left)) {
            $context['error_message'] = $txt['languages_download_not_chmod'];
        } elseif (!empty($install_files)) {
            $archive_content = read_tgz_file('http://download.simplemachines.org/fetch_language.php?version=' . urlencode(strtr($forum_version, array('SMF ' => ''))) . ';fetch=' . urlencode($_GET['did']), $boarddir, false, true, $install_files);
            // Make sure the files aren't stuck in the cache.
            package_flush_cache();
            $context['install_complete'] = sprintf($txt['languages_download_complete_desc'], $scripturl . '?action=admin;area=languages');
            return;
        }
    }
    // Open up the old china.
    if (!isset($archive_content)) {
        $archive_content = read_tgz_file('http://download.simplemachines.org/fetch_language.php?version=' . urlencode(strtr($forum_version, array('SMF ' => ''))) . ';fetch=' . urlencode($_GET['did']), null);
    }
    if (empty($archive_content)) {
        fatal_error($txt['add_language_error_no_response']);
    }
    // Now for each of the files, let's do some *stuff*
    $context['files'] = array('lang' => array(), 'other' => array());
    $context['make_writable'] = array();
    foreach ($archive_content as $file) {
        $dirname = dirname($file['filename']);
        $filename = basename($file['filename']);
        $extension = substr($filename, strrpos($filename, '.') + 1);
        // Don't do anything with files we don't understand.
        if (!in_array($extension, array('php', 'jpg', 'gif', 'jpeg', 'png', 'txt'))) {
            continue;
        }
        // Basic data.
        $context_data = array('name' => $filename, 'destination' => $boarddir . '/' . $file['filename'], 'generaldest' => $file['filename'], 'size' => $file['size'], 'writable' => false, 'default_copy' => true, 'exists' => false);
        // Does the file exist, is it different and can we overwrite?
        if (file_exists($boarddir . '/' . $file['filename'])) {
            if (is_writable($boarddir . '/' . $file['filename'])) {
                $context_data['writable'] = true;
            }
            // Finally, do we actually think the content has changed?
            if ($file['size'] == filesize($boarddir . '/' . $file['filename']) && $file['md5'] == md5_file($boarddir . '/' . $file['filename'])) {
                $context_data['exists'] = 'same';
                $context_data['default_copy'] = false;
            } elseif ($file['md5'] == md5(preg_replace("~[\r]?\n~", "\r\n", file_get_contents($boarddir . '/' . $file['filename'])))) {
                $context_data['exists'] = 'same';
                $context_data['default_copy'] = false;
            } else {
                $context_data['exists'] = 'different';
            }
        } else {
            // Can we at least stick it in the directory...
            if (is_writable($boarddir . '/' . $dirname)) {
                $context_data['writable'] = true;
            }
        }
        // I love PHP files, that's why I'm a developer and not an artistic type spending my time drinking absinth and living a life of sin...
        if ($extension == 'php' && preg_match('~\\w+\\.\\w+(?:-utf8)?\\.php~', $filename)) {
            $context_data += array('version' => '??', 'cur_version' => false, 'version_compare' => 'newer');
            list($name, $language) = explode('.', $filename);
            // Let's get the new version, I like versions, they tell me that I'm up to date.
            if (preg_match('~\\s*Version:\\s+(.+?);\\s*' . preg_quote($name, '~') . '~i', $file['preview'], $match) == 1) {
                $context_data['version'] = $match[1];
            }
            // Now does the old file exist - if so what is it's version?
            if (file_exists($boarddir . '/' . $file['filename'])) {
                // OK - what is the current version?
                $fp = fopen($boarddir . '/' . $file['filename'], 'rb');
                $header = fread($fp, 768);
                fclose($fp);
                // Find the version.
                if (preg_match('~(?://|/\\*)\\s*Version:\\s+(.+?);\\s*' . preg_quote($name, '~') . '(?:[\\s]{2}|\\*/)~i', $header, $match) == 1) {
                    $context_data['cur_version'] = $match[1];
                    // How does this compare?
                    if ($context_data['cur_version'] == $context_data['version']) {
                        $context_data['version_compare'] = 'same';
                    } elseif ($context_data['cur_version'] > $context_data['version']) {
                        $context_data['version_compare'] = 'older';
                    }
                    // Don't recommend copying if the version is the same.
                    if ($context_data['version_compare'] != 'newer') {
                        $context_data['default_copy'] = false;
                    }
                }
            }
            // Add the context data to the main set.
            $context['files']['lang'][] = $context_data;
        } else {
            // If we think it's a theme thing, work out what the theme is.
            if (substr($dirname, 0, 6) == 'Themes' && preg_match('~Themes[\\/]([^\\/]+)[\\/]~', $dirname, $match)) {
                $theme_name = $match[1];
            } else {
                $theme_name = 'misc';
            }
            // Assume it's an image, could be an acceptance note etc but rare.
            $context['files']['images'][$theme_name][] = $context_data;
        }
        // Collect together all non-writable areas.
        if (!$context_data['writable']) {
            $context['make_writable'][] = $context_data['destination'];
        }
    }
    // So, I'm a perfectionist - let's get the theme names.
    $theme_indexes = array();
    foreach ($context['files']['images'] as $k => $dummy) {
        $indexes[] = $k;
    }
    $context['theme_names'] = array();
    if (!empty($indexes)) {
        $value_data = array('query' => array(), 'params' => array());
        foreach ($indexes as $k => $index) {
            $value_data['query'][] = 'value LIKE {string:value_' . $k . '}';
            $value_data['params']['value_' . $k] = '%' . $index;
        }
        $request = $smcFunc['db_query']('', '
			SELECT id_theme, value
			FROM {db_prefix}themes
			WHERE id_member = {int:no_member}
				AND variable = {string:theme_dir}
				AND (' . implode(' OR ', $value_data['query']) . ')', array_merge($value_data['params'], array('no_member' => 0, 'theme_dir' => 'theme_dir', 'index_compare_explode' => 'value LIKE \'%' . implode('\' OR value LIKE \'%', $indexes) . '\'')));
        $themes = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Find the right one.
            foreach ($indexes as $index) {
                if (strpos($row['value'], $index) !== false) {
                    $themes[$row['id_theme']] = $index;
                }
            }
        }
        $smcFunc['db_free_result']($request);
        if (!empty($themes)) {
            // Now we have the id_theme we can get the pretty description.
            $request = $smcFunc['db_query']('', '
				SELECT id_theme, value
				FROM {db_prefix}themes
				WHERE id_member = {int:no_member}
					AND variable = {string:name}
					AND id_theme IN ({array_int:theme_list})', array('theme_list' => array_keys($themes), 'no_member' => 0, 'name' => 'name'));
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                // Now we have it...
                $context['theme_names'][$themes[$row['id_theme']]] = $row['value'];
            }
            $smcFunc['db_free_result']($request);
        }
    }
    // Before we go to far can we make anything writable, eh, eh?
    if (!empty($context['make_writable'])) {
        // What is left to be made writable?
        $file_status = create_chmod_control($context['make_writable']);
        $context['still_not_writable'] = $file_status['files']['notwritable'];
        // Mark those which are now writable as such.
        foreach ($context['files'] as $type => $data) {
            if ($type == 'lang') {
                foreach ($data as $k => $file) {
                    if (!$file['writable'] && !in_array($file['destination'], $context['still_not_writable'])) {
                        $context['files'][$type][$k]['writable'] = true;
                    }
                }
            } else {
                foreach ($data as $theme => $files) {
                    foreach ($files as $k => $file) {
                        if (!$file['writable'] && !in_array($file['destination'], $context['still_not_writable'])) {
                            $context['files'][$type][$theme][$k]['writable'] = true;
                        }
                    }
                }
            }
        }
        // Are we going to need more language stuff?
        if (!empty($context['still_not_writable'])) {
            loadLanguage('Packages');
        }
    }
    // This is the list for the main files.
    $listOptions = array('id' => 'lang_main_files_list', 'title' => $txt['languages_download_main_files'], 'get_items' => array('function' => create_function('', '
				global $context;
				return $context[\'files\'][\'lang\'];
			')), 'columns' => array('name' => array('header' => array('value' => $txt['languages_download_filename']), 'data' => array('function' => create_function('$rowData', '
						global $context, $txt;

						return \'<strong>\' . $rowData[\'name\'] . \'</strong><br /><span class="smalltext">\' . $txt[\'languages_download_dest\'] . \': \' . $rowData[\'destination\'] . \'</span>\' . ($rowData[\'version_compare\'] == \'older\' ? \'<br />\' . $txt[\'languages_download_older\'] : \'\');
					'))), 'writable' => array('header' => array('value' => $txt['languages_download_writable']), 'data' => array('function' => create_function('$rowData', '
						global $txt;

						return \'<span style="color: \' . ($rowData[\'writable\'] ? \'green\' : \'red\') . \';">\' . ($rowData[\'writable\'] ? $txt[\'yes\'] : $txt[\'no\']) . \'</span>\';
					'), 'style' => 'text-align: center')), 'version' => array('header' => array('value' => $txt['languages_download_version']), 'data' => array('function' => create_function('$rowData', '
						global $txt;

						return \'<span style="color: \' . ($rowData[\'version_compare\'] == \'older\' ? \'red\' : ($rowData[\'version_compare\'] == \'same\' ? \'orange\' : \'green\')) . \';">\' . $rowData[\'version\'] . \'</span>\';
					'))), 'exists' => array('header' => array('value' => $txt['languages_download_exists']), 'data' => array('function' => create_function('$rowData', '
						global $txt;

						return $rowData[\'exists\'] ? ($rowData[\'exists\'] == \'same\' ? $txt[\'languages_download_exists_same\'] : $txt[\'languages_download_exists_different\']) : $txt[\'no\'];
					'))), 'copy' => array('header' => array('value' => $txt['languages_download_copy']), 'data' => array('function' => create_function('$rowData', '
						return \'<input type="checkbox" name="copy_file[]" value="\' . $rowData[\'generaldest\'] . \'" \' . ($rowData[\'default_copy\'] ? \'checked="checked"\' : \'\') . \' class="input_check" />\';
					'), 'style' => 'text-align: center; width: 4%;'))));
    // Kill the cache, as it is now invalid..
    if (!empty($modSettings['cache_enable'])) {
        cache_put_data('known_languages', null, !empty($modSettings['cache_enable']) && $modSettings['cache_enable'] < 1 ? 86400 : 3600);
        cache_put_data('known_languages_all', null, !empty($modSettings['cache_enable']) && $modSettings['cache_enable'] < 1 ? 86400 : 3600);
    }
    require_once $sourcedir . '/Subs-List.php';
    createList($listOptions);
    $context['default_list'] = 'lang_main_files_list';
}
Ejemplo n.º 2
0
function PackageDownload()
{
    global $txt, $scripturl, $boarddir, $context, $sourcedir, $smcFunc;
    // Use the downloaded sub template.
    $context['sub_template'] = 'downloaded';
    // Security is good...
    checkSession('get');
    // To download something, we need a valid server or url.
    if (empty($_GET['server']) && (!empty($_GET['get']) && !empty($_REQUEST['package']))) {
        fatal_lang_error('package_get_error_is_zero', false);
    }
    if (isset($_GET['server'])) {
        $server = (int) $_GET['server'];
        // Query the server table to find the requested server.
        $request = $smcFunc['db_query']('', '
			SELECT name, url
			FROM {db_prefix}package_servers
			WHERE id_server = {int:current_server}
			LIMIT 1', array('current_server' => $server));
        list($name, $url) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // If server does not exist then dump out.
        if (empty($url)) {
            fatal_lang_error('couldnt_connect', false);
        }
        $url = $url . '/';
    } else {
        // Initialize the requried variables.
        $server = '';
        $url = '';
    }
    if (isset($_REQUEST['byurl']) && !empty($_POST['filename'])) {
        $package_name = basename($_REQUEST['filename']);
    } else {
        $package_name = basename($_REQUEST['package']);
    }
    if (isset($_REQUEST['conflict']) || isset($_REQUEST['auto']) && file_exists($boarddir . '/Packages/' . $package_name)) {
        // Find the extension, change abc.tar.gz to abc_1.tar.gz...
        if (strrpos(substr($package_name, 0, -3), '.') !== false) {
            $ext = substr($package_name, strrpos(substr($package_name, 0, -3), '.'));
            $package_name = substr($package_name, 0, strrpos(substr($package_name, 0, -3), '.')) . '_';
        } else {
            $ext = '';
        }
        // Find the first available.
        $i = 1;
        while (file_exists($boarddir . '/Packages/' . $package_name . $i . $ext)) {
            $i++;
        }
        $package_name = $package_name . $i . $ext;
    }
    // First make sure it's a package.
    $packageInfo = getPackageInfo($url . $_REQUEST['package']);
    if (!is_array($packageInfo)) {
        fatal_lang_error($packageInfo);
    }
    // Use FTP if necessary.
    create_chmod_control(array($boarddir . '/Packages/' . $package_name), array('destination_url' => $scripturl . '?action=admin;area=packages;get;sa=download' . (isset($_GET['server']) ? ';server=' . $_GET['server'] : '') . (isset($_REQUEST['auto']) ? ';auto' : '') . ';package=' . $_REQUEST['package'] . (isset($_REQUEST['conflict']) ? ';conflict' : '') . ';' . $context['session_var'] . '=' . $context['session_id'], 'crash_on_error' => true));
    package_put_contents($boarddir . '/Packages/' . $package_name, fetch_web_data($url . $_REQUEST['package']));
    // Done!  Did we get this package automatically?
    if (preg_match('~^http://[\\w_\\-]+\\.simplemachines\\.org/~', $_REQUEST['package']) == 1 && strpos($_REQUEST['package'], 'dlattach') === false && isset($_REQUEST['auto'])) {
        redirectexit('action=admin;area=packages;sa=install;package=' . $package_name);
    }
    // You just downloaded a mod from SERVER_NAME_GOES_HERE.
    $context['package_server'] = $server;
    $context['package'] = getPackageInfo($package_name);
    if (!is_array($context['package'])) {
        fatal_lang_error('package_cant_download', false);
    }
    if ($context['package']['type'] == 'modification') {
        $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['install_mod'] . ' ]</a>';
    } elseif ($context['package']['type'] == 'avatar') {
        $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['use_avatars'] . ' ]</a>';
    } elseif ($context['package']['type'] == 'language') {
        $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['add_languages'] . ' ]</a>';
    } else {
        $context['package']['install']['link'] = '';
    }
    $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['list_files'] . ' ]</a>';
    // Free a little bit of memory...
    unset($context['package']['xml']);
    $context['page_title'] = $txt['download_success'];
}
Ejemplo n.º 3
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];
 }
Ejemplo n.º 4
0
function PackageFTPTest()
{
    global $context, $txt, $package_ftp;
    checkSession('get');
    // Try to make the FTP connection.
    create_chmod_control(array(), array('force_find_error' => true));
    // Deal with the template stuff.
    loadTemplate('Xml');
    $context['sub_template'] = 'generic_xml';
    $context['template_layers'] = array();
    // Define the return data, this is simple.
    $context['xml_data'] = array('results' => array('identifier' => 'result', 'children' => array(array('attributes' => array('success' => !empty($package_ftp) ? 1 : 0), 'value' => !empty($package_ftp) ? $txt['package_ftp_test_success'] : (isset($context['package_ftp'], $context['package_ftp']['error']) ? $context['package_ftp']['error'] : $txt['package_ftp_test_failed'])))));
}
Ejemplo n.º 5
0
 /**
  * Install a smiley set.
  */
 public function action_install()
 {
     global $modSettings, $scripturl, $context, $txt, $user_info;
     isAllowedTo('manage_smileys');
     checkSession('request');
     // One of these two may be necessary
     loadLanguage('Errors');
     loadLanguage('Packages');
     require_once SUBSDIR . '/Smileys.subs.php';
     require_once SUBSDIR . '/Package.subs.php';
     // Installing unless proven otherwise
     $testing = false;
     $destination = '';
     $name = '';
     if (isset($_REQUEST['set_gz'])) {
         $base_name = strtr(basename($_REQUEST['set_gz']), ':/', '-_');
         $name = Util::htmlspecialchars(strtok(basename($_REQUEST['set_gz']), '.'));
         $name_pr = preg_replace(array('/\\s/', '/\\.[\\.]+/', '/[^\\w_\\.\\-]/'), array('_', '.', ''), $name);
         $context['filename'] = $base_name;
         // Check that the smiley is from simplemachines.org, for now... maybe add mirroring later.
         if (!isAuthorizedServer($_REQUEST['set_gz']) == 0) {
             fatal_lang_error('not_valid_server');
         }
         $destination = BOARDDIR . '/packages/' . $base_name;
         if (file_exists($destination)) {
             fatal_lang_error('package_upload_error_exists');
         }
         // Let's copy it to the packages directory
         file_put_contents($destination, fetch_web_data($_REQUEST['set_gz']));
         $testing = true;
     } elseif (isset($_REQUEST['package'])) {
         $base_name = basename($_REQUEST['package']);
         $name = Util::htmlspecialchars(strtok(basename($_REQUEST['package']), '.'));
         $name_pr = preg_replace(array('/\\s/', '/\\.[\\.]+/', '/[^\\w_\\.\\-]/'), array('_', '.', ''), $name);
         $context['filename'] = $base_name;
         $destination = BOARDDIR . '/packages/' . basename($_REQUEST['package']);
     }
     if (!file_exists($destination)) {
         fatal_lang_error('package_no_file', false);
     }
     // Make sure temp directory exists and is empty.
     if (file_exists(BOARDDIR . '/packages/temp')) {
         deltree(BOARDDIR . '/packages/temp', false);
     }
     if (!mktree(BOARDDIR . '/packages/temp', 0755)) {
         deltree(BOARDDIR . '/packages/temp', false);
         if (!mktree(BOARDDIR . '/packages/temp', 0777)) {
             deltree(BOARDDIR . '/packages/temp', false);
             // @todo not sure about url in destination_url
             create_chmod_control(array(BOARDDIR . '/packages/temp/delme.tmp'), array('destination_url' => $scripturl . '?action=admin;area=smileys;sa=install;set_gz=' . $_REQUEST['set_gz'], 'crash_on_error' => true));
             deltree(BOARDDIR . '/packages/temp', false);
             if (!mktree(BOARDDIR . '/packages/temp', 0777)) {
                 fatal_lang_error('package_cant_download', false);
             }
         }
     }
     $extracted = read_tgz_file($destination, BOARDDIR . '/packages/temp');
     // @todo needs to change the URL in the next line ;)
     if (!$extracted) {
         fatal_lang_error('packageget_unable', false, array('http://custom.elkarte.net/index.php?action=search;type=12;basic_search=' . $name));
     }
     if ($extracted && !file_exists(BOARDDIR . '/packages/temp/package-info.xml')) {
         foreach ($extracted as $file) {
             if (basename($file['filename']) == 'package-info.xml') {
                 $base_path = dirname($file['filename']) . '/';
                 break;
             }
         }
     }
     if (!isset($base_path)) {
         $base_path = '';
     }
     if (!file_exists(BOARDDIR . '/packages/temp/' . $base_path . 'package-info.xml')) {
         fatal_lang_error('package_get_error_missing_xml', false);
     }
     $smileyInfo = getPackageInfo($context['filename']);
     if (!is_array($smileyInfo)) {
         fatal_lang_error($smileyInfo);
     }
     // See if it is installed?
     if (isSmileySetInstalled($smileyInfo['id'])) {
         fata_lang_error('package_installed_warning1');
     }
     // Everything is fine, now it's time to do something, first we test
     $actions = parsePackageInfo($smileyInfo['xml'], true, 'install');
     $context['post_url'] = $scripturl . '?action=admin;area=smileys;sa=install;package=' . $base_name;
     $context['has_failure'] = false;
     $context['actions'] = array();
     $context['ftp_needed'] = false;
     foreach ($actions as $action) {
         if ($action['type'] == 'readme' || $action['type'] == 'license') {
             $type = 'package_' . $action['type'];
             if (file_exists(BOARDDIR . '/packages/temp/' . $base_path . $action['filename'])) {
                 $context[$type] = htmlspecialchars(trim(file_get_contents(BOARDDIR . '/packages/temp/' . $base_path . $action['filename']), "\n\r"), ENT_COMPAT, 'UTF-8');
             } elseif (file_exists($action['filename'])) {
                 $context[$type] = htmlspecialchars(trim(file_get_contents($action['filename']), "\n\r"), ENT_COMPAT, 'UTF-8');
             }
             if (!empty($action['parse_bbc'])) {
                 require_once SUBSDIR . '/Post.subs.php';
                 preparsecode($context[$type]);
                 $context[$type] = parse_bbc($context[$type]);
             } else {
                 $context[$type] = nl2br($context[$type]);
             }
             continue;
         } elseif ($action['type'] == 'require-dir') {
             // Do this one...
             $thisAction = array('type' => $txt['package_extract'] . ' ' . ($action['type'] == 'require-dir' ? $txt['package_tree'] : $txt['package_file']), 'action' => Util::htmlspecialchars(strtr($action['destination'], array(BOARDDIR => '.'))));
             $file = BOARDDIR . '/packages/temp/' . $base_path . $action['filename'];
             if (isset($action['filename']) && (!file_exists($file) || !is_writable(dirname($action['destination'])))) {
                 $context['has_failure'] = true;
                 $thisAction += array('description' => $txt['package_action_error'], 'failed' => true);
             }
             // Show a description for the action if one is provided
             if (empty($thisAction['description'])) {
                 $thisAction['description'] = isset($action['description']) ? $action['description'] : '';
             }
             $context['actions'][] = $thisAction;
         } elseif ($action['type'] == 'credits') {
             // Time to build the billboard
             $credits_tag = array('url' => $action['url'], 'license' => $action['license'], 'copyright' => $action['copyright'], 'title' => $action['title']);
         }
     }
     if ($testing) {
         $context['sub_template'] = 'view_package';
         $context['uninstalling'] = false;
         $context['is_installed'] = false;
         $context['package_name'] = $smileyInfo['name'];
         loadTemplate('Packages');
     } else {
         $actions = parsePackageInfo($smileyInfo['xml'], false, 'install');
         foreach ($context['actions'] as $action) {
             updateSettings(array('smiley_sets_known' => $modSettings['smiley_sets_known'] . ',' . basename($action['action']), 'smiley_sets_names' => $modSettings['smiley_sets_names'] . "\n" . $smileyInfo['name'] . (count($context['actions']) > 1 ? ' ' . (!empty($action['description']) ? Util::htmlspecialchars($action['description']) : basename($action['action'])) : '')));
         }
         package_flush_cache();
         // Time to tell pacman we have a new package installed!
         package_put_contents(BOARDDIR . '/packages/installed.list', time());
         // Credits tag?
         $credits_tag = empty($credits_tag) ? '' : serialize($credits_tag);
         $installed = array('filename' => $smileyInfo['filename'], 'name' => $smileyInfo['name'], 'package_id' => $smileyInfo['id'], 'version' => $smileyInfo['filename'], 'id_member' => $user_info['id'], 'member_name' => $user_info['name'], 'credits_tag' => $credits_tag);
         logPackageInstall($installed);
         logAction('install_package', array('package' => Util::htmlspecialchars($smileyInfo['name']), 'version' => Util::htmlspecialchars($smileyInfo['version'])), 'admin');
         cache_put_data('parsing_smileys', null, 480);
         cache_put_data('posting_smileys', null, 480);
     }
     if (file_exists(BOARDDIR . '/packages/temp')) {
         deltree(BOARDDIR . '/packages/temp');
     }
     if (!$testing) {
         redirectexit('action=admin;area=smileys');
     }
 }
Ejemplo n.º 6
0
 /**
  * Download a package.
  *
  * - Accessed by action=admin;area=packageservers;sa=download
  */
 public function action_download()
 {
     global $txt, $scripturl, $context;
     require_once SUBSDIR . '/PackageServers.subs.php';
     // Use the downloaded sub template.
     $context['sub_template'] = 'downloaded';
     // Security is good...
     checkSession('get');
     // To download something, we need a valid server or url.
     if (empty($_GET['server']) && (!empty($_GET['get']) && !empty($_REQUEST['package']))) {
         fatal_lang_error('package_get_error_is_zero', false);
     }
     if (isset($_GET['server'])) {
         $server = (int) $_GET['server'];
         // Query the server table to find the requested server.
         $packageserver = fetchPackageServers($server);
         $url = $packageserver[0]['url'];
         // If server does not exist then dump out.
         if (empty($url)) {
             fatal_lang_error('couldnt_connect', false);
         }
         $url = $url . '/';
     } else {
         // Initialize the required variables.
         $server = '';
         $url = '';
     }
     // Entered a url and name to download?
     if (isset($_REQUEST['byurl']) && !empty($_POST['filename'])) {
         $package_name = basename($_REQUEST['filename']);
     } else {
         $package_name = basename($_REQUEST['package']);
     }
     // Is this a "master" package from github or bitbucket?
     if (preg_match('~^http(s)?://(www.)?(bitbucket\\.org|github\\.com)/(.+?(master(\\.zip|\\.tar\\.gz)))$~', $_REQUEST['package'], $matches) == 1) {
         // @todo maybe use the name/version in the package instead, although the link will be cleaner
         // Name this master.zip based on repo name in the link
         $path_parts = pathinfo($matches[4]);
         list(, $newname, ) = explode('/', $path_parts['dirname']);
         // Just to be safe, no invalid file characters
         $invalid = array_merge(array_map('chr', range(0, 31)), array('<', '>', ':', '"', '/', '\\', '|', '?', '*'));
         $package_name = str_replace($invalid, '_', $newname) . $matches[6];
         // We could read the package info and see if we have a duplicate id & version, however that is
         // not always accurate, especially when dealing with repos.  So for now just put in in no conflict mode
         // and do the save.
         $_REQUEST['auto'] = true;
     }
     if (isset($_REQUEST['conflict']) || isset($_REQUEST['auto']) && file_exists(BOARDDIR . '/packages/' . $package_name)) {
         // Find the extension, change abc.tar.gz to abc_1.tar.gz...
         if (strrpos(substr($package_name, 0, -3), '.') !== false) {
             $ext = substr($package_name, strrpos(substr($package_name, 0, -3), '.'));
             $package_name = substr($package_name, 0, strrpos(substr($package_name, 0, -3), '.')) . '_';
         } else {
             $ext = '';
         }
         // Find the first available.
         $i = 1;
         while (file_exists(BOARDDIR . '/packages/' . $package_name . $i . $ext)) {
             $i++;
         }
         $package_name = $package_name . $i . $ext;
     }
     // First make sure it's a package.
     $packageInfo = getPackageInfo($url . $_REQUEST['package']);
     if (!is_array($packageInfo)) {
         fatal_lang_error($packageInfo);
     }
     // Save the package to disk, use FTP if necessary
     create_chmod_control(array(BOARDDIR . '/packages/' . $package_name), array('destination_url' => $scripturl . '?action=admin;area=packageservers;sa=download' . (isset($_GET['server']) ? ';server=' . $_GET['server'] : '') . (isset($_REQUEST['auto']) ? ';auto' : '') . ';package=' . $_REQUEST['package'] . (isset($_REQUEST['conflict']) ? ';conflict' : '') . ';' . $context['session_var'] . '=' . $context['session_id'], 'crash_on_error' => true));
     package_put_contents(BOARDDIR . '/packages/' . $package_name, fetch_web_data($url . $_REQUEST['package']));
     // Done!  Did we get this package automatically?
     if (preg_match('~^http://[\\w_\\-]+\\.elkarte\\.net/~', $_REQUEST['package']) == 1 && strpos($_REQUEST['package'], 'dlattach') === false && isset($_REQUEST['auto'])) {
         redirectexit('action=admin;area=packages;sa=install;package=' . $package_name);
     }
     // You just downloaded a addon from SERVER_NAME_GOES_HERE.
     $context['package_server'] = $server;
     // Read in the newly saved package information
     $context['package'] = getPackageInfo($package_name);
     if (!is_array($context['package'])) {
         fatal_lang_error('package_cant_download', false);
     }
     if ($context['package']['type'] == 'modification') {
         $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['install_mod'] . ' ]</a>';
     } elseif ($context['package']['type'] == 'avatar') {
         $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['use_avatars'] . ' ]</a>';
     } elseif ($context['package']['type'] == 'language') {
         $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['add_languages'] . ' ]</a>';
     } else {
         $context['package']['install']['link'] = '';
     }
     $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['list_files'] . ' ]</a>';
     // Free a little bit of memory...
     unset($context['package']['xml']);
     $context['page_title'] = $txt['download_success'];
 }
Ejemplo n.º 7
0
 /**
  * Download a package.
  *
  * What it does:
  * - Accessed by action=admin;area=packageservers;sa=download
  * - If server is set, loads json file from package server
  *     - requires both section and num values to validate the file to download from the json file
  * - If $_POST['byurl']) $_POST['filename'])) are set, will download a file from the url and save it as filename
  * - If just $_POST['byurl']) is set will fetch that file and save it
  *     - github and bitbucket master files are renamed to repo name to avoid collisions
  * - Files are saved to the package directory and validate to be ElkArte packages
  */
 public function action_download()
 {
     global $txt, $scripturl, $context;
     require_once SUBSDIR . '/PackageServers.subs.php';
     // Use the downloaded sub template.
     $context['sub_template'] = 'downloaded';
     // Security is good...
     if (isset($_GET['server'])) {
         checkSession('get');
     } else {
         checkSession();
     }
     // To download something, we need either a valid server or url.
     if (empty($_GET['server']) && (!empty($_GET['get']) && !empty($_POST['package']))) {
         fatal_lang_error('package_get_error_is_zero', false);
     }
     // Start off with nothing
     $package_name = '';
     $server = '';
     $url = '';
     // Download from a package server?
     if (!empty($_GET['server'])) {
         list(, $url, $server) = $this->_package_server();
         // Fetch the package listing from the package server
         $listing = json_decode(fetch_web_data($url));
         // Find the requested package by section and number, make sure it matches
         $section = $listing->{$_GET}['section'];
         // This is what they requested, yes?
         if (basename($section[$_GET['num']]->server[0]->download) === $_GET['package']) {
             // Where to download it from
             $package_name = $this->_rename_master($section[$_GET['num']]->server[0]->download);
             $path_url = pathinfo($section[$_GET['num']]->server[0]->download);
             $url = isset($path_url['dirname']) ? $path_url['dirname'] . '/' : '';
         } else {
             fatal_lang_error('package_cant_download', false);
         }
     } elseif (isset($_POST['byurl']) && !empty($_POST['filename'])) {
         $package_name = basename($_POST['filename']);
     } else {
         $package_name = $this->_rename_master($_POST['package']);
     }
     // Avoid over writing any existing package files of the same name
     if (isset($_REQUEST['conflict']) || isset($_REQUEST['auto']) && file_exists(BOARDDIR . '/packages/' . $package_name)) {
         // Find the extension, change abc.tar.gz to abc_1.tar.gz...
         if (strrpos(substr($package_name, 0, -3), '.') !== false) {
             $ext = substr($package_name, strrpos(substr($package_name, 0, -3), '.'));
             $package_name = substr($package_name, 0, strrpos(substr($package_name, 0, -3), '.')) . '_';
         } else {
             $ext = '';
         }
         // Find the first available free name
         $i = 1;
         while (file_exists(BOARDDIR . '/packages/' . $package_name . $i . $ext)) {
             $i++;
         }
         $package_name = $package_name . $i . $ext;
     }
     // First make sure it's a package.
     $packageInfo = getPackageInfo($url . $_REQUEST['package']);
     if (!is_array($packageInfo)) {
         fatal_lang_error($packageInfo);
     }
     // Save the package to disk as $package_name, use FTP if necessary
     create_chmod_control(array(BOARDDIR . '/packages/' . $package_name), array('destination_url' => $scripturl . '?action=admin;area=packageservers;sa=download' . (isset($_GET['server']) ? ';server=' . $_GET['server'] : '') . (isset($_REQUEST['auto']) ? ';auto' : '') . ';package=' . $_REQUEST['package'] . (isset($_REQUEST['conflict']) ? ';conflict' : '') . ';' . $context['session_var'] . '=' . $context['session_id'], 'crash_on_error' => true));
     package_put_contents(BOARDDIR . '/packages/' . $package_name, fetch_web_data($url . $_REQUEST['package']));
     // Done!  Did we get this package automatically?
     if (preg_match('~^http://[\\w_\\-]+\\.elkarte\\.net/~', $_REQUEST['package']) == 1 && strpos($_REQUEST['package'], 'dlattach') === false && isset($_REQUEST['auto'])) {
         redirectexit('action=admin;area=packages;sa=install;package=' . $package_name);
     }
     // You just downloaded a addon from SERVER_NAME_GOES_HERE.
     $context['package_server'] = $server;
     // Read in the newly saved package information
     $context['package'] = getPackageInfo($package_name);
     if (!is_array($context['package'])) {
         fatal_lang_error('package_cant_download', false);
     }
     if ($context['package']['type'] == 'modification') {
         $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['install_mod'] . ' ]</a>';
     } elseif ($context['package']['type'] == 'avatar') {
         $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['use_avatars'] . ' ]</a>';
     } elseif ($context['package']['type'] == 'language') {
         $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['add_languages'] . ' ]</a>';
     } else {
         $context['package']['install']['link'] = '';
     }
     $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['list_files'] . ' ]</a>';
     // Free a little bit of memory...
     unset($context['package']['xml']);
     $context['page_title'] = $txt['download_success'];
 }