API / Minn\Login

Minn\Login

/wp-login.php and the sign-in surface. 5 classes, 31 public methods and 25 internals. This page is the public surface; each class name opens the whole class.

LoginController final readonly class

public/minn/src/Minn/Login/LoginController.php · 501 lines · Open the class →

Signing in. The page people see is /minn-admin/login: the form, the lost-password and reset flows, and logout all live there and link there. /wp-login.php stays as the address tooling knows (one-time login links, uptime probes, scripted sign-ins) and answers in place with the same shapes; a bare GET of it sends a browser to the clean page. Sessions and cookies validate on the engine AND on WordPress either way.

constPATH = '/minn-admin/login'
new__construct(Minn\Content\Site $site, Minn\Front\Permalinks $permalinks, Minn\Auth\Authenticator $authenticator, Minn\Auth\SignIn $signIn, Minn\Content\Users $users, Minn\Auth\PasswordReset $reset)
methodform(Minn\Http\Request $request): Minn\Http\ResponseGET /minn-admin/loginGET /minn-admin/login/{segment:lost-password|reset|logout|register|confirm-email}GET /wp-login.php (public)

The sign-in, lost-password, reset, and logout pages.

methodsignIn(Minn\Http\Request $request): Minn\Http\ResponsePOST /minn-admin/loginPOST /minn-admin/login/{segment:lost-password|reset|logout|confirm-email}POST /wp-login.php (public)

Handles the posted form for each of those pages.

insidelandingFor(), asked(), checkEmail(), signInNotices(), lostPassword(), retrieve(), openResetLink(), resetSession(), savePassword(), register(), validateReset(), parts(), tokenLogin(), adminEmail(), safeRedirect(), logout(), action(), actionUrl(), siteName(), base(), tooManyAttempts(), render()

LoginForm final class

public/minn/src/Minn/Login/LoginForm.php · 263 lines · Open the class →

The sign-in page markup.

staticrender(string $siteName, string $action, string $redirectTo, string $error, string $message = '', string $lostPasswordUrl = '', array $parts = array ( )): string

The sign-in page's HTML. With plugins loaded, $parts carries what they put on the page (LoginHooks::page()): the title, head, body classes, the header's link and words, a message above the form, fields inside it, and the footer, each where the reference's page puts it; and its answers about the page's own furniture (LoginHooks::signInFurniture()): the word on Remember Me, the lost-password link, the focus.

@param array{title?: string, head?: string, bodyClass?: string, headerUrl?: string, headerText?: string, message?: string, errors?: string, messages?: string, form?: string, footer?: string, rememberHelp?: string, lostLink?: string, separator?: string, autofocus?: bool} $parts
staticembedded(array $args, string $top, string $middle, string $bottom): string

The sign-in form a theme embeds in a page, as distinct from the engine's own sign-in page above. Every label, id and class is a seam themes and plugins style against, so the shape is fixed.

@param array<string, mixed> $args the parsed wp_login_form arguments
staticlostPassword(string $siteName, string $action, string $error, string $message, array $parts = array ( ), string $redirect = ''): string

The lost-password form: one field, posts to itself, keeping where the reader goes once the mail is out ($redirect, LoginHooks::lostPasswordPage()).

@param array{title?: string, head?: string, bodyClass?: string, headerUrl?: string, headerText?: string, message?: string, form?: string, footer?: string} $parts what plugins put on the page (LoginHooks::page())
staticregister(string $siteName, string $action, string $error, string $login, string $email, string $redirect, array $parts = array ( )): string

The registration form: a username and an email, what plugins add, where a sign-up lands (registration_redirect's answer), and word that the confirmation comes by email.

@param array{title?: string, head?: string, bodyClass?: string, headerUrl?: string, headerText?: string, message?: string, form?: string, footer?: string} $parts
staticresetPassword(string $siteName, string $action, string $key, string $login, string $error, array $parts = array ( )): string

The new-password form; the key rides in a hidden field as on the reference.

@param array{title?: string, head?: string, bodyClass?: string, headerUrl?: string, headerText?: string, message?: string, form?: string, footer?: string} $parts
staticconfirmed(string $siteName, string $message, string $homeUrl, array $parts = array ( )): string

A personal data request confirmed from its mail: the page's word (the confirmation message, which comes as markup) and the way to the site.

@param array{title?: string, head?: string, bodyClass?: string, message?: string, errors?: string, messages?: string, footer?: string} $parts
staticadminEmail(string $siteName, string $action, string $redirect, string $remindUrl, array $screen, array $parts = array ( )): string

The administration email check an administrator's sign-in may stop at: the site's address, to confirm (posting the nonce field) or change, and a later reminder when one is offered. $screen is what _minn_admin_email_screen() handed over.

@param array<string, string> $screen
@param array{title?: string, head?: string, bodyClass?: string, message?: string, errors?: string, messages?: string, footer?: string} $parts
staticfailure(string $siteName, string $message): string

The plain page a refused link gets: the reason, nothing else to do.

staticnotice(string $siteName, string $title, string $message, string $loginUrl): string

A message with a link back to sign-in.

staticcheckEmail(string $siteName, string $loginUrl, array $parts = array ( )): string

The check-your-email page: no form, only its word (in the message area) and the way back to sign in.

@param array{title?: string, head?: string, bodyClass?: string, message?: string, errors?: string, messages?: string, footer?: string} $parts
insidenotices(), page()

LoginHooks final readonly class

public/minn/src/Minn/Login/LoginHooks.php · 140 lines · Open the class →

The sign-in as plugins see it, when they are loaded. The credentials go through the reference's authenticate chain, so a plugin may refuse a sign-in (a breached password, a second factor, a locked account) or accept one the password alone would not; wp_login_failed is the chain's own report. wp_login follows a good sign-in and wp_logout a sign-out. The refusal is shown as the page's notices (LoginNotices): the chain's own as one vague sentence, a plugin's in its own words.

new__construct(Minn\Content\Users $users)
methodauthenticate(string $login, string $password): Minn\Content\UserRecord|Minn\Objects\Errors|null

The credentials through wp_authenticate and the authenticate filters, as the reference's sign-in runs them: the user, or the refusal (a WP_Error, or null when the chain gave none).

methodsignedIn(Minn\Content\UserRecord $user): void

After a good sign-in. The chain read the user through the runtime, which cached their meta before the new session was written, so the cache is let go first: a plugin reading session_tokens on wp_login (CleanTalk keeps the first session's address) must see the new one.

methodenter(string $action): void

A sign-in page request arriving, as wp-login.php announces it: login_init, then login_form_{action}.

methodpage(string $action, string $title, string $siteName, string $homeUrl, ?Minn\Content\UserRecord $user = NULL, ?Minn\Login\LoginNotices $notices = NULL): array

What plugins put on the sign-in page, where the reference's page puts it: the title (login_title), the head (login_enqueue_scripts, then login_head, which prints the styles and scripts), the body classes (login_body_class), the header's link and words (login_headerurl, login_headertext), the message above the form (login_message), the page's notices (login_errors, login_messages), the fields inside the form (login_form, lostpassword_form or resetpass_form, as the page is), and the footer (login_footer).

@return array{title: string, head: string, bodyClass: string, headerUrl: string, headerText: string, message: string, errors?: string, messages?: string, form: string, footer: string}
methodlanding(string $redirect, string $requested, Minn\Content\UserRecord|Minn\Objects\Errors|null $user): string

Where a sign-in lands, as login_redirect says (the requested address beside it, and the user it found or why not).

methodleaving(string $redirect, string $requested, int $userId): string

Where a sign-out lands, as logout_redirect says.

methodsignedOut(int $userId): void

After a sign-out ended the session.

methodsignInFurniture(string $lostPasswordUrl): array

What the sign-in page asks plugins about its own furniture, as the reference's page asks: the word beside Remember Me (login_remember_me_help_text), the lost-password link (lost_password_html_link), what stands between the page's links (login_link_separator), and whether the name field takes the focus (enable_login_autofocus).

@return array{rememberHelp: string, lostLink: string, separator: string, autofocus: bool}
methodlostPasswordPage(string $requested, Minn\Objects\Errors $errors): string

The lost-password page's questions, as the reference's page asks them: what stands between its links, where the form sends a reader once the mail is out (lostpassword_redirect, kept in the form), and lost_password with the page's errors. Returns the address the form keeps.

methodpostPasswordExpiry(int $expires): int

When a post password's cookie runs out (post_password_expires; 0 is when the browser closes).

LoginNotices final readonly class

public/minn/src/Minn/Login/LoginNotices.php · 113 lines · Open the class →

What a sign-in page tells the reader, held as the reference's pages hold it: notices by code, each an error or (severity "message") a message, their words as HTML. Printed, the errors are one paragraph, or a list when there are several, and the messages a paragraph each; with plugins loaded the sign-in page hands them through wp_login_errors first, and every page prints them through login_errors and login_messages. The authenticate chain's own refusals read as the engine's one sentence, so a page never says which half of a sign-in was wrong.

staticnone(): self

No notices.

staticplain(string $code, string $text, string $severity = ''): self

The engine's own plain words as one notice; an "Error:" lead takes the reference's strong label.

staticrefused(mixed $refusal): self

A sign-in refused: the chain's refusal, or (none given, or not one) the engine's one sentence.

staticof(mixed $errors): self

The notices a WP_Error holds (a plugin may have handed back something else: then none).

methodwith(string $code, string $html, string $severity = ''): self

These notices and one more.

methodisEmpty(): bool

Whether there are none.

methodwpError(): Minn\Objects\Errors

As the WP_Error plugins are handed.

methodforSignIn(string $redirect): self

The sign-in page's notices after wp_login_errors, which is handed where a sign-in would land.

methodareas(): array

The error and message areas' HTML ('' for an area with none), through login_errors and login_messages.

@return array{errors: string, messages: string}
insidewords()

ServeLogin final class

public/minn/src/Minn/Login/ServeLogin.php · 3 lines · implements Throwable, Stringable · extends Exception · Open the class →

Thrown by the wp-login.php shape file when plugin code require's it mid-request (a hide-login plugin serving its own sign-in URL, the perfmatters pattern). Engine::respond() catches it and answers the current request with the sign-in surface.