Пример #1
0
/**
*  Disables all plugins with unresolved dependencies
*  and resolves the load order for all enabled plugins.
*
* @return   bool    True or False, depending on whether it was
*                   necessary to alter the load order of a plugin
* @since            Geeklog 1.8.0
*/
function PLG_resolveDependencies()
{
    global $_PLUGINS, $_TABLES;
    $retval = '';
    $flag = true;
    // false means that all dependencies are resolved
    while ($flag) {
        // loop until ALL dependencies are satisfied
        $flag = false;
        // set this if any plugin has been disabled during the loop
        foreach ($_PLUGINS as $key => $pi_name) {
            if (!PLG_checkDependencies($pi_name)) {
                // plugin has unresolved dependencies
                // disable plugin;
                $flag = true;
                // disabling a plugin can break the dependencies of a plugin that has already been checked, remember to loop again
                PLG_enableStateChange($pi_name, false);
                DB_change($_TABLES['plugins'], 'pi_enabled', 0, 'pi_name', $pi_name);
                PLG_pluginStateChange($pi_name, 'disabled');
                unset($_PLUGINS[$key]);
            }
        }
    }
    // automatically resolve load order for enabled plugins
    $index = 2000;
    // how far through the load order to push back plugins
    $maxqueries = 50;
    // just in case...
    $globalflag = false;
    // remember if we change the load order of any plugin
    $flag = true;
    // set true if we need another pass in the while loop
    while ($flag && $maxqueries) {
        // Now check if the load order is correct
        $flag = false;
        // get the load orders of all enabled plugins
        $q = DB_query("SELECT pi_name, pi_load FROM {$_TABLES['plugins']} WHERE pi_enabled='1'");
        $plo = array();
        // Plugins Load Order
        while ($a = DB_fetchArray($q)) {
            $plo[] = $a;
        }
        $params = array();
        foreach ($plo as $key => $value) {
            // for each available plugin
            $maxqueries--;
            $params = PLG_getParams($value['pi_name']);
            // get dependencies
            if (isset($params['requires']) && is_array($params['requires'])) {
                // if any
                foreach ($params['requires'] as $rkey => $rvalue) {
                    // process each dependency
                    if (isset($rvalue['plugin'])) {
                        // get the load order of the required plugin
                        foreach ($plo as $new_key => $new_value) {
                            if ($new_value['pi_name'] == $rvalue['plugin']) {
                                $dep_load = $new_value['pi_load'];
                                break;
                            }
                        }
                        if ($dep_load > $value['pi_load']) {
                            // incorrect load order
                            // move down the order
                            DB_query("UPDATE {$_TABLES['plugins']} SET pi_load = '{$index}' WHERE pi_name = '{$value['pi_name']}'");
                            $index++;
                            $flag = true;
                            $globalflag = true;
                        }
                    }
                }
            }
        }
    }
    reorderplugins();
    if ($globalflag == false) {
        return true;
        // no change
    } else {
        return false;
        // something changed
    }
}
Пример #2
0
/**
* Continue a plugin upgrade that started in plugin_upload()
*
* @param    string  $plugin         plugin name
* @param    string  $pi_version     current plugin version
* @param    string  $code_version   plugin version to be upgraded to
* @return   string                  HTML refresh
* @see      function plugin_upload
*
*/
function continue_upgrade($plugin, $pi_version, $code_version)
{
    global $_CONF, $_TABLES;
    $retval = '';
    $msg_with_plugin_name = false;
    // simple sanity checks
    if (empty($plugin) || empty($pi_version) || empty($code_version) || $pi_version == $code_version) {
        $msg = 72;
    } else {
        // more sanity checks
        $result = DB_query("SELECT pi_version, pi_enabled FROM {$_TABLES['plugins']} WHERE pi_name = '" . addslashes($plugin) . "'");
        $A = DB_fetchArray($result);
        if (!empty($A['pi_version']) && $A['pi_enabled'] == 1 && $A['pi_version'] == $pi_version && $A['pi_version'] != $code_version) {
            // continue upgrade process that started in plugin_upload()
            $result = PLG_upgrade($plugin);
            if ($result === true) {
                PLG_pluginStateChange($plugin, 'upgraded');
                $msg = 60;
                // successfully updated
            } else {
                $msg_with_plugin_name = true;
                $msg = $result;
                // message provided by the plugin
            }
        } else {
            $msg = 72;
        }
    }
    $url = $_CONF['site_admin_url'] . '/plugins.php?msg=' . $msg;
    if ($msg_with_plugin_name) {
        $url .= '&plugin=' . $plugin;
    }
    $retval = COM_refresh($url);
    return $retval;
}
Пример #3
0
/**
* Handle uploaded plugin
*
* @return   string      HTML: redirect or main plugin screen + error message
*
*/
function plugin_upload()
{
    global $_CONF, $_TABLES;
    $retval = '';
    $path_admin = $_CONF['path_html'] . substr($_CONF['site_admin_url'], strlen($_CONF['site_url']) + 1) . '/';
    $upload_success = false;
    // If an error occured while uploading the file.
    $error_msg = plugin_getUploadError($_FILES['plugin']);
    if (!empty($error_msg)) {
        $retval .= plugin_main($error_msg);
    } else {
        require_once $_CONF['path_system'] . 'classes/unpacker.class.php';
        $plugin_file = $_CONF['path_data'] . $_FILES['plugin']['name'];
        // Name the plugin file
        $archive = new unpacker($_FILES['plugin']['tmp_name'], $_FILES['plugin']['type']);
        $tmp = $archive->getlist();
        // Grab the contents of the tarball to see what the plugin name is
        $dirname = preg_replace('/\\/.*$/', '', $tmp[0]['filename']);
        if (empty($dirname)) {
            // If $dirname is blank it's probably because the user uploaded a non Tarball file.
            $retval = COM_refresh($_CONF['site_admin_url'] . '/plugins.php?msg=100');
        } else {
            $pi_did_exist = false;
            // plugin directory already existed
            $pi_had_entry = false;
            // plugin had an entry in the database
            $pi_was_enabled = false;
            // plugin was enabled
            if (file_exists($_CONF['path'] . 'plugins/' . $dirname)) {
                $pi_did_exist = true;
                // plugin directory already exists
                $pstatus = DB_query("SELECT pi_name, pi_enabled FROM {$_TABLES['plugins']} WHERE pi_name = '{$dirname}'");
                $A = DB_fetchArray($pstatus);
                if (isset($A['pi_name'])) {
                    $pi_had_entry = true;
                    $pi_was_enabled = $A['pi_enabled'] == 1;
                }
                if ($pi_was_enabled) {
                    // disable temporarily while we move the files around
                    DB_change($_TABLES['plugins'], 'pi_enabled', 0, 'pi_name', $dirname);
                }
                require_once 'System.php';
                $plugin_dir = $_CONF['path'] . 'plugins/' . $dirname;
                if (file_exists($plugin_dir . '.previous')) {
                    @System::rm('-rf ' . $plugin_dir . '.previous');
                }
                if (file_exists($plugin_dir)) {
                    rename($plugin_dir, $plugin_dir . '.previous');
                }
                $public_dir = $_CONF['path_html'] . $dirname;
                if (file_exists($public_dir . '.previous')) {
                    @System::rm('-rf ' . $public_dir . '.previous');
                }
                if (file_exists($public_dir)) {
                    rename($public_dir, $public_dir . '.previous');
                }
                $admin_dir = $path_admin . 'plugins/' . $dirname;
                if (file_exists($admin_dir . '.previous')) {
                    @System::rm('-rf ' . $admin_dir . '.previous');
                }
                if (file_exists($admin_dir)) {
                    rename($admin_dir, $admin_dir . '.previous');
                }
            }
            /**
             * Install the plugin
             * This doesn't work if the public_html & public_html/admin/plugins directories aren't 777
             */
            // Extract the tarball to data so we can get the $pi_name name from admin/install.php
            $archive->unpack($_CONF['path'] . 'data/', array($dirname . '/admin/install.php'));
            $plugin_inst = $_CONF['path'] . 'data/' . $dirname . '/admin/install.php';
            $fdata = '';
            $fhandle = @fopen($plugin_inst, 'r');
            if ($fhandle) {
                $fdata = fread($fhandle, filesize($plugin_inst));
                fclose($fhandle);
            }
            // Remove the plugin from data/
            require_once 'System.php';
            @System::rm('-rf ' . $_CONF['path'] . 'data/' . $dirname);
            /**
             * One time I wanted to install a muffler on my car and
             * needed to match up the outside diameter of the car's
             * exhaust pipe to the inside diameter of the muffler.
             * Unfortunately, when I went to the auto parts store they
             * didn't have a coupling adapter that would perfectly
             * match the two pipes, only a bunch of smaller adapters.
             * I ended up using about 4 small adapters to step down
             * one size at a time to the size of the muffler's input.
             *
             * It's kind of like this regular expression:
             *
             */
            $fdata = preg_replace('/\\n/', '', $fdata);
            $fdata = preg_replace('/ /', '', $fdata);
            $pi_name = preg_replace('/^.*\\$pi\\_name=\'/', '', $fdata);
            $pi_name = preg_replace('/\'.*$/', '', $pi_name);
            // Some plugins don't have $pi_name set in their install.php file,
            // This means our regex won't work and we should just use $dirname
            if (preg_match('/\\<\\?php/', $pi_name) || preg_match('/--/', $pi_name)) {
                $pi_name = $dirname;
            } elseif (empty($pi_name)) {
                $pi_name = $dirname;
            }
            // Extract the uploaded archive to the plugins directory
            $upload_success = $archive->unpack($_CONF['path'] . 'plugins/');
            $plg_path = $_CONF['path'] . 'plugins/' . $pi_name . '/';
            if ($upload_success) {
                if (file_exists($plg_path . 'public_html')) {
                    rename($plg_path . 'public_html', $_CONF['path_html'] . $pi_name);
                }
                if (file_exists($plg_path . 'admin')) {
                    rename($plg_path . 'admin', $path_admin . 'plugins/' . $pi_name);
                }
            }
            unset($archive);
            // Collect some garbage
            // cleanup when uploading a new version
            if ($pi_did_exist) {
                $plugin_dir = $_CONF['path'] . 'plugins/' . $dirname;
                if (file_exists($plugin_dir . '.previous')) {
                    @System::rm('-rf ' . $plugin_dir . '.previous');
                }
                $public_dir = $_CONF['path_html'] . $dirname;
                if (file_exists($public_dir . '.previous')) {
                    @System::rm('-rf ' . $public_dir . '.previous');
                }
                $admin_dir = $path_admin . 'plugins/' . $dirname;
                if (file_exists($admin_dir . '.previous')) {
                    @System::rm('-rf ' . $admin_dir . '.previous');
                }
                if ($pi_was_enabled) {
                    DB_change($_TABLES['plugins'], 'pi_enabled', 1, 'pi_name', $dirname);
                }
            }
            $msg_with_plugin_name = false;
            if ($pi_did_exist) {
                if ($pi_was_enabled) {
                    // check if we have to perform an update
                    $pi_version = DB_getItem($_TABLES['plugins'], 'pi_version', "pi_name = '{$dirname}'");
                    $code_version = PLG_chkVersion($dirname);
                    if (!empty($code_version) && $code_version != $pi_version) {
                        $result = PLG_upgrade($dirname);
                        if ($result === true) {
                            PLG_pluginStateChange($dirname, 'upgraded');
                            $msg = 60;
                            // successfully updated
                        } else {
                            $msg_with_plugin_name = true;
                            $msg = $result;
                            // message provided by the plugin
                        }
                    } else {
                        $msg = 98;
                        // successfully uploaded
                    }
                } else {
                    $msg = 98;
                    // successfully uploaded
                }
            } elseif (file_exists($plg_path . 'autoinstall.php')) {
                // if the plugin has an autoinstall.php, install it now
                if (plugin_autoinstall($pi_name)) {
                    PLG_pluginStateChange($pi_name, 'installed');
                    $msg = 44;
                    // successfully installed
                } else {
                    $msg = 72;
                    // an error occured while installing the plugin
                }
            } else {
                $msg = 98;
                // successfully uploaded
            }
            $url = $_CONF['site_admin_url'] . '/plugins.php?msg=' . $msg;
            if ($msg_with_plugin_name) {
                $url .= '&amp;plugin=' . $dirname;
            }
            $retval = COM_refresh($url);
        }
    }
    return $retval;
}