From 8a985f04d68b939ca4e3e5e839402d8d3bc2c6d9 Mon Sep 17 00:00:00 2001 From: James Griffin Date: Tue, 28 Jul 2026 22:50:10 -0300 Subject: [PATCH] Link a signed-in visitor to the configured continue page The registration page's already-logged-in branch returned a bare sentence with nowhere to go, leaving the visitor to find their own way to their account. The invited-student branch a few lines above already built exactly the link that was missing. Extract that into continueLink() and use it for both logged-in outcomes. There is deliberately still no wp_login_url() fallback: sending someone already signed in to the login screen is the same dead end with extra steps, so with no page configured there is no link. Both messages now carry the us-register-form wrapper and enqueue the plugin stylesheet, which the invite branch emitted markup for but never loaded. Closes #131 --- docs/features/account-registration.md | 2 +- src/Auth/RegistrationPage.php | 41 +++++++++++++++++------- tests/Unit/Auth/RegistrationPageTest.php | 31 ++++++++++++++++++ 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/docs/features/account-registration.md b/docs/features/account-registration.md index 4e20698..2baea72 100644 --- a/docs/features/account-registration.md +++ b/docs/features/account-registration.md @@ -132,7 +132,7 @@ recorded in `us_policy_acceptances` with `registration_type = account` and The block's **After registration** panel picks the page a student continues to once registration finishes, and whether they get there by hand or automatically. -- **Sign-in page** (`loginPageId` / `login_page_id`) — the target of the "Sign in to your account" link shown after email confirmation (`?us_confirmed=1|ready`, falling back to the WordPress login screen) and of the "Continue to your account" link an invited student sees on the spot (`?us_registered=invite`; no link at all with no page chosen, since an already-signed-in student has no use for the login screen). +- **Sign-in page** (`loginPageId` / `login_page_id`) — the target of the "Sign in to your account" link shown after email confirmation (`?us_confirmed=1|ready`, falling back to the WordPress login screen) and of the "Continue to your account" link every **logged-in** visitor gets (`RegistrationPage::continueLink()`): an invited student who just finished signing up (`?us_registered=invite`), and anyone who simply arrives at the registration page already signed in. Neither gets the WordPress-login-screen fallback — with no page chosen there is no link at all, since sending someone already signed in to the login screen is the same dead end with extra steps. - **Redirect automatically** (`autoRedirect`, block only) — sends the student to that page instead of showing the link, via `BlockRegistrar::maybeAutoRedirect()` on `template_redirect`. It fires only on those two finished states (`RegistrationPage::isRegistrationComplete()`), so the "check your email" step, a validation error, and an `expired` confirmation link are always shown rather than redirected past. With no page chosen nothing happens — there is deliberately no login-screen fallback for the redirect. See `editor-blocks.md`. ## Token Redirect diff --git a/src/Auth/RegistrationPage.php b/src/Auth/RegistrationPage.php index 831de7e..5e0db1a 100644 --- a/src/Auth/RegistrationPage.php +++ b/src/Auth/RegistrationPage.php @@ -65,24 +65,21 @@ class RegistrationPage { $registered = sanitize_key( Val::string( wp_unslash( $_GET['us_registered'] ?? '' ) ) ); if ( is_user_logged_in() ) { - if ( self::RESULT_INVITE === $registered ) { - // An invited student is done the moment they land here logged in, - // so this is where their "continue" link belongs. The sign-in-page - // fallback is deliberately not used: pointing someone who is - // already signed in at the login screen helps nobody. - $continue = $this->continueUrl( $this->successPageId( $atts ) ); - $link = null === $continue - ? '' - : '

' - . esc_html__( 'Continue to your account', 'unsupervised-schedular' ) - . '

'; + // Both logged-in outcomes are dead ends without somewhere to go next, + // so both offer the same "continue" link to the configured page. + wp_enqueue_style( 'us-scheduler' ); + $link = $this->continueLink( $atts ); + if ( self::RESULT_INVITE === $registered ) { + // An invited student is done the moment they land here logged in. return '

' . esc_html__( 'Your account has been created and you are now logged in.', 'unsupervised-schedular' ) . '

' . $link . '
'; } - return '

' . esc_html__( 'You already have an account and are logged in.', 'unsupervised-schedular' ) . '

'; + return '

' + . esc_html__( 'You already have an account and are logged in.', 'unsupervised-schedular' ) + . '

' . $link . '
'; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- token identifies the invite; the form submit is nonce-checked in maybeHandleSubmit. @@ -353,6 +350,26 @@ class RegistrationPage { return $this->continueUrl( $loginPageId ) ?? wp_login_url(); } + /** + * The "continue to your account" paragraph shown to a logged-in visitor, or + * an empty string when no destination page is configured. + * + * The sign-in-page fallback {@see loginUrl()} applies is deliberately not + * used here: pointing someone who is already signed in at the login screen is + * the same dead end with extra steps, so no link is better than that one. + * + * @param array $atts + */ + private function continueLink( array $atts ): string { + $continue = $this->continueUrl( $this->successPageId( $atts ) ); + + return null === $continue + ? '' + : '

' + . esc_html__( 'Continue to your account', 'unsupervised-schedular' ) + . '

'; + } + /** * The chosen post-registration page's URL, or null when none is configured * (or it has since been deleted). Unlike {@see loginUrl()} this has no diff --git a/tests/Unit/Auth/RegistrationPageTest.php b/tests/Unit/Auth/RegistrationPageTest.php index 91f02a3..ff0f88a 100644 --- a/tests/Unit/Auth/RegistrationPageTest.php +++ b/tests/Unit/Auth/RegistrationPageTest.php @@ -504,6 +504,37 @@ class RegistrationPageTest extends TestCase self::assertStringContainsString('href="http://home.test/welcome/"', $html); } + public function testAlreadyLoggedInVisitorIsLinkedToTheChosenPage(): void + { + // No us_registered flag: someone who simply happens to be signed in and + // lands on the registration page. They still need a way onward. + Functions\when('is_user_logged_in')->justReturn(true); + Functions\when('sanitize_key')->alias(static fn ($v) => strtolower((string) $v)); + Functions\expect('get_permalink')->once()->with(4)->andReturn('http://home.test/welcome/'); + + $html = $this->ctx['page']->render([ 'loginPageId' => 4 ]); + + self::assertStringContainsString('already have an account', $html); + self::assertStringContainsString('href="http://home.test/welcome/"', $html); + // Not the just-registered message — that branch needs its own flag. + self::assertStringNotContainsString('us-success', $html); + } + + public function testAlreadyLoggedInVisitorGetsNoLinkWithoutAChosenPage(): void + { + Functions\when('is_user_logged_in')->justReturn(true); + Functions\when('sanitize_key')->alias(static fn ($v) => strtolower((string) $v)); + Functions\when('get_permalink')->justReturn(false); + + // A deleted page resolves to false, which must not become a broken link. + $html = $this->ctx['page']->render([ 'loginPageId' => 4 ]); + + self::assertStringContainsString('already have an account', $html); + self::assertStringNotContainsString('ctx['page']->render([])); + } + public function testContinueUrlIsNullWithoutAResolvablePage(): void { Functions\when('get_permalink')->justReturn(false);