Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/trunk' into add/ci-php-8.4
Browse files Browse the repository at this point in the history
  • Loading branch information
anomiex committed Nov 19, 2024
2 parents 7777ebc + d438fb8 commit 68bda8f
Show file tree
Hide file tree
Showing 15 changed files with 280 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Add Stats icon
13 changes: 13 additions & 0 deletions projects/js-packages/components/components/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,18 @@ export const AiIcon: React.FC< BaseIconProps > = ( {
);
};

export const StatsIcon: React.FC< BaseIconProps > = ( { opacity = 1, size, color } ) => {
return (
<IconWrapper size={ size } opacity={ opacity } color={ color }>
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M11.25 5H12.75V20H11.25V5ZM6 10H7.5V20H6V10ZM18 14H16.5V20H18V14Z"
/>
</IconWrapper>
);
};

const jetpackIcons = {
'anti-spam': AntiSpamIcon,
backup: BackupIcon,
Expand All @@ -249,6 +261,7 @@ const jetpackIcons = {
jetpack: JetpackIcon,
share: ShareIcon,
ai: AiIcon,
stats: StatsIcon,
};

const iconsMap = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ export const JetpackModuleToProductCard: {
scan: null,
security: null,
creator: null,
growth: null,
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type DisplayItemType = Record<
// We don't have a card for Security or Extras, and scan is displayed as protect.
// 'jetpack-ai' is the official slug for the AI module, so we also exclude 'ai'.
// The backend still supports the 'ai' slug, so it is part of the JetpackModule type.
Exclude< JetpackModule, 'extras' | 'scan' | 'security' | 'ai' | 'creator' >,
Exclude< JetpackModule, 'extras' | 'scan' | 'security' | 'ai' | 'creator' | 'growth' >,
FC< { admin: boolean } >
>;

Expand Down Expand Up @@ -104,7 +104,12 @@ const ProductCardsSection: FC< ProductCardsSectionProps > = ( { noticeMessage }

const filterProducts = ( products: JetpackModule[] ) => {
return products.filter( product => {
if ( product === 'scan' || product === 'security' || product === 'extras' ) {
if (
product === 'scan' ||
product === 'security' ||
product === 'growth' ||
product === 'extras'
) {
return false;
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ import boostImage from './boost.png';
import crmImage from './crm.png';
import extrasImage from './extras.png';
import searchImage from './search.png';
import socialImage from './social.png';
import statsImage from './stats.png';
import styles from './style.module.scss';
import videoPressImage from './videopress.png';

Expand Down Expand Up @@ -408,17 +406,7 @@ export function ScanInterstitial() {
* @return {object} SocialInterstitial react component.
*/
export function SocialInterstitial() {
return (
<ProductInterstitial slug="social" installsPlugin={ true }>
<img
src={ socialImage }
alt={ __(
'Image displaying logos of social media platforms supported by Jetpack Social.',
'jetpack-my-jetpack'
) }
/>
</ProductInterstitial>
);
return <ProductInterstitial slug="social" installsPlugin={ true } bundle="growth" />;
}

/**
Expand Down Expand Up @@ -462,15 +450,8 @@ export function StatsInterstitial() {
directCheckout={ true }
installsPlugin={ true }
ctaButtonLabel={ __( 'Get Stats', 'jetpack-my-jetpack' ) }
>
<img
src={ statsImage }
alt={ __(
'Illustration showing the Stats feature, highlighting important statistics for your site.',
'jetpack-my-jetpack'
) }
/>
</ProductInterstitial>
bundle="growth"
/>
);
}

Expand Down
1 change: 1 addition & 0 deletions projects/packages/my-jetpack/_inc/data/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ export const PRODUCT_SLUGS = {
PROTECT: 'protect',
VIDEOPRESS: 'videopress',
STATS: 'stats',
GROWTH: 'growth',
} satisfies Record< string, JetpackModule >;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Add growth upsell to Stats and Social interstitials
3 changes: 2 additions & 1 deletion projects/packages/my-jetpack/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ type JetpackModule =
| 'security'
| 'protect'
| 'videopress'
| 'stats';
| 'stats'
| 'growth';

type ThreatItem = {
// Protect API properties (free plan)
Expand Down
1 change: 1 addition & 0 deletions projects/packages/my-jetpack/src/class-products.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ public static function get_products_classes() {
'videopress' => Products\Videopress::class,
'stats' => Products\Stats::class,
'ai' => Products\Jetpack_Ai::class,
'growth' => Products\Growth::class,
);

/**
Expand Down
209 changes: 209 additions & 0 deletions projects/packages/my-jetpack/src/products/class-growth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
<?php
/**
* Growth plan
*
* @package my-jetpack
*/

namespace Automattic\Jetpack\My_Jetpack\Products;

use Automattic\Jetpack\My_Jetpack\Module_Product;
use Automattic\Jetpack\My_Jetpack\Wpcom_Products;
use WP_Error;

/**
* Class responsible for handling the Growth plan
*/
class Growth extends Module_Product {

/**
* The product slug
*
* @var string
*/
public static $slug = 'growth';

/**
* The Jetpack module name
*
* @var string
*/
public static $module_name = 'growth';

/**
* Get the product name
*
* @return string
*/
public static function get_name() {
return 'Growth';
}

/**
* Get the product title
*
* @return string
*/
public static function get_title() {
return 'Jetpack Growth';
}

/**
* Get the internationalized product description
*
* @return string
*/
public static function get_description() {
return __( 'Grow and track your audience effortlessly.', 'jetpack-my-jetpack' );
}

/**
* Get the internationalized product description
*
* @return string
*/
public static function get_long_description() {
return __( 'Essential tools to help you grow your audience, track visitor engagement, and turn leads into loyal customers and advocates.', 'jetpack-my-jetpack' );
}

/**
* Get the internationalized feature list
*
* @return array Growth features list
*/
public static function get_features() {
return array(
_x( 'Jetpack Social', 'Growth Product Feature', 'jetpack-my-jetpack' ),
_x( 'Jetpack Stats (up to 100K site views)', 'Growth Product Feature', 'jetpack-my-jetpack' ),
_x( 'Unlimited subscriber imports', 'Growth Product Feature', 'jetpack-my-jetpack' ),
_x( 'Earn more from your content', 'Growth Product Feature', 'jetpack-my-jetpack' ),
_x( 'Accept payments with PayPal', 'Growth Product Feature', 'jetpack-my-jetpack' ),
_x( 'Increase earnings with WordAds', 'Growth Product Feature', 'jetpack-my-jetpack' ),
);
}

/**
* Get the product pricing details
*
* @return array Pricing details
*/
public static function get_pricing_for_ui() {
$product_slug = static::get_wpcom_product_slug();
return array_merge(
array(
'available' => true,
'wpcom_product_slug' => $product_slug,
),
Wpcom_Products::get_product_pricing( $product_slug )
);
}

/**
* Get the WPCOM product slug used to make the purchase
*
* @return string
*/
public static function get_wpcom_product_slug() {
return 'jetpack_growth_yearly';
}

/**
* Checks whether the Jetpack module is active
*
* This is a bundle and not a product. We should not use this information for anything
*
* @return bool
*/
public static function is_module_active() {
return false;
}

/**
* Activates the product by installing and activating its plugin
*
* @param WP_Error|bool $current_result Is the result of the top level activation actions. You probably won't do anything if it is an WP_Error.
* @return bool|\WP_Error
*/
public static function do_product_specific_activation( $current_result ) {
$product_activation = parent::do_product_specific_activation( $current_result );

// A bundle is not a module. There's nothing in the plugin to be activated, so it's ok to fail to activate the module.
if ( is_wp_error( $product_activation ) && 'module_activation_failed' === $product_activation->get_error_code() ) {
return $product_activation;
}

// At this point, Jetpack plugin is installed. Let's activate each individual product.
$activation = Social::activate();
if ( is_wp_error( $activation ) ) {
return $activation;
}

$activation = Stats::activate();
if ( is_wp_error( $activation ) ) {
return $activation;
}

return $activation;
}

/**
* Checks whether the Product is active
*
* Growth is a bundle and not a module. Activation takes place on WPCOM. So lets consider it active if jetpack is active and has the plan.
*
* @return bool
*/
public static function is_active() {
return static::is_jetpack_plugin_active() && static::has_required_plan();
}

/**
* Checks whether the current plan (or purchase) of the site already supports the product
*
* @return bool
*/
public static function has_required_plan() {
$purchases_data = Wpcom_Products::get_site_current_purchases();
if ( is_wp_error( $purchases_data ) ) {
return false;
}
if ( is_array( $purchases_data ) && ! empty( $purchases_data ) ) {
foreach ( $purchases_data as $purchase ) {
if (
str_starts_with( $purchase->product_slug, 'jetpack_growth' ) ||
str_starts_with( $purchase->product_slug, 'jetpack_complete' )
) {
return true;
}
}
}
return false;
}

/**
* Checks whether the product is a bundle
*
* @return bool
*/
public static function is_bundle_product() {
return true;
}

/**
* Returns all products it contains.
*
* @return array Product slugs
*/
public static function get_supported_products() {
return array( 'social', 'stats' );
}

/**
* Get the URL where the user manages the product
*
* @return string
*/
public static function get_manage_url() {
return '';
}
}
11 changes: 6 additions & 5 deletions projects/packages/my-jetpack/src/products/class-security.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static function get_long_description() {
/**
* Get the internationalized features list
*
* @return array Boost features list
* @return array Security features list
*/
public static function get_features() {
return array(
Expand All @@ -81,17 +81,18 @@ public static function get_features() {
}

/**
* Get the product princing details
* Get the product pricing details
*
* @return array Pricing details
*/
public static function get_pricing_for_ui() {
$product_slug = static::get_wpcom_product_slug();
return array_merge(
array(
'available' => true,
'wpcom_product_slug' => static::get_wpcom_product_slug(),
'wpcom_product_slug' => $product_slug,
),
Wpcom_Products::get_product_pricing( static::get_wpcom_product_slug() )
Wpcom_Products::get_product_pricing( $product_slug )
);
}

Expand Down Expand Up @@ -195,7 +196,7 @@ public static function is_bundle_product() {
/**
* Return all the products it contains.
*
* @return Array Product slugs
* @return array Product slugs
*/
public static function get_supported_products() {
return array( 'backup', 'scan', 'anti-spam' );
Expand Down
Loading

0 comments on commit 68bda8f

Please sign in to comment.