Skip to content

Commit

Permalink
Update & refine logic to determine if products is expired/expiring.
Browse files Browse the repository at this point in the history
  • Loading branch information
elliottprogrammer committed Oct 22, 2024
1 parent 8784bb5 commit ecbd97d
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 53 deletions.
2 changes: 1 addition & 1 deletion projects/packages/my-jetpack/_inc/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ export const PRODUCT_STATUSES = {
NEEDS_FIRST_SITE_CONNECTION: 'needs_first_site_connection',
USER_CONNECTION_ERROR: 'user_connection_error',
CAN_UPGRADE: 'can_upgrade',
EXPIRING_SOON: 'expiring_soon',
EXPIRING_SOON: 'expiring',
EXPIRED: 'expired',
};
2 changes: 1 addition & 1 deletion projects/packages/my-jetpack/src/class-products.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Products {
const STATUS_USER_CONNECTION_ERROR = 'user_connection_error';
const STATUS_ACTIVE = 'active';
const STATUS_CAN_UPGRADE = 'can_upgrade';
const STATUS_EXPIRING_SOON = 'expiring_soon';
const STATUS_EXPIRING_SOON = 'expiring';
const STATUS_EXPIRED = 'expired';
const STATUS_INACTIVE = 'inactive';
const STATUS_MODULE_DISABLED = 'module_disabled';
Expand Down
80 changes: 60 additions & 20 deletions projects/packages/my-jetpack/src/products/class-product.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ abstract class Product {
*/
public static $requires_plan = false;

/**
* The feature slug that identifies the highest paid plan
*
* @var string
*/
public static $feature_identifying_paid_plan = '';

/**
* Get the plugin slug
*
Expand Down Expand Up @@ -189,7 +196,7 @@ public static function get_info() {
*
* @return WP_Error|array
*/
private static function get_site_features_from_wpcom() {
public static function get_site_features_from_wpcom() {
static $features = null;

if ( $features !== null ) {
Expand All @@ -206,7 +213,11 @@ private static function get_site_features_from_wpcom() {

$body = wp_remote_retrieve_body( $response );
$feature_return = json_decode( $body );
$features = $feature_return->active;

$features = array(
'active' => $feature_return->active,
'available' => $feature_return->available,
);

return $features;
}
Expand All @@ -228,7 +239,7 @@ public static function does_site_have_feature( $feature ) {
return false;
}

return in_array( $feature, $features, true );
return in_array( $feature, $features['active'], true );
}

/**
Expand Down Expand Up @@ -407,32 +418,61 @@ public static function has_any_plan_for_product() {
return static::has_paid_plan_for_product() || static::has_free_plan_for_product();
}

/**
* Get the product-slugs of the paid plans for this product (not including bundles).
*
* @return array
*/
public static function get_paid_plan_product_slugs() {
return array();
}

/**
* Get the product-slugs of the paid bundles/plans that this product/module is included in
*
* @return array
*/
public static function get_paid_bundles_that_include_product() {
$features = static::get_site_features_from_wpcom();
if ( is_wp_error( $features ) ) {
return array();
}
$idendifying_feature = static::$feature_identifying_paid_plan;
if ( empty( $features['available'] ) || empty( $idendifying_feature ) ) {
return array();
}
$paid_bundles = $features['available']->$idendifying_feature;

return $paid_bundles;
}

/**
* Gets the paid plan's expiry status, or null if: no paid plan, or not expired, or not expiring soon.
*
* @return string
* @return string|null
*/
public static function get_paid_plan_expiration_status() {
if ( ! static::has_paid_plan_for_product() ) {
return null;
}
$product_slug = static::get_wpcom_product_slug();
$paid_plans = array_merge(
static::get_paid_plan_product_slugs(),
static::get_paid_bundles_that_include_product()
);

$purchases_data = Wpcom_Products::get_site_current_purchases();
if ( is_wp_error( $purchases_data ) ) {
return null;
}

if ( is_array( $purchases_data ) && ! empty( $purchases_data ) ) {
foreach ( $purchases_data as $purchase ) {
if ( strpos( $purchase->product_slug, $product_slug ) !== false ) {
// Check if expired or expiring soon
$now = time();
$expiry_date = strtotime( $purchase->expiry_date );
$expiring_soon = strtotime( $purchase->expiry_date . ' -30 days' );
if ( $now > $expiring_soon && $now < $expiry_date ) {
return Products::STATUS_EXPIRING_SOON;
}
if ( $now > $expiry_date ) {
return Products::STATUS_EXPIRED;
foreach ( $paid_plans as $plan ) {
if ( strpos( $purchase->product_slug, $plan ) !== false ) {
// Check if expired or expiring soon
if ( $purchase->expiry_status === Products::STATUS_EXPIRING_SOON ) {
return Products::STATUS_EXPIRING_SOON;
}
if ( $purchase->expiry_status === Products::STATUS_EXPIRED ) {
return Products::STATUS_EXPIRED;
}
}
}
}
Expand Down Expand Up @@ -539,10 +579,10 @@ public static function get_status() {
}
} elseif ( static::$requires_user_connection && ! ( new Connection_Manager() )->has_connected_owner() ) {
$status = Products::STATUS_USER_CONNECTION_ERROR;
} elseif ( static::is_upgradable() ) {
$status = Products::STATUS_CAN_UPGRADE;
} elseif ( static::has_paid_plan_for_product() && in_array( static::get_paid_plan_expiration_status(), Products::$expiring_or_expired_module_statuses, true ) ) {
$status = static::get_paid_plan_expiration_status();
} elseif ( static::is_upgradable() ) {
$status = Products::STATUS_CAN_UPGRADE;
}
// Check specifically for inactive modules, which will prevent a product from being active
} elseif ( static::$module_name && ! static::is_module_active() ) {
Expand Down
21 changes: 21 additions & 0 deletions projects/packages/my-jetpack/src/products/class-stats.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ class Stats extends Module_Product {
*/
public static $has_free_offering = true;

/**
* The feature slug that identifies the paid plan
*
* @var string
*/
public static $feature_identifying_paid_plan = 'stats-paid';

/**
* Get the product name
*
Expand Down Expand Up @@ -237,6 +244,20 @@ public static function has_paid_plan_for_product() {
return false;
}

/**
* Get the product-slugs of the paid plans for this product (not including bundles)
*
* @return array
*/
public static function get_paid_plan_product_slugs() {
return array(
'jetpack_stats_yearly',
'jetpack_stats_monthly',
'jetpack_stats_bi_yearly',
'jetpack_stats_pwyw_yearly',
);
}

/**
* Returns a productType parameter for an upgrade URL, determining whether
* to show the PWYW upgrade interstitial or commercial upgrade interstitial.
Expand Down
44 changes: 13 additions & 31 deletions projects/packages/my-jetpack/src/products/class-videopress.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
namespace Automattic\Jetpack\My_Jetpack\Products;

use Automattic\Jetpack\My_Jetpack\Hybrid_Product;
use Automattic\Jetpack\My_Jetpack\Products;
use Automattic\Jetpack\My_Jetpack\Wpcom_Products;

/**
Expand Down Expand Up @@ -69,6 +68,13 @@ class Videopress extends Hybrid_Product {
*/
public static $has_free_offering = true;

/**
* The feature slug that identifies the paid plan
*
* @var string
*/
public static $feature_identifying_paid_plan = 'videopress-1tb-storage';

/**
* Get the product name
*
Expand Down Expand Up @@ -203,39 +209,15 @@ public static function has_paid_plan_for_product() {
}

/**
* Gets the paid plan's expiry status, or null if: no paid plan, or not expired, or not expiring soon.
* Get the product-slugs of the paid plans for this product (not including bundles)
*
* @return boolean
* @return array
*/
public static function get_paid_plan_expiration_status() {
$plans_with_videopress = array(
public static function get_paid_plan_product_slugs() {
return array(
'jetpack_videopress',
'jetpack_complete',
'jetpack_business',
'jetpack_premium',
'jetpack_videopress_monthly',
'jetpack_videopress_bi_yearly',
);
$purchases_data = Wpcom_Products::get_site_current_purchases();
if ( is_wp_error( $purchases_data ) ) {
return null;
}
if ( is_array( $purchases_data ) && ! empty( $purchases_data ) ) {
foreach ( $purchases_data as $purchase ) {
foreach ( $plans_with_videopress as $plan ) {
if ( strpos( $purchase->product_slug, $plan ) !== false ) {
// Check if expired or expiring soon
$now = time();
$expiry_date = strtotime( $purchase->expiry_date );
$expiring_soon = strtotime( $purchase->expiry_date . ' -30 days' );
if ( $now > $expiring_soon && $now < $expiry_date ) {
return Products::STATUS_EXPIRING_SOON;
}
if ( $now > $expiry_date ) {
return Products::STATUS_EXPIRED;
}
}
}
}
}
return null;
}
}

0 comments on commit ecbd97d

Please sign in to comment.