Skip to content

Commit

Permalink
Refactor LYS to use unidirectional state flow (#1506)
Browse files Browse the repository at this point in the history
* Refactor LYS to use unidirectional data flow to prevent out-of-sync issues and simplify data handling, added admin notice when site is unlaunched to move users to lys task

* Changelog

* Fix logic for coming soon feature disabled

* Small code move
  • Loading branch information
ilyasfoo authored Sep 2, 2024
1 parent 1c78762 commit 6f4d9e8
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 72 deletions.
169 changes: 97 additions & 72 deletions includes/class-wc-calypso-bridge-coming-soon.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,22 @@ final public static function get_instance() {
public function __construct() {
add_filter( 'a8c_show_coming_soon_page', array( $this, 'should_show_a8c_coming_soon_page' ), PHP_INT_MAX, 1 );
add_filter( 'woocommerce_coming_soon_exclude', array( $this, 'should_exclude_lys_coming_soon' ) );
add_action( 'update_option_wpcom_public_coming_soon', array( $this, 'sync_coming_soon_wpcom_to_lys' ), 10, 3 );
$this->hook_update_option_woocommerce_coming_soon();
}
add_filter( 'pre_option_woocommerce_coming_soon', array( $this, 'override_option_woocommerce_coming_soon' ) );
add_filter( 'pre_update_option_woocommerce_coming_soon', array( $this, 'override_update_woocommerce_coming_soon' ), 10, 2 );

/**
* Hook on woocommerce_coming_soon option update for ease of use.
*/
public function hook_update_option_woocommerce_coming_soon() {
add_action( 'update_option_woocommerce_coming_soon' , array( $this, 'sync_coming_soon_lys_to_wpcom' ), 10, 3 );
}

/**
* Unhook on woocommerce_coming_soon option update for ease of use.
*/
public function unhook_update_option_woocommerce_coming_soon() {
remove_action( 'update_option_woocommerce_coming_soon' , array( $this, 'sync_coming_soon_lys_to_wpcom' ), 10, 3 );
if ( is_admin() ) {
add_filter( 'plugins_loaded', array( $this, 'maybe_add_admin_notice_pre_launch' ) );
}
}

/**
* Hide the a8c coming soon page if the Launch Your Store feature is enabled.
*
* @param bool $should_show
* @param bool $should_show Whether to show the coming soon page.
* @return bool
*/
public function should_show_a8c_coming_soon_page( $should_show ) {
if (
class_exists( '\Automattic\WooCommerce\Admin\Features\Features' ) && \Automattic\WooCommerce\Admin\Features\Features::is_enabled( 'launch-your-store' )
) {
if ( $this->is_feature_enabled() ) {
return false;
}

Expand All @@ -74,7 +62,7 @@ class_exists( '\Automattic\WooCommerce\Admin\Features\Features' ) && \Automattic
/**
* Exclude the coming soon page if the user is accessing the site via a valid share link.
*
* @param bool $exclude
* @param bool $exclude Whether to exclude the coming soon page.
* @return bool
*/
public function should_exclude_lys_coming_soon( $exclude ) {
Expand All @@ -91,50 +79,35 @@ public function should_exclude_lys_coming_soon( $exclude ) {
}

/**
* Sync the coming soon option from wpcom_public_coming_soon to woocommerce_coming_soon.
* Override the coming soon option value.
*
* @param int $old_value
* @param int $new_value
* @return void
* @param string $current_value The current option value.
* @return string
*/
public function sync_coming_soon_wpcom_to_lys( $old_value, $new_value ) {
if ( ! class_exists( '\Automattic\WooCommerce\Admin\Features\Features' ) || ! \Automattic\WooCommerce\Admin\Features\Features::is_enabled( 'launch-your-store' ) ) {
return;
public function override_option_woocommerce_coming_soon( $current_value ) {
if ( ! $this->is_feature_enabled() || ! $this->is_private_site_available() ) {
return $current_value;
}

$woocommerce_coming_soon = get_option( 'woocommerce_coming_soon', false );
$is_coming_soon_wpcom = 1 === (int) $new_value;

// Value is already set, we don't need to update option.
if ( ( 'yes' === $woocommerce_coming_soon && $is_coming_soon_wpcom ) ||
( 'no' === $woocommerce_coming_soon && ! $is_coming_soon_wpcom ) ) {
return;
}

// Unhook listener to prevent a loop of updating option between WPCOM <-> LYS.
$this->unhook_update_option_woocommerce_coming_soon();

if ( $is_coming_soon_wpcom ) {
update_option( 'woocommerce_coming_soon', 'yes' );
} else {
update_option( 'woocommerce_coming_soon', 'no' );
}

$this->hook_update_option_woocommerce_coming_soon();
// Either private or coming soon is considered as coming soon.
return \Private_Site\site_is_private() || \Private_Site\site_is_public_coming_soon() ? 'yes' : 'no';
}

/**
* Sync the coming soon option from to woocommerce_coming_soon wpcom.
* Does not include a check of existing wpcom option values since
* there could be multiple options that are affected.
* Sends API request to WPCOM to update coming soon state or launch the site
* when the option is updated. Still sets the underlying option value
* to accommodate exporting sites via manual means.
*
* @param int $old_value
* @param int $new_value
* @return void
* @param string $new_value The new option value.
* @param string $old_value The old option value.
* @return string
*/
public function sync_coming_soon_lys_to_wpcom( $old_value, $new_value ) {
$is_atomic_launched = 'launched' === get_option( 'launch-status' );
$response = false;
public function override_update_woocommerce_coming_soon( $new_value, $old_value ) {
if ( ! $this->is_feature_enabled() || ! $this->is_private_site_available() ) {
return $new_value;
}

$is_atomic_launched = 'unlaunched' !== \Private_Site\site_launch_status();
$response = false;

if ( 'no' === $new_value ) {
if ( ! $is_atomic_launched ) {
Expand All @@ -151,32 +124,84 @@ public function sync_coming_soon_lys_to_wpcom( $old_value, $new_value ) {
$error = json_decode( $body, true );

if ( isset( $error['message'] ) ) {
$this->add_admin_notice( $error[ 'message' ], 'error' );
$this->add_admin_notice( $error['message'], 'error' );
} else {
$this->add_admin_notice( __( 'There was a problem trying to update site visibility.', 'wc-calypso-bridge' ), 'error' );
}

// Don't update option value if there's an error.
return $old_value;
}

return $new_value;
}

public function add_admin_notice( $message, $notice_type = 'info' ) {
add_action( 'admin_notices', function () use ( $message, $notice_type ) {
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
/**
* Conditionally add a notice when site is unlaunched.
*
* @return void
*/
public function maybe_add_admin_notice_pre_launch() {
if ( ! $this->is_feature_enabled() || ! $this->is_private_site_available() ) {
return;
}

if ( 'woocommerce_page_wc-settings' !== $screen_id ) {
return;
}
$launch_status = \Private_Site\site_launch_status();
if ( 'unlaunched' === $launch_status ) {
$task_url = '/wp-admin/admin.php?page=wc-admin&path=%2Flaunch-your-store';
$this->add_admin_notice( sprintf( __( 'Looking to launch your site? Please visit <a href="%s">this link</a> to get started.', 'wc-calypso-bridge' ), esc_url( $task_url ) ), 'info' );
}
}

if ( ! isset( $_GET['tab'] ) || 'site-visibility' !== $_GET['tab'] ) {
return;
/**
* Add admin notice to the Site Visibility settings page.
*
* @param string $message The message to display.
* @param string $notice_type The notice type.
* @return void
*/
public function add_admin_notice( $message, $notice_type = 'info' ) {
add_action(
'admin_notices',
function () use ( $message, $notice_type ) {
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';

if ( 'woocommerce_page_wc-settings' !== $screen_id ) {
return;
}

if ( ! isset( $_GET['tab'] ) || 'site-visibility' !== $_GET['tab'] ) {
return;
}

?>
<div class="notice notice-<?php echo esc_attr( $notice_type ); ?>">
<p><?php echo wp_kses_post( $message ); ?></p>
</div>
<?php
}
);
}

/**
* Check if the Launch Your Store feature is enabled.
*
* @return bool
*/
private function is_feature_enabled() {
return class_exists( '\Automattic\WooCommerce\Admin\Features\Features' ) && \Automattic\WooCommerce\Admin\Features\Features::is_enabled( 'launch-your-store' );
}

?>
<div class="notice notice-<?php echo $notice_type ?>">
<p><?php echo $message; ?></p>
</div>
<?php
} );
/**
* Check if Private_Site class and functions are available.
*
* @return bool
*/
private function is_private_site_available() {
return function_exists( '\Private_Site\site_is_private' ) &&
function_exists( '\Private_Site\site_is_public_coming_soon' ) &&
function_exists( '\Private_Site\site_launch_status' );
}
}

Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This section describes how to install the plugin and get it working.
* Exclude LYS coming soon page for WPCOM share link #1501
* Sync WPCOM coming soon status to LYS #1502
* Add sync coming soon status from LYS to WPCOM #1503
* Refactor LYS to use unidirectional data flow #1506

= 2.5.5 =
* Add a new class to customize for Stripe from Partner Aware Onboarding #1492
Expand Down

0 comments on commit 6f4d9e8

Please sign in to comment.