/**
 * Loads a plugin out of our shared plugins directory.
 *
 * Note - This function does not trigger plugin activation / deactivation hooks.
 * As such, it may not be compatible with all plugins
 *
 * @link http://lobby.vip.wordpress.com/plugins/ VIP Shared Plugins
 * @param string $plugin Optional. Plugin folder name of the plugin, or the folder and
 * plugin file name (such as wp-api/plugin.php), relative to either the VIP shared-plugins folder, or WP_PLUGIN_DIR
 * @param string $folder Deprecated. No longer used
 * @param bool $load_release_candidate Whether to load a release candidate version of this plugin, if available
 * @return bool True if the include was successful
 */
function wpcom_vip_load_plugin($plugin = false, $folder_not_used = null, $load_release_candidate = false)
{
    // Make sure there's a plugin to load
    if (empty($plugin)) {
        if (!WPCOM_IS_VIP_ENV) {
            die('wpcom_vip_load_plugin() was called without a first parameter!');
        }
    }
    // Is it a plugin file with multiple directories? Not supported. _could_ be supported
    // with some refactoring, but no real need to, just complicates things
    $exploded = explode(DIRECTORY_SEPARATOR, $plugin);
    if (count($exploded) > 2) {
        if (!WPCOM_IS_VIP_ENV) {
            die('wpcom_vip_load_plugin() was called with multiple subdirectories');
        } else {
            _doing_it_wrong('wpcom_vip_load_plugin', 'Subdirectories not supported in file paths', '');
            return false;
        }
    }
    // Is this a valid path? We know it has less than 3 parts, but it could still be
    // 'plugin/plugin' (need a php file, if specifying a path rather than a slug)
    if (count($exploded) === 2) {
        $pathinfo = pathinfo($plugin);
        if (!isset($pathinfo['extension']) || 'php' !== $pathinfo['extension']) {
            if (!WPCOM_IS_VIP_ENV) {
                die('wpcom_vip_load_plugin() was called with a path, but no php file was specified');
            } else {
                _doing_it_wrong('wpcom_vip_load_plugin', 'Must specify php file when loading via path', '');
                return false;
            }
        }
    }
    // Array of files to check for loading the plugin. This is to support
    // non-standard plugin structures, such as $folder/plugin.php
    $test_files = array("{$plugin}.php", 'plugin.php');
    // Is $plugin a filepath? If so, that's the only file we should test
    if (basename($plugin) !== $plugin) {
        $test_files = array(basename($plugin));
        // Update the $plugin to the slug, so we store it correctly and build paths correctly
        $plugin = dirname($plugin);
    }
    // Make sure $plugin and $folder are valid
    $plugin = _wpcom_vip_load_plugin_sanitizer($plugin);
    // Array of directories to check for the above files in, in priority order
    $test_directories = array();
    if (true === $load_release_candidate) {
        $test_directories[] = WP_CONTENT_DIR . '/mu-plugins/shared-plugins/release-candidates';
    }
    $test_directories[] = WP_PLUGIN_DIR;
    $test_directories[] = WP_CONTENT_DIR . '/mu-plugins/shared-plugins';
    $includepath = null;
    $plugin_type = null;
    foreach ($test_directories as $directory) {
        foreach ($test_files as $file) {
            // Prevent any traversal here
            $plugin = basename($plugin);
            // Just to be double, extra sure
            $file = basename($file);
            $path = "{$directory}/{$plugin}/{$file}";
            if (file_exists($path)) {
                $includepath = $path;
                // Store where we found it, so we can properly represent that in UI
                // This is usually the directory above
                $plugin_type = basename($directory);
                // release-candidates is a special case, as it's in a nested folder,
                // so we must look up one level
                if ('release-candidates' === $plugin_type) {
                    $plugin_type = dirname($directory);
                }
                // We found what we were looking for, break from both loops
                break 2;
            }
        }
    }
    if ($includepath && file_exists($includepath)) {
        wpcom_vip_add_loaded_plugin("{$plugin_type}/{$plugin}");
        return _wpcom_vip_include_plugin($includepath);
    } else {
        if (!WPCOM_IS_VIP_ENV) {
            die("Unable to load {$plugin} using wpcom_vip_load_plugin()!");
        }
    }
}
/**
 * Loads a plugin out of our shared plugins directory.
 *
 * @link http://lobby.vip.wordpress.com/plugins/ VIP Shared Plugins
 * @param string $plugin Optional. Plugin folder name (and filename) of the plugin
 * @param string $folder Optional. Folder to include from; defaults to "plugins". Useful for when you have multiple themes and your own shared plugins folder.
 * @return bool True if the include was successful
 */
function wpcom_vip_load_plugin($plugin = false, $folder = 'plugins', $load_release_candidate = false)
{
    // Force release candidate loading if the site has the correct sticker
    if (defined('WPCOM_IS_VIP_ENV') && true === WPCOM_IS_VIP_ENV && has_blog_sticker('vip-plugins-ui-rc-plugins')) {
        $load_release_candidate = true;
    }
    // Make sure there's a plugin to load
    if (empty($plugin)) {
        // On WordPress.com, use an internal function to message VIP about a bad call to this function
        if (function_exists('wpcom_is_vip')) {
            if (function_exists('send_vip_team_debug_message')) {
                // Use an expiring cache value to avoid spamming messages
                if (!wp_cache_get('noplugin', 'wpcom_vip_load_plugin')) {
                    send_vip_team_debug_message('WARNING: wpcom_vip_load_plugin() is being called without a $plugin parameter', 1);
                    wp_cache_set('noplugin', 1, 'wpcom_vip_load_plugin', 3600);
                }
            }
            return false;
        } else {
            die('wpcom_vip_load_plugin() was called without a first parameter!');
        }
    }
    // Make sure $plugin and $folder are valid
    $plugin = _wpcom_vip_load_plugin_sanitizer($plugin);
    if ('plugins' !== $folder) {
        $folder = _wpcom_vip_load_plugin_sanitizer($folder);
    }
    // Shared plugins are located at /wp-content/themes/vip/plugins/example-plugin/
    // You should keep your local copies of the plugins in the same location
    $includepath = WP_CONTENT_DIR . "/themes/vip/{$folder}/{$plugin}/{$plugin}.php";
    $release_candidate_includepath = WP_CONTENT_DIR . "/themes/vip/{$folder}/release-candidates/{$plugin}/{$plugin}.php";
    if (true === $load_release_candidate && file_exists($release_candidate_includepath)) {
        $includepath = $release_candidate_includepath;
    }
    if (file_exists($includepath)) {
        wpcom_vip_add_loaded_plugin("{$folder}/{$plugin}");
        // Since we're going to be include()'ing inside of a function,
        // we need to do some hackery to get the variable scope we want.
        // See http://www.php.net/manual/en/language.variables.scope.php#91982
        // Start by marking down the currently defined variables (so we can exclude them later)
        $pre_include_variables = get_defined_vars();
        // Now include
        include_once $includepath;
        // If there's a wpcom-helper file for the plugin, load that too
        $helper_path = WP_CONTENT_DIR . "/themes/vip/{$folder}/{$plugin}/wpcom-helper.php";
        if (file_exists($helper_path)) {
            require_once $helper_path;
        }
        // Blacklist out some variables
        $blacklist = array('blacklist' => 0, 'pre_include_variables' => 0, 'new_variables' => 0);
        // Let's find out what's new by comparing the current variables to the previous ones
        $new_variables = array_diff_key(get_defined_vars(), $GLOBALS, $blacklist, $pre_include_variables);
        // global each new variable
        foreach ($new_variables as $new_variable => $devnull) {
            global ${$new_variable};
        }
        // Set the values again on those new globals
        extract($new_variables);
        return true;
    } else {
        // On WordPress.com, use an internal function to message VIP about the bad call to this function
        if (function_exists('wpcom_is_vip')) {
            if (function_exists('send_vip_team_debug_message')) {
                // Use an expiring cache value to avoid spamming messages
                $cachekey = md5($folder . '|' . $plugin);
                if (!wp_cache_get("notfound_{$cachekey}", 'wpcom_vip_load_plugin')) {
                    send_vip_team_debug_message("WARNING: wpcom_vip_load_plugin() is trying to load a non-existent file ( /{$folder}/{$plugin}/{$plugin}.php )", 1);
                    wp_cache_set("notfound_{$cachekey}", 1, 'wpcom_vip_load_plugin', 3600);
                }
            }
            return false;
            // die() in non-WordPress.com environments so you know you made a mistake
        } else {
            die("Unable to load {$plugin} ({$folder}) using wpcom_vip_load_plugin()!");
        }
    }
}