Skip to content

fix: preserve multi-step checkout account fields - #1611

Merged
superdav42 merged 2 commits into
mainfrom
fix/checkout-step-session
Jul 8, 2026
Merged

fix: preserve multi-step checkout account fields#1611
superdav42 merged 2 commits into
mainfrom
fix/checkout-step-session

Conversation

@superdav42

@superdav42 superdav42 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Persist validated non-final checkout step values during the AJAX validation request.
  • Reuse the same persistence helper for the existing native multi-step POST path.
  • Add focused coverage for preserving email_address, username, password, and password_conf in the signup session.

Reproduction and verification

Created a local 2-step checkout form at http://wordpress.local:8080/aidevops-two-step-repro/:

  • Step 1: products, email, username, password
  • Step 2: site title, site URL, order summary, payment, submit

Before the fix:

  • Step 1 wu_validate_form AJAX returned success: true.
  • Step 2 wu_validate_form AJAX, without reposting step-1 account fields, returned required-field errors for email_address, username, and password.

After the fix:

  • The same two AJAX requests returned success: true on step 2.
  • Checkout created the customer using the email and username submitted on step 1.

Tests

  • php -l inc/checkout/class-checkout.php && php -l tests/WP_Ultimo/Checkout/Checkout_Test.php
  • vendor/bin/phpcs inc/checkout/class-checkout.php tests/WP_Ultimo/Checkout/Checkout_Test.php
  • vendor/bin/phpstan analyse inc/checkout/class-checkout.php tests/WP_Ultimo/Checkout/Checkout_Test.php --no-progress
  • vendor/bin/phpunit --filter test_persist_current_step_to_session_saves_account_fields
  • vendor/bin/phpunit --filter Checkout_Test

Notes:

  • PHPUnit passed with existing vendor/WordPress deprecation notices and 1 skipped test in Checkout_Test.
  • Local dev plugin symlink and CAPTCHA add-on were restored after the manual HTTP verification.

aidevops.sh v3.32.2 plugin for OpenCode v1.17.13

Summary by CodeRabbit

  • Bug Fixes
    • Checkout progress now saves the information you’ve already entered immediately after each validated step, helping prevent data loss when continuing.
    • Saved interim step data is handled consistently, with checkout control fields excluded to keep progress storage clean.
  • Tests
    • Added coverage to verify that only the expected user-entered fields are persisted, and improved checkout-related test setup/teardown to reduce cross-test interference.

@superdav42 superdav42 added the origin:interactive Created by interactive user session label Jul 8, 2026
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f251f2a5-c0d5-47aa-a59b-6d4361b25a90

📥 Commits

Reviewing files that changed from the base of the PR and between 9d2db79 and 60183bd.

📒 Files selected for processing (1)
  • tests/WP_Ultimo/Checkout/Checkout_Test.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/WP_Ultimo/Checkout/Checkout_Test.php

📝 Walkthrough

Walkthrough

This PR adds shared checkout-step session persistence, routes both AJAX and native submission paths through it, and expands checkout test coverage around the new helper and related test-state cleanup.

Changes

Checkout step session persistence

Layer / File(s) Summary
Session persistence helpers
inc/checkout/class-checkout.php
Adds get_current_step_session_values() to filter customer-entered POST fields and persist_current_step_to_session() to store them in the signup session with pre-flight mapped to pre_selected.
Submission flow wiring
inc/checkout/class-checkout.php
maybe_handle_order_submission() now persists validated step fields before the AJAX success response, and maybe_process_checkout() delegates its non-final-step session write to the new helper.
Checkout test updates
tests/WP_Ultimo/Checkout/Checkout_Test.php
Adds reflection-based coverage for session persistence and updates teardown plus a few unrelated assertions and comments in the checkout test file.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

Suggested labels: review-feedback-scanned, status:in-review

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: preserving multi-step checkout account fields.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/checkout-step-session

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/WP_Ultimo/Checkout/Checkout_Test.php (1)

523-579: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Good coverage for the core persistence path.

Test correctly validates that account fields are persisted while control/nonce fields are excluded, matching get_current_step_session_values()'s filtering contract in inc/checkout/class-checkout.php.

One gap: the pre-flight branch of persist_current_step_to_session() (which stores values under pre_selected instead) isn't covered by any test. Given this is a distinct code path in the exact method under test, consider adding a follow-up case.

💡 Suggested additional test case
public function test_persist_current_step_to_session_handles_pre_flight(): void {

	$checkout   = Checkout::get_instance();
	$reflection = new \ReflectionClass($checkout);

	$this->ensure_session($checkout);

	$session_prop = $this->get_session_prop($reflection);
	$session      = $session_prop->getValue($checkout);

	$session->set('signup', []);

	$_POST['pre-flight']      = '1';
	$_POST['email_address']   = 'pre-flight@example.com';

	$method = $reflection->getMethod('persist_current_step_to_session');
	if (PHP_VERSION_ID < 80100) {
		$method->setAccessible(true);
	}

	$saved  = $method->invoke($checkout);
	$signup = $session->get('signup');

	$this->assertArrayNotHasKey('pre-flight', $saved);
	$this->assertSame('pre-flight@example.com', $signup['pre_selected']['email_address']);

	$session->set('signup', []);
	unset($_POST['pre-flight'], $_POST['email_address']);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/WP_Ultimo/Checkout/Checkout_Test.php` around lines 523 - 579, Add a
follow-up test for the pre-flight branch in persist_current_step_to_session(),
since the current test only covers the normal account path. Create a new case
around Checkout::persist_current_step_to_session that sets the pre-flight
request input, invokes the method via reflection like the existing test, and
asserts the returned data omits control fields while the session stores values
under signup['pre_selected'] rather than the regular account keys. Reuse the
same setup helpers and cleanup pattern from
test_persist_current_step_to_session_saves_account_fields().
inc/checkout/class-checkout.php (1)

3639-3655: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Apply input sanitization per coding guidelines.

get_current_step_session_values() returns raw $_POST values without sanitization. Per coding guidelines, input should be sanitized using wu_clean() or WordPress sanitization functions. Password fields (e.g., password, password_conf) should be excluded from sanitization to avoid altering credentials.

🛡️ Proposed sanitization wrapper
 protected function get_current_step_session_values() {

-	return array_filter(
-		$_POST, // phpcs:ignore WordPress.Security.NonceVerification.Missing
-		fn($key) => ! str_starts_with((string) $key, 'checkout_') && ! str_starts_with((string) $key, '_'),
-		ARRAY_FILTER_USE_KEY
-	);
+	$values = array_filter(
+		$_POST, // phpcs:ignore WordPress.Security.NonceVerification.Missing
+		fn($key) => ! str_starts_with((string) $key, 'checkout_') && ! str_starts_with((string) $key, '_'),
+		ARRAY_FILTER_USE_KEY
+	);
+
+	foreach ($values as $key => $value) {
+		if ( ! str_contains((string) $key, 'password')) {
+			$values[ $key ] = wu_clean($value);
+		}
+	}
+
+	return $values;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@inc/checkout/class-checkout.php` around lines 3639 - 3655,
`get_current_step_session_values()` is returning raw `$_POST` data without
sanitization. Update the method to sanitize each retained value before returning
it, using `wu_clean()` or an appropriate WordPress sanitization function, while
preserving the existing exclusion logic for checkout control/private nonce keys.
Make sure password-related fields such as `password` and `password_conf` are
left unsanitized so credentials are not altered, and keep the behavior localized
to `get_current_step_session_values()`.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@inc/checkout/class-checkout.php`:
- Around line 3639-3655: `get_current_step_session_values()` is returning raw
`$_POST` data without sanitization. Update the method to sanitize each retained
value before returning it, using `wu_clean()` or an appropriate WordPress
sanitization function, while preserving the existing exclusion logic for
checkout control/private nonce keys. Make sure password-related fields such as
`password` and `password_conf` are left unsanitized so credentials are not
altered, and keep the behavior localized to `get_current_step_session_values()`.

In `@tests/WP_Ultimo/Checkout/Checkout_Test.php`:
- Around line 523-579: Add a follow-up test for the pre-flight branch in
persist_current_step_to_session(), since the current test only covers the normal
account path. Create a new case around Checkout::persist_current_step_to_session
that sets the pre-flight request input, invokes the method via reflection like
the existing test, and asserts the returned data omits control fields while the
session stores values under signup['pre_selected'] rather than the regular
account keys. Reuse the same setup helpers and cleanup pattern from
test_persist_current_step_to_session_saves_account_fields().

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fc986c58-76b9-4b9c-acfc-93e86b5e4342

📥 Commits

Reviewing files that changed from the base of the PR and between b61f22a and 9d2db79.

📒 Files selected for processing (2)
  • inc/checkout/class-checkout.php
  • tests/WP_Ultimo/Checkout/Checkout_Test.php

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@superdav42
superdav42 merged commit 4cfccfd into main Jul 8, 2026
11 checks passed
@superdav42 superdav42 added the review-feedback-scanned Merged PR already scanned for quality feedback label Jul 9, 2026
@superdav42

Copy link
Copy Markdown
Collaborator Author

REVIEW_FOLLOWUP_CREATED source_pr=1611 issue=1612 fingerprint=source-pr-1611 runner=superdav42 ts=2026-07-11T10:31:06Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

origin:interactive Created by interactive user session review-feedback-scanned Merged PR already scanned for quality feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant