Account Restriction Hooks
The six hooks over blacklisting, bulk suspension, dormant accounts and bulk messages.
Overview
The operations that narrow what an account may do live here: blacklisting, suspending or cancelling every service, and deleting an account left unused.
All of them reach wide and are hard to undo. That is what makes the gates valuable: they are the only place a wrong click can still be stopped.
Reference
Stopping a blacklisting
Runs before a customer is put on the blacklist.
Hook::add('gate:user.blacklist_add', 10, function ($user_id, $reason, $restrictions) {
// Ask for a second approval on an enterprise account.
if (Acme::isEnterprise($user_id)) return 'An enterprise account needs manager approval.';
return null;
});Following a blacklist change
Runs after the blacklist state of a customer changes.
add, add-2 or remove. There are two separate adding values; a listener watching only one misses the other.Hook::add('action:user.blacklist_changed', 10,
function ($user_id, $status, $reason, $admin_id) {
// There are two separate adding values.
if ($status !== 'remove') Acme::flagRisk($user_id, $reason);
});Stopping a bulk service cancellation
Runs before every service of a customer is cancelled. It is one click, and hard to undo.
Hook::add('gate:user.services_bulk_cancel', 10, function ($user_id) {
// One click takes every service.
if (Acme::hasActiveContract($user_id)) return 'An account under contract cannot be cancelled in bulk.';
return null;
});Following a bulk suspension
Runs after every service of a customer is suspended.
Hook::add('action:user.services_bulk_suspended', 10, function ($user_id) {
Acme::notifyAccountFrozen($user_id);
});Stopping a dormant account being deleted
Runs before an account left unused for a long time is deleted. The hook fires per candidate: one round can call it hundreds of times.
Hook::add('gate:user.delete_dormant', 10, function ($userId, $u) {
// It runs per account: keep it light.
if (Acme::hasRetentionHold($userId)) return 'under a retention obligation';
return null;
});Changing the bulk message recipients
Runs once the recipient pool for a bulk email or text message is built.
Hook::add('filter:user.bulk_recipients', 10,
function (&$result, $dbType, $notifType, $filters) {
// The COUNT and the LIST must stay in step.
$result['contacts'] = Acme::dropOptedOut($result['contacts'] ?? []);
$result['count'] = count($result['contacts']);
});Pitfalls
The status field carries three values and two of them mean adding. A listener watching only one misses a customer blacklisted through the other path. Testing for removal and treating the rest as adding is safer.
The bulk recipient filter carries both the contacts and the count. Dropping a contact and leaving the count alone shows the administrator a wrong recipient total and skews the decision to send.
Related Articles
Merci pour votre retour !
Notre équipe d'assistance est disponible 24h/24 pour tout ce que vous ne trouvez pas ci-dessus.