diff --git a/includes/api/wccom-site/class-wc-rest-wccom-site-installer-controller.php b/includes/api/wccom-site/class-wc-rest-wccom-site-installer-controller.php index 2e78c3b1a72..a9446e63b61 100644 --- a/includes/api/wccom-site/class-wc-rest-wccom-site-installer-controller.php +++ b/includes/api/wccom-site/class-wc-rest-wccom-site-installer-controller.php @@ -97,10 +97,15 @@ class WC_REST_WCCOM_Site_Installer_Controller extends WC_REST_Controller { } $data = json_decode( $body, true ); - if ( empty( $data['products'] ) || ! is_array( $data['products'] ) ) { + if ( empty( $data['products'] ) ) { return new WP_Error( 'missing_products', __( 'Missing products in request body.', 'woocommerce' ), array( 'status' => 400 ) ); } + $validation_result = $this->validate_products( $data['products'] ); + if ( is_wp_error( $validation_result ) ) { + return $validation_result; + } + return rest_ensure_response( WC_WCCOM_Site_Installer::schedule_install( $data['products'] ) ); } @@ -117,4 +122,32 @@ class WC_REST_WCCOM_Site_Installer_Controller extends WC_REST_Controller { return $resp; } + + /** + * Validate products from request body. + * + * @param array $products Array of products where key is product ID and + * element is install args. + * + * @return bool|WP_Error + */ + protected function validate_products( $products ) { + $err = new WP_Error( 'invalid_products', __( 'Invalid products in request body.', 'woocommerce' ), array( 'status' => 400 ) ); + + if ( ! is_array( $products ) ) { + return $err; + } + + foreach ( $products as $product_id => $install_args ) { + if ( ! absint( $product_id ) ) { + return $err; + } + + if ( empty( $install_args ) || ! is_array( $install_args ) ) { + return $err; + } + } + + return true; + } } diff --git a/includes/wccom-site/class-wc-wccom-site-installer.php b/includes/wccom-site/class-wc-wccom-site-installer.php index c1b489f5f4f..58f22176f0f 100644 --- a/includes/wccom-site/class-wc-wccom-site-installer.php +++ b/includes/wccom-site/class-wc-wccom-site-installer.php @@ -40,6 +40,7 @@ class WC_WCCOM_Site_Installer { 'download_path' => '', 'unpacked_path' => '', 'installed_path' => '', + 'activate' => false, ); /** @@ -99,7 +100,8 @@ class WC_WCCOM_Site_Installer { /** * Schedule installing given list of products. * - * @param array $products List of product IDs. + * @param array $products Array of products where key is product ID and + * element is install args. * * @return array State. */ @@ -111,7 +113,7 @@ class WC_WCCOM_Site_Installer { } self::update_state( 'status', 'in-progress' ); - $steps = array_fill_keys( $products, self::$default_step_state ); + $steps = array_fill_keys( array_keys( $products ), self::$default_step_state ); self::update_state( 'steps', $steps ); $args = array( @@ -129,7 +131,8 @@ class WC_WCCOM_Site_Installer { * * Run via `woocommerce_wccom_install_products` hook. * - * @param array $products List of product IDs. + * @param array $products Array of products where key is product ID and + * element is install args. * * @return array State. */ @@ -144,8 +147,8 @@ class WC_WCCOM_Site_Installer { $upgrader->init(); wp_clean_plugins_cache(); - foreach ( $products as $product_id ) { - self::install_product( $product_id, $upgrader ); + foreach ( $products as $product_id => $install_args ) { + self::install_product( $product_id, $install_args, $upgrader ); } self::finish_installation(); @@ -177,23 +180,25 @@ class WC_WCCOM_Site_Installer { /** * Install a single product given its ID. * - * @param int $product_id Product ID. - * @param \WP_Upgrader $upgrader Core class to handle installation. + * @param int $product_id Product ID. + * @param array $install_args Install args. + * @param \WP_Upgrader $upgrader Core class to handle installation. */ - private static function install_product( $product_id, $upgrader ) { + private static function install_product( $product_id, $install_args, $upgrader ) { foreach ( self::$install_steps as $step ) { - self::do_install_step( $product_id, $step, $upgrader ); + self::do_install_step( $product_id, $install_args, $step, $upgrader ); } } /** * Perform product installation step. * - * @param int $product_id Product ID. - * @param string $step Installation step. - * @param \WP_Upgrader $upgrader Core class to handle installation. + * @param int $product_id Product ID. + * @param array $install_args Install args. + * @param string $step Installation step. + * @param \WP_Upgrader $upgrader Core class to handle installation. */ - private static function do_install_step( $product_id, $step, $upgrader ) { + private static function do_install_step( $product_id, $install_args, $step, $upgrader ) { $state_steps = self::get_state( 'steps' ); if ( empty( $state_steps[ $product_id ] ) ) { $state_steps[ $product_id ] = self::$default_step_state; @@ -205,6 +210,10 @@ class WC_WCCOM_Site_Installer { $state_steps[ $product_id ]['last_step'] = $step; + if ( ! empty( $install_args['activate'] ) ) { + $state_steps[ $product_id ]['activate'] = true; + } + self::update_state( 'current_step', array( @@ -362,6 +371,10 @@ class WC_WCCOM_Site_Installer { */ private static function activate_product( $product_id ) { $steps = self::get_state( 'steps' ); + if ( ! $steps[ $product_id ]['activate'] ) { + return null; + } + if ( 'plugin' === $steps[ $product_id ]['product_type'] ) { return self::activate_plugin( $product_id ); }