<?php

if (!defined('ABSPATH')) {
    exit;
}
if (!class_exists('WP_Rollback')) {
    final class WP_Rollback
    {
        private static $instance;
        public $wpr_settings;
        public $plugins_api = 'https://api.wordpress.org/plugins';
        public $themes_repo = 'https://themes.svn.wordpress.org';
        public $plugin_file;
        public $plugin_slug;
        public $versions = array();
        public $current_version;
        public static function instance()
        {
            if (!isset(self::$instance) && !self::$instance instanceof WP_Rollback && is_admin()) {
                self::$instance = new WP_Rollback();
                self::$instance->setup_constants();
                if (isset($_GET['plugin_file']) && $_GET['page'] == 'wp-rollback') {
                    self::$instance->setup_plugin_vars();
                }
                self::$instance->hooks();
                self::$instance->includes();
            }
            return self::$instance;
        }
        public function __clone()
        {
            _doing_it_wrong(__FUNCTION__, __('Cheatin&#8217; huh?', 'wp-rollback'), '1.0');
        }
        public function __wakeup()
        {
            _doing_it_wrong(__FUNCTION__, __('Cheatin&#8217; huh?', 'wp-rollback'), '1.0');
        }
        private function setup_constants()
        {
            if (!defined('WP_ROLLBACK_PLUGIN_DIR')) {
                define('WP_ROLLBACK_PLUGIN_DIR', plugin_dir_path(__FILE__));
            }
            if (!defined('WP_ROLLBACK_PLUGIN_URL')) {
                define('WP_ROLLBACK_PLUGIN_URL', plugin_dir_url(__FILE__));
            }
            if (!defined('WP_ROLLBACK_PLUGIN_FILE')) {
                define('WP_ROLLBACK_PLUGIN_FILE', __FILE__);
            }
        }
        private function setup_plugin_vars()
        {
            $this->set_plugin_slug();
            $svn_tags = $this->get_svn_tags('plugin', $this->plugin_slug);
            $this->set_svn_versions_data($svn_tags);
        }
        private function hooks()
        {
            add_action('plugins_loaded', array(self::$instance, 'load_textdomain'));
            add_action('admin_enqueue_scripts', array(self::$instance, 'scripts'));
            add_action('admin_menu', array(self::$instance, 'admin_menu'), 20);
            add_action('pre_current_active_plugins', array(self::$instance, 'pre_current_active_plugins'), 20, 1);
            add_action('wp_ajax_is_wordpress_theme', array(self::$instance, 'is_wordpress_theme'));
            add_action('set_site_transient_update_themes', array(self::$instance, 'wpr_theme_updates_list'));
            add_filter('wp_prepare_themes_for_js', array(self::$instance, 'wpr_prepare_themes_js'));
            add_filter('plugin_action_links', array(self::$instance, 'plugin_action_links'), 20, 4);
            add_action('network_admin_menu', array(self::$instance, 'admin_menu'), 20);
            add_filter('network_admin_plugin_action_links', array(self::$instance, 'plugin_action_links'), 20, 4);
            add_filter('theme_action_links', array(self::$instance, 'theme_action_links'), 20, 4);
            add_filter('wp_ajax_wpr_check_changelog', array(self::$instance, 'get_plugin_changelog'));
        }
        private function includes()
        {
        }
        public function scripts($hook)
        {
            if ('themes.php' === $hook) {
                wp_enqueue_script('wp_rollback_themes_script', plugin_dir_url(__FILE__) . 'assets/js/themes-wp-rollback.js', array('jquery'), false, true);
                wp_localize_script('wp_rollback_themes_script', 'wpr_vars', array('ajaxurl' => admin_url(), 'ajax_loader' => admin_url('images/spinner.gif'), 'nonce' => wp_create_nonce('wpr_rollback_nonce'), 'text_rollback_label' => __('Rollback', 'wp-rollback'), 'text_not_rollbackable' => __('No Rollback Available: This is a non-WordPress.org theme.', 'wp-rollback'), 'text_loading_rollback' => __('Loading...', 'wp-rollback')));
            }
            if (!in_array($hook, array('index_page_wp-rollback', 'dashboard_page_wp-rollback'))) {
                return;
            }
            $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
            wp_register_style('wp_rollback_css', plugin_dir_url(__FILE__) . 'assets/css/wp-rollback.css');
            wp_enqueue_style('wp_rollback_css');
            wp_register_style('wp_rollback_modal_css', plugin_dir_url(__FILE__) . 'assets/css/magnific-popup.css');
            wp_enqueue_style('wp_rollback_modal_css');
            wp_register_script('wp_rollback_modal', plugin_dir_url(__FILE__) . 'assets/js/jquery.magnific-popup' . $suffix . '.js', array('jquery'));
            wp_enqueue_script('wp_rollback_modal');
            wp_register_script('wp_rollback_script', plugin_dir_url(__FILE__) . 'assets/js/wp-rollback.js', array('jquery'));
            wp_enqueue_script('wp_rollback_script');
            wp_enqueue_script('updates');
            wp_localize_script('wp_rollback_script', 'wpr_vars', array('ajaxurl' => admin_url(), 'text_no_changelog_found' => isset($_GET['plugin_slug']) ? sprintf(__('Sorry, we couldn\'t find a changelog entry found for this version. Try checking the <a href="%s" target="_blank">developer log</a> on WP.org.', 'wp-rollback'), 'https://wordpress.org/plugins/' . $_GET['plugin_slug'] . '/#developers') : '', 'version_missing' => __('Please select a version number to perform a rollback.', 'wp-rollback')));
        }
        public function load_textdomain()
        {
            $wpr_lang_dir = dirname(plugin_basename(WP_ROLLBACK_PLUGIN_FILE)) . '/languages/';
            $wpr_lang_dir = apply_filters('wpr_languages_directory', $wpr_lang_dir);
            $locale = apply_filters('plugin_locale', get_locale(), 'wp-rollback');
            $mofile = sprintf('%1$s-%2$s.mo', 'wp-rollback', $locale);
            $mofile_local = $wpr_lang_dir . $mofile;
            $mofile_global = WP_LANG_DIR . '/wp-rollback/' . $mofile;
            if (file_exists($mofile_global)) {
                load_textdomain('wp-rollback', $mofile_global);
            } elseif (file_exists($mofile_local)) {
                load_textdomain('wp-rollback', $mofile_local);
            } else {
                load_plugin_textdomain('wp-rollback', false, $wpr_lang_dir);
            }
        }
        public function html()
        {
            if (!current_user_can('update_plugins')) {
                wp_die(__('You do not have sufficient permissions to perform rollbacks for this site.', 'wp-rollback'));
            }
            include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
            $defaults = apply_filters('wpr_rollback_html_args', array('page' => 'wp-rollback', 'plugin_file' => '', 'action' => '', 'plugin_version' => '', 'plugin' => ''));
            $args = wp_parse_args($_GET, $defaults);
            if (!empty($args['plugin_version'])) {
                check_admin_referer('wpr_rollback_nonce');
                include WP_ROLLBACK_PLUGIN_DIR . '/includes/class-rollback-plugin-upgrader.php';
                include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-action.php';
            } elseif (!empty($args['theme_version'])) {
                check_admin_referer('wpr_rollback_nonce');
                include WP_ROLLBACK_PLUGIN_DIR . '/includes/class-rollback-theme-upgrader.php';
                include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-action.php';
            } else {
                check_admin_referer('wpr_rollback_nonce');
                include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-menu.php';
            }
        }
        public function get_plugin_changelog()
        {
            if (!isset($_POST['slug']) || empty($_POST['slug'])) {
                return false;
            }
            $url = 'https://api.wordpress.org/plugins/info/1.0/' . $_POST['slug'];
            $response = wp_remote_get($url);
            if (wp_remote_retrieve_response_code($response) !== 200) {
                return null;
            }
            $response = maybe_unserialize(wp_remote_retrieve_body($response));
            echo $response->sections['changelog'];
            wp_die();
        }
        public function get_svn_tags($type, $slug)
        {
            if ('plugin' === $type) {
                $url = $this->plugins_api . '/info/1.0/' . $this->plugin_slug . '.json';
            } elseif ('theme' === $type) {
                $url = $this->themes_repo . '/' . $slug;
            }
            $response = wp_remote_get($url);
            if (wp_remote_retrieve_response_code($response) !== 200) {
                return null;
            }
            return wp_remote_retrieve_body($response);
        }
        public function set_svn_versions_data($html)
        {
            if (!$html) {
                return false;
            }
            if (($json = json_decode($html)) && $html != $json) {
                $versions = array_keys((array) $json->versions);
            } else {
                $DOM = new DOMDocument();
                $DOM->loadHTML($html);
                $versions = array();
                $items = $DOM->getElementsByTagName('a');
                foreach ($items as $item) {
                    $href = str_replace('/', '', $item->getAttribute('href'));
                    if (strpos($href, 'http') === false && '..' !== $href) {
                        $versions[] = $href;
                    }
                }
            }
            $this->versions = array_reverse($versions);
            return $versions;
        }
        public function versions_select($type)
        {
            if (empty($this->versions)) {
                $versions_html = '<div class="wpr-error"><p>' . sprintf(__('It appears there are no version to select. This is likely due to the %s author not using tags for their versions and only committing new releases to the repository trunk.', 'wp-rollback'), $type) . '</p></div>';
                return apply_filters('versions_failure_html', $versions_html);
            }
            $versions_html = '<ul class="wpr-version-list">';
            usort($this->versions, 'version_compare');
            $this->versions = array_reverse($this->versions);
            foreach ($this->versions as $version) {
                $versions_html .= '<li class="wpr-version-li">';
                $versions_html .= '<label><input type="radio" value="' . esc_attr($version) . '" name="' . $type . '_version">' . $version;
                if ($version === $this->current_version) {
                    $versions_html .= '<span class="current-version">' . __('Installed Version', 'wp-rollback') . '</span>';
                }
                $versions_html .= '</label>';
                if ('plugin' === $type) {
                    $versions_html .= ' <a href="#" class="wpr-changelog-link" data-version="' . $version . '">' . __('View Changelog', 'wp-rollback') . '</a>';
                }
                $versions_html .= '</li>';
            }
            $versions_html .= '</ul>';
            return apply_filters('versions_select_html', $versions_html);
        }
        private function set_plugin_slug()
        {
            if (!isset($_GET['plugin_file'])) {
                return false;
            }
            if (isset($_GET['current_version'])) {
                $curr_version = explode(' ', $_GET['current_version']);
                $this->current_version = apply_filters('wpr_current_version', $curr_version[0]);
            }
            include_once ABSPATH . 'wp-admin/includes/plugin.php';
            $plugin_file = WP_PLUGIN_DIR . '/' . $_GET['plugin_file'];
            if (!file_exists($plugin_file)) {
                wp_die('Plugin you\'re referencing does not exist.');
            }
            $plugin_slug = explode('/', plugin_basename($plugin_file));
            $this->plugin_file = apply_filters('wpr_plugin_file', $plugin_file);
            $this->plugin_slug = apply_filters('wpr_plugin_slug', $plugin_slug[0]);
            return $plugin_slug;
        }
        public function admin_menu()
        {
            if (isset($_GET['page']) && $_GET['page'] == 'wp-rollback') {
                add_dashboard_page(__('Rollback', 'wp-rollback'), __('Rollback', 'wp-rollback'), 'update_plugins', 'wp-rollback', array(self::$instance, 'html'));
            }
        }
        public function pre_current_active_plugins($plugins)
        {
            $updated = $plugins;
            foreach ($updated as $key => $value) {
                $updated[$key] = $value;
                $updated[$key]['rollback'] = true;
            }
            return $updated;
        }
        public function plugin_action_links($actions, $plugin_file, $plugin_data, $context)
        {
            $plugin_data = apply_filters('wpr_plugin_data', $plugin_data);
            if (!isset($plugin_data['package']) || strpos($plugin_data['package'], 'https://downloads.wordpress.org') === false) {
                return $actions;
            }
            if (is_multisite() && (!is_network_admin() && !is_main_site())) {
                return $actions;
            }
            if (!isset($plugin_data['Version'])) {
                return $actions;
            }
            $rollback_url = 'index.php?page=wp-rollback&type=plugin&plugin_file=' . $plugin_file;
            $rollback_url = add_query_arg(apply_filters('wpr_plugin_query_args', array('current_version' => urlencode($plugin_data['Version']), 'rollback_name' => urlencode($plugin_data['Name']), 'plugin_slug' => urlencode($plugin_data['slug']), '_wpnonce' => wp_create_nonce('wpr_rollback_nonce'))), $rollback_url);
            $actions['rollback'] = apply_filters('wpr_plugin_markup', '<a href="' . esc_url($rollback_url) . '">' . __('Rollback', 'wp-rollback') . '</a>');
            return apply_filters('wpr_plugin_action_links', $actions);
        }
        public function theme_action_links($actions, $theme, $context)
        {
            $rollback_themes = get_site_transient('rollback_themes');
            if (!is_object($rollback_themes)) {
                $this->wpr_theme_updates_list();
                $rollback_themes = get_site_transient('rollback_themes');
            }
            $theme_slug = isset($theme->template) ? $theme->template : '';
            if (empty($theme_slug) || !array_key_exists($theme_slug, $rollback_themes->response)) {
                return $actions;
            }
            $theme_file = isset($rollback_themes->response[$theme_slug]['package']) ? $rollback_themes->response[$theme_slug]['package'] : '';
            $rollback_url = 'index.php?page=wp-rollback&type=theme&theme_file=' . $theme_file;
            if (!$theme->get('Version')) {
                return $actions;
            }
            $rollback_url = add_query_arg(apply_filters('wpr_theme_query_args', array('theme_file' => urlencode($theme_slug), 'current_version' => urlencode($theme->get('Version')), 'rollback_name' => urlencode($theme->get('Name')), '_wpnonce' => wp_create_nonce('wpr_rollback_nonce'))), $rollback_url);
            $actions['rollback'] = apply_filters('wpr_theme_markup', '<a href="' . esc_url($rollback_url) . '">' . __('Rollback', 'wp-rollback') . '</a>');
            return apply_filters('wpr_theme_action_links', $actions);
        }
        public function is_wordpress_theme()
        {
            if (is_multisite() && (!is_network_admin() && !is_main_site())) {
                return false;
            }
            $url = add_query_arg('request[slug]', $_POST['theme'], 'https://api.wordpress.org/themes/info/1.1/?action=theme_information');
            $wp_api = wp_remote_get($url);
            if (!is_wp_error($wp_api)) {
                if (isset($wp_api['body']) && strlen($wp_api['body']) > 0 && $wp_api['body'] !== 'false') {
                    echo 'wp';
                } else {
                    echo 'non-wp';
                }
            } else {
                echo 'error';
            }
            wp_die();
        }
        public function plugin_row_meta($plugin_meta, $plugin_file, $plugin_data, $status)
        {
            return $plugin_meta;
        }
        function wpr_theme_updates_list()
        {
            include ABSPATH . WPINC . '/version.php';
            if (defined('WP_INSTALLING') || !is_admin()) {
                return false;
            }
            $expiration = 12 * HOUR_IN_SECONDS;
            $installed_themes = wp_get_themes();
            $last_update = get_site_transient('update_themes');
            if (!is_object($last_update)) {
                set_site_transient('rollback_themes', time(), $expiration);
            }
            $themes = $checked = $request = array();
            $request['active'] = get_option('stylesheet');
            foreach ($installed_themes as $theme) {
                $checked[$theme->get_stylesheet()] = $theme->get('Version');
                $themes[$theme->get_stylesheet()] = array('Name' => $theme->get('Name'), 'Title' => $theme->get('Name'), 'Version' => '0.0.0.0.0.0', 'Author' => $theme->get('Author'), 'Author URI' => $theme->get('AuthorURI'), 'Template' => $theme->get_template(), 'Stylesheet' => $theme->get_stylesheet());
            }
            $request['themes'] = $themes;
            $timeout = 3 + (int) (count($themes) / 10);
            global $wp_version;
            $options = array('timeout' => $timeout, 'body' => array('themes' => json_encode($request)), 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo('url'));
            $url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/';
            if ($ssl = wp_http_supports(array('ssl'))) {
                $url = set_url_scheme($url, 'https');
            }
            $raw_response = wp_remote_post($url, $options);
            if ($ssl && is_wp_error($raw_response)) {
                trigger_error(__('An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.', 'wp-rollback') . ' ' . __('(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)', 'wp-rollback'), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE);
                $raw_response = wp_remote_post($http_url, $options);
            }
            set_site_transient('rollback_themes', time(), $expiration);
            if (is_wp_error($raw_response) || 200 != wp_remote_retrieve_response_code($raw_response)) {
                return false;
            }
            $new_update = new stdClass();
            $new_update->last_checked = time();
            $new_update->checked = $checked;
            $response = json_decode(wp_remote_retrieve_body($raw_response), true);
            if (is_array($response) && isset($response['themes'])) {
                $new_update->response = $response['themes'];
            }
            set_site_transient('rollback_themes', $new_update);
            return true;
        }
        function wpr_prepare_themes_js($prepared_themes)
        {
            $themes = array();
            $rollbacks = array();
            $wp_themes = get_site_transient('rollback_themes');
            if (empty($wp_themes) || !is_object($wp_themes)) {
                $this->wpr_theme_updates_list();
                $wp_themes = get_site_transient('rollback_themes');
            }
            if (is_object($wp_themes)) {
                $rollbacks = $wp_themes->response;
            }
            foreach ($prepared_themes as $key => $value) {
                $themes[$key] = $prepared_themes[$key];
                $themes[$key]['hasRollback'] = isset($rollbacks[$key]);
            }
            return $themes;
        }
    }
}
function WP_Rollback()
{
    return WP_Rollback::instance();
}
WP_Rollback();