HEX
Server: LiteSpeed
System: Linux eko108.isimtescil.net 4.18.0-477.21.1.lve.1.el8.x86_64 #1 SMP Tue Sep 5 23:08:35 UTC 2023 x86_64
User: uyarreklamcomtr (11202)
PHP: 7.4.33
Disabled: opcache_get_status
Upload Files
File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/installation.tar
class-wc-wccom-site-installation-manager.php000064400000013715151547357720015177 0ustar00<?php
/**
 * Installation Manager
 *
 * @package WooCommerce\WCCom
 */

use WC_REST_WCCOM_Site_Installer_Error_Codes as Installer_Error_Codes;
use WC_REST_WCCOM_Site_Installer_Error as Installer_Error;

defined( 'ABSPATH' ) || exit;

/**
 * WC_WCCOM_Site_Installation_Manager class
 */
class WC_WCCOM_Site_Installation_Manager {

	const STEPS = array(
		'get_product_info',
		'download_product',
		'unpack_product',
		'move_product',
		'activate_product',
	);

	/**
	 * The product ID.
	 *
	 * @var int
	 */
	protected $product_id;

	/**
	 * The idempotency key.
	 *
	 * @var string
	 */
	protected $idempotency_key;

	/**
	 * Constructor.
	 *
	 * @param int    $product_id The product ID.
	 * @param string $idempotency_key The idempotency key.
	 */
	public function __construct( int $product_id, string $idempotency_key ) {
		$this->product_id      = $product_id;
		$this->idempotency_key = $idempotency_key;
	}

	/**
	 * Run the installation.
	 *
	 * @param string $run_until_step The step to run until.
	 * @return bool
	 * @throws WC_REST_WCCOM_Site_Installer_Error If installation failed to run.
	 */
	public function run_installation( string $run_until_step ): bool {
		$state = WC_WCCOM_Site_Installation_State_Storage::get_state( $this->product_id );

		if ( $state && $state->get_idempotency_key() !== $this->idempotency_key ) {
			throw new Installer_Error( Installer_Error_Codes::IDEMPOTENCY_KEY_MISMATCH );
		}

		if ( ! $state ) {
			$state = WC_WCCOM_Site_Installation_State::initiate_new( $this->product_id, $this->idempotency_key );
		}

		$this->can_run_installation( $run_until_step, $state );

		$next_step          = $this->get_next_step( $state );
		$installation_steps = $this->get_installation_steps( $next_step, $run_until_step );

		array_walk(
			$installation_steps,
			function ( $step_name ) use ( $state ) {
				$this->run_step( $step_name, $state );
			}
		);

		return true;
	}

	/**
	 * Get the next step to run.
	 *
	 * @return bool
	 * @throws WC_REST_WCCOM_Site_Installer_Error If the installation cannot be rest.
	 */
	public function reset_installation(): bool {
		$state = WC_WCCOM_Site_Installation_State_Storage::get_state( $this->product_id );

		if ( ! $state ) {
			throw new Installer_Error( Installer_Error_Codes::NO_INITIATED_INSTALLATION_FOUND );
		}

		if ( $state->get_idempotency_key() !== $this->idempotency_key ) {
			throw new Installer_Error( Installer_Error_Codes::IDEMPOTENCY_KEY_MISMATCH );
		}

		$result = WC_WCCOM_Site_Installation_State_Storage::delete_state( $state );
		if ( ! $result ) {
			throw new Installer_Error( Installer_Error_Codes::FAILED_TO_RESET_INSTALLATION_STATE );
		}

		return true;
	}

	/**
	 * Check if the installation can be run.
	 *
	 * @param string                           $run_until_step Run until this step.
	 * @param WC_WCCOM_Site_Installation_State $state Installation state.
	 * @return void
	 * @throws WC_REST_WCCOM_Site_Installer_Error If the installation cannot be run.
	 */
	protected function can_run_installation( $run_until_step, $state ) {

		if ( $state->get_last_step_status() === \WC_WCCOM_Site_Installation_State::STEP_STATUS_IN_PROGRESS ) {
			throw new Installer_Error( Installer_Error_Codes::INSTALLATION_ALREADY_RUNNING );
		}

		if ( $state->get_last_step_status() === \WC_WCCOM_Site_Installation_State::STEP_STATUS_FAILED ) {
			throw new Installer_Error( Installer_Error_Codes::INSTALLATION_FAILED );
		}

		if ( $state->get_last_step_name() === self::STEPS[ count( self::STEPS ) - 1 ] ) {
			throw new Installer_Error( Installer_Error_Codes::ALL_INSTALLATION_STEPS_RUN );
		}

		if ( array_search( $state->get_last_step_name(), self::STEPS, true ) >= array_search(
			$run_until_step,
			self::STEPS,
			true
		) ) {
			throw new Installer_Error( Installer_Error_Codes::REQUESTED_STEP_ALREADY_RUN );
		}

		if ( ! is_writable( WP_CONTENT_DIR ) ) {
			throw new Installer_Error( Installer_Error_Codes::FILESYSTEM_REQUIREMENTS_NOT_MET );
		}
	}

	/**
	 * Get the next step to run.
	 *
	 * @param WC_WCCOM_Site_Installation_State $state Installation state.
	 * @return string
	 */
	protected function get_next_step( $state ): string {
		$last_executed_step = $state->get_last_step_name();

		if ( ! $last_executed_step ) {
			return self::STEPS[0];
		}

		$last_executed_step_index = array_search( $last_executed_step, self::STEPS, true );

		return self::STEPS[ $last_executed_step_index + 1 ];
	}

	/**
	 * Get the steps to run.
	 *
	 * @param string $start_step The step to start from.
	 * @param string $end_step  The step to end at.
	 * @return string[]
	 */
	protected function get_installation_steps( string $start_step, string $end_step ) {
		$start_step_offset = array_search( $start_step, self::STEPS, true );
		$end_step_index    = array_search( $end_step, self::STEPS, true );
		$length            = $end_step_index - $start_step_offset + 1;

		return array_slice( self::STEPS, $start_step_offset, $length );
	}

	/**
	 * Run the step.
	 *
	 * @param string                           $step_name Step name.
	 * @param WC_WCCOM_Site_Installation_State $state Installation state.
	 * @return void
	 * @throws WC_REST_WCCOM_Site_Installer_Error If the step fails.
	 */
	protected function run_step( $step_name, $state ) {
		$state->initiate_step( $step_name );
		WC_WCCOM_Site_Installation_State_Storage::save_state( $state );

		try {
			$class_name   = "WC_WCCOM_Site_Installation_Step_$step_name";
			$current_step = new $class_name( $state );
			$current_step->run();
		} catch ( Installer_Error $exception ) {
			$state->capture_failure( $step_name, $exception->get_error_code() );
			WC_WCCOM_Site_Installation_State_Storage::save_state( $state );

			throw $exception;
		} catch ( Throwable $error ) {
			$state->capture_failure( $step_name, Installer_Error_Codes::UNEXPECTED_ERROR );
			WC_WCCOM_Site_Installation_State_Storage::save_state( $state );

			throw new Installer_Error( Installer_Error_Codes::UNEXPECTED_ERROR, $error->getMessage() );
		}

		$state->complete_step( $step_name );
		WC_WCCOM_Site_Installation_State_Storage::save_state( $state );
	}
}
class-wc-wccom-site-installation-state-storage.php000064400000006353151547357720016347 0ustar00<?php
/**
 * State storage for the WCCOM Site installation process.
 *
 * @package WooCommerce\WCCOM
 */

defined( 'ABSPATH' ) || exit;

/**
 * WC_WCCOM_Site_Installation_State_Storage class
 */
class WC_WCCOM_Site_Installation_State_Storage {

	/**
	 * Get state from storage.
	 *
	 * @param int $product_id The product ID.
	 * @return WC_WCCOM_Site_Installation_State|null
	 */
	public static function get_state( $product_id ) : ?WC_WCCOM_Site_Installation_State {
		$storage_key = self::get_storage_key( $product_id );
		$data        = get_option( $storage_key );

		if ( ! is_array( $data ) ) {
			return null;
		}

		$installation_state = WC_WCCOM_Site_Installation_State::initiate_existing(
			$product_id,
			$data['idempotency_key'],
			$data['last_step_name'],
			$data['last_step_status'],
			$data['last_step_error'],
			$data['started_date']
		);

		$installation_state->set_product_type( $data['product_type'] ?? null );
		$installation_state->set_product_name( $data['product_name'] ?? null );
		$installation_state->set_download_url( $data['download_url'] ?? null );
		$installation_state->set_download_path( $data['download_path'] ?? null );
		$installation_state->set_unpacked_path( $data['unpacked_path'] ?? null );
		$installation_state->set_installed_path( $data['installed_path'] ?? null );
		$installation_state->set_already_installed_plugin_info( $data['already_installed_plugin_info'] ?? null );

		return $installation_state;
	}

	/**
	 * Save state to storage.
	 *
	 * @param WC_WCCOM_Site_Installation_State $state The state to save.
	 * @return bool
	 */
	public static function save_state( WC_WCCOM_Site_Installation_State $state ) : bool {
		$storage_key = self::get_storage_key( $state->get_product_id() );

		return update_option(
			$storage_key,
			array(
				'product_id'                    => $state->get_product_id(),
				'idempotency_key'               => $state->get_idempotency_key(),
				'last_step_name'                => $state->get_last_step_name(),
				'last_step_status'              => $state->get_last_step_status(),
				'last_step_error'               => $state->get_last_step_error(),
				'product_type'                  => $state->get_product_type(),
				'product_name'                  => $state->get_product_name(),
				'download_url'                  => $state->get_download_url(),
				'download_path'                 => $state->get_download_path(),
				'unpacked_path'                 => $state->get_unpacked_path(),
				'installed_path'                => $state->get_installed_path(),
				'already_installed_plugin_info' => $state->get_already_installed_plugin_info(),
				'started_date'                  => $state->get_started_date(),
			)
		);
	}

	/**
	 * Delete state from storage.
	 *
	 * @param WC_WCCOM_Site_Installation_State $state The state to delete.
	 * @return bool
	 */
	public static function delete_state( WC_WCCOM_Site_Installation_State $state ) : bool {
		$storage_key = self::get_storage_key( $state->get_product_id() );

		return delete_option( $storage_key );
	}

	/**
	 * Get the storage key for a product ID.
	 *
	 * @param int $product_id The product ID.
	 * @return string
	 */
	protected static function get_storage_key( $product_id ) : string {
		return sprintf( 'wccom-product-installation-state-%d', $product_id );
	}
}

class-wc-wccom-site-installation-state.php000064400000016112151547357720014677 0ustar00<?php
/**
 * State for the WCCOM Site installation process.
 *
 * @package WooCommerce\WCCOM
 */

defined( 'ABSPATH' ) || exit;

/**
 * WC_WCCOM_Site_Installation_State class
 */
class WC_WCCOM_Site_Installation_State {
	/**
	 * The product ID.
	 *
	 * @var string
	 */
	protected $product_id;
	/**
	 * The idempotency key.
	 *
	 * @var string
	 */
	protected $idempotency_key;
	/**
	 * The last step name.
	 *
	 * @var string
	 */
	protected $last_step_name;
	/**
	 * The last step status.
	 *
	 * @var string
	 */
	protected $last_step_status;
	/**
	 * The last step error.
	 *
	 * @var string
	 */
	protected $last_step_error;

	/**
	 * The product type.
	 *
	 * @var string
	 */
	protected $product_type;
	/**
	 * The product name.
	 *
	 * @var string
	 */
	protected $product_name;
	/**
	 * The product slug.
	 *
	 * @var string
	 */
	protected $download_url;
	/**
	 * The path to the downloaded file.
	 *
	 * @var string
	 */
	protected $download_path;
	/**
	 * The path to the unpacked file.
	 *
	 * @var string
	 */
	protected $unpacked_path;
	/**
	 * The path to the installed file.
	 *
	 * @var string
	 */
	protected $installed_path;
	/**
	 * The plugin info for the already installed plugin.
	 *
	 * @var array
	 */
	protected $already_installed_plugin_info;
	/**
	 * The timestamp of the installation start.
	 *
	 * @var int
	 */
	protected $started_date;

	const STEP_STATUS_IN_PROGRESS = 'in-progress';
	const STEP_STATUS_FAILED      = 'failed';
	const STEP_STATUS_COMPLETED   = 'completed';

	/**
	 * Constructor.
	 *
	 * @param string $product_id The product ID.
	 */
	protected function __construct( $product_id ) {
		$this->product_id = $product_id;
	}

	/**
	 * Initiate an existing installation state.
	 *
	 * @param int    $product_id The product ID.
	 * @param string $idempotency_key The idempotency key.
	 * @param string $last_step_name The last step name.
	 * @param string $last_step_status The last step status.
	 * @param string $last_step_error The last step error.
	 * @param int    $started_date The timestamp of the installation start.
	 * @return WC_WCCOM_Site_Installation_State The instance.
	 */
	public static function initiate_existing( $product_id, $idempotency_key, $last_step_name, $last_step_status, $last_step_error, $started_date ) {
		$instance                   = new self( $product_id );
		$instance->idempotency_key  = $idempotency_key;
		$instance->last_step_name   = $last_step_name;
		$instance->last_step_status = $last_step_status;
		$instance->last_step_error  = $last_step_error;
		$instance->started_date     = $started_date;

		return $instance;
	}

	/**
	 * Initiate a new installation state.
	 *
	 * @param init   $product_id The product ID.
	 * @param string $idempotency_key The idempotency key.
	 * @return WC_WCCOM_Site_Installation_State The instance.
	 */
	public static function initiate_new( $product_id, $idempotency_key ) {
		$instance                  = new self( $product_id );
		$instance->idempotency_key = $idempotency_key;
		$instance->started_date    = time();

		return $instance;
	}

	/**
	 * Get the product ID.
	 *
	 * @return string
	 */
	public function get_product_id() {
		return $this->product_id;
	}

	/**
	 * Get the idempotency key.
	 *
	 * @return string
	 */
	public function get_idempotency_key() {
		return $this->idempotency_key;
	}

	/**
	 * Get the timestamp of the installation start.
	 *
	 * @return int
	 */
	public function get_last_step_name() {
		return $this->last_step_name;
	}

	/**
	 * Get the last step status.
	 *
	 * @return string
	 */
	public function get_last_step_status() {
		return $this->last_step_status;
	}

	/**
	 * Get the last step error.
	 *
	 * @return int
	 */
	public function get_last_step_error() {
		return $this->last_step_error;
	}

	/**
	 * Initiate a step.
	 *
	 * @param string $step_name Step name.
	 * @return void
	 */
	public function initiate_step( $step_name ) {
		$this->last_step_name   = $step_name;
		$this->last_step_status = self::STEP_STATUS_IN_PROGRESS;
	}

	/**
	 * Capture a successful installation of a step.
	 *
	 * @param string $step_name The step name.
	 */
	public function complete_step( $step_name ) {
		$this->last_step_name   = $step_name;
		$this->last_step_status = self::STEP_STATUS_COMPLETED;
	}

	/**
	 * Capture an installation failure.
	 *
	 * @param string $step_name  The step name.
	 * @param string $error_code The error code.
	 */
	public function capture_failure( $step_name, $error_code ) {
		$this->last_step_name   = $step_name;
		$this->last_step_error  = $error_code;
		$this->last_step_status = self::STEP_STATUS_FAILED;
	}

	/**
	 * Get the product type.
	 *
	 * @return string
	 */
	public function get_product_type() {
		return $this->product_type;
	}

	/**
	 * Set the product type.
	 *
	 * @param string $product_type The product type.
	 */
	public function set_product_type( $product_type ) {
		$this->product_type = $product_type;
	}
	/**
	 * Get the product name.
	 *
	 * @return string
	 */
	public function get_product_name() {
		return $this->product_name;
	}
	/**
	 * Set the product name.
	 *
	 * @param string $product_name The product name.
	 */
	public function set_product_name( $product_name ) {
		$this->product_name = $product_name;
	}
	/**
	 * Get the download URL.
	 *
	 * @return string
	 */
	public function get_download_url() {
		return $this->download_url;
	}
	/**
	 * Set the download URL.
	 *
	 * @param string $download_url The download URL.
	 */
	public function set_download_url( $download_url ) {
		$this->download_url = $download_url;
	}
	/**
	 * Get the path to the downloaded file.
	 *
	 * @return string
	 */
	public function get_download_path() {
		return $this->download_path;
	}
	/**
	 * Set the path to the downloaded file.
	 *
	 * @param string $download_path The path to the downloaded file.
	 */
	public function set_download_path( $download_path ) {
		$this->download_path = $download_path;
	}
	/**
	 * Get the path to the unpacked file.
	 *
	 * @return string
	 */
	public function get_unpacked_path() {
		return $this->unpacked_path;
	}
	/**
	 * Set the path to the unpacked file.
	 *
	 * @param string $unpacked_path The path to the unpacked file.
	 */
	public function set_unpacked_path( $unpacked_path ) {
		$this->unpacked_path = $unpacked_path;
	}
	/**
	 * Get the path to the installed file.
	 *
	 * @return string
	 */
	public function get_installed_path() {
		return $this->installed_path;
	}
	/**
	 * Set the path to the installed file.
	 *
	 * @param string $installed_path The path to the installed file.
	 */
	public function set_installed_path( $installed_path ) {
		$this->installed_path = $installed_path;
	}
	/**
	 * Get the plugin info for the already installed plugin.
	 *
	 * @return array
	 */
	public function get_already_installed_plugin_info() {
		return $this->already_installed_plugin_info;
	}
	/**
	 * Set the plugin info for the already installed plugin.
	 *
	 * @param array $plugin_info The plugin info.
	 */
	public function set_already_installed_plugin_info( $plugin_info ) {
		$this->already_installed_plugin_info = $plugin_info;
	}
	/**
	 * Get the timestamp of the installation start.
	 *
	 * @return int
	 */
	public function get_started_date() {
		return $this->started_date;
	}
}
installation-steps/class-wc-wccom-site-installation-step-activate-product.php000064400000006472151547357720023653 0ustar00<?php
/**
 * Activate product step.
 *
 * @package WooCommerce\WCCom
 * @since   7.7.0
 */

use WC_REST_WCCOM_Site_Installer_Error_Codes as Installer_Error_Codes;
use WC_REST_WCCOM_Site_Installer_Error as Installer_Error;

defined( 'ABSPATH' ) || exit;

/**
 * WC_WCCOM_Site_Installation_Step_Activate_Product Class
 */
class WC_WCCOM_Site_Installation_Step_Activate_Product implements WC_WCCOM_Site_Installation_Step {
	/**
	 * The current installation state.
	 *
	 * @var WC_WCCOM_Site_Installation_State
	 */
	protected $state;

	/**
	 * Constructor.
	 *
	 * @param array $state The current installation state.
	 */
	public function __construct( $state ) {
		$this->state = $state;
	}

	/**
	 * Run the step installation process.
	 */
	public function run() {
		$product_id = $this->state->get_product_id();

		if ( 'plugin' === $this->state->get_product_type() ) {
			$this->activate_plugin( $product_id );
		} else {
			$this->activate_theme( $product_id );
		}

		return $this->state;
	}

	/**
	 * Activate plugin.
	 *
	 * @param int $product_id Product ID.
	 */
	private function activate_plugin( $product_id ) {
		// Clear plugins cache used in `WC_Helper::get_local_woo_plugins`.
		wp_clean_plugins_cache();
		$filename = false;

		// If product is WP.org one, find out its filename.
		$dir_name = $this->get_wporg_product_dir_name();
		if ( false !== $dir_name ) {
			$filename = \WC_WCCOM_Site_Installer::get_wporg_plugin_main_file( $dir_name );
		}

		if ( false === $filename ) {
			$plugins = wp_list_filter(
				WC_Helper::get_local_woo_plugins(),
				array(
					'_product_id' => $product_id,
				)
			);

			$filename = is_array( $plugins ) && ! empty( $plugins ) ? key( $plugins ) : '';
		}

		if ( empty( $filename ) ) {
			return new Installer_Error( Installer_Error_Codes::UNKNOWN_FILENAME );
		}

		$result = activate_plugin( $filename );

		if ( is_wp_error( $result ) ) {
			return new Installer_Error( Installer_Error_Codes::PLUGIN_ACTIVATION_ERROR, $result->get_error_message() );
		}
	}

	/**
	 * Activate theme.
	 *
	 * @param int $product_id Product ID.
	 */
	private function activate_theme( $product_id ) {
		// Clear plugins cache used in `WC_Helper::get_local_woo_themes`.
		wp_clean_themes_cache();
		$theme_slug = false;

		// If product is WP.org theme, find out its slug.
		$dir_name = $this->get_wporg_product_dir_name();
		if ( false !== $dir_name ) {
			$theme_slug = basename( $dir_name );
		}

		if ( false === $theme_slug ) {
			$themes = wp_list_filter(
				WC_Helper::get_local_woo_themes(),
				array(
					'_product_id' => $product_id,
				)
			);

			$theme_slug = is_array( $themes ) && ! empty( $themes ) ? dirname( key( $themes ) ) : '';
		}

		if ( empty( $theme_slug ) ) {
			return new Installer_Error( Installer_Error_Codes::UNKNOWN_FILENAME );
		}

		switch_theme( $theme_slug );
	}

	/**
	 * Get WP.org product directory name.
	 *
	 * @return string|false
	 */
	private function get_wporg_product_dir_name() {
		if ( empty( $this->state->get_installed_path() ) ) {
			return false;
		}

		// Check whether product was downloaded from WordPress.org.
		$download_url = $this->state->get_download_url();
		$parsed_url   = wp_parse_url( $download_url );
		if ( ! empty( $parsed_url['host'] ) && 'downloads.wordpress.org' !== $parsed_url['host'] ) {
			return false;
		}

		return basename( $this->state->get_installed_path() );
	}
}
installation-steps/class-wc-wccom-site-installation-step-download-product.php000064400000002204151547357730023650 0ustar00<?php
/**
 * Download product step.
 *
 * @package WooCommerce\WCCom
 * @since   7.7.0
 */

use WC_REST_WCCOM_Site_Installer_Error_Codes as Installer_Error_Codes;
use WC_REST_WCCOM_Site_Installer_Error as Installer_Error;

defined( 'ABSPATH' ) || exit;

/**
 * WC_WCCOM_Site_Installation_Step_Download_Product class
 */
class WC_WCCOM_Site_Installation_Step_Download_Product implements WC_WCCOM_Site_Installation_Step {
	/**
	 * The current installation state.
	 *
	 * @var WC_WCCOM_Site_Installation_State
	 */
	protected $state;

	/**
	 * Constructor.
	 *
	 * @param array $state The current installation state.
	 */
	public function __construct( $state ) {
		$this->state = $state;
	}

	/**
	 * Run the step installation process.
	 *
	 * @throws Installer_Error Installer Error.
	 */
	public function run() {
		$upgrader = WC_WCCOM_Site_Installer::get_wp_upgrader();

		$download_path = $upgrader->download_package( $this->state->get_download_url() );

		if ( empty( $download_path ) ) {
			throw new Installer_Error( Installer_Error_Codes::MISSING_DOWNLOAD_PATH );
		}

		$this->state->set_download_path( $download_path );

		return $this->state;
	}
}
installation-steps/class-wc-wccom-site-installation-step-get-product-info.php000064400000006002151547357730023551 0ustar00<?php
/**
 * Get product info step.
 *
 * @package WooCommerce\WCCom
 * @since   7.7.0
 */

use WC_REST_WCCOM_Site_Installer_Error_Codes as Installer_Error_Codes;
use WC_REST_WCCOM_Site_Installer_Error as Installer_Error;

defined( 'ABSPATH' ) || exit;

/**
 * WC_WCCOM_Site_Installation_Step_Get_Product_Info class
 */
class WC_WCCOM_Site_Installation_Step_Get_Product_Info implements WC_WCCOM_Site_Installation_Step {
	/**
	 * The current installation state.
	 *
	 * @var WC_WCCOM_Site_Installation_State
	 */
	protected $state;

	/**
	 * Constructor.
	 *
	 * @param array $state The current installation state.
	 */
	public function __construct( $state ) {
		$this->state = $state;
	}

	/**
	 * Run the step installation process.
	 *
	 * @throws Installer_Error Installer Error.
	 * @return array
	 */
	public function run() {
		$product_id = $this->state->get_product_id();

		// Get product info from woocommerce.com.
		$request = WC_Helper_API::get(
			add_query_arg(
				array( 'product_id' => $product_id ),
				'info'
			),
			array(
				'authenticated' => true,
			)
		);

		if ( 200 !== wp_remote_retrieve_response_code( $request ) ) {
			throw new Installer_Error( Installer_Error_Codes::FAILED_GETTING_PRODUCT_INFO );
		}

		$result = json_decode( wp_remote_retrieve_body( $request ), true );

		if ( ! isset( $result['_product_type'], $result['name'] ) ) {
			throw new Installer_Error( Installer_Error_Codes::INVALID_PRODUCT_INFO_RESPONSE );
		}

		if ( ! empty( $result['_wporg_product'] ) ) {
			$download_url = $this->get_wporg_download_url( $result );
		} else {
			$download_url = $this->get_wccom_download_url( $product_id );
		}

		$this->state->set_product_type( $result['_product_type'] );
		$this->state->set_product_name( $result['name'] );
		$this->state->set_download_url( $download_url );

		return $this->state;
	}

	/**
	 * Get download URL for wporg product.
	 *
	 * @param array $data Product data.
	 *
	 * @return string|null
	 * @throws Installer_Error Installer Error.
	 */
	protected function get_wporg_download_url( $data ) {
		if ( empty( $data['_wporg_product'] ) ) {
			return null;
		}

		if ( empty( $data['download_link'] ) ) {
			throw new Installer_Error( Installer_Error_Codes::WPORG_PRODUCT_MISSING_DOWNLOAD_LINK );
		}

		return $data['download_link'];
	}

	/**
	 * Get download URL for wccom product.
	 *
	 * @param int $product_id Product ID.
	 *
	 * @return string
	 * @throws Installer_Error Installer Error.
	 */
	protected function get_wccom_download_url( $product_id ) {
		WC_Helper::_flush_subscriptions_cache();

		if ( ! WC_Helper::has_product_subscription( $product_id ) ) {
			throw new Installer_Error( Installer_Error_Codes::WCCOM_PRODUCT_MISSING_SUBSCRIPTION );
		}

		// Retrieve download URL for non-wporg product.
		WC_Helper_Updater::flush_updates_cache();
		$updates = WC_Helper_Updater::get_update_data();

		if ( empty( $updates[ $product_id ]['package'] ) ) {
			return new Installer_Error( Installer_Error_Codes::WCCOM_PRODUCT_MISSING_PACKAGE );
		}

		return $updates[ $product_id ]['package'];
	}
}
installation-steps/class-wc-wccom-site-installation-step-move-product.php000064400000003245151547357730023015 0ustar00<?php
/**
 * Move product to the correct location.
 *
 * @package WooCommerce\WCCom
 * @since   7.7.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * WC_WCCOM_Site_Installation_Step_Move_Product class
 */
class WC_WCCOM_Site_Installation_Step_Move_Product implements WC_WCCOM_Site_Installation_Step {
	/**
	 * The current installation state.
	 *
	 * @var WC_WCCOM_Site_Installation_State
	 */
	protected $state;

	/**
	 * Constructor.
	 *
	 * @param array $state The current installation state.
	 */
	public function __construct( $state ) {
		$this->state = $state;
	}

	/**
	 * Run the step installation process.
	 */
	public function run() {
		$upgrader = WC_WCCOM_Site_Installer::get_wp_upgrader();

		$destination = 'plugin' === $this->state->get_product_type()
			? WP_PLUGIN_DIR
			: get_theme_root();

		$package = array(
			'source'        => $this->state->get_unpacked_path(),
			'destination'   => $destination,
			'clear_working' => true,
			'hook_extra'    => array(
				'type'   => $this->state->get_product_type(),
				'action' => 'install',
			),
		);

		$result = $upgrader->install_package( $package );

		/**
		 * If install package returns error 'folder_exists' treat as success.
		 */
		if ( is_wp_error( $result ) && array_key_exists( 'folder_exists', $result->errors ) ) {
			$existing_folder_path = $result->error_data['folder_exists'];
			$plugin_info          = WC_WCCOM_Site_Installer::get_plugin_info( $existing_folder_path );

			$this->state->set_installed_path( $existing_folder_path );
			$this->state->set_already_installed_plugin_info( $plugin_info );

			return $this->state;
		}

		$this->state->set_installed_path( $result['destination'] );

		return $this->state;
	}
}
installation-steps/class-wc-wccom-site-installation-step-unpack-product.php000064400000002131151547357730023321 0ustar00<?php
/**
 * Get product info step.
 *
 * @package WooCommerce\WCCom
 * @since   7.7.0
 */

use WC_REST_WCCOM_Site_Installer_Error_Codes as Installer_Error_Codes;
use WC_REST_WCCOM_Site_Installer_Error as Installer_Error;

defined( 'ABSPATH' ) || exit;

/**
 * WC_WCCOM_Site_Installation_Step_Unpack_Product class
 */
class WC_WCCOM_Site_Installation_Step_Unpack_Product implements WC_WCCOM_Site_Installation_Step {
	/**
	 * The current installation state.
	 *
	 * @var WC_WCCOM_Site_Installation_State
	 */
	protected $state;

	/**
	 * Constructor.
	 *
	 * @param array $state The current installation state.
	 */
	public function __construct( $state ) {
		$this->state = $state;
	}

	/**
	 * Run the step installation process.
	 */
	public function run() {
		$upgrader      = WC_WCCOM_Site_Installer::get_wp_upgrader();
		$unpacked_path = $upgrader->unpack_package( $this->state->get_download_path(), true );

		if ( empty( $unpacked_path ) ) {
			return new Installer_Error( Installer_Error_Codes::MISSING_UNPACKED_PATH );
		}

		$this->state->set_unpacked_path( $unpacked_path );

		return $this->state;
	}
}
installation-steps/interface-installaton-step.php000064400000000575151547357730016401 0ustar00<?php
/**
 * Interface for installation steps.
 *
 * @package WooCommerce\WCCom
 * @since   7.7.0
 */

defined( 'ABSPATH' ) || exit;

interface WC_WCCOM_Site_Installation_Step {
	/**
	 * Constructor.
	 *
	 * @param array $state The current installation state.
	 */
	public function __construct( $state );

	/**
	 * Run the step installation process.
	 */
	public function run();
}