Access Denied.'; exit; } render_header(t('user_registration'), 'admin'); echo '
Access Denied.
'; render_footer(); exit; } $errors = []; $values = [ 'full_name' => '', 'email' => '', 'phone' => '', 'country_id' => '', 'city_id' => '', 'address_line' => '', 'company_name' => '', 'bank_account' => '', 'bank_name' => '', 'bank_branch' => '', 'is_company' => '0', 'ctr_number' => '', 'notes' => '', 'status' => 'active', ]; $countries = db()->query("SELECT id, name_en, name_ar FROM countries ORDER BY name_en ASC")->fetchAll(); $cities = db()->query("SELECT id, country_id, name_en, name_ar FROM cities ORDER BY name_en ASC")->fetchAll(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!$isAjax) validate_csrf_token(); // CSRF token usually passed in form, but for AJAX we might rely on cookie or verify it if passed $fullName = trim($_POST['full_name'] ?? ''); $email = trim($_POST['email'] ?? ''); $phone = trim($_POST['phone'] ?? ''); $countryId = (int)($_POST['country_id'] ?? 0); $cityId = (int)($_POST['city_id'] ?? 0); $addressLine = trim($_POST['address_line'] ?? ''); $companyName = trim($_POST['company_name'] ?? ''); $passwordRaw = (string)($_POST['password'] ?? ''); $status = $_POST['status'] ?? 'active'; $values = [ 'full_name' => $fullName, 'email' => $email, 'phone' => $phone, 'country_id' => $countryId > 0 ? (string)$countryId : '', 'city_id' => $cityId > 0 ? (string)$cityId : '', 'address_line' => $addressLine, 'company_name' => $companyName, 'bank_account' => trim($_POST['bank_account'] ?? ''), 'bank_name' => trim($_POST['bank_name'] ?? ''), 'bank_branch' => trim($_POST['bank_branch'] ?? ''), 'is_company' => isset($_POST['is_company']) ? '1' : '0', 'ctr_number' => trim($_POST['ctr_number'] ?? ''), 'notes' => trim($_POST['notes'] ?? ''), 'status' => $status, ]; if ($fullName === '') $errors[] = t('error_required'); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = t('error_invalid') . ' (Email)'; if ($phone === '') $errors[] = t('error_required'); if ($countryId <= 0 || $cityId <= 0) $errors[] = t('error_required'); if ($addressLine === '') $errors[] = t('error_required'); if (strlen($passwordRaw) < 6) $errors[] = t('password_too_short'); if ($role === 'shipper' && $companyName === '') $errors[] = t('error_required'); if (!$errors) { $password = password_hash($passwordRaw, PASSWORD_DEFAULT); $pdo = db(); try { $pdo->beginTransaction(); $stmt = $pdo->prepare("INSERT INTO users (email, password, full_name, role, status) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$email, $password, $fullName, $role, $status]); $userId = (int)$pdo->lastInsertId(); if ($role === 'shipper') { $shipperStmt = $pdo->prepare( "INSERT INTO shipper_profiles (user_id, company_name, phone, country_id, city_id, address_line) VALUES (?, ?, ?, ?, ?, ?)" ); $shipperStmt->execute([$userId, $companyName, $phone, $countryId, $cityId, $addressLine]); } else { // Truck Owner $uploadDir = __DIR__ . '/uploads/profiles/' . $userId . '/'; if (!is_dir($uploadDir)) mkdir($uploadDir, 0775, true); $allowed = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp']; $saveImage = function ($fileKey, $prefix) use ($uploadDir, $allowed) { if (!isset($_FILES[$fileKey]) || $_FILES[$fileKey]['error'] !== UPLOAD_ERR_OK) return null; $tmpName = $_FILES[$fileKey]['tmp_name']; $mime = mime_content_type($tmpName) ?: ''; if (!isset($allowed[$mime])) return null; $filename = uniqid($prefix, true) . '.' . $allowed[$mime]; move_uploaded_file($tmpName, $uploadDir . $filename); return 'uploads/profiles/' . basename($uploadDir) . '/' . $filename; }; $ctrPath = null; $idCardPaths = []; if ($values['is_company'] === '1') { $ctrPath = $saveImage('ctr_document', 'ctr_'); } else { $f = $saveImage('id_card_front', 'id_front_'); if ($f) $idCardPaths[] = $f; $b = $saveImage('id_card_back', 'id_back_'); if ($b) $idCardPaths[] = $b; } $ownerStmt = $pdo->prepare( "INSERT INTO truck_owner_profiles (user_id, phone, country_id, city_id, address_line, bank_account, bank_name, bank_branch, id_card_path, is_company, ctr_number, notes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ); $ownerStmt->execute([ $userId, $phone, $countryId, $cityId, $addressLine, $values['bank_account'], $values['bank_name'], $values['bank_branch'], $values['is_company'] === '1' ? $ctrPath : json_encode($idCardPaths, JSON_UNESCAPED_SLASHES), $values['is_company'], $values['ctr_number'], $values['notes'] ]); } $pdo->commit(); set_flash('success', t('create_success')); if ($isAjax) { echo json_encode(['success' => true]); exit; } if ($role === 'shipper') { header('Location: admin_shippers.php'); } else { header('Location: admin_truck_owners.php'); } exit; } catch (Throwable $e) { $pdo->rollBack(); if (stripos($e->getMessage(), 'Duplicate entry') !== false) { $err = t('error_email_exists') ?: 'Email already exists.'; } else { $err = $e->getMessage(); } $errors[] = $err; if ($isAjax) { echo json_encode(['success' => false, 'message' => implode('
', $errors)]); exit; } } } else { if ($isAjax) { echo json_encode(['success' => false, 'message' => implode('
', $errors)]); exit; } } } $pageTitle = $role === 'shipper' ? t('create_shipper') : t('create_owner'); // --- Render Logic --- if ($isAjax) { // Return only the form HTML for the modal ?>
', $errors)) ?>
:
/
onchange="toggleCompanyFields()">