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/emp.outerorbittech.in/

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


OR Upload from URL:
URL: Save as:

📄 File: submit.php

Path: /home2/outerorb/emp.outerorbittech.in/submit.php

Size: 16.44 KB

Permissions: 0666

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

// Determine which page submitted the form so we can redirect back on error.
$fromOnboarding = (($_GET['from'] ?? '') === 'onboarding');
$backUrl = $fromOnboarding ? 'onboarding.php' : 'index.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: ' . $backUrl);
    exit;
}

if (!isset($_POST['csrf_token']) || !verify_csrf($_POST['csrf_token'])) {
    // Preserve entered data so the user does not need to retype on session timeout.
    // 'docs' is a multi-value checkbox array — handle it separately to avoid TypeError.
    $docsRaw = $_POST['docs'] ?? [];
    $postScalars = array_filter($_POST, 'is_string');
    $old = array_map('sanitize_text', $postScalars);
    $old['docs'] = array_map('sanitize_text', (array) $docsRaw);
    redirect_with_message($backUrl, 'Invalid session token. Please retry.', 'error', [
        'old' => $old,
    ]);
}

ensure_employees_table();
ensure_designations_table();

$input = [];
foreach ([
    'first_name',
    'last_name',
    'mother_name',
    'email',
    'phone',
    'emergency_contact_name',
    'emergency_contact_number',
    'emergency_contact_relation',
    'dob',
    'date_of_joining',
    'address',
    'permanent_address',
    'zip',
    'aadhaar_number',
    'pan_number',
    'highest_qualification',
    'department',
    'marital_status',
    'gender',
    'identity_mark',
    'blood_group',
    'referred_by',
    'referral_name',
    'designation_id',
    'account_number',
    'ifsc_code',
    'bank_name',
] as $field) {
    $input[$field] = sanitize_text($_POST[$field] ?? '');
}

$maritalStatusOptions = ['Single', 'Married', 'Divorced', 'Widowed', 'Separated'];
$genderOptions = ['Male', 'Female', 'Other', 'Prefer not to say'];
$bloodGroupOptions = ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-'];
$qualificationOptions = ['10th Pass', '12th Pass', 'Diploma', "Bachelor's Degree", "Master's Degree", 'PhD', 'Other'];

// Normalize date inputs to YYYY-MM-DD for MySQL
$dateFields = ['dob' => 'Date of birth', 'date_of_joining' => 'Date of joining'];
foreach ($dateFields as $field => $label) {
    $normalized = normalize_date($input[$field]);
    if ($normalized === null) {
        $input[$field] = '';
    } else {
        $input[$field] = $normalized;
    }
}

$errors = validate_required([
    'first_name' => 'Full name',
    'last_name' => "Father's name",
    'email' => 'Email',
    'phone' => 'Contact number',
    'mother_name' => "Mother's name",
    'emergency_contact_name' => 'Emergency contact name',
    'emergency_contact_number' => 'Emergency contact number',
    'emergency_contact_relation' => 'Emergency contact relation',
    'dob' => 'Date of birth',
    'date_of_joining' => 'Date of joining',
    'address' => 'Present address',
    'permanent_address' => 'Permanent address',
    'zip' => 'Present ZIP / PIN',
    'aadhaar_number' => 'Aadhaar number',
    'pan_number' => 'PAN number',
    'highest_qualification' => 'Highest qualification',
    'department' => 'Department / Process',
    'designation_id' => 'Designation',
    'marital_status' => 'Marital status',
    'gender' => 'Gender',
    'identity_mark' => 'Identity mark',
    'blood_group' => 'Blood group',
    'referred_by' => 'Referred by',
    'account_number' => 'Account number',
    'ifsc_code' => 'IFSC code',
    'bank_name' => 'Bank name',
], $input);

$departments = list_departments();
if (empty($departments)) {
    $errors['department'] = 'No departments configured. Please contact an admin.';
} elseif (!in_array($input['department'], $departments, true)) {
    $errors['department'] = 'Please select a valid department';
}

$designationRows = list_designations(true);
$designationIds = array_map(fn($row) => (int) $row['id'], $designationRows);
$designationId = (int) $input['designation_id'];
if (empty($designationRows)) {
    $errors['designation_id'] = 'No designations configured. Please contact an admin.';
} elseif (!$designationId || !in_array($designationId, $designationIds, true)) {
    $errors['designation_id'] = 'Please select a valid designation';
}

$validReferrers = ['consultancy', 'person', 'walkin'];
if (!in_array($input['referred_by'], $validReferrers, true)) {
    $errors['referred_by'] = 'Please select how you were referred';
}

if (in_array($input['referred_by'], ['consultancy', 'person'], true) && $input['referral_name'] === '') {
    $errors['referral_name'] = $input['referred_by'] === 'consultancy' ? 'Consultancy name is required' : 'Person name is required';
}

if (!preg_match('/^[A-Za-z ]+$/', $input['mother_name'])) {
    $errors['mother_name'] = "Mother's name should contain only letters and spaces";
}

if (!preg_match('/^[A-Za-z ]+$/', $input['first_name'])) {
    $errors['first_name'] = 'Full name should contain only letters and spaces';
}

if (!preg_match('/^[A-Za-z ]+$/', $input['last_name'])) {
    $errors['last_name'] = "Father's name should contain only letters and spaces";
}

if (!preg_match('/^\d{10}$/', $input['phone'])) {
    $errors['phone'] = 'Contact number must be 10 digits';
}

if (!preg_match('/^[A-Za-z ]+$/', $input['emergency_contact_name'])) {
    $errors['emergency_contact_name'] = 'Emergency contact name should contain only letters and spaces';
}

if (!preg_match('/^\d{10}$/', $input['emergency_contact_number'])) {
    $errors['emergency_contact_number'] = 'Emergency contact number must be 10 digits';
}

if (!in_array($input['marital_status'], $maritalStatusOptions, true)) {
    $errors['marital_status'] = 'Select a valid marital status';
}

if (!in_array($input['gender'], $genderOptions, true)) {
    $errors['gender'] = 'Select a valid gender';
}

if (!in_array($input['blood_group'], $bloodGroupOptions, true)) {
    $errors['blood_group'] = 'Select a valid blood group';
}

if (!in_array($input['highest_qualification'], $qualificationOptions, true)) {
    $errors['highest_qualification'] = 'Select a valid qualification';
}

$emergencyRelations = ['Father', 'Mother', 'Brother', 'Sister', 'Spouse', 'Relative', 'Friend', 'Other'];
if (!in_array($input['emergency_contact_relation'], $emergencyRelations, true)) {
    $errors['emergency_contact_relation'] = 'Select a valid emergency contact relation';
}

if ($input['email'] && !filter_var($input['email'], FILTER_VALIDATE_EMAIL)) {
    $errors['email'] = 'Invalid email format';
}

if ($input['aadhaar_number'] !== '' && !preg_match('/^\d{12}$/', $input['aadhaar_number'])) {
    $errors['aadhaar_number'] = 'Aadhaar number must be exactly 12 digits';
}

if ($input['pan_number'] !== '' && !preg_match('/^[A-Z]{5}[0-9]{4}[A-Z]$/i', $input['pan_number'])) {
    $errors['pan_number'] = 'PAN number must be in format ABCDE1234F';
}

if ($input['zip'] !== '' && !preg_match('/^\d{6}$/', $input['zip'])) {
    $errors['zip'] = 'Present ZIP / PIN must be exactly 6 digits';
}

if ($input['ifsc_code'] !== '' && !preg_match('/^[A-Z]{4}0[A-Z0-9]{6}$/i', $input['ifsc_code'])) {
    $errors['ifsc_code'] = 'IFSC code must be in format ABCD0123456';
}

if ($input['account_number'] !== '' && !preg_match('/^\d{9,18}$/', $input['account_number'])) {
    $errors['account_number'] = 'Account number must be 9 to 18 digits';
}

foreach ($dateFields as $field => $label) {
    if ($input[$field] === '') {
        $errors[$field] = $label . ' must be a valid date (YYYY-MM-DD)';
    }
}

if ($input['dob'] !== '') {
    $dobTs = strtotime($input['dob']);
    if ($dobTs === false) {
        $errors['dob'] = 'Date of birth must be a valid date';
    } else {
        $todayTs = strtotime(date('Y-m-d'));
        if ($dobTs > $todayTs) {
            $errors['dob'] = 'Date of birth cannot be in the future';
        } else {
            $age = (int) date('Y') - (int) date('Y', $dobTs);
            $birthdayPassed = date('md') >= date('md', $dobTs);
            if (!$birthdayPassed) {
                $age--;
            }
            if ($age < 18) {
                $errors['dob'] = 'Employee must be at least 18 years old';
            }
        }
    }
}

if ($input['date_of_joining'] !== '') {
    $dojTs = strtotime($input['date_of_joining']);
    if ($dojTs === false) {
        $errors['date_of_joining'] = 'Date of joining must be a valid date';
    } elseif ($dojTs > strtotime(date('Y-m-d'))) {
        $errors['date_of_joining'] = 'Date of joining cannot be in the future';
    }
}

// City and state columns are unused; populate with empty strings
$input['city'] = '';
$input['state'] = '';

if (!empty($errors)) {
    redirect_with_message($backUrl, 'Please fix the highlighted errors and try again.', 'error', [
        'errors' => $errors,
        'old' => array_merge($input, ['docs' => (array)($_POST['docs'] ?? [])]),
    ]);
}

$config = app_config();
$docMimes = $config['security']['allowed_doc_mimes'];
$photoMimes = $config['security']['allowed_photo_mimes'];
$stagedUploads = staged_uploads();

$documentRules = [
    'aadhaar' => ['label' => 'Aadhaar Document', 'mimes' => $docMimes, 'size' => $config['uploads']['max_size']],
    'aadhaar_front' => ['label' => 'Aadhaar Front', 'mimes' => $docMimes, 'size' => $config['uploads']['max_size']],
    'aadhaar_back' => ['label' => 'Aadhaar Back', 'mimes' => $docMimes, 'size' => $config['uploads']['max_size']],
    'pan' => ['label' => 'PAN Document', 'mimes' => $docMimes, 'size' => $config['uploads']['max_size']],
    'qualification' => ['label' => 'Graduation', 'mimes' => $docMimes, 'size' => $config['uploads']['max_size']],
    'tenth_marksheet' => ['label' => '10th Marksheet', 'mimes' => $docMimes, 'size' => $config['uploads']['max_size']],
    'twelfth_marksheet' => ['label' => '12th Marksheet', 'mimes' => $docMimes, 'size' => $config['uploads']['max_size']],
    'bank_proof' => ['label' => 'Bank Proof', 'mimes' => $docMimes, 'size' => $config['uploads']['max_size']],
    'photo' => ['label' => 'Passport Photo', 'mimes' => $photoMimes, 'size' => $config['uploads']['photo_max_size']],
];

$selectedDocs = array_values(array_intersect(array_keys($documentRules), (array)($_POST['docs'] ?? [])));
$mandatoryDocs = ['tenth_marksheet', 'twelfth_marksheet'];
$selectedDocs = array_values(array_unique(array_merge($selectedDocs, $mandatoryDocs)));
$uploads = $stagedUploads;
$docErrors = [];
$uploadErrors = [];

// Build an identifier prefix for uploaded filenames so files can be traced back to this candidate.
$uploadPrefix = make_upload_prefix($input['first_name'] ?? '', $input['last_name'] ?? '', $input['phone'] ?? '');

foreach ($documentRules as $field => $rule) {
    $fileError = isset($_FILES[$field]) ? ($_FILES[$field]['error'] ?? UPLOAD_ERR_NO_FILE) : UPLOAD_ERR_NO_FILE;
    $hasFile = $fileError !== UPLOAD_ERR_NO_FILE;
    $isSelected = in_array($field, $selectedDocs, true);
    $isRequired = in_array($field, $mandatoryDocs, true);
    $existing = $stagedUploads[$field] ?? '';

    if ($isRequired && !$hasFile && !$existing) {
        $docErrors[$field] = $rule['label'] . ' is mandatory';
        $uploads[$field] = '';
        continue;
    }

    if ($isSelected && !$hasFile && !$existing) {
        $docErrors[$field] = $rule['label'] . ' was selected but no file was uploaded';
        $uploads[$field] = '';
        continue;
    }

    if (!$hasFile) {
        // Reuse staged upload if present; otherwise leave empty.
        $uploads[$field] = $existing ?: '';
        continue;
    }

    $result = handle_upload($field, $rule['mimes'], $rule['size'], $uploadPrefix);
    if (!empty($result['error'])) {
        $uploadErrors[$field] = $rule['label'] . ': ' . $result['error'];
        $uploads[$field] = $existing ?: '';
        continue;
    }
    if ($existing && $existing !== $result['path']) {
        @unlink($existing);
    }
    remember_upload($field, $result['path']);
    $uploads[$field] = $result['path'];
}

if (!empty($docErrors)) {
    redirect_with_message($backUrl, 'Please fix the highlighted errors and try again.', 'error', [
        'errors' => $docErrors,
        'old' => array_merge($input, ['docs' => $selectedDocs]),
    ]);
}

if (!empty($uploadErrors)) {
    redirect_with_message($backUrl, 'Please fix the highlighted errors and try again.', 'error', [
        'errors' => $uploadErrors,
        'old' => array_merge($input, ['docs' => $selectedDocs]),
    ]);
}

try {
    $pdo = db();
    $data = [
        'first_name' => $input['first_name'],
        'last_name' => $input['last_name'],
        'email' => $input['email'],
        'phone' => $input['phone'],
        'emergency_contact' => $input['emergency_contact_number'],
        'mother_name' => $input['mother_name'],
        'emergency_contact_name' => $input['emergency_contact_name'],
        'emergency_contact_number' => $input['emergency_contact_number'],
        'emergency_contact_relation' => $input['emergency_contact_relation'],
        'dob' => $input['dob'],
        'date_of_joining' => $input['date_of_joining'],
        'address' => $input['address'],
        'permanent_address' => $input['permanent_address'],
        'city' => $input['city'],
        'state' => $input['state'],
        'zip' => $input['zip'],
        'aadhaar_number' => $input['aadhaar_number'],
        'pan_number' => $input['pan_number'],
        'highest_qualification' => $input['highest_qualification'],
        'department' => $input['department'],
        'employee_status' => 'Active',
        'approval_status' => $fromOnboarding ? 'pending' : 'approved',
        'last_working_date' => null,
        'reason_for_leaving' => null,
        'marital_status' => $input['marital_status'],
        'gender' => $input['gender'],
        'identity_mark' => $input['identity_mark'],
        'blood_group' => $input['blood_group'],
        'referred_by' => $input['referred_by'],
        'referral_name' => $input['referral_name'] ?: null,
        'designation_id' => $designationId ?: null,
        'account_number' => $input['account_number'],
        'ifsc_code' => $input['ifsc_code'],
        'bank_name' => $input['bank_name'],
        'aadhaar_path' => compose_aadhaar_value([
            'front' => $uploads['aadhaar_front'] ?? null,
            'back' => $uploads['aadhaar_back'] ?? null,
            'single' => $uploads['aadhaar'] ?? null,
        ]),
        'pan_path' => $uploads['pan'],
        'qualification_path' => $uploads['qualification'],
        'tenth_marksheet_path' => $uploads['tenth_marksheet'],
        'twelfth_marksheet_path' => $uploads['twelfth_marksheet'],
        'bank_proof_path' => $uploads['bank_proof'],
        'photo_path' => $uploads['photo'],
    ];

    $placeholders = array_map(fn($key) => ':' . $key, array_keys($data));
    $sql = 'INSERT INTO employees (' . implode(', ', array_keys($data)) . ') VALUES (' . implode(', ', $placeholders) . ')';

    $stmt = $pdo->prepare($sql);
    $stmt->execute($data);
} catch (Throwable $e) {
    error_log('Employee insert failed: ' . $e->getMessage());

    $dbFieldErrors = [];
    $dbMessage = $e->getMessage();
    if ($e instanceof PDOException && (string) $e->getCode() === '23000') {
        $lower = strtolower($dbMessage);
        if (strpos($lower, 'email') !== false) {
            $dbFieldErrors['email'] = 'This email is already registered';
        }
        if (strpos($lower, 'phone') !== false) {
            $dbFieldErrors['phone'] = 'This contact number is already registered';
        }
        if (strpos($lower, 'aadhaar') !== false) {
            $dbFieldErrors['aadhaar_number'] = 'This Aadhaar number is already registered';
        }
        if (strpos($lower, 'pan') !== false) {
            $dbFieldErrors['pan_number'] = 'This PAN number is already registered';
        }
    }

    if (!empty($dbFieldErrors)) {
        redirect_with_message($backUrl, 'Please fix the highlighted errors and try again.', 'error', [
            'errors' => $dbFieldErrors,
            'old' => array_merge($input, ['docs' => $selectedDocs]),
        ]);
    }

    $msg = 'Could not save your submission. Please try again.';
    redirect_with_message($backUrl, $msg, 'error', [
        'old' => array_merge($input, ['docs' => $selectedDocs]),
    ]);
}

clear_staged_uploads();
if ($fromOnboarding) {
    redirect_with_message('onboarding.php', 'Your details have been submitted. HR will review and activate your account. You will be able to log in once approved.');
}
redirect_with_message('index.php', 'Onboarding submitted successfully.');

← Back to Directory Edit File 🔒 Chmod

WP File Manager