Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion inc/checkout/class-checkout-pages.php
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ public function maybe_redirect_to_admin_panel(): void {
*/
public function add_verify_email_notice($payment, $membership, $customer): void {

if ($payment->get_total() === 0.0 && $customer->get_email_verification() === 'pending') {
if ($customer->get_email_verification() === 'pending') {
printf(
'<div class="wu-p-4 wu-bg-yellow-200 wu-mb-2 wu-text-yellow-700 wu-rounded">
%s
Expand Down
7 changes: 7 additions & 0 deletions inc/managers/class-customer-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,13 @@ public function maybe_verify_email_address(): void {
$membership->save();
} elseif ($membership->get_status() === Membership_Status::TRIALING) {
$membership->publish_pending_site_async();
} elseif ($membership->get_status() === Membership_Status::ACTIVE) {
/*
* Membership was activated (e.g. by the payment gateway) before
* the customer completed email verification. Now that the email is
* verified, publish the pending site that was held back.
*/
$membership->publish_pending_site_async();
}

$payments = $membership->get_payments();
Expand Down
12 changes: 12 additions & 0 deletions inc/managers/class-membership-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,18 @@ public function transition_membership_status($old_status, $new_status, $membersh
*/
$membership = wu_get_membership($membership_id);

/*
* If the customer has not yet verified their email, hold off on
* publishing the pending site. The site will be published later
* when the customer completes email verification (handled in
* Customer_Manager::handle_email_verification()).
*/
$customer = $membership->get_customer();

if ($customer && $customer->get_email_verification() === 'pending') {
return;
}

$membership->publish_pending_site_async();
}

Expand Down
100 changes: 100 additions & 0 deletions tests/WP_Ultimo/Managers/Membership_Manager_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,106 @@ public function test_log_file_name_constant(): void {
$this->assertEquals('memberships', Membership_Manager::LOG_FILE_NAME);
}

// ========================================================================
// email verification gate — GH#935
// ========================================================================

/**
* When enable_email_verification=always and the customer has not yet verified
* their email, transitioning from pending → active must NOT publish the pending
* site. The site is held until the customer completes email verification.
*/
public function test_transition_status_skips_publish_when_customer_email_pending(): void {

// Make publishing synchronous so we can detect it via a hook.
wu_save_setting('force_publish_sites_sync', true);

// Create a customer whose email is still pending verification.
$this->customer->set_email_verification('pending');
$this->customer->save();

$membership = $this->create_membership(['status' => Membership_Status::PENDING]);

$membership->create_pending_site(
[
'title' => 'Email Pending Site',
'path' => '/emailpending/',
]
);

// Track whether wu_before_pending_site_published fires.
$published = false;
add_action(
'wu_before_pending_site_published',
function () use (&$published) {
$published = true;
}
);

$manager = $this->get_manager_instance();

$manager->transition_membership_status(
Membership_Status::PENDING,
Membership_Status::ACTIVE,
$membership->get_id()
);

$this->assertFalse(
$published,
'Site must not be published while customer email is pending verification (GH#935).'
);

// Restore setting.
wu_save_setting('force_publish_sites_sync', false);
}

/**
* When the customer has already verified their email (email_verification=none),
* transitioning from pending → active must publish the pending site normally.
*/
public function test_transition_status_publishes_when_customer_email_not_pending(): void {

// Make publishing synchronous so we can detect it via a hook.
wu_save_setting('force_publish_sites_sync', true);

// Customer email is verified (default: none).
$this->customer->set_email_verification('none');
$this->customer->save();

$membership = $this->create_membership(['status' => Membership_Status::PENDING]);

$membership->create_pending_site(
[
'title' => 'Email Verified Site',
'path' => '/emailverified/',
]
);

$published = false;
add_action(
'wu_before_pending_site_published',
function () use (&$published) {
$published = true;
}
);

$manager = $this->get_manager_instance();

$manager->transition_membership_status(
Membership_Status::PENDING,
Membership_Status::ACTIVE,
$membership->get_id()
);

$this->assertTrue(
$published,
'Site must be published when customer email is not pending verification.'
);

// Restore setting.
wu_save_setting('force_publish_sites_sync', false);
}

// ========================================================================
// handle_pending_site_on_cancellation()
// ========================================================================
Expand Down
Loading