Privacy Deletion Planner
Plans user data deletion/anonymization across related tables.
Function signature
ogPlanPrivacyDeletion(user_id, data_map = array(), policy = array())
Categories
- Security
Parameters
user_idUser ID whose privacy action plan is being built.data_mapConfigured data groups and action types for privacy deletion/anonymization planning.policyCaller-approved workflow policy for the ecommerce, admin, privacy, or export decision.Return value
Public-safe status string returned by the function for explicit controller branching or logging.
- success
- message
- data
Compatibility
Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.
Minimum PHP version: 7.4
Security notes
Use caller-owned allowlists and context-specific escaping; validate admin actions, export fields, privacy plans, cache keys, templates, settings, routes, and ecommerce policies before production use.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Plans user data deletion or anonymization across declared tables and fields.
*
* This function intentionally returns a plan only. It does not execute DELETE or
* UPDATE statements because privacy actions require review and approval.
*
* @param int $user_id User/account ID being processed.
* @param array $data_map Declared tables and actions.
* @param array $policy Planning policy.
* @return array Privacy action plan.
*/
function ogPlanPrivacyDeletion($user_id, $data_map = array(), $policy = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
$user_id = (int)$user_id;
if ($user_id <= 0) {
$result['message'] = 'Valid user ID is required.';
return $result;
}
if (!is_array($data_map)) {
$result['message'] = 'Data map must be an array.';
return $result;
}
if (!is_array($policy)) {
$policy = array();
}
$allowed_actions = array('delete', 'anonymize', 'retain', 'review');
$plan = array();
$warnings = array();
foreach ($data_map as $table => $table_policy) {
$table = trim((string)$table);
if (!preg_match('/^[a-zA-Z0-9_]+$/', $table)) {
$warnings[] = 'Skipped invalid table name: ' . $table;
continue;
}
if (!is_array($table_policy)) {
$warnings[] = 'Skipped table with invalid policy: ' . $table;
continue;
}
$action = 'review';
if (!empty($table_policy['action'])) {
$action = strtolower(trim((string)$table_policy['action']));
}
if (!in_array($action, $allowed_actions, true)) {
$action = 'review';
$warnings[] = 'Invalid action changed to review for table: ' . $table;
}
$user_field = 'user_id';
if (!empty($table_policy['user_field'])) {
$user_field = trim((string)$table_policy['user_field']);
}
if (!preg_match('/^[a-zA-Z0-9_]+$/', $user_field)) {
$warnings[] = 'Invalid user field for table: ' . $table;
continue;
}
$fields = array();
if (!empty($table_policy['fields']) && is_array($table_policy['fields'])) {
foreach ($table_policy['fields'] as $field) {
$field = trim((string)$field);
if (preg_match('/^[a-zA-Z0-9_]+$/', $field)) {
$fields[] = $field;
}
}
}
$plan[] = array(
'table' => $table,
'user_field' => $user_field,
'action' => $action,
'fields' => array_values(array_unique($fields)),
'where' => $user_field . ' = ' . $user_id,
'requires_manual_review' => ($action == 'review')
);
}
$result['success'] = true;
$result['message'] = 'Privacy deletion plan created.';
$result['data'] = array(
'user_id' => $user_id,
'plan' => $plan,
'warnings' => $warnings,
'executes_sql' => false
);
return $result;
}