<?php
defined( 'ABSPATH' ) || exit;

/**
 * Custom Demo Importer exclusive for the Total theme.
 *
 * @package Total Theme Core
 * @subpackage demo-importer
 * @version 1.3
 */
if ( ! class_exists( 'WPEX_Demo_Importer' ) ) {

	class WPEX_Demo_Importer {

		/**
		 * The URL to the demos' data.
		 *
		 * @var string
		 */
		private $demos_remote_url;

		/**
		 * Contains the data for the demos.
		 *
		 * @var array
		 */
		private $demos;

		/**
		 * Contains the categories of demos.
		 *
		 * @var array
		 */
		private $categories;

		/**
		 * Contains the plugins required by the demos.
		 *
		 * @var array
		 */
		private $plugins;

		/**
		 * Instance of the WPEX_Plugin_Installer class which is used to
		 * activate and install plugins automatically.
		 *
		 * @var Object
		 */
		private $plugin_installer;

		/**
		 * Instance of the WPEX_Content_Importer class, which is used to import
		 * the XML content, theme customizations, widgets, sliders and other
		 * available data.
		 *
		 * @var Object
		 */
		private $content_importer;

		/**
		 * Start things up.
		 */
		public function __construct() {

			if ( ! defined( 'TOTAL_THEME_ACTIVE' ) ) {
				return; // Total only functionality
			}

			// Not needed here...
			if ( ! is_admin() || is_customize_preview() ) {
				return;
			}

			// Disable Woo Wizard.
			// @todo is it possible to remove this with new versions of WooCommerce?
			if ( apply_filters( 'wpex_demo_importer_disable_woo_wizard', true ) ) {
				add_filter( 'woocommerce_enable_setup_wizard', '__return_false' );
				add_filter( 'woocommerce_show_admin_notice', '__return_false' );
				add_filter( 'woocommerce_prevent_automatic_wizard_redirect', '__return_false' );
			}

			// Disable bbPress redirect.
			if ( class_exists( 'bbPress' ) ) {
				remove_action( 'bbp_admin_init', 'bbp_do_activation_redirect', 1 );
			}

			// Constants.
			define( 'WPEX_DEMO_IMPORTER_DIR', TTC_PLUGIN_DIR_PATH . '/inc/demo-importer' );
			define( 'WPEX_DEMO_IMPORTER_URI', TTC_PLUGIN_DIR_URL . 'inc/demo-importer' );

			// Include core classes.
			require_once WPEX_DEMO_IMPORTER_DIR . '/classes/class-wpex-demo-importer-utils.php';
			require_once WPEX_DEMO_IMPORTER_DIR . '/classes/class-wpex-content-importer.php';
			require_once WPEX_DEMO_IMPORTER_DIR . '/classes/class-wpex-plugin-installer.php';

			// Start things up.
			add_action( 'admin_menu', array( $this, 'add_page' ), 2 );
			add_action( 'admin_init', array( $this, 'init' ), 20 );
			add_filter( 'upload_mimes', array( $this, 'allow_xml_uploads' ) );
		}

		/**
		 * Make sure the demo importer can run on the server.
		 */
		public function init_checks() {
			$errors = array();
			if ( ! function_exists( 'json_last_error' ) ) {
				$errors['json_last_error'] = esc_html__( 'Unfortuantely your server is using a version of PHP not supported by WordPress. Please make sure to update your PHP version to at least version 5.5 in order to proceed with the import.', 'total-theme-core' );
			}
			if ( $errors ) {
				return $errors;
			} else {
				return 'passed';
			}
		}

		/**
		 * Initialize everything.
		 */
		public function init() {

			// Enqueue the admin style and javascript
			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );

			// Register the AJAX methods
			add_action( 'wp_ajax_wpex_get_selected_demo_data', array( $this, 'ajax_get_selected_demo_data' ) );
			add_action( 'wp_ajax_wpex_post_content_to_import', array( $this, 'ajax_post_content_to_import' ) );
			add_action( 'wp_ajax_wpex_get_import_data', array( $this, 'ajax_get_import_data' ) );

			add_action( 'wp_ajax_wpex_post_import_xml_data', array( $this, 'ajax_post_import_xml_data' ) );
			add_action( 'wp_ajax_wpex_post_import_mods', array( $this, 'ajax_post_import_mods' ) );
			add_action( 'wp_ajax_wpex_post_import_widgets', array( $this, 'ajax_post_import_widgets' ) );
			add_action( 'wp_ajax_wpex_post_import_sliders', array( $this, 'ajax_post_import_sliders' ) );
			add_action( 'wp_ajax_wpex_post_import_complete', array( $this, 'ajax_post_import_complete' ) );

			add_action( 'wp_ajax_wpex_post_install_plugin', array( $this, 'ajax_post_install_plugin' ) );
			add_action( 'wp_ajax_wpex_post_activate_plugin', array( $this, 'ajax_post_activate_plugin' ) );

			add_action( 'wp_ajax_wpex_demo_import_refresh', array( $this, 'ajax_refresh_list' ) );
		}

		/**
		 * Add sub menu page.
		 */
		public function add_page() {

			if ( ! defined( 'WPEX_THEME_PANEL_SLUG' ) ) {
				return;
			}

			add_submenu_page(
				WPEX_THEME_PANEL_SLUG,
				esc_html__( 'Demo Importer', 'total-theme-core' ),
				esc_html__( 'Demo Importer', 'total-theme-core' ),
				'administrator',
				WPEX_THEME_PANEL_SLUG . '-demo-importer',
				array( $this, 'demos_page' )
			);

		}

		/**
		 * Renders the main Demo Imported page.
		 */
		public function demos_page() {

			//delete_transient( 'wpex_demos_data' ); // for testing purposes
			$this->init_checks = self::init_checks();

			if ( is_string( $this->init_checks ) && 'passed' === $this->init_checks ) {
				$this->init_demos_data();
			} else {
				include_once( 'views/not-supported.php' );
			}

			// Clear xml file on demos page load as extra precaution.
			$temp_xml = WPEX_DEMO_IMPORTER_DIR . '/temp.xml';
			file_put_contents( $temp_xml, '' );

			if ( ! empty( $this->demos ) ) {
				include_once( 'views/demos.php' );
			} else {
				delete_transient( 'wpex_demos_data' );
				include_once( 'views/no-demos.php' );
			}

		}

		/**
		 * Enqueue admin stylesheets.
		 */
		public function enqueue_admin_styles( $hook ) {

			if ( ! WPEX_Demo_Importer_Utils::is_admin_page( $hook ) ) {
				return;
			}

			wp_enqueue_style(
				'total-theme-demo-importer',
				WPEX_DEMO_IMPORTER_URI . '/assets/css/wpex-demo-import.css',
				array(),
				TTC_VERSION
			);

		}

		/**
		 * Enqueue admin JavaScript files.
		 */
		public function enqueue_admin_scripts( $hook ) {

			if ( ! WPEX_Demo_Importer_Utils::is_admin_page( $hook ) ) {
				return;
			}

			wp_enqueue_script( 'jquery' );

			wp_enqueue_script(
				'isotope', WPEX_DEMO_IMPORTER_URI . '/assets/js/isotope.pkgd.min.js',
				array( 'jquery' ),
				false,
				true
			);

			wp_enqueue_script(
				'total-theme-demo-importer', WPEX_DEMO_IMPORTER_URI . '/assets/js/wpex-demo-import.js',
				array( 'jquery' ),
				TTC_VERSION,
				true
			);

			wp_localize_script( 'total-theme-demo-importer', 'wpex_strings', array(
				'installingPlugin' => esc_html__( 'Installing plugin', 'total-theme-core' ),
				'activatingPlugin' => esc_html__( 'Activating plugin', 'total-theme-core' ),
			) );

			// Pass some PHP variables to the JavaScript file.
			wp_localize_script( 'total-theme-demo-importer', 'wpex_js_vars', array(
				'ajaxurl'                         => admin_url( 'admin-ajax.php' ),
				'get_selected_demo_data_nonce'    => wp_create_nonce( 'get-selected-demo-data' ),
				'get_import_data_nonce'           => wp_create_nonce( 'get-import-data' ),
				'plugin_failed_activation'        => esc_html__( 'The plugin failed to activate.', 'total-theme-core' ),
				'plugin_failed_activation_retry'  => esc_html__( 'The plugin failed to activate. Please try again.', 'total-theme-core' ),
				'plugin_failed_activation_memory' => esc_html__( 'The plugin failed to activate. Please try to increase the memory_limit on your server.', 'total-theme-core' ),
				'content_importing_error'         => esc_html__( 'There was a problem during the importing process resulting in the following error code from your server:', 'total-theme-core' ),
			) );

		}

		/**
		 * Allows xml uploads so we can import from github.
		 */
		public function allow_xml_uploads( $mimes ) {
			$mimes = array_merge( $mimes, array(
				'xml' => 'application/xml'
			) );
    		return $mimes;
		}

		/**
		 * Initializes the demos data.
		 */
		protected function init_demos_data() {

			// the remote URL where the data is stored
			$this->demos_remote_url = apply_filters( 'wpex_get_demos_remote_url', 'https://totalwptheme.s3.amazonaws.com/sample-data/demos.json' );

			// demo data
			$demos_data = $this->get_demos_data();

			// list of all the currently available demos
			$this->demos = $demos_data[ 'demos' ];

			//print_r( $this->demos );

			// list of all the currently available categories
			$this->categories = $demos_data[ 'categories' ];

			// list of all the currently available plugins
			$this->plugins = $demos_data[ 'plugins' ];

			// add the slug and source for each plugin
			foreach( $this->plugins as $key => $value ) {

				// Set correct plugin slug
				$this->plugins[ $key ]['slug'] = $key;

				// Fix contact form 7 issue where the plugin name isn't the same as the folder name
				if ( 'contact-form-7' == $key ) {
					$this->plugins[ $key ][ 'slug' ] = 'wp-contact-form-7';
					$this->plugins[ 'wp-contact-form-7' ] = $this->plugins[ 'contact-form-7' ];
					unset( $this->plugins[ 'contact-form-7' ] );
				}

				if ( $value['location'] === 'bundled' ) {

					if ( function_exists( 'wpex_recommended_plugins' ) ) {

						$plugins = wpex_recommended_plugins();

						if ( ! empty( $plugins[ $key ][ 'source' ] ) ) {
							$this->plugins[$key]['source'] = esc_url( $plugins[ $key ][ 'source' ] );
						}

					}

				}

			}

		}

		/**
		 * Gets the list of demos, demo categories and required plugins from the json file.
		 */
		protected function get_demos_data() {

			// Try to retrieve the demos data from the transient option.
			// If it doesn't exist or it's expired, load it from the remote location
			// and then store it in the transient for later use.
			if ( ( $demos = get_transient( 'wpex_demos_data' ) ) === false ) {

				// Get list of demos
				$response = WPEX_Demo_Importer_Utils::remote_get( $this->demos_remote_url );

				if ( $response === false ) {
					return array(
						'demos' => array(),
						'categories' => array(),
						'plugins' => array()
					);
				} else {

					// Extract json data
					$data = json_decode( $response, true );

					if ( '0' == json_last_error() ) {
						$demos = $data;

						// Store the demos in a transient for 1 hour
						set_transient( 'wpex_demos_data', $demos, HOUR_IN_SECONDS );

					} else {
						return array(
							'demos' => array(),
							'categories' => array(),
							'plugins' => array()
						);
					}
				}
			}

			return array(
				'demos'      => $demos['demos'],
				'categories' => $demos['categories'],
				'plugins'    => $demos['plugins']
			);
		}

		/**
		 * Gets the popup content associated with the selected demo.
		 */
		public function ajax_get_selected_demo_data() {
			$demo = $_GET['demo_name'];

			if ( ! wp_verify_nonce( $_GET['get_selected_demo_data_nonce'], 'get-selected-demo-data' ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			$this->init_demos_data();

			$this->plugin_installer = new WPEX_Plugin_Installer();

			$this->plugin_installer->set_plugins_data( $this->plugins );

			// Extract demo data
			$demo_data = $this->demos[ $demo ];

			include( 'views/selected.php' );

			die();
		}

		/**
		 * Returns an array containing all the importable content with the corresponding data
		 * (the name of the input field, the name of the AJAX method) for each content type.
		 */
		public function ajax_get_import_data() {
			if ( ! wp_verify_nonce( $_GET['get_import_data_nonce'], 'get-import-data' ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			echo json_encode(
				array(
					'mods' => array(
						'input_name' => 'wpex_import_mods',
						'action' => 'wpex_post_import_mods',
						'method' => 'ajax_post_import_mods',
						'preloader' => esc_html__( 'Importing Customizer Settings', 'total-theme-core' )
					),
					'widgets' => array(
						'input_name' => 'wpex_import_widgets',
						'action' => 'wpex_post_import_widgets',
						'method' => 'ajax_post_import_widgets',
						'preloader' => esc_html__( 'Importing Widgets', 'total-theme-core' )
					),
					'sliders' => array(
						'input_name' => 'wpex_import_sliders',
						'action' => 'wpex_post_import_sliders',
						'method' => 'ajax_post_import_sliders',
						'preloader' => esc_html__( 'Importing Sliders', 'total-theme-core' )
					),
					// Process xml data last.
					'xml_data' => array(
						'input_name' => 'wpex_import_xml',
						'action' => 'wpex_post_import_xml_data',
						'method' => 'ajax_post_import_xml_data',
						'preloader' => esc_html__( 'Importing XML Data', 'total-theme-core' )
					),
				)
			);

			die();
		}

		/**
		 * Activates a plugin.
		 */
		public function ajax_post_activate_plugin() {
			$nonce = $_POST['wpex_plugin_nonce'];
			$plugin = $_POST['wpex_plugin_slug'];

			if ( ! wp_verify_nonce( $nonce, 'activate-plugin_' . $plugin ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			$this->init_demos_data();

			$this->plugin_installer = new WPEX_Plugin_Installer();
			$this->plugin_installer->set_plugins_data( $this->plugins );

			// Check if the plugin is not already activated
			if ( $this->plugin_installer->is_plugin_activated( $plugin ) === false ) {

				$result = $this->plugin_installer->activate_plugin( $plugin );

				if ( $result === true ) {
					echo 'successful activation';
				} else {
					echo 'failed activation';
				}
			} else {
				echo 'successful activation';
			}

			die();
		}

		/**
		 * Installs a plugin and then activates it.
		 */
		public function ajax_post_install_plugin() {
			$nonce = $_POST['wpex_plugin_nonce'];
			$plugin = $_POST['wpex_plugin_slug'];
			$plugin_installed = false;

			if ( ! wp_verify_nonce( $nonce, 'install-plugin_' . $plugin ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			$this->init_demos_data();

			$this->plugin_installer = new WPEX_Plugin_Installer();
			$this->plugin_installer->set_plugins_data( $this->plugins );

			// Check if the plugin is not already installed
			if ( $this->plugin_installer->is_plugin_installed( $plugin ) ) {
				$plugin_installed = true;
			} else {

				// Try to install the plugin.
				$plugin_installed = $this->plugin_installer->install_plugin( $plugin );
			}

			// If the plugins is installed.
			if ( $plugin_installed === true ) {

				// Check if the plugin is not already activated.
				if ( $this->plugin_installer->is_plugin_activated( $plugin ) === false ) {

					// Get the file path of the plugin in order to pass it to the activation method.
					$plugin_file_path = $this->plugin_installer->get_plugin_file_path( $plugin );

					// Try to activate the plugin.
					$activation_result = $this->plugin_installer->activate_plugin( $plugin_file_path );

					if ( $activation_result === true ) {
						echo 'successful installation';
					} else {
						echo 'failed activation';
					}
				} else {
					echo 'successful installation';
				}
			} else {
				$plugin_source = $this->plugin_installer->get_download_link( $plugin );

				echo wp_kses_post( sprintf( __( 'The plugin failed to install. Please check the permissions for the "plugins" directory or <a href="%s" target="_blank">download</a> the plugin and install it manually.', 'total-theme-core' ), $plugin_source ) );
			}

			die();
		}

		/**
		 * Deletes transient to refresh demos list.
		 */
		public function ajax_refresh_list() {
			check_ajax_referer( 'wpex_demos_ajax_refresh_list_nonce', 'nonce' );
			delete_transient( 'wpex_demos_data' );
			echo 1;
			exit;
		}

		/**
		 * Import XML Data and, optionally, the attachments.
		 */
		public function ajax_post_import_xml_data() {
			if ( ! wp_verify_nonce( $_POST['wpex_import_demo_nonce'], 'wpex_import_demo_nonce' ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			@set_time_limit(0);

			$this->init_demos_data();

			$this->content_importer = new WPEX_Content_Importer();
			$this->content_importer->set_demos_data( $this->demos );

			// get the slug of the demo.
			$demo = $_POST['wpex_import_demo'];

			// indicates if the images will be imported.
			$import_images = ( isset( $_POST[ 'wpex_import_xml_attachments' ] ) && $_POST[ 'wpex_import_xml_attachments' ] === 'true' ) ? true : false;

			// delete the default post and pages.
			$sample_page = get_page_by_path( 'sample-page', OBJECT, 'page' );

			if ( ! is_null( $sample_page ) ) {
				wp_delete_post( $sample_page->ID, true );
			}

			$hello_world_post = get_page_by_path( 'hello-world', OBJECT, 'post' );

			if ( ! is_null( $hello_world_post ) ) {
				wp_delete_post( $hello_world_post->ID, true );
			}

			$result = $this->content_importer->process_xml( $demo, $import_images );

			if ( is_wp_error( $result ) ) {
				echo json_encode( $result->errors );
			} else {
				echo 'successful import';
			}

			die();
		}

		/**
		 * Import customizer settings.
		 */
		public function ajax_post_import_mods() {
			if ( ! wp_verify_nonce( $_POST['wpex_import_demo_nonce'], 'wpex_import_demo_nonce' ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			$this->init_demos_data();

			$this->content_importer = new WPEX_Content_Importer();
			$this->content_importer->set_demos_data( $this->demos );

			// get the slug of the demo
			$demo = $_POST['wpex_import_demo'];

			$result = $this->content_importer->process_theme_mods( $demo );

			if ( is_wp_error( $result ) ) {
				echo json_encode( $result->errors );
			} else {
				echo 'successful import';
			}

			die();
		}

		/**
		 * Import widgets.
		 */
		public function ajax_post_import_widgets() {
			if ( ! wp_verify_nonce( $_POST['wpex_import_demo_nonce'], 'wpex_import_demo_nonce' ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			$this->init_demos_data();

			$this->content_importer = new WPEX_Content_Importer();
			$this->content_importer->set_demos_data( $this->demos );

			// get the slug of the demo
			$demo = $_POST['wpex_import_demo'];

			$result = $this->content_importer->process_widget_import( $demo );

			if ( is_wp_error( $result ) ) {
				echo json_encode( $result->errors );
			} else {
				echo 'successful import';
			}

			die();
		}

		/**
		 * Import sliders.
		 */
		public function ajax_post_import_sliders() {
			if ( ! wp_verify_nonce( $_POST['wpex_import_demo_nonce'], 'wpex_import_demo_nonce' ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			$this->init_demos_data();

			$this->content_importer = new WPEX_Content_Importer();
			$this->content_importer->set_demos_data( $this->demos );

			// get the name of the demo
			$demo = $_POST['wpex_import_demo'];

			$result = $this->content_importer->process_sliders_import( $demo );

			if ( is_wp_error( $result ) ) {
				echo json_encode( $result->errors );
			} else {
				echo 'successful import';
			}

			die();
		}

		/**
		 * Called when all the selected content has been imported.
		 */
		public function ajax_post_import_complete() {
			if ( ! wp_verify_nonce( $_POST['wpex_import_demo_nonce'], 'wpex_import_demo_nonce' ) ) {
				die( 'This action was stopped for security purposes.' );
			}

			if ( $_POST['wpex_import_is_xml'] === 'true' ) {
				$this->init_demos_data();

				$this->content_importer = new WPEX_Content_Importer();
				$this->content_importer->set_demos_data( $this->demos );

				$demo = $_POST['wpex_import_demo'];

				$this->content_importer->set_menus( $demo );
				$this->content_importer->set_homepage( $demo );
				$this->content_importer->set_posts_page( $demo );
				$this->content_importer->set_shop_page( $demo );

				do_action( 'wpex_demo_importer_ajax_post_import_complete' );
			}

			die();

		}

	}

}
new WPEX_Demo_Importer();