Skip to content

Commit

Permalink
Update move backup endpoint to product class (#41730)
Browse files Browse the repository at this point in the history
* Move backup endpoint to Backup product class

* changelog

* Add visibility to constants in Initializer

* Add test for registering endpoint

* Remove new test
  • Loading branch information
CodeyGuyDylan authored Feb 18, 2025
1 parent e8cf9c2 commit 5b9915d
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 130 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Move backup endpoint to product class
21 changes: 11 additions & 10 deletions projects/packages/my-jetpack/src/class-initializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ class Initializer {
/**
* HTML container ID for the IDC screen on My Jetpack page.
*/
const IDC_CONTAINER_ID = 'my-jetpack-identity-crisis-container';
private const IDC_CONTAINER_ID = 'my-jetpack-identity-crisis-container';

const JETPACK_PLUGIN_SLUGS = array(
private const JETPACK_PLUGIN_SLUGS = array(
'jetpack-backup',
'jetpack-boost',
'zerobscrm',
Expand All @@ -59,12 +59,12 @@ class Initializer {
'jetpack-search',
);

const MY_JETPACK_SITE_INFO_TRANSIENT_KEY = 'my-jetpack-site-info';
const UPDATE_HISTORICALLY_ACTIVE_JETPACK_MODULES_KEY = 'update-historically-active-jetpack-modules';
const MISSING_CONNECTION_NOTIFICATION_KEY = 'missing-connection';
const VIDEOPRESS_STATS_KEY = 'my-jetpack-videopress-stats';
const VIDEOPRESS_PERIOD_KEY = 'my-jetpack-videopress-period';
const MY_JETPACK_RED_BUBBLE_TRANSIENT_KEY = 'my-jetpack-red-bubble-transient';
private const MY_JETPACK_SITE_INFO_TRANSIENT_KEY = 'my-jetpack-site-info';
private const UPDATE_HISTORICALLY_ACTIVE_JETPACK_MODULES_KEY = 'update-historically-active-jetpack-modules';
private const MISSING_CONNECTION_NOTIFICATION_KEY = 'missing-connection';
private const VIDEOPRESS_STATS_KEY = 'my-jetpack-videopress-stats';
private const VIDEOPRESS_PERIOD_KEY = 'my-jetpack-videopress-period';
private const MY_JETPACK_RED_BUBBLE_TRANSIENT_KEY = 'my-jetpack-red-bubble-transient';

/**
* Holds info/data about the site (from the /sites/%d endpoint)
Expand Down Expand Up @@ -235,7 +235,7 @@ public static function enqueue_scripts() {
}
$latest_score['previousScores'] = $previous_score['scores'] ?? array();

Products\Protect::initialize();
Products::initialize_products();
$scan_data = Products\Protect::get_protect_data();

self::update_historically_active_jetpack_modules();
Expand Down Expand Up @@ -556,10 +556,11 @@ public static function register_rest_endpoints() {
new REST_Products();
new REST_Purchases();
new REST_Zendesk_Chat();
new REST_Product_Data();
new REST_AI();
new REST_Recommendations_Evaluation();

Products::register_product_endpoints();

register_rest_route(
'my-jetpack/v1',
'site',
Expand Down
56 changes: 41 additions & 15 deletions projects/packages/my-jetpack/src/class-products.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ class Products {
*
* @var string
*/
const STATUS_SITE_CONNECTION_ERROR = 'site_connection_error';
const STATUS_USER_CONNECTION_ERROR = 'user_connection_error';
const STATUS_ACTIVE = 'active';
const STATUS_CAN_UPGRADE = 'can_upgrade';
const STATUS_EXPIRING_SOON = 'expiring';
const STATUS_EXPIRED = 'expired';
const STATUS_INACTIVE = 'inactive';
const STATUS_MODULE_DISABLED = 'module_disabled';
const STATUS_PLUGIN_ABSENT = 'plugin_absent';
const STATUS_PLUGIN_ABSENT_WITH_PLAN = 'plugin_absent_with_plan';
const STATUS_NEEDS_PLAN = 'needs_plan';
const STATUS_NEEDS_ACTIVATION = 'needs_activation';
const STATUS_NEEDS_FIRST_SITE_CONNECTION = 'needs_first_site_connection';
const STATUS_NEEDS_ATTENTION__WARNING = 'needs_attention_warning';
const STATUS_NEEDS_ATTENTION__ERROR = 'needs_attention_error';
public const STATUS_SITE_CONNECTION_ERROR = 'site_connection_error';
public const STATUS_USER_CONNECTION_ERROR = 'user_connection_error';
public const STATUS_ACTIVE = 'active';
public const STATUS_CAN_UPGRADE = 'can_upgrade';
public const STATUS_EXPIRING_SOON = 'expiring';
public const STATUS_EXPIRED = 'expired';
public const STATUS_INACTIVE = 'inactive';
public const STATUS_MODULE_DISABLED = 'module_disabled';
public const STATUS_PLUGIN_ABSENT = 'plugin_absent';
public const STATUS_PLUGIN_ABSENT_WITH_PLAN = 'plugin_absent_with_plan';
public const STATUS_NEEDS_PLAN = 'needs_plan';
public const STATUS_NEEDS_ACTIVATION = 'needs_activation';
public const STATUS_NEEDS_FIRST_SITE_CONNECTION = 'needs_first_site_connection';
public const STATUS_NEEDS_ATTENTION__WARNING = 'needs_attention_warning';
public const STATUS_NEEDS_ATTENTION__ERROR = 'needs_attention_error';

/**
* List of statuses that display the module as disabled
Expand Down Expand Up @@ -176,6 +176,32 @@ public static function get_products_classes() {
return $final_classes;
}

/**
* Inititializes all products with an initialize method.
*
* @return void
*/
public static function initialize_products() {
$classes = self::get_products_classes();

foreach ( $classes as $class ) {
$class::initialize();
}
}

/**
* Register endpoints related to product classes
*
* @return void
*/
public static function register_product_endpoints() {
$classes = self::get_products_classes();

foreach ( $classes as $class ) {
$class::register_endpoints();
}
}

/**
* List of product slugs that are displayed on the main My Jetpack page
*
Expand Down
102 changes: 0 additions & 102 deletions projects/packages/my-jetpack/src/class-rest-product-data.php

This file was deleted.

93 changes: 90 additions & 3 deletions projects/packages/my-jetpack/src/products/class-backup.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* Class responsible for handling the Backup product
*/
class Backup extends Hybrid_Product {
public const BACKUP_STATUS_TRANSIENT_KEY = 'my-jetpack-backup-status';

/**
* The product slug
Expand Down Expand Up @@ -78,7 +79,23 @@ class Backup extends Hybrid_Product {
*/
public static $feature_identifying_paid_plan = 'backups';

public const BACKUP_STATUS_TRANSIENT_KEY = 'my-jetpack-backup-status';
/**
* Backup initialization
*
* @return void
*/
public static function register_endpoints(): void {
// Get backup undo event
register_rest_route(
'my-jetpack/v1',
'/site/backup/undo-event',
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => __CLASS__ . '::get_site_backup_undo_event',
'permission_callback' => __CLASS__ . '::permissions_callback',
)
);
}

/**
* Get the product name
Expand Down Expand Up @@ -180,12 +197,82 @@ public static function get_pricing_for_ui() {
);
}

/**
* Checks if the user has the correct permissions
*/
public static function permissions_callback() {
return current_user_can( 'manage_options' );
}

/**
* This will fetch the last rewindable event from the Activity Log and
* the last rewind_id prior to that.
*
* @return array|WP_Error|null
*/
public static function get_site_backup_undo_event() {
$blog_id = \Jetpack_Options::get_option( 'id' );

$response = Client::wpcom_json_api_request_as_user(
'/sites/' . $blog_id . '/activity/rewindable?force=wpcom',
'v2',
array(),
null,
'wpcom'
);

if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
return null;
}

$body = json_decode( $response['body'], true );

if ( ! isset( $body['current'] ) ) {
return null;
}

// Preparing the response structure
$undo_event = array(
'last_rewindable_event' => null,
'undo_backup_id' => null,
);

// List of events that will not be considered to be undo.
// Basically we should not `undo` a full backup event, but we could
// use them to undo any other action like plugin updates.
$last_event_exceptions = array(
'rewind__backup_only_complete_full',
'rewind__backup_only_complete_initial',
'rewind__backup_only_complete',
'rewind__backup_complete_full',
'rewind__backup_complete_initial',
'rewind__backup_complete',
);

// Looping through the events to find the last rewindable event and the last backup_id.
// The idea is to find the last rewindable event and then the last rewind_id before that.
$found_last_event = false;
foreach ( $body['current']['orderedItems'] as $event ) {
if ( $event['is_rewindable'] ) {
if ( ! $found_last_event && ! in_array( $event['name'], $last_event_exceptions, true ) ) {
$undo_event['last_rewindable_event'] = $event;
$found_last_event = true;
} elseif ( $found_last_event ) {
$undo_event['undo_backup_id'] = $event['rewind_id'];
break;
}
}
}

return rest_ensure_response( $undo_event );
}

/**
* Hits the wpcom api to check rewind status.
*
* @todo Maybe add caching.
*
* @return Object|WP_Error
* @return object|WP_Error
*/
private static function get_state_from_wpcom() {
static $status = null;
Expand Down Expand Up @@ -217,7 +304,7 @@ private static function get_state_from_wpcom() {
/**
* Hits the wpcom api to retrieve the last 10 backup records.
*
* @return Object|WP_Error
* @return object|WP_Error
*/
public static function get_latest_backups() {
static $backups = null;
Expand Down
18 changes: 18 additions & 0 deletions projects/packages/my-jetpack/src/products/class-product.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,24 @@ public static function get_plugin_filename() {
return static::$plugin_filename;
}

/**
* This method will be called in the class initializer to perform any necessary initialization
*
* @return void
*/
public static function initialize() {
// This method should be implemented in the child class.
}

/**
* This method will be called in the class initializer to register the product's endpoints
*
* @return void
*/
public static function register_endpoints(): void {
// This method should be implemented in the child class.
}

/**
* Get the installed plugin filename, considering all possible filenames a plugin might have
*
Expand Down

0 comments on commit 5b9915d

Please sign in to comment.