Personal Data Hooks
The nine hooks over consent, exports, data requests and identity documents.
Overview
The four moments of personal data: a customer gives consent, exports their data, asks for it to go, and submits identity documents.
Two hooks deliberately withhold content: the document on export, the identity paper on submission. Listeners get only a summary, because spreading that data to a second place works against the point.
Reference
Following a consent change
Runs when a customer gives or withdraws consent for data processing. It fires only on a real change: saving the same value again does not raise it.
Hook::add('action:user.gdpr_consent_changed', 10, function ($uid, $status, $given_at) {
// Take the proof stamp from here rather than reading it back.
Acme::recordConsent($uid, (bool) $status, $given_at);
});Following a data export
Runs when a customer exports their own data.
Hook::add('action:user.gdpr_exported', 10, function ($uid, $meta) {
// The document content is deliberately withheld.
Acme::auditExport($uid, (int) ($meta['size'] ?? 0));
});Following a data request being opened
Runs when a customer opens a deletion or anonymisation request.
remove for deletion, anonymize for anonymisation.Hook::add('action:user.gdpr_request_created', 10, function ($uid, $type) {
Acme::openComplianceCase($uid, $type);
});Following a data request being cancelled
Runs when a customer withdraws a request they opened.
Hook::add('action:user.gdpr_request_cancelled', 10, function ($uid, $request_id) {
Acme::closeComplianceCase($request_id);
});Following a data request being carried out
Runs after a data request is carried out. Deletion and anonymisation cannot be undone: by this point the data is already gone.
Hook::add('action:user.gdpr_processed', 10, function ($request_id, $user_id, $action) {
// The data is gone: clear your own copy as well.
if ($action !== 'cancelled') Acme::purgeMirror($user_id);
});Following documents being submitted
Runs when a customer submits identity documents.
Hook::add('action:user.documents_submitted', 10, function ($uid, $doc_meta) {
// No document content, only the reference.
Acme::queueReview($uid);
});Widening the document field types
Runs while the list of types offered when defining a document field is built. Add a field type of your own here.
Hook::add('filter:user.document_field_types', 10, function (&$types) {
$types['acme-iban'] = 'Acme IBAN check';
});Changing a document field definition
Runs before a document field is saved, from the panel and from the admin API alike. Fill in the settings of a type you added here, or return a reason to refuse the save. On the admin API your listener reads the request body the same way it reads the panel form, and a reason you return reaches the caller as a 422 field_rejected error.
null to let it through; changes go over the data. Return the reason, do not throw it: a thrown exception only reaches the error log and the field is saved without your settings. Supported from 5.0-beta.4 (5.0-beta.3 with its latest fix package); older versions ignore the return.Hook::add('filter:user.document_field_input', 10, function (&$values, &$type) {
// Check whether it is your type first.
if ($type !== 'acme-iban') return null;
// A returned reason refuses the save; the administrator sees it.
if (trim((string) Filter::init('POST/acme_bank', 'hclear')) === '') return 'Choose the bank this check runs against.';
$values['max_size'] = 512;
return null;
});Changing the document records view
Runs when an administrator looks at a customer’s documents, before the records reach the screen.
Hook::add('filter:user.document_records_view', 10, function (&$records, &$user_id) {
// Hide the identity number from eyes without clearance.
if (Acme::canSeeFullId()) return;
foreach ($records as $i => $r) $records[$i]['field_value'] = Acme::mask($r['field_value'] ?? '');
});Pitfalls
The export hook does not carry the document, and the submission hook does not carry the identity paper; both give a summary only. That is design, not omission: handing the data to listeners works against the protection. If you need the content, read it through your own permitted path.
By the time the removal or anonymisation hook runs the data is already gone. You must clear your own copy as well, or the customer's data lives on with you.
Related Articles
¡Gracias por sus comentarios!
Nuestro equipo de soporte está disponible las 24 horas para ayudarle con lo que no encuentre aquí.