Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

My Jetpack: Requires/Push to connection only if needed #27615

Merged
merged 7 commits into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import ProductCard from '../product-card';
const ConnectedProductCard = ( { admin, slug } ) => {
const { isRegistered, isUserConnected } = useConnection();
const { detail, status, activate, deactivate, isFetching } = useProduct( slug );
const { name, description, manageUrl } = detail;
const { name, description, manageUrl, requiresUserConnection } = detail;

const navigateToConnectionPage = useMyJetpackNavigate( '/connection' );

Expand All @@ -25,14 +25,20 @@ const ConnectedProductCard = ( { admin, slug } ) => {
/*
* Redirect only if connected
*/
const callOnlyIfAllowed = callback => () => {
if ( ! isRegistered || ! isUserConnected ) {
const handleActivate = useCallback( () => {
if ( ( ! isRegistered || ! isUserConnected ) && requiresUserConnection ) {
navigateToConnectionPage();
return;
}

callback();
};
activate();
}, [
activate,
isRegistered,
isUserConnected,
requiresUserConnection,
navigateToConnectionPage,
] );

const Icon = getIconBySlug( slug );

Expand All @@ -46,8 +52,8 @@ const ConnectedProductCard = ( { admin, slug } ) => {
isFetching={ isFetching }
onDeactivate={ deactivate }
slug={ slug }
onActivate={ activate }
onAdd={ callOnlyIfAllowed( navigateToAddProductPage ) }
onActivate={ handleActivate }
onAdd={ navigateToAddProductPage }
onManage={ onManage }
onFixConnection={ navigateToConnectionPage }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ import {
H3,
Alert,
} from '@automattic/jetpack-components';
import { useProductCheckoutWorkflow } from '@automattic/jetpack-connection';
import { ExternalLink } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { Icon, check, plus } from '@wordpress/icons';
import classnames from 'classnames';
import React, { useCallback } from 'react';
import useAnalytics from '../../hooks/use-analytics';
import useMyJetpackConnection from '../../hooks/use-my-jetpack-connection';
import { useProduct } from '../../hooks/use-product';
import getProductCheckoutUrl from '../../utils/get-product-checkout-url';
import ProductDetailButton from '../product-detail-button';
import styles from './style.module.scss';

Expand Down Expand Up @@ -67,7 +66,8 @@ function Price( { value, currency, isOld } ) {
* @returns {object} ProductDetailCard react component.
*/
const ProductDetailCard = ( { slug, onClick, trackButtonClick, className, supportingInfo } ) => {
const fileSystemWriteAccess = window?.myJetpackInitialState?.fileSystemWriteAccess;
const { fileSystemWriteAccess, siteSuffix, myJetpackUrl } = window?.myJetpackInitialState ?? {};

const { detail, isFetching } = useProduct( slug );
const {
title,
Expand All @@ -93,7 +93,6 @@ const ProductDetailCard = ( { slug, onClick, trackButtonClick, className, suppor
wpcomProductSlug,
wpcomFreeProductSlug,
} = pricingForUi;
const { isUserConnected } = useMyJetpackConnection();

const { recordEvent } = useAnalytics();

Expand All @@ -104,15 +103,25 @@ const ProductDetailCard = ( { slug, onClick, trackButtonClick, className, suppor
*/
const needsPurchase = ! isFree && ! hasRequiredPlan;

const addProductUrl =
needsPurchase && wpcomProductSlug
? getProductCheckoutUrl( wpcomProductSlug, isUserConnected ) // @ToDo: Remove this when we have a new product structure.
: null;
const {
run: mainCheckoutRedirect,
hasCheckoutStarted: hasMainCheckoutStarted,
} = useProductCheckoutWorkflow( {
productSlug: wpcomProductSlug,
redirectUrl: myJetpackUrl,
siteSuffix,
from: 'my-jetpack',
} );

const addFreeProductUrl =
trialAvailable && wpcomFreeProductSlug
? getProductCheckoutUrl( wpcomFreeProductSlug, isUserConnected ) // @ToDo: Remove this when we have a new product structure.
: null;
const {
run: trialCheckoutRedirect,
hasCheckoutStarted: hasTrialCheckoutStarted,
} = useProductCheckoutWorkflow( {
productSlug: wpcomFreeProductSlug,
redirectUrl: myJetpackUrl,
siteSuffix,
from: 'my-jetpack',
} );

// Suppported products icons.
const icons = isBundle
Expand All @@ -138,13 +147,13 @@ const ProductDetailCard = ( { slug, onClick, trackButtonClick, className, suppor

const clickHandler = useCallback( () => {
trackButtonClick();
onClick?.( addProductUrl );
}, [ onClick, trackButtonClick, addProductUrl ] );
onClick?.( mainCheckoutRedirect );
}, [ onClick, trackButtonClick, mainCheckoutRedirect ] );

const trialClickHandler = useCallback( () => {
trackButtonClick( wpcomFreeProductSlug );
onClick?.( addFreeProductUrl );
}, [ onClick, trackButtonClick, addFreeProductUrl, wpcomFreeProductSlug ] );
onClick?.( trialCheckoutRedirect );
}, [ onClick, trackButtonClick, trialCheckoutRedirect, wpcomFreeProductSlug ] );

const disclaimerClickHandler = useCallback(
id => {
Expand Down Expand Up @@ -246,10 +255,9 @@ const ProductDetailCard = ( { slug, onClick, trackButtonClick, className, suppor
<Text
component={ ProductDetailButton }
onClick={ clickHandler }
isLoading={ isFetching }
isLoading={ isFetching || hasMainCheckoutStarted }
disabled={ cantInstallPlugin }
isPrimary={ ! isBundle }
href={ onClick ? undefined : addProductUrl }
className={ styles[ 'checkout-button' ] }
variant="body"
>
Expand All @@ -264,10 +272,9 @@ const ProductDetailCard = ( { slug, onClick, trackButtonClick, className, suppor
<Text
component={ ProductDetailButton }
onClick={ trialClickHandler }
isLoading={ isFetching }
isLoading={ isFetching || hasTrialCheckoutStarted }
disabled={ cantInstallPlugin }
isPrimary={ false }
href={ onClick ? undefined : addFreeProductUrl }
className={ [ styles[ 'checkout-button' ], styles[ 'free-product-checkout-button' ] ] }
variant="body"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default function ProductInterstitial( {
const navigateToMyJetpackOverviewPage = useMyJetpackNavigate( '/' );

const clickHandler = useCallback(
checkoutUrl => {
checkout => {
activate().finally( () => {
const product = select( STORE_ID ).getProduct( slug );
const postActivationUrl = product?.postActivationUrl;
Expand All @@ -71,12 +71,12 @@ export default function ProductInterstitial( {
return;
}

if ( ! needsPurchase || ! checkoutUrl ) {
if ( ! needsPurchase ) {
return navigateToMyJetpackOverviewPage();
}

// Redirect to the checkout page.
window.location.href = checkoutUrl;
checkout?.();
} );
},
[ navigateToMyJetpackOverviewPage, activate, slug ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

My Jetpack: Requires connection only if needed
41 changes: 28 additions & 13 deletions projects/packages/my-jetpack/src/class-wpcom-products.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,36 @@ class Wpcom_Products {
* @return Object|WP_Error
*/
private static function get_products_from_wpcom() {

$blog_id = \Jetpack_Options::get_option( 'id' );
$endpoint = sprintf( '/sites/%d/products/?_locale=%s&type=jetpack', $blog_id, get_user_locale() );

$wpcom_request = Client::wpcom_json_api_request_as_blog(
$endpoint,
'1.1',
array(
'method' => 'GET',
'headers' => array(
'X-Forwarded-For' => ( new Visitor() )->get_ip( true ),
),
)
$blog_id = \Jetpack_Options::get_option( 'id' );
$ip = ( new Visitor() )->get_ip( true );
$headers = array(
'X-Forwarded-For' => $ip,
);

// If has a blog id, use connected endpoint.

if ( $blog_id ) {
$endpoint = sprintf( '/sites/%d/products/?_locale=%s&type=jetpack', $blog_id, get_user_locale() );

$wpcom_request = Client::wpcom_json_api_request_as_blog(
$endpoint,
'1.1',
array(
'method' => 'GET',
'headers' => $headers,
)
);
} else {
$endpoint = 'https://public-api.wordpress.com/rest/v1.1/products?locale=' . get_user_locale() . '&type=jetpack';

$wpcom_request = wp_remote_get(
esc_url_raw( $endpoint ),
array(
'headers' => $headers,
)
);
}

$response_code = wp_remote_retrieve_response_code( $wpcom_request );

if ( 200 === $response_code ) {
Expand Down