106 lines
3.8 KiB
PHP
106 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Actions\Jetstream\DeleteUser;
|
|
use App\Models\Admin;
|
|
use App\Models\Bank;
|
|
use App\Models\Organization;
|
|
use App\Models\User;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class PermanentlyDeleteExpiredProfiles extends Command
|
|
{
|
|
protected $signature = 'profiles:permanently-delete-expired';
|
|
|
|
protected $description = 'Permanently delete (anonymize) profiles that have exceeded the grace period after deletion';
|
|
|
|
protected $logFile;
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
$this->logFile = storage_path('logs/permanent-deletions.log');
|
|
}
|
|
|
|
public function handle()
|
|
{
|
|
$this->info('Processing profiles pending permanent deletion...');
|
|
$this->logMessage('=== Starting permanent deletion processing ===');
|
|
|
|
// Get grace period from config (in days)
|
|
$gracePeriodDays = timebank_config('delete_profile.grace_period_days', 30);
|
|
$gracePeriodSeconds = $gracePeriodDays * 86400;
|
|
|
|
$totalPermanentDeletions = 0;
|
|
|
|
// Process each profile type
|
|
$profileTypes = [
|
|
'User' => User::class,
|
|
'Organization' => Organization::class,
|
|
'Bank' => Bank::class,
|
|
'Admin' => Admin::class,
|
|
];
|
|
|
|
foreach ($profileTypes as $typeName => $modelClass) {
|
|
// Find profiles that:
|
|
// 1. Have deleted_at set (marked for deletion)
|
|
// 2. Grace period has expired
|
|
// 3. Have not been anonymized yet (check by email not being removed-*@remove.ed)
|
|
$profiles = $modelClass::whereNotNull('deleted_at')
|
|
->where('deleted_at', '<=', now()->subSeconds($gracePeriodSeconds))
|
|
->where('email', 'not like', 'removed-%@remove.ed')
|
|
->get();
|
|
|
|
foreach ($profiles as $profile) {
|
|
$result = $this->permanentlyDeleteProfile($profile, $typeName);
|
|
if ($result === 'deleted') {
|
|
$totalPermanentDeletions++;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->info("Processing complete: {$totalPermanentDeletions} profiles permanently deleted");
|
|
$this->logMessage("=== Completed: {$totalPermanentDeletions} permanent deletions ===\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
protected function permanentlyDeleteProfile($profile, $profileType)
|
|
{
|
|
$profileName = $profile->name;
|
|
$profileId = $profile->id;
|
|
$deletedAt = $profile->deleted_at;
|
|
|
|
try {
|
|
// Use the DeleteUser action's permanentlyDelete method
|
|
$deleteUser = new DeleteUser();
|
|
$result = $deleteUser->permanentlyDelete($profile);
|
|
|
|
if ($result['status'] === 'success') {
|
|
$this->logMessage("[{$profileType}] PERMANENTLY DELETED {$profileName} (ID: {$profileId}) - Originally deleted at {$deletedAt}");
|
|
$this->info("[{$profileType}] Permanently deleted: {$profileName}");
|
|
return 'deleted';
|
|
} else {
|
|
$this->logMessage("[{$profileType}] ERROR permanently deleting {$profileName} (ID: {$profileId}): {$result['message']}");
|
|
$this->error("[{$profileType}] Error: {$profileName} - {$result['message']}");
|
|
return null;
|
|
}
|
|
} catch (\Exception $e) {
|
|
$this->logMessage("[{$profileType}] ERROR permanently deleting {$profileName} (ID: {$profileId}): {$e->getMessage()}");
|
|
$this->error("[{$profileType}] Error: {$profileName} - {$e->getMessage()}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected function logMessage($message)
|
|
{
|
|
$timestamp = now()->format('Y-m-d H:i:s');
|
|
$logEntry = "[{$timestamp}] {$message}\n";
|
|
|
|
file_put_contents($this->logFile, $logEntry, FILE_APPEND);
|
|
Log::info($message);
|
|
}
|
|
}
|