Your IP : 216.73.216.171


Current Path : /home/ereika83/public_html/wp-content/plugins/snapshot/lib/Snapshot/Controller/
Upload File :
Current File : /home/ereika83/public_html/wp-content/plugins/snapshot/lib/Snapshot/Controller/Hosting.php

<?php // phpcs:ignore

/**
 * Hosting backups controller abstraction
 */
class Snapshot_Controller_Hosting {

	const CODE_ERROR_BULK_DELETE = 'bdel';
	const REQUEST_GET = 'GET';
	const REQUEST_POST = 'POST';
	const OPTIONS_BACKUP_FLAG = 'snapshot_current_hosting_backup_run';
	const HUB_BACKUP_URL = 'https://premium.wpmudev.org/hub/hosting/?view=site&site_id=%s&tab=backups';

	/**
	 * Singleton instance
	 *
	 * @var object Snapshot_Controller_Hosting
	 */
	private static $_instance;

	/**
	 * Hosting Model reference
	 *
	 * @var object Snapshot_Model_Hosting
	 */
	protected $_hosting_model;

	/**
	 * Full Backup Model
	 *
	 * @var object Snapshot_Model_Full_Backup;
	 */
	protected $_managed_model;

	/**
	 * Constructs an instance, never to the outside world.
	 *
	 * Also sets up a model reference to be used by it and
	 * implementing classes.
	 */
	protected function __construct() {
		$this->_hosting_model = new Snapshot_Model_Hosting();
		$this->_managed_model = new Snapshot_Model_Full_Backup();
	}

	/**
	 * No public cloning kthxbai
	 */
	protected function __clone() {}

	/**
	 * Singleton instance getter
	 *
	 * @return object Snapshot_Controller_Hosting
	 */
	public static function get() {
		if ( empty( self::$_instance ) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	/**
	 * Gets the backup type of this controller
	 *
	 * For future use
	 *
	 * @return string Backup type
	 */
	protected function _get_backup_type() {
		return 'hosting';
	}

	/**
	 * Gets prefixed filter/action name
	 *
	 * @param string $action Action/filter name to prefix
	 *
	 * @return string
	 */
	public function get_filter( $action ) {
		return 'snapshot-controller-' . $this->_get_backup_type() . '-' . $action;
	}

	/**
	 * Dispatch admin view and AJAX controllers.
	 */
	public function run() {

		if ( is_admin() && current_user_can( 'manage_snapshots_items' ) ) {
			Snapshot_Controller_Hosting_Ajax::get()->run();
		}

		add_action( 'current_screen', array( $this, 'process_actions' ) );
	}

	/**
	 * Dispatch actions processing.
	 */
	public function process_actions() {
		// phpcs:ignore
		if ( isset( $_GET['action'] ) && isset( $_GET['page'] ) && 'snapshot_pro_hosting_backups' === $_GET['page'] && 'delete' === $_GET['action'] ) {
			$_POST = $_GET; // phpcs:ignore
		}
		$data = new Snapshot_Model_Post();

		if ( $data->has( 'snapshot-full_backups-list-nonce' ) && $data->has( 'delete-bulk' ) && $data->has( 'action' ) && 'delete' === $data->value( 'action' ) ) {
			$this->_bulk_delete( $data );
		}
	}

	/**
	 * Deletes the snapshots in bulk
	 *
	 * @param Snapshot_Model_Post $data Request data
	 *
	 * @return bool False on failure
	 */
	private function _bulk_delete( Snapshot_Model_Post $data ) {
		if (
			! wp_verify_nonce( $data->value( 'snapshot-full_backups-list-nonce' ), 'snapshot-full_backups-list' )
		) {
			return false;
		}

		$to_remove = $data->value( 'delete-bulk' );
		if ( empty( $to_remove ) || ! is_array( $to_remove ) ) {
			return false;
		} // Not valid data

		$status = true; // Assume all is good
		foreach ( $to_remove as $timestamp ) {
			$timestamp = (int) $timestamp;
			if ( ! $timestamp ) {
				continue;
			} // Not a valid timestamp

			$status = $this->_managed_model->delete_backup( $timestamp );
			if ( ! $status ) {
				break;
			}
		}

		$url = WPMUDEVSnapshot::instance()->snapshot_get_pagehook_url( 'snapshots-newui-hosting-backups' );
		$url = ! empty( $status )
			? remove_query_arg( 'error', $url )
			: add_query_arg( 'error', self::CODE_ERROR_BULK_DELETE, $url );
		wp_safe_redirect( $url );
		die;
	}

	/**
	 * Checks if user is logged in the WPMUDEV Dashboard
	 */
	public function logged_in_wpmudev_user() {
		return $this->_hosting_model->active_dashboard_key();
	}

	/**
	 * Retrieve site's id.
	 */
	public function get_site_id() {
		return $this->_hosting_model->get_site_id();
	}

	/**
	 * Actually start the backup.
	 *
	 * @return bool
	 */
	protected function _start_backup() {
		$status = $this->get_api_result( 'backups', self::REQUEST_POST );

		return $status;
	}

	/**
	 * Actually process the backup
	 *
	 * @throws Snapshot_Exception On error limit reached.
	 *
	 * @param string $idx Backup index to process
	 *
	 * @return bool Is backup done?
	 */
	protected function _process_backup( $idx ) {
		$status = false;

		return $status;
	}

	/**
	 * Wrapping up and clearing backup.
	 *
	 * @throws Snapshot_Exception On error limit reached.
	 *
	 * @param string $idx Backup index to process
	 *
	 * @return bool
	 */
	protected function _finish_backup( $idx ) {
		return false;
	}

	/**
	 * Backup restoration dispatch method
	 *
	 * @param string $backup_id Backup ID.
	 *
	 * @return bool True for done, false for in progress
	 */
	protected function _restore_backup( $backup_id ) {
		$status = $this->get_api_result(
			'backups/test/restore',
			self::REQUEST_POST,
			array( 'backup_id' => $backup_id )
		);

		return $status;
	}

	/**
	 * Backup export dispatch method
	 *
	 * @param string $backup_id Backup ID.
	 *
	 */
	protected function _export_backup( $backup_id ) {
		$status = $this->get_api_result(
			'backups/test/export',
			self::REQUEST_POST,
			array( 'backup_id' => $backup_id )
		);
		return $status;
	}

	/**
	 * Gets data about currently running backup/restore
	 *
	 * @param string $action_id Action ID.
	 *
	 * @return array
	 */
	protected function get_currently_running_action( $action_id ) {
		if ( ! $action_id || empty( $action_id ) ) return array();

		$status = $this->get_action_status( $action_id );

		$is_errored = is_wp_error( $status ) || ( isset( $status['status'] ) && 'errored' === $status['status']);
		$status['is_done'] = is_array( $status ) && ! empty( $status['completed_at'] );
		$status['error'] = $is_errored;

		return $status;
	}

	/**
	 * Gets a list of backups
	 *
	 * @return array A list of full backup items
	 */
	protected function get_backups_list() {
		$result = $this->get_api_result( 'backups', self::REQUEST_GET );
		if ( is_wp_error( $result ) ) {
			return $result;
		}
		$this->_backups_cache = is_array( $result )
			? $result
			: array();

		return $this->_backups_cache;
	}

	/**
	 * Fetches result from API
	 *
	 * @uses WPMUDEV_HOSTING_SITE_ID define
	 *
	 * @param string $action API endpoint.
	 * @param string $type Optional request type - defaults to GET.
	 * @param array $params Optional additional params.
	 *
	 * @return WP_Error|array Error if something went wrong, parsed JSON array otherwise.
	 */
	protected function get_api_result( $action, $type = false, $params = array() ) {
		$api_key = $this->logged_in_wpmudev_user();
		if ( is_wp_error( $api_key ) ) {
			return new WP_Error(
				get_class(),
				'No valid API KEY'
			);
		}

		$url = sprintf(
			'https://premium.wpmudev.org/api/hosting/v1/%s/%s',
			$this->get_site_id(), // <-- This is pretty important
			sanitize_text_field( $action )
		);
		$type = self::REQUEST_POST === $type
			? self::REQUEST_POST
			: self::REQUEST_GET;
		$args = array(
			'method' => $type,
			'timeout' => 60,
			'headers' => array(
				'Authorization' => $api_key,
			),
		);
		if ( self::REQUEST_POST === $type && ! empty( $params ) ) {
			$args['body'] = $params;
		}

		$result = wp_remote_request( $url, $args );

		if ( is_wp_error( $result ) ) return $result;
		$status = wp_remote_retrieve_response_code( $result );
		if ( 200 !== (int) $status ) {
			return new WP_Error(
				get_class(),
				'Service responded with non-200'
			);
		}

		return json_decode( wp_remote_retrieve_body( $result ), true );
	}

	/**
	 * Queries the api for action status
	 *
	 * @param int $action_id Action ID
	 *
	 * @return WP_Error|array
	 */
	protected function get_action_status( $action_id ) {
		return $this->get_api_result( sprintf(
			'actions/%d',
			$action_id
		));
	}

	/**
	 * Builds the arguments for any backup restore AJAX calls
	 *
	 * @param string $backup_id Backup ID
	 * @param array $current_restore Current restore state
	 */
	protected function deal_with_backup_restore( $backup_id ) {
		$status = $this->_restore_backup( $backup_id );

		if ( ! $status || ! is_array( $status ) || is_wp_error( $status ) ) {
			// The API call wasnt successful.
			$args = array(
				'is_done' => false,
				'error' => true,
			);
		} else {
			if ( ! empty( $status['action_id'] )  ) {
				if ( ! empty( $status['completed_at'] ) ) {
					// The restore completed on the first go, so we need to set it complete.
					$args = array(
						'is_done' => true,
					);
				} else {
					// The restore didn't complete on the first go, so we need to somehow persist this action ID.
					$args = array(
						'is_done' => false,
						'action_id' => $status['action_id'],
					);
				}
			}
		}

		return $args;
	}

	/**
	 * Builds the arguments for any following AJAX calls, depending on any previous ran backups
	 *
	 * @param array $current Any previous ran backup
	 * @param bool $new_backup Whether called from the new backup creation
	 *
	 * @return array
	 */
	protected function deal_with_running_backup( $current, $new_backup ) {
		if ( isset( $current['is_done'] ) && $current['is_done'] ) {
			// The previously ran backup has been completed.
			update_site_option( self::OPTIONS_BACKUP_FLAG, false );

			//Now lets check if it completed as errored, or as success.
			$args = ( isset( $current['error'] ) &&  $current['error'] ) ? array(
				'is_done' => false,
				'error' => true
			) : array( 'is_done' => true );

		} else if ( isset( $current['type'] ) && 'backup' === $current['type'] && 'in-progress' === $current['status'] ) {
			// The previously ran backup is still running.
			$args = array(
				'is_done' => false,
				'action_id' => $current['id' ],
				'older_backup' => true,
			);
		} else {
			if ( $new_backup ) {
				// Let's create a new backup. But only if there are no older backups still running.
				// We have checked nonces coming into the function.
				// phpcs:ignore
				if ( ! get_site_option( self::OPTIONS_BACKUP_FLAG ) && ( ! isset( $_POST['older_backup'] ) || false === $_POST['older_backup'] ) ){
					$status = $this->_start_backup();

					if ( ! $status || ! is_array( $status ) || is_wp_error( $status ) ) {
						// The API call wasnt successful.
						$args = array(
							'is_done' => false,
							'error' => true,
						);
					} else {
						if ( ! empty( $status['action_id'] )  ) {
							if ( ! empty( $status['completed_at'] ) ) {
								// The backup completed on the first go, so we need to set it complete.
								update_site_option( self::OPTIONS_BACKUP_FLAG, false );
								$args = array(
									'is_done' => true,
								);
							} else {
								// The backup didn't complete on the first go, so we need to persist this action ID.
								update_site_option( self::OPTIONS_BACKUP_FLAG, $status['action_id' ] );
								$args = array(
									'is_done' => false,
									'action_id' => $status['action_id' ],
								);
							}
						}
					}
				} else {
					if ( ! get_site_option( self::OPTIONS_BACKUP_FLAG ) ) {
						$args = array(
							'is_done' => true,
							'older_backup' => true,
						);
					} else {
						$args = array(
							'is_done' => false,
							'action_id' => get_site_option( self::OPTIONS_BACKUP_FLAG ),
							'older_backup' => true,
						);
					}
				}
			} else {
				$args = array();
			}
		}
		return $args;
	}

	/**
	 * Builds the UI for listing managed and hosting backups
	 *
	 * @param array $raw_backups Combined hosting and managed backups.
	 * @param bool $dashboard Whether on dashboard.
	 *
	 * @return array
	 */
	public function deal_with_listing_backups( $raw_backups, $dashboard ) {
		$backups = array();
		foreach ( $raw_backups as $key => $backup ) {
			$backups[ $key ] = $backup;

			$download_tooltip = ! $dashboard ? " wps-tooltip sui-tooltip sui-tooltip-small sui-tooltip-top-center" : "";
			$download_tooltip_content = ! $dashboard ? ' data-tooltip="Download" ' : "";

			if ( isset( $backup['Key'] ) ) {
				// Hosting backup
				$backups[ $key ]['id']      = esc_attr( substr( $backup['Key'], strpos( $backup['Key'], '@' ) + 1 ) );

				$backups[ $key ]['link']    = $dashboard ? esc_attr( Snapshot_Helper_Utility::show_date_time( strtotime( $backups[ $key ]['creation_time'] ), 'M d, Y g:i a' ) ) : '<a href="#" class="snapshot-hosting-backup-export' .  $download_tooltip . '" data-backup-id="' . esc_attr( $backups[ $key ]['id'] ) . '"' .  $download_tooltip_content . '>' . esc_attr( Snapshot_Helper_Utility::show_date_time( strtotime( $backups[ $key ]['creation_time'] ), 'M d, Y g:i a' ) ) . '</a>';

				$backup_menu = $this->get_backup_menu( $backups, $key, $backup, true );
			} else {
				// Managed Backup
				$backup_link = $this->_managed_model->remote()->get_backup_link( $backup['timestamp'] );

				/* If there is no remote URL, build a local download link */
				if ( ! $backup_link ) {
					$backup_link = network_admin_url('admin.php?page=snapshot_pro_hosting_backups');
					$backup_link = add_query_arg( 'snapshot-action', 'download-backup-archive', $backup_link );
					$backup_link = add_query_arg( 'backup-item', sanitize_text_field( $backup['timestamp'] ), $backup_link );
				}
				$backups[ $key ]['link']    = $dashboard ? esc_attr( Snapshot_Helper_Utility::show_date_time( strtotime( $backups[ $key ]['creation_time'] ), 'M d, Y g:i a' ) ) : '<a href="' . esc_url( $backup_link ) . '" class="' .  $download_tooltip . '" ' . $download_tooltip_content . '>' . esc_attr( Snapshot_Helper_Utility::show_date_time( strtotime( $backups[ $key ]['creation_time'] ), 'M d, Y g:i a' ) ) . '</a>';

				$backup_menu = $this->get_backup_menu( $backups, $key, $backup, false );
			}

			$backups[ $key ]['date'] = esc_attr( Snapshot_Helper_Utility::show_date_time( strtotime( $backups[ $key ]['creation_time'] ), 'F j, Y' ) );
			$backups[ $key ]['time'] = esc_html__( 'at', SNAPSHOT_I18N_DOMAIN ) . ' ' . esc_attr( Snapshot_Helper_Utility::show_date_time( strtotime( $backups[ $key ]['creation_time'] ), 'g:ia' ) );

			$backups[ $key ]['icon']    = $this->get_backup_icon( $backup );
			$backups[ $key ]['tooltip'] = $this->get_backup_tooltip( $backup, $dashboard );

			$backups[ $key ]['type']    = $this->get_backup_type( $backup );
			$backups[ $key ]['context'] = isset( $backups[ $key ]['context'] ) ? str_replace( array( 'Manual', 'Nightly' ), array( 'Once', 'Daily, @ ' . esc_attr( Snapshot_Helper_Utility::get_hosting_backup_local_time() ) ), $backups[ $key ]['context'] ) : '-';

			if ( ! $dashboard ) {
				$backups[ $key ]['menu'] = $backup_menu;

				if ( ! empty( $backup['local'] ) ) {
					if ( is_multisite() ) {
						$page_url = network_admin_url( 'admin.php?page=snapshot_pro_hosting_backups' );
					} else {
						$page_url = admin_url( 'admin.php?page=snapshot_pro_hosting_backups' );
					}

					$delete_link = add_query_arg(
						array(
							'action' => 'delete',
							'item' => $backup['timestamp'],
							'snapshot-full_backups-list-nonce' => wp_create_nonce( 'snapshot-full_backups-list' ),
							'delete-bulk' => array( $backup['timestamp'] )
						),
						$page_url
					);

					$backups[ $key ]['menu'] = '
						<a class="button button-small button-outline button-gray" href="' . esc_url( $delete_link ) . '">
							<span class="wps-destination-config-text">' . esc_html__( 'Delete', SNAPSHOT_I18N_DOMAIN ) . '</span>
						</a>
					';
				}
			}

		}

		return $backups;
	}

	/**
	 * Return icon tooltip
	 *
	 * @param $backup
	 * @param $dashboard
	 *
	 * @return string
	 */
	private function get_backup_tooltip( $backup, $dashboard ) {
		$tooltip = '';

		if ( ! empty( $backup['local'] ) ) {
			$tooltip = esc_html__( "This backup failed to upload to The Hub. Usually we'd recommend re-trying the upload, but since you're hosting with us you already have daily backups running. Therefore, you can probably delete this backup.", SNAPSHOT_I18N_DOMAIN );
			if ( $dashboard ) {
				$tooltip .= esc_html__( " Visit the Backups page to delete it.", SNAPSHOT_I18N_DOMAIN );
			}
		}

		return $tooltip;
	}

	/**
	 * Return hosting icon
	 *
	 * @param array $backup
	 *
	 * @return string
	 */
	private function get_backup_icon( $backup ) {
		if ( ! empty( $backup['local'] ) ) {
			$local = ' i-snapshot-error';
		} else {
			$local = '';
		}

		if ( isset( $backup['context'] ) ) {
			if( preg_match( "/Automate/i", $backup['context'] ) ) {
				return 'i-cloud-automate';
			} else {
				return 'i-cloud-hosting';
			}
		} else {
			if (Snapshot_Helper_Backup::is_automated_backup($backup['name'])) {
				return 'i-cloud-automate' . $local;
			} else {
				return 'i-snapshot' . $local;
			}
		}

		return 'i-snapshot';
	}

	/**
	 * Return backup type
	 *
	 * @param array $backup
	 *
	 * @return string
	 */
	private function get_backup_type( $backup ) {
		if ( isset( $backup['Key'] ) ) {
			return esc_html__( 'Hosting', SNAPSHOT_I18N_DOMAIN );
		} else {
			if ( Snapshot_Helper_Backup::is_automated_backup( $backup['name'] ) ) {
				return esc_html__( 'Automated', SNAPSHOT_I18N_DOMAIN );
			} else {
				return esc_html__( 'Managed', SNAPSHOT_I18N_DOMAIN );
			}
		}
	}

	/**
	 * Return backup menu
	 *
	 * @param array $backup
	 * @param bool $hosting_backup
	 *
	 * @return string
	 */
	private function get_backup_menu( $backups, $key, $backup, $hosting_backup ) {
		if ( $hosting_backup ) {
			$is_staging = strpos( $_SERVER['HTTP_HOST'], '.staging.wpmudev.host' ) !== false;
			if ( $is_staging ) {
				$restore_item =
				'<li class="snapshot-hosting-backup-restore sui-tooltip sui-constrained sui-tooltip-left" data-tooltip="You can\'t restore the backup, because you\'re on staging. Please log in to your regular account and try again.">
					<a style="opacity: .5; pointer-events: none;" href="#" data-backup-id="' . esc_attr( $backups[ $key ]['id'] ) . '">' . esc_html__( 'Restore', SNAPSHOT_I18N_DOMAIN ) . '</a>
				</li>
				';
			} else {
				$restore_item =
				'<li>
					<a href="#" class="snapshot-hosting-backup-restore" data-backup-id="' . esc_attr( $backups[ $key ]['id'] ) . '">' . esc_html__( 'Restore', SNAPSHOT_I18N_DOMAIN ) . '</a>
				</li>
				';
			}
			$backup_menu =
'<div class="wps-menu">

	<div class="wps-menu-dots">

		<div class="wps-menu-dot"></div>

		<div class="wps-menu-dot"></div>

		<div class="wps-menu-dot"></div>

	</div>

	<div class="wps-menu-holder">

		<ul class="wps-menu-list">

			<li class="wps-menu-list-title">' . esc_html__( 'Options', SNAPSHOT_I18N_DOMAIN ) . '</li>
			<li>
				<a href="' . esc_url( sprintf( self::HUB_BACKUP_URL, $this->get_site_id() ) ) . '" target="_blank" >' . esc_html__( 'Info', SNAPSHOT_I18N_DOMAIN ) . '</a>
			</li>' . $restore_item . '
		</ul>

	</div>

</div>';
		} else {
			$restore_link = add_query_arg(
				array(
					'snapshot-action' => 'restore',
					'item' => $backup['timestamp'],
					'snapshot-full_backups-noonce-field' => wp_create_nonce( 'snapshot-full_backups' ),
				),
				network_admin_url('admin.php?page=snapshot_pro_managed_backups')
			);

			$delete_link = add_query_arg(
				array(
					'action' => 'delete',
					'item' => $backup['timestamp'],
					'snapshot-full_backups-list-nonce' => wp_create_nonce( 'snapshot-full_backups-list' ),
					'delete-bulk' => array( $backup['timestamp'] )
				),
				network_admin_url('admin.php?page=snapshot_pro_hosting_backups')
			);

			$backup_menu =
'<div class="wps-menu">

	<div class="wps-menu-dots">

		<div class="wps-menu-dot"></div>

		<div class="wps-menu-dot"></div>

		<div class="wps-menu-dot"></div>

	</div>

	<div class="wps-menu-holder">

		<ul class="wps-menu-list">

			<li class="wps-menu-list-title">' . esc_html__( 'Options', SNAPSHOT_I18N_DOMAIN ) . '</li>
			<li>
				<a href="' . esc_url( $restore_link ) . '">' . esc_html__( 'Restore', SNAPSHOT_I18N_DOMAIN ) . '</a>
			</li>
			<li>
				<a href="' . esc_attr( $delete_link ) . '" class="snapshot-older-managed-backup-delete">' . esc_html__( 'Delete', SNAPSHOT_I18N_DOMAIN ) . '</a>
			</li>

		</ul>

	</div>

</div>';
		}

		return $backup_menu;
	}
}