all(); if (get_frontend_settings('recaptcha_status') == true && check_recaptcha($input['g-recaptcha-response']) == false) { Session::flash('error', get_phrase('Recaptcha verification failed')); return redirect(route('register.form')); } $validator = Validator::make($request->all(), [ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'unique:users,email'], 'password' => ['required', Rules\Password::defaults()], ], [ 'name.required' => get_phrase('Name is required'), 'name.string' => get_phrase('Name must be a valid text'), 'name.max' => get_phrase('Name may not be greater than 255 characters'), 'email.required' => get_phrase('Email is required'), 'email.string' => get_phrase('Email must be a valid text'), 'email.email' => get_phrase('Please enter a valid email address'), 'email.unique' => get_phrase('This email is already registered. Please use a different email.'), 'password.required' => get_phrase('Password is required'), 'password.min' => get_phrase('Password must be at least 8 characters'), ]); if ($validator->fails()) { $firstError = $validator->errors()->first(); Session::flash('error', $firstError); return redirect()->back()->withErrors($validator)->withInput(); } // Check if the user is applying to be an instructor and validate instructor fields if ($request->has('instructor') && $request->instructor == 1) { // Validate instructor-specific fields (NIDN, Phone, Document) $instructorValidator = Validator::make($request->all(), [ 'nidn' => ['required', 'string', 'max:11'], 'phone' => ['required', 'string'], 'document' => ['required', 'file', 'mimes:pdf,doc,docx', 'max:2048'], ], [ 'nidn.required' => get_phrase('NIDN is required'), 'nidn.string' => get_phrase('NIDN must be a valid number'), 'nidn.max' => get_phrase('NIDN may not be greater than 11 characters'), 'phone.required' => get_phrase('Phone number is required'), 'document.required' => get_phrase('Document is required'), 'document.file' => get_phrase('Document must be a valid file'), 'document.mimes' => get_phrase('Document must be PDF, DOC, or DOCX'), 'document.max' => get_phrase('Document size must be less than 2MB'), ]); if ($instructorValidator->fails()) { $firstError = $instructorValidator->errors()->first(); Session::flash('error', $firstError); return redirect()->back()->withErrors($instructorValidator)->withInput(); } } // Start database transaction for the entire registration process $user = null; try { DB::beginTransaction(); $user_data = [ 'name' => $request->name, 'email' => $request->email, 'role' => 'student', 'status' => 1, 'password' => Hash::make($request->password), ]; if (get_settings('student_email_verification') != 1) { $user_data['email_verified_at'] = Carbon::now(); } $user = User::create($user_data); event(new Registered($user)); // If applying as an instructor, process the application if ($request->has('instructor')) { $result = $this->processInstructorApplication($request, $user); if ($result instanceof RedirectResponse && $result->getSession()->get('error')) { // If there was an error in instructor application, rollback DB::rollBack(); return $result; } } DB::commit(); // Log the user in after successful registration Auth::login($user); //send notification to user $application = Application::max('id') + 1; $user->notify(new \App\Notifications\InstructorApplicant($application)); return redirect(RouteServiceProvider::HOME); } catch (\Exception $e) { if (DB::transactionLevel() > 0) { DB::rollBack(); } Log::error('Registration error:', ['error' => $e->getMessage()]); Session::flash('error', get_phrase('Error during registration. Please try again.')); return redirect()->back()->withInput(); } } private function processInstructorApplication(Request $request, User $user): RedirectResponse { // Check if application already exists if (Application::where('user_id', $user->id)->exists()) { Session::flash('error', get_phrase('Your request is in process. Please wait for admin to respond.')); return redirect()->route('become.instructor'); } // Check if NIDN already exists in Instructors table with status = 1 (active) $nidn = $request->nidn; $existingInstructor = Instructors::where('nidn', $nidn) ->where('status', 1) ->first(); if ($existingInstructor) { Session::flash('error', get_phrase('This NIDN is already registered as an active instructor.')); return redirect()->back()->withInput(); } // Check NIDN with the API $api_url = "https://sindig.unesa.ac.id/apipddikti/api?nidn={$nidn}&auto=1"; $response = Http::timeout(30)->get($api_url); $data = $response->json(); Log::info('API Response for NIDN: ' . $nidn, ['response' => $data]); // Extract matched dosen data $matched_dosen = $data['matched_dosen'][0]; Log::info('Instructor data to be saved:', $matched_dosen); if (!isset($data['ok']) || !isset($data['matched_dosen']) || count($data['matched_dosen']) == 0) { Session::flash('error', get_phrase('NIDN not found in the system. Please check your NIDN.')); return redirect()->back()->withInput(); } else if (strtolower($matched_dosen['nama']) != strtolower($user->name)) { Session::flash('error', get_phrase('Name does not match PDDikti records. Please check your name.')); return redirect()->back()->withInput(); } // Prepare instructor data - adjust fields according to your database $instructor = [ 'user_id' => $user->id, 'nidn' => $nidn, 'name' => $matched_dosen['nama'] ?? $user->name, 'id_sdm' => $matched_dosen['id'] ?? null, 'id_sms' => $matched_dosen['nama_prodi'] ?? null, 'id_pt' => $matched_dosen['nama_pt'] ?? null, 'status' => 0 ]; Log::info('Instructor data to be saved:', $instructor); // Upload document if ($request->hasFile('document') && $request->file('document')->isValid()) { $doc = $request->file('document'); $fileName = 'uploads/applications/' . $user->id . Str::random(20) . '.' . $doc->extension(); FileUploader::upload($doc, $fileName, null, null, 300); } else { Session::flash('error', 'Document upload failed or no document selected.'); return redirect()->back()->withInput(); } // Prepare application data $application = [ 'user_id' => $user->id, 'phone' => $request->phone, 'description' => $request->description ]; // Create both application and instructor records Application::create($application); Instructors::create($instructor); Session::flash('success', get_phrase('Your application has been submitted successfully.')); return redirect(RouteServiceProvider::HOME); } }