Server : LiteSpeed
System : Linux terra.hostitbro.com 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64
User : outerorb ( 1091)
PHP Version : 8.1.34
Disable Function : mail
Directory :  /home2/outerorb/.trash/

📁 Create New:
⬆️ Upload File:
Current Dir [ Writable ] Root [ Writable ]


OR Upload from URL:
URL: Save as:

📄 File: 2026-04-20-rename-uploads.php

Path: /home2/outerorb/.trash/2026-04-20-rename-uploads.php

Size: 10.7 KB

Permissions: 0644

<?php
/**
 * Migration: Rename existing uploaded files to include employee name + phone prefix.
 *
 * SAFE TO RUN:
 *  - Reads DB paths, renames the physical file, then updates the DB in the same transaction.
 *  - Skips files that are already prefixed or cannot be found on disk.
 *  - Dry-run mode (default) shows what WOULD be renamed without touching anything.
 *
 * HOW TO RUN:
 *  1. Upload this file to the server (or run locally on Laragon).
 *  2. Open in browser:
 *       https://emp.outerorbittech.in/migrations/2026-04-20-rename-uploads.php?run=1&secret=CHANGE_ME
 *     Or on localhost:
 *       http://localhost/emp.outerorbittech.in/migrations/2026-04-20-rename-uploads.php?run=1&secret=CHANGE_ME
 *  3. Omit ?run=1 (or keep ?run=0) for a dry-run preview first.
 *  4. DELETE this file from the server after running.
 *
 * SECURITY: Change the secret below before uploading to the server.
 */

define('MIGRATION_SECRET', 'OuterOrbit@2026');

if (php_sapi_name() !== 'cli') {
    $secret = $_GET['secret'] ?? '';
    if (!hash_equals(MIGRATION_SECRET, $secret)) {
        http_response_code(403);
        die('Forbidden. Pass ?secret=YOUR_SECRET in the URL.');
    }
}

$dryRun = !(($_GET['run'] ?? '0') === '1' || (php_sapi_name() === 'cli' && in_array('--run', array_slice($argv ?? [], 1), true)));

require __DIR__ . '/../includes/helpers.php';

// Remove execution time limit and disable output buffering so progress is visible.
set_time_limit(0);
while (ob_get_level() > 0) {
    ob_end_clean();
}
ob_implicit_flush(true);

$pdo = db();

// -----------------------------------------------------------------------
// Helper: build prefix the same way handle_upload() does
// -----------------------------------------------------------------------
function build_prefix(string $firstName, string $lastName, string $phone): string
{
    return make_upload_prefix($firstName, $lastName, $phone);
}

// -----------------------------------------------------------------------
// Detect whether a filename looks like the old random-only format
// (32 hex chars with optional extension) so we skip already-prefixed files.
// -----------------------------------------------------------------------
function is_legacy_filename(string $basename): bool
{
    return (bool) preg_match('/^[a-f0-9]{16,32}(\.[a-z0-9]+)?$/i', $basename);
}

// -----------------------------------------------------------------------
// Rename a file on disk and return the new path, or null on failure.
// -----------------------------------------------------------------------
function safe_rename_file(string $oldPath, string $newPath): bool
{
    if (!file_exists($oldPath)) {
        return false;
    }
    if (file_exists($newPath)) {
        // Destination already exists – generate a slightly different name to avoid collision
        $info    = pathinfo($newPath);
        $newPath = $info['dirname'] . '/' . $info['filename'] . '_1.' . ($info['extension'] ?? '');
    }
    return rename($oldPath, $newPath);
}

// -----------------------------------------------------------------------
// Process a single stored path value (plain path OR JSON aadhaar value)
// Returns ['updated' => bool, 'newValue' => string, 'log' => array]
// -----------------------------------------------------------------------
function process_path_value(
    ?string $storedValue,
    string $prefix,
    string $uploadDir,
    bool $dryRun,
    bool $isAadhaar = false
): array {
    $log = [];
    $stored = trim((string) $storedValue);
    if ($stored === '') {
        return ['updated' => false, 'newValue' => $stored, 'log' => $log];
    }

    if ($isAadhaar) {
        // May be JSON {"front":"/path","back":"/path"} or a plain legacy path
        $decoded = json_decode($stored, true);
        if (is_array($decoded)) {
            $changed = false;
            foreach (['front', 'back', 'single'] as $part) {
                if (empty($decoded[$part])) {
                    continue;
                }
                $result = process_single_path($decoded[$part], $prefix . '_aadhaar-' . $part, $uploadDir, $dryRun, $log);
                if ($result['updated']) {
                    $decoded[$part] = $result['newPath'];
                    $changed = true;
                }
            }
            return [
                'updated'  => $changed,
                'newValue' => $changed ? json_encode($decoded, JSON_UNESCAPED_SLASHES) : $stored,
                'log'      => $log,
            ];
        }
        // Fallthrough: plain legacy path for aadhaar
        $result = process_single_path($stored, $prefix . '_aadhaar', $uploadDir, $dryRun, $log);
        return ['updated' => $result['updated'], 'newValue' => $result['newPath'], 'log' => $log];
    }

    $result = process_single_path($stored, $prefix, $uploadDir, $dryRun, $log);
    return ['updated' => $result['updated'], 'newValue' => $result['newPath'], 'log' => $log];
}

function process_single_path(string $stored, string $prefix, string $uploadDir, bool $dryRun, array &$log): array
{
    $basename = basename($stored);
    if (!is_legacy_filename($basename)) {
        $log[] = "  SKIP (already prefixed): $basename";
        return ['updated' => false, 'newPath' => $stored];
    }

    // Resolve actual file location
    $realPath = null;
    if (file_exists($stored)) {
        $realPath = $stored;
    } else {
        $candidate = rtrim($uploadDir, '/\\') . DIRECTORY_SEPARATOR . $basename;
        if (file_exists($candidate)) {
            $realPath = $candidate;
        }
    }

    if (!$realPath) {
        // Check if the file was already renamed in a previous partial run.
        // The new name would be: $prefix . '_' . first16charsOfHex . '.' . ext
        $ext     = pathinfo($basename, PATHINFO_EXTENSION);
        $random  = substr($basename, 0, 16);
        $expectedNewBasename = $prefix . '_' . $random . ($ext ? '.' . $ext : '');
        $expectedNewPath     = rtrim($uploadDir, '/\\') . DIRECTORY_SEPARATOR . $expectedNewBasename;
        if (file_exists($expectedNewPath)) {
            // File was already renamed in a previous partial run — only update the DB.
            $newStored = (dirname($stored) !== '.' ? dirname($stored) . '/' : '') . $expectedNewBasename;
            $log[] = "  DB-ONLY (already renamed on disk): $basename → $expectedNewBasename";
            return ['updated' => true, 'newPath' => $newStored];
        }
        $log[] = "  SKIP (file not found on disk): $basename";
        return ['updated' => false, 'newPath' => $stored];
    }

    $ext        = pathinfo($basename, PATHINFO_EXTENSION);
    $random     = substr($basename, 0, 16); // keep first 16 chars of old random for uniqueness
    $newBasename = $prefix . '_' . $random . ($ext ? '.' . $ext : '');
    $newRealPath = dirname($realPath) . DIRECTORY_SEPARATOR . $newBasename;

    // The stored DB value may be an absolute path or just the basename.
    // Reconstruct the new stored value in the same style.
    $newStored = (dirname($stored) !== '.' ? dirname($stored) . '/' : '') . $newBasename;

    $log[] = "  RENAME: $basename → $newBasename";

    if (!$dryRun) {
        if (!safe_rename_file($realPath, $newRealPath)) {
            $log[] = "  ERROR: rename failed for $realPath";
            return ['updated' => false, 'newPath' => $stored];
        }
    }

    return ['updated' => true, 'newPath' => $newStored];
}

// -----------------------------------------------------------------------
// Main loop
// -----------------------------------------------------------------------
$stmt = $pdo->query(
    'SELECT id, first_name, last_name, phone,
            aadhaar_path, pan_path, qualification_path, bank_proof_path, photo_path
     FROM employees WHERE deleted_at IS NULL ORDER BY id'
);
$employees = $stmt->fetchAll(PDO::FETCH_ASSOC);

$columns = [
    'aadhaar_path'       => ['isAadhaar' => true,  'label' => 'Aadhaar'],
    'pan_path'           => ['isAadhaar' => false, 'label' => 'PAN'],
    'qualification_path' => ['isAadhaar' => false, 'label' => 'Qualification'],
    'bank_proof_path'    => ['isAadhaar' => false, 'label' => 'Bank Proof'],
    'photo_path'         => ['isAadhaar' => false, 'label' => 'Photo'],
];

$config    = app_config();
$uploadDir = $config['uploads']['dir'];

$totalRenamed = 0;
$totalSkipped = 0;
$totalErrors  = 0;

header('Content-Type: text/plain; charset=utf-8');
echo ($dryRun ? "DRY RUN — no files will be changed. Add ?run=1 to apply.\n" : "LIVE RUN — renaming files.\n");
echo "=========================================================\n\n";

// Ensure aadhaar_path column is wide enough for JSON with two long absolute paths.
try {
    $pdo->exec("ALTER TABLE employees MODIFY COLUMN aadhaar_path TEXT NOT NULL");
    echo "ALTER TABLE: aadhaar_path expanded to TEXT.\n\n";
} catch (Throwable $e) {
    echo "ALTER TABLE skipped/failed: " . $e->getMessage() . "\n\n";
}

foreach ($employees as $emp) {
    $prefix  = build_prefix($emp['first_name'], $emp['last_name'], $emp['phone']);
    $updates = [];
    $allLog  = [];

    foreach ($columns as $col => $opts) {
        $result = process_path_value(
            $emp[$col],
            $prefix . '_' . str_replace('_path', '', $col),
            $uploadDir,
            $dryRun,
            $opts['isAadhaar']
        );
        if ($result['updated']) {
            $updates[$col] = $result['newValue'];
            $totalRenamed++;
        }
        foreach ($result['log'] as $line) {
            $allLog[] = "[{$opts['label']}] $line";
        }
    }

    if (!empty($updates) || !empty($allLog)) {
        echo "Employee #{$emp['id']}: {$emp['first_name']} {$emp['last_name']} ({$emp['phone']})\n";
        foreach ($allLog as $line) {
            echo "  $line\n";
        }
    }

    if (!empty($updates) && !$dryRun) {
        $setClauses = implode(', ', array_map(fn($c) => "`$c` = ?", array_keys($updates)));
        $values     = array_values($updates);
        $values[]   = $emp['id'];
        try {
            $pdo->prepare("UPDATE employees SET $setClauses WHERE id = ?")->execute($values);
            echo "  DB updated.\n";
        } catch (Throwable $e) {
            echo "  DB ERROR: " . $e->getMessage() . "\n";
            $totalErrors++;
        }
    }

    // Flush output so progress is visible even under buffering/timeout.
    flush();
}

echo "\n=========================================================\n";
echo "Done. Renamed: $totalRenamed | Errors: $totalErrors\n";
if ($dryRun) {
    echo "\nThis was a DRY RUN. No files or DB rows were changed.\n";
    echo "To apply, add ?run=1&secret=" . MIGRATION_SECRET . " to the URL.\n";
}

← Back to Directory Edit File 🔒 Chmod

WP File Manager