captchaService->verify($captcha)) { return [ 'ok' => false, 'code' => 'captcha_invalid', 'message' => 'Incorrect CAPTCHA answer. Please try again.', ]; } $isParent = !empty($payload['is_parent']); $noSecondInfo = !empty($payload['no_second_parent_info']); $formatted = $this->formatter->format($payload); $email = (string) ($formatted['email'] ?? ''); $existing = User::query()->where('email', $email)->first(); if ($existing) { $pending = !empty($existing->token) && (int) ($existing->is_verified ?? 0) === 0; if ($pending) { return [ 'ok' => false, 'code' => 'pending_activation', 'message' => 'This email address is already registered and pending activation.', ]; } return [ 'ok' => false, 'code' => 'email_exists', 'message' => 'The email address you entered is already in use.', ]; } $roleName = $isParent ? 'parent' : 'guest'; $role = Role::query()->where('name', $roleName)->first(); if (!$role) { return [ 'ok' => false, 'code' => 'role_missing', 'message' => 'Role not found.', ]; } $token = bin2hex(random_bytes(48)); $schoolYear = Configuration::getConfig('school_year'); $semester = Configuration::getConfig('semester'); $userData = [ 'firstname' => (string) ($formatted['firstname'] ?? ''), 'lastname' => (string) ($formatted['lastname'] ?? ''), 'gender' => (string) ($formatted['gender'] ?? ''), 'email' => $email, 'cellphone' => (string) ($formatted['cellphone'] ?? ($payload['cellphone'] ?? '')), 'address_street' => (string) ($formatted['address_street'] ?? ''), 'apt' => $formatted['apt'] ?? null, 'city' => (string) ($formatted['city'] ?? ''), 'state' => (string) ($formatted['state'] ?? ''), 'zip' => (string) ($formatted['zip'] ?? ''), 'token' => $token, 'is_verified' => 0, 'accept_school_policy' => (int) ($formatted['accept_school_policy'] ?? 0), 'status' => 'Inactive', 'school_id' => $this->schoolIdService->generateUserSchoolId(), 'semester' => (string) ($semester ?? ''), 'school_year' => $schoolYear, 'password' => pbkdf2_hash(bin2hex(random_bytes(8))), ]; $user = null; DB::transaction(function () use ( $userData, $role, $isParent, $noSecondInfo, $formatted, $schoolYear, $semester, &$user ) { $user = User::query()->create($userData); UserRole::query()->create([ 'user_id' => (int) $user->id, 'role_id' => (int) $role->id, 'created_at' => now(), ]); if ($isParent && !$noSecondInfo && !empty($formatted['second_firstname'])) { ParentModel::query()->create([ 'secondparent_firstname' => $formatted['second_firstname'] ?? null, 'secondparent_lastname' => $formatted['second_lastname'] ?? null, 'secondparent_gender' => $formatted['second_gender'] ?? null, 'secondparent_email' => $formatted['second_email'] ?? null, 'secondparent_phone' => $formatted['second_cellphone'] ?? null, 'firstparent_id' => (int) $user->id, 'semester' => $semester, 'school_year' => $schoolYear, ]); } }); $activationLink = $this->urls->spaRegistrationConfirmUrl($token); $recipientName = trim((string) ($formatted['firstname'] ?? '') . ' ' . (string) ($formatted['lastname'] ?? '')); $html = '

Hello ' . e($recipientName !== '' ? $recipientName : 'there') . ',

' . '

Please confirm your email by clicking the link below:

' . '

Activate your account

' . '

Thank you.

'; $sent = $this->emailService->send($email, 'Email Confirmation', $html, 'general'); $this->captchaService->clear(); return [ 'ok' => true, 'user' => $user, 'role' => $roleName, 'activation_sent' => $sent, ]; } }