Customer Account Hooks

3 vues Markdown

The 103 hooks about the customer account itself: signing up, signing in, verifying, blocking, sub-accounts and affiliates.

Overview

This domain carries the account itself: its opening, its sign-in, its verification, its blocking, its deletion. The screens a customer sees are a domain of their own.

Some of these hooks fire in the management panel, because an operator can change an account too. So when writing a listener, the answer to "who did this" is not always the customer.

Reference

The account's life

action:user.created An account was opened. The return is ignored.
action:user.updated Account details changed. The return is ignored.
action:user.status_changed The account status changed. The return is ignored.
action:user.account_blocked The account was blocked, or unblocked. The return is ignored.
action:user.deleted The account was deleted. The return is ignored.
action:user.deleted_dormant A long-dormant account was deleted on its own. The return is ignored.

Sign-in and security

action:user.logged_in A sign-in happened. The return is ignored.
action:user.login_failed A sign-in attempt failed. The return is ignored.
action:user.logged_in_as A staff member entered a customer account. The return is ignored.
action:user.password_changed The password changed. The return is ignored.
action:user.two_factor_changed Two-step verification was switched on or off. The return is ignored; by here the change is already saved.
action:user.session_revoked A session was ended. The return is ignored.
action:user.account_switched The customer switched to another account. The return is ignored; the session is already written.

Gates

Eighteen gates stand in front of every weighty account action. They share one contract: a non-empty string stops the action. An empty return — null or '' — lets it through.

gate:user.create Opening an account. A filled return stops it, and that text becomes the error.
gate:user.login Signing in — after the password checked out. A filled return stops it; a string and ['message' => '…'] are both taken.
gate:user.login_as A staff member entering a customer account. A filled return stops it.
gate:user.delete Deleting an account. A filled return stops it, and the delete answers false.
gate:user.block Blocking an account. A filled return stops it.
gate:user.add_funds Adding funds — before the invoice is issued. A filled return stops it, and the text reaches the customer.
gate:user.email_change Changing the e-mail address. A filled return stops it.
gate:user.two_factor_disable Switching two-step verification off. A filled return stops it; a string and ['message' => '…'] are both taken.
gate:user.affiliate_enroll Joining the affiliate programme. A filled return stops it, and no record is opened.
gate:user.affiliate_withdrawal An affiliate payout request. A filled return stops it.
gate:user.gdpr_process Processing a data request. A filled return stops it.
gate:user.subuser_invite Inviting a sub-account. A filled return stops it, and the text reaches the customer.

Filters

These eight do not share one contract. Three shapes stand side by side, so read the return of the one you are writing for.

filter:user.required_fields The required fields on signing up and on the profile. Return an array; every listener's return is merged in.
filter:user.login_resolve Which account the entered identity resolves to. The value changes by reference; the return is not used.
filter:user.password_verify The password check. Returning true counts the password as good; every other return is ignored.
filter:user.login_redirect Where a sign-in lands. The value changes by reference; the return is not used.
filter:user.add_funds_amount The amount being added. The value changes by reference; the return is not used.
filter:custom_field.save_value The value a custom field saves. The value changes by reference; the return is not used.
filter:custom_field.load_value The value a custom field loads. The value changes by reference; the return is not used.
filter:user.verification_fields The fields on a verification document. The fields change by reference; the return is ignored.

Example

coremio/hooks/acme-account.php
// A GATE: no account from a blocked country.
Hook::add('gate:user.create', 10, function ($data) {
    $cc = strtoupper((string) ($data['country'] ?? ''));
    if (Acme::blockedCountry($cc)) return 'We take no sign-ups from there.';
    return null;
});

// AN EVENT: put the new account on the marketing list.
Hook::add('action:user.created', 10, function ($user_id, $data) {
    Crm::subscribe((int) $user_id, (string) ($data['email'] ?? ''));
});

Pitfalls

Both the customer and an operator change an account

Most hooks here fire from two places: the customer's own screen and the management panel. Writing a gate to say "the customer cannot do this" stops the operator as well. Where you need to tell them apart, read the actor the hook hands you.

The sign-in gate does not check the password

The sign-in gate runs after the credentials check. The work there is not checking a password but stopping for another reason. To touch the password check itself, a filter of its own exists.

Sub-accounts and switching blur the identity

A customer can enter another account as a sub-user. The person signed in and the account being worked on are then different. Use the account id the hook hands you; an id read from the session points at the wrong person after a switch.

The delete hook is a point of no return

Deleting an account takes its records with it. By the time the delete event fires the work is done; gather what you need at the gate instead. The gate is earlier, and it can stop the action where that is wanted.

Cet article vous a-t-il été utile ?

Merci pour votre retour !

Besoin d'aide supplémentaire ?

Notre équipe d'assistance est disponible 24h/24 pour tout ce que vous ne trouvez pas ci-dessus.