PluginProbe
wpForo Forum / 3.2.1
wpForo Forum v3.2.1
3.2.1 3.2.0 3.1.7 3.1.6 3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 All 141 releases
← All changes | admin/pages/license/src/Services/ActionsService.php +45 -2 3.1.5 → 3.2.1 View file →
@@ -49,8 +49,9 @@
49 49 add_action( $p . 'install_addon', [ $this, 'ajax_install_addon' ] );
50 50 add_action( $p . 'activate_addon', [ $this, 'ajax_activate_addon' ] );
51 51 add_action( $p . 'deactivate_addon', [ $this, 'ajax_deactivate_addon' ] );
52 52 add_action( $p . 'install_activate_addon', [ $this, 'ajax_install_activate_addon' ] );
53 + add_action( $p . 'download_addon', [ $this, 'ajax_download_addon' ] );
53 54
54 55 // Subscription
55 56 add_action( $p . 'cancel_subscription', [ $this, 'ajax_cancel_subscription' ] );
56 57 add_action( $p . 'resume_subscription', [ $this, 'ajax_resume_subscription' ] );
@@ -172,8 +173,23 @@
172 173 $product['active_price_interval'] = $matched_price['interval_label'] ?? '';
173 174 }
174 175 }
175 176 unset( $product );
177 +
178 + // Probe the filesystem only when a licensed addon still needs installing (the probe writes a temp file)
179 + $needs_install = false;
180 + foreach( $products as $product ) {
181 + if( ( $product['is_licensed'] || $product['is_trial'] ) && empty( $product['is_bundle'] ) && $product['addon_status'] === 'not_installed' ) {
182 + $needs_install = true;
183 + break;
184 + }
185 + }
186 + $can_install = ! $needs_install || $this->addonsService->can_install_addons();
187 + foreach( $products as &$product ) {
188 + $product['can_install'] = $can_install;
189 + }
190 + unset( $product );
191 +
176 192 $products = array_values( $products );
177 193 wp_send_json_success( [ 'products' => $products, 'checkout_mode' => $checkout_mode ] );
178 194 } else {
179 195 wp_send_json_error( [ 'message' => __( 'Failed to load products', 'gvectors' ) ] );
@@ -662,9 +678,12 @@
662 678 $result = $this->addonsService->install( $product_id );
663 679 if( ! empty( $result['success'] ) ) {
664 680 wp_send_json_success( $result );
665 681 } else {
666 - wp_send_json_error( [ 'message' => $result['error'] ?? __( 'Installation failed', 'gvectors' ) ] );
682 + wp_send_json_error( [
683 + 'message' => $result['error'] ?? __( 'Installation failed', 'gvectors' ),
684 + 'manual_install' => ! empty( $result['manual_install'] ),
685 + ] );
667 686 }
668 687 }
669 688
670 689 public function ajax_activate_addon(): void {
@@ -716,9 +735,33 @@
716 735 $result = $this->addonsService->install_and_activate( $product_id );
717 736 if( ! empty( $result['success'] ) ) {
718 737 wp_send_json_success( $result );
719 738 } else {
720 - wp_send_json_error( [ 'message' => $result['error'] ?? __( 'Install & activate failed', 'gvectors' ) ] );
739 + wp_send_json_error( [
740 + 'message' => $result['error'] ?? __( 'Install & activate failed', 'gvectors' ),
741 + 'manual_install' => ! empty( $result['manual_install'] ),
742 + ] );
743 + }
744 + }
745 +
746 + /**
747 + * Signed addon ZIP URL for a manual (FTP) install — the browser downloads it straight from the proxy
748 + */
749 + public function ajax_download_addon(): void {
750 + if( ! $this->verify_admin() ) return;
751 +
752 + $product_id = isset( $_POST['product_id'] ) ? sanitize_text_field( $_POST['product_id'] ) : '';
753 + if( empty( $product_id ) ) {
754 + wp_send_json_error( [ 'message' => __( 'Product ID required', 'gvectors' ) ] );
755 +
756 + return;
757 + }
758 +
759 + $result = $this->addonsService->get_download_link( $product_id );
760 + if( ! empty( $result['success'] ) ) {
761 + wp_send_json_success( $result );
762 + } else {
763 + wp_send_json_error( [ 'message' => $result['error'] ?? __( 'Failed to get download URL', 'gvectors' ) ] );
721 764 }
722 765 }
723 766
724 767 // ==========================================