diff --git a/includes/AdminBarSiteStatusBadge.php b/includes/AdminBarSiteStatusBadge.php
new file mode 100644
index 0000000..76cc98e
--- /dev/null
+++ b/includes/AdminBarSiteStatusBadge.php
@@ -0,0 +1,150 @@
+container = $container;
+
+ $this->defaults = array(
+ 'admin_bar_cs_active' => __( 'Coming soon', 'newfold-module-coming-soon' ),
+ 'admin_bar_cs_inactive' => __( 'Live', 'newfold-module-coming-soon' ),
+ );
+
+ add_action( 'admin_bar_menu', array( $this, 'site_status_badge' ), 31 );
+ add_action( 'wp_head', array( $this, 'site_status_badge_styles' ) );
+ add_action( 'admin_head', array( $this, 'site_status_badge_styles' ) );
+ add_action( 'update_option_nfd_coming_soon', array( __CLASS__, 'site_status_badge_timer' ), 10, 2 );
+ }
+
+ /**
+ * Add site status badge to WP admin bar.
+ *
+ * @param WP_Admin_Bar $admin_bar An instance of the WP_Admin_Bar class.
+ */
+ public function site_status_badge( WP_Admin_Bar $admin_bar ): void {
+ if ( current_user_can( 'manage_options' ) ) {
+
+ $is_coming_soon = isComingSoonActive();
+ $title = $is_coming_soon ? $this->defaults['admin_bar_cs_active'] : $this->defaults['admin_bar_cs_inactive'];
+ $class = $this->site_status_badge_class( $is_coming_soon );
+
+ $site_status_menu = array(
+ 'id' => 'nfd-site-visibility-badge',
+ 'parent' => 'root-default',
+ 'href' => admin_url( 'admin.php?page=' . $this->container->plugin()->id . '&nfd-target=coming-soon-section#/settings' ),
+ 'title' => $title,
+ 'meta' => array(
+ 'class' => 'nfd-site-status-badge-' . $class,
+ ),
+ );
+ $admin_bar->add_menu( $site_status_menu );
+ }
+ }
+
+ /**
+ * Determine the class for the site status badge.
+ *
+ * @param bool $is_coming_soon Whether the site is in Coming Soon mode.
+ */
+ private function site_status_badge_class( $is_coming_soon ): string {
+ $class = $is_coming_soon ? 'coming-soon' : 'live';
+
+ // Hide badge if the site has been live for more than 10 minutes.
+ if ( ! $is_coming_soon && ! get_transient( 'nfd_coming_soon_site_status_badge_timer' ) ) {
+ $class = 'hidden';
+ }
+
+ return $class;
+ }
+
+ /**
+ * Output CSS for site status badge.
+ */
+ public function site_status_badge_styles(): void {
+ if ( is_admin_bar_showing() ) {
+ ?>
+
+ container()->plugin()->id,
'admin_app_url' => \admin_url( 'admin.php?page=newfold' ),
'admin_notice_text' => __( 'Your site has Coming Soon mode active.', 'newfold-module-coming-soon' ),
- 'admin_bar_text' => '
' . __( 'Coming Soon Active', 'newfold-module-coming-soon' ) . '
',
- 'admin_bar_label' => __( 'Site Status: ', 'newfold-module-coming-soon' ),
- 'admin_bar_cs_active' => __( 'Not Live', 'newfold-module-coming-soon' ),
- 'admin_bar_cs_inactive' => __( 'Live', 'newfold-module-coming-soon' ),
'template_page_title' => __( 'Coming Soon!', 'newfold-module-coming-soon' ),
'template_styles' => false,
'template_content' => false,
@@ -49,6 +45,9 @@ public function __construct( Container $container ) {
// add plugin version to plugin styles file for cache busting
$this->args['template_styles'] = $this->args['template_styles'] . '?v=' . container()->plugin()->version;
}
+
+ new WooCommerceOptionsSync();
+
// set up all actions
\add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
\add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
@@ -58,15 +57,13 @@ public function __construct( Container $container ) {
\add_action( 'wp_ajax_newfold_coming_soon_subscribe', array( $this, 'coming_soon_subscribe' ) );
\add_action( 'wp_ajax_nopriv_newfold_coming_soon_subscribe', array( $this, 'coming_soon_subscribe' ) );
\add_action( 'plugins_loaded', array( $this, 'coming_soon_prevent_emails' ) );
- \add_action( 'admin_bar_menu', array( $this, 'newfold_site_status' ), 100 );
- \add_action( 'wp_body_open', array( $this, 'site_preview_warning' ) );
- \add_action( 'admin_head', array( $this, 'admin_bar_coming_soon_admin_styles' ) );
- \add_action( 'wp_head', array( $this, 'admin_bar_coming_soon_admin_styles' ) );
\add_filter( 'default_option_nfd_coming_soon', array( $this, 'filter_coming_soon_fallback' ) );
\add_action( 'update_option_nfd_coming_soon', array( $this, 'on_update_nfd_coming_soon' ), 10, 2 );
\add_action( 'update_option_mm_coming_soon', array( $this, 'on_update_mm_coming_soon' ), 10, 2 );
\add_filter( 'jetpack_is_under_construction_plugin', array( $this, 'filter_jetpack_is_under_construction' ) );
+ new AdminBarSiteStatusBadge( $container );
+ new SitePreviewWarning();
new PrePublishModal();
}
@@ -245,99 +242,6 @@ public function notice_display() {
}
}
- /**
- * Some basic styles to control visibility of the coming soon state in the admin bar
- */
- public function admin_bar_coming_soon_admin_styles() {
- if( is_user_logged_in() ) {
- ?>
-
- ';
- $content .= $this->args['admin_bar_label'];
- $content .= '';
- $content .= $this->args['admin_bar_cs_active'];
- $content .= '';
- $content .= '';
- $content .= $this->args['admin_bar_cs_inactive'];
- $content .= '';
- $content .= '';
-
- $site_status_menu = array(
- 'id' => 'site-status',
- 'parent' => 'top-secondary',
- 'href' => admin_url( 'admin.php?page=' . $this->container->plugin()->id . '&nfd-target=coming-soon-section#/settings' ),
- 'title' => $content,
- );
- $admin_bar->add_menu( $site_status_menu );
- }
- }
-
- /**
- * Load warning on site Preview
- */
- public function site_preview_warning() {
- if ( isComingSoonActive() ) {
- echo "" . esc_html__( 'Site Preview - This site is NOT LIVE, only admins can see this view.', 'newfold-module-coming-soon' ) . "
";
- }
- }
-
/**
* Load the coming soon page, if necessary.
*/
diff --git a/includes/SitePreviewWarning.php b/includes/SitePreviewWarning.php
new file mode 100644
index 0000000..fb21086
--- /dev/null
+++ b/includes/SitePreviewWarning.php
@@ -0,0 +1,29 @@
+" . esc_html__( 'Site Preview - This site is NOT LIVE, only admins can see this view.', 'newfold-module-coming-soon' ) . "";
+ }
+}
diff --git a/includes/WooCommerceOptionsSync.php b/includes/WooCommerceOptionsSync.php
new file mode 100644
index 0000000..322c349
--- /dev/null
+++ b/includes/WooCommerceOptionsSync.php
@@ -0,0 +1,152 @@
+disable();
+ } else {
+ $nfd_coming_soon_service->enable();
+ }
+ }
+
+ // Sync the coming soon options when the woocommerce_coming_soon option is updated.
+ if ( 'woocommerce_coming_soon' === $option_name ) {
+ if ( $value ) {
+ $nfd_coming_soon_service->enable();
+ } else {
+ $nfd_coming_soon_service->disable();
+ }
+ }
+ }
+
+ /**
+ * Sync the coming soon options when the woocommerce_coming_soon option is newly added.
+ */
+ public static function sync_when_woocommerce_option_is_added(): void {
+ $nfd_coming_soon_service = self::get_service();
+ $new_value = $nfd_coming_soon_service->is_enabled();
+
+ self::sync_woocommerce_coming_soon_option( $new_value );
+ }
+
+ /**
+ * Sync options when WooCommerce is initialized but the 'woocommerce_coming_soon' option is not set.
+ */
+ public static function sync_when_woocommerce_option_is_missing(): void {
+ if ( optionExists( 'woocommerce_coming_soon' ) ) {
+ return;
+ }
+
+ self::sync_when_woocommerce_option_is_added();
+ }
+}
diff --git a/includes/functions.php b/includes/functions.php
index 3fec9b3..f41e1ee 100644
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -4,9 +4,24 @@
/**
* Check if the coming soon module is active.
- *
- * @return bool
*/
-function isComingSoonActive() {
+function isComingSoonActive(): bool {
return ( new Service() )->is_enabled();
-}
\ No newline at end of file
+}
+
+/**
+ * Check if WooCommerce is activated
+ */
+function isWoocommerceActive(): bool {
+ return class_exists( 'woocommerce' );
+}
+
+/**
+ * Check if an option exists
+ *
+ * @param string $option_name The option name
+ */
+function optionExists( $option_name ): bool {
+ $value = get_option( $option_name, 'not_set' );
+ return 'not_set' !== $value;
+}
diff --git a/static/js/coming-soon.js b/static/js/coming-soon.js
index f192671..9f43d2d 100644
--- a/static/js/coming-soon.js
+++ b/static/js/coming-soon.js
@@ -107,16 +107,93 @@
return value;
};
+ /**
+ * Toggle the site status badge in the admin bar.
+ *
+ * @param {boolean} newState The new state of the site status.
+ */
const toggleAdminBarSiteStatus = ( newState ) => {
- const siteStatus = document.querySelector(
- '#wp-toolbar #nfd-site-status'
+ /**
+ * The badge elements for NFD and WooCommerce.
+ * Only one of them will be active at a time.
+ * When WooCommerce is active, the WooCommerce badge will be used.
+ * When WooCommerce is not active, the NFD badge will be used.
+ */
+ const badge = {
+ nfd: {
+ selector: '#wp-toolbar #wp-admin-bar-nfd-site-visibility-badge',
+ comingSoon: {
+ text: 'Coming soon',
+ class: 'nfd-site-status-badge-coming-soon',
+ },
+ live: {
+ text: 'Live',
+ class: 'nfd-site-status-badge-live',
+ },
+ hidden: {
+ class: 'nfd-site-status-badge-hidden',
+ },
+ },
+ woocommerce: {
+ selector:
+ '#wp-toolbar #wp-admin-bar-woocommerce-site-visibility-badge',
+ comingSoon: {
+ text: 'Coming soon',
+ class: 'woocommerce-site-status-badge-coming-soon',
+ },
+ live: {
+ text: 'Live',
+ class: 'woocommerce-site-status-badge-live',
+ },
+ hidden: {
+ class: 'woocommerce-site-status-badge-hidden',
+ },
+ },
+ };
+
+ const getActiveBadge = () => {
+ // Return the WooCommerce badge if WooCommerce is active.
+ if ( window.NewfoldRuntime.isWoocommerceActive ) {
+ return badge.woocommerce;
+ }
+ return badge.nfd;
+ };
+ const activeBadge = getActiveBadge();
+
+ const siteVisibilityBadge = document.querySelector(
+ activeBadge.selector
);
- if ( ! siteStatus ) {
+ if ( ! siteVisibilityBadge ) {
return;
}
- siteStatus.setAttribute( 'data-coming-soon', newState );
+ const toggle = ( newState ) => {
+ if ( newState ) {
+ // Coming soon
+ siteVisibilityBadge.classList.remove(
+ activeBadge.live.class,
+ activeBadge.hidden.class
+ );
+ siteVisibilityBadge.classList.add( activeBadge.comingSoon.class );
+ const textElement = siteVisibilityBadge.querySelector( 'a.ab-item' );
+ if ( textElement ) {
+ textElement.textContent = activeBadge.comingSoon.text;
+ }
+ } else {
+ // Live
+ siteVisibilityBadge.classList.remove(
+ activeBadge.comingSoon.class,
+ activeBadge.hidden.class
+ );
+ siteVisibilityBadge.classList.add( activeBadge.live.class );
+ const textElement = siteVisibilityBadge.querySelector( 'a.ab-item' );
+ if ( textElement ) {
+ textElement.textContent = activeBadge.live.text;
+ }
+ }
+ };
+ toggle( newState );
};
window.addEventListener( 'DOMContentLoaded', () => {
diff --git a/tests/cypress/integration/coming-soon-woo.cy.js b/tests/cypress/integration/coming-soon-woo.cy.js
new file mode 100644
index 0000000..84e2e45
--- /dev/null
+++ b/tests/cypress/integration/coming-soon-woo.cy.js
@@ -0,0 +1,67 @@
+//
+
+describe( 'Coming Soon with WooCommerce', function () {
+ before( () => {
+ // Set coming soon option to true to start with
+ cy.exec( `npx wp-env run cli wp option update mm_coming_soon true` );
+ cy.exec( `npx wp-env run cli wp option update nfd_coming_soon true` );
+
+ // Activate WooCommerce
+ cy.exec( `npx wp-env run cli wp plugin install woocommerce --activate`, {
+ timeout: 40000,
+ log: true,
+ } );
+ } );
+
+ after( () => {
+ // Deactivate WooCommerce
+ cy.exec( `npx wp-env run cli wp plugin deactivate woocommerce`, {
+ timeout: 40000,
+ } );
+ } );
+
+ it( 'Replace our admin bar site status badge with WooCommerce\'s when active', () => {
+ // Visit settings page
+ cy.visit(
+ '/wp-admin/admin.php?page=' +
+ Cypress.env( 'pluginId' ) +
+ '#/settings'
+ );
+
+ // Our badge shouldn't be visible
+ cy.get( '#wp-toolbar #wp-admin-bar-nfd-site-visibility-badge' )
+ .should( 'not.exist' );
+
+ // WooCommerce badge should be visible
+ cy.get( '#wp-toolbar #wp-admin-bar-woocommerce-site-visibility-badge a.ab-item' )
+ .contains( 'a', 'Coming soon' )
+ .should( 'be.visible' );
+ });
+
+ it ( 'Our plugin settings should toggle WooCommerce admin bar badge', () => {
+ // Deactivate coming soon - Launch Site
+ cy.get( '[data-id="coming-soon-toggle"]' ).click();
+ cy.wait( 1000 );
+
+ // WooCommerce badge should now be live
+ cy.get( '#wp-toolbar .woocommerce-site-status-badge-live a.ab-item' )
+ .contains( 'a', 'Live' )
+ .should( 'be.visible' );
+
+ // Re-enable coming soon mode
+ cy.get( '[data-id="coming-soon-toggle"]' )
+ .click();
+ cy.wait( 1000 );
+
+ // WooCommerce badge should now be coming soon
+ cy.get( '#wp-toolbar .woocommerce-site-status-badge-coming-soon a.ab-item' )
+ .contains( 'a', 'Coming soon' )
+ .should( 'be.visible' );
+ });
+
+ it( 'Hide our site preview notice when WooCommerce is active', () => {
+ cy.visit( '/' );
+ cy.get( '.nfd-site-preview-warning' )
+ .should( 'not.exist' );
+ });
+} );
diff --git a/tests/cypress/integration/coming-soon.cy.js b/tests/cypress/integration/coming-soon.cy.js
index cc3a7ae..150127b 100644
--- a/tests/cypress/integration/coming-soon.cy.js
+++ b/tests/cypress/integration/coming-soon.cy.js
@@ -6,7 +6,12 @@ describe( 'Coming Soon', function () {
before( () => {
// Set coming soon option to true to start with
cy.exec( `npx wp-env run cli wp option update mm_coming_soon true` );
- cy.exec( `npx wp-env run cli wp option update nfd_coming_soon true` );
+ cy.exec( `npx wp-env run cli wp option update nfd_coming_soon true` );
+
+ // Deactivate WooCommerce
+ cy.exec( `npx wp-env run cli wp plugin deactivate woocommerce`, {
+ timeout: 40000,
+ } );
} );
it( 'Coming Soon is active', () => {
@@ -18,7 +23,7 @@ describe( 'Coming Soon', function () {
cy.reload();
// Initial Coming Soon State
- cy.get( '#wp-toolbar #wp-admin-bar-site-status #nfd-site-status-coming-soon' )
+ cy.get( '#wp-toolbar #wp-admin-bar-nfd-site-visibility-badge' )
.scrollIntoView()
.should( 'be.visible' );
@@ -39,15 +44,9 @@ describe( 'Coming Soon', function () {
it( 'Displays Coming Soon in Site Status Admin Toolbar', () => {
// Admin bar contains label
- cy.get( '#wp-toolbar #wp-admin-bar-site-status' )
- .contains( 'div', 'Site Status' )
- .should( 'be.visible' );
- // Admin bar contains status
- cy.get( '#wp-toolbar #wp-admin-bar-site-status #nfd-site-status-coming-soon' )
- .scrollIntoView()
+ cy.get( '#wp-toolbar #wp-admin-bar-nfd-site-visibility-badge a.ab-item' )
+ .contains( 'a', 'Coming soon' )
.should( 'be.visible' );
- cy.get( '#wp-toolbar #wp-admin-bar-site-status #nfd-site-status-live' )
- .should( 'not.be.visible' );
} );
it( 'Has Coming Soon Section on Home', () => {
@@ -73,7 +72,7 @@ describe( 'Coming Soon', function () {
} );
it( 'Coming Soon Admin bar links to setting', () => {
- cy.get( '#wp-toolbar #wp-admin-bar-site-status #nfd-site-status-coming-soon' ).click();
+ cy.get( '#wp-toolbar #wp-admin-bar-nfd-site-visibility-badge a.ab-item' ).click();
cy.location().should( ( loc ) => {
expect( loc.hash ).to.eq( '#/settings' )
});
@@ -87,7 +86,7 @@ describe( 'Coming Soon', function () {
);
// Deactivate coming soon - Launch Site
cy.get( '[data-id="coming-soon-toggle"]' ).click();
- cy.wait( 500 );
+ cy.wait( 2000 );
// Toggle is false
cy.get( '[data-id="coming-soon-toggle"]' )
@@ -95,8 +94,9 @@ describe( 'Coming Soon', function () {
.and( 'include', 'false' );
// Admin bar is updated
- cy.get( '#wp-toolbar #wp-admin-bar-site-status #nfd-site-status-live' )
+ cy.get( '#wp-toolbar .nfd-site-status-badge-live a.ab-item' )
.scrollIntoView()
+ .contains( 'a', 'Live' )
.should( 'be.visible' );
// Snackbar notice displays properly
@@ -114,7 +114,7 @@ describe( 'Coming Soon', function () {
// Activate Coming Soon - Unlaunch Site
cy.get( '[data-id="coming-soon-toggle"]' ).click();
- cy.wait( 500 );
+ cy.wait( 2000 );
// Toggle is true
cy.get( '[data-id="coming-soon-toggle"]' )
@@ -122,8 +122,9 @@ describe( 'Coming Soon', function () {
.and( 'include', 'true' );
// Admin bar is updated
- cy.get( '#wp-toolbar #wp-admin-bar-site-status #nfd-site-status-coming-soon' )
+ cy.get( '#wp-toolbar .nfd-site-status-badge-coming-soon a.ab-item' )
.scrollIntoView()
+ .contains( 'a', 'Coming soon' )
.should( 'be.visible' );
// Snackbar notice displays properly
@@ -139,6 +140,13 @@ describe( 'Coming Soon', function () {
.should( 'be.visible' );
} );
+ it( 'Displays Coming Soon Site Preview Warning', () => {
+ cy.visit( '/' );
+ cy.get( '.nfd-site-preview-warning' )
+ .contains( 'div', 'Site Preview' )
+ .should( 'be.visible' );
+ } );
+
it( 'Displays Coming Soon on Frontend', () => {
cy.logout();
cy.visit( '/' );