|string> */ public function rules(): array { return [ 'data' => 'required|array|min:1', 'data.*.nama_klasifikasi' => 'required|string' ]; } public function messages(){ return [ 'data.array' => 'Format data harus berupa array', 'data.min' => 'Minimal harus ada satu data Klasifikasi', 'data.*.nama_klasifikasi.required' => 'Nama Klasifikasi wajib diisi', 'data.*.nama_klasifikasi.string' => 'Nama Klasifikasi harus berupa teks', ]; } protected function failedValidation(Validator $validator){ throw new HttpResponseException( response()->json([ 'status' => 'VALIDATION_FAILED', 'message' => 'Validasi Gagal', 'errors' => $validator->errors()->messages(), ], 422) ); } public function withValidator($validator){ $validator->after(function ($validator){ $namaKategori = collect($this->input('data'))->pluck('nama_klasifikasi')->filter(); $namaListLower = $namaKategori->map(fn($n) => strtolower(trim($n))); // ✅ Cek duplikat antar input user $duplicates = $namaListLower->duplicates(); if ($duplicates->isNotEmpty()) { foreach ($namaKategori as $index => $nama) { if ($duplicates->contains(strtolower(trim($nama)))) { $validator->errors()->add("data.$index.nama_klasifikasi", "Nama '$nama' duplikat dalam input."); } } } $namaList = $namaKategori->map(fn($n) => strtolower(trim($n))); if($namaList->isEmpty()) return; $exists = DB::connection('dbDirectory') ->table('public.master_klasifikasi_directory') ->where('statusenabled', true) ->whereIn(DB::raw('LOWER(nama_klasifikasi_directory)'), $namaList->toArray()) ->selectRaw('LOWER(nama_klasifikasi_directory) as nama') ->pluck('nama') ->toArray(); foreach ($namaKategori as $index => $nama) { $lowerNama = strtolower(trim($nama)); if(in_array($lowerNama, $exists)){ $validator->errors()->add("data.$index.nama_klasifikasi", "Nama '$nama' Sudah digunakan."); } } }); } }