zipcode) && str_contains($row->zipcode, '-')) { [$zip1, $zip2] = explode('-', $row->zipcode); } // 電話番号:数字以外を除去 → 2桁+4桁+4桁 に分割 if (!empty($row->tel_num)) { $tel = preg_replace('/\D/', '', $row->tel_num); // 数字以外を除去 $tel1 = substr($tel, 0, 2); $tel2 = substr($tel, 2, 4); $tel3 = substr($tel, 6, 4); } // FAX番号:同じく 2桁+4桁+4桁 if (!empty($row->fax_num)) { $fax = preg_replace('/\D/', '', $row->fax_num); $fax1 = substr($fax, 0, 2); $fax2 = substr($fax, 2, 4); $fax3 = substr($fax, 6, 4); } } return view('admin.invsettings._form', compact( 'row', 'zip1', 'zip2', 'tel1', 'tel2', 'tel3', 'fax1', 'fax2', 'fax3' )); } /** * 登録・更新処理 */ public function save(Request $request) { // ▼ バリデーションルール $rules = [ 't_number' => 'required|string|max:20', 't_name' => 'required|string|max:50', 'zip1' => 'required|digits:3', 'zip2' => 'required|digits:4', 'adrs' => 'required|string|max:100', 'bldg' => 'nullable|string|max:80', 'tel1' => 'nullable|digits_between:2,4', 'tel2' => 'nullable|digits_between:2,4', 'tel3' => 'nullable|digits_between:3,4', 'fax1' => 'nullable|digits_between:2,4', 'fax2' => 'nullable|digits_between:2,4', 'fax3' => 'nullable|digits_between:3,4', 'company_image_path' => 'nullable|string|max:255', ]; // ▼ カスタム日本語メッセージ $messages = [ 't_number.required' => '適格請求書発行事業者番号を入力してください。', 't_number.max' => '適格請求書発行事業者番号は20文字以内で入力してください。', 't_name.required' => '適格事業者名を入力してください。', 't_name.max' => '適格事業者名は50文字以内で入力してください。', 'zip1.required' => '郵便番号(前半)を入力してください。', 'zip1.digits' => '郵便番号(前半)は3桁で入力してください。', 'zip2.required' => '郵便番号(後半)を入力してください。', 'zip2.digits' => '郵便番号(後半)は4桁で入力してください。', 'adrs.required' => '表示住所を入力してください。', 'adrs.max' => '表示住所は100文字以内で入力してください。', 'tel1.digits_between' => '電話番号1は2桁から4桁で入力してください。', 'tel2.digits_between' => '電話番号2は2桁から4桁で入力してください。', 'tel3.digits_between' => '電話番号3は3桁から4桁で入力してください。', 'fax1.digits_between' => 'FAX番号1は2桁から4桁で入力してください。', 'fax2.digits_between' => 'FAX番号2は2桁から4桁で入力してください。', 'fax3.digits_between' => 'FAX番号3は3桁から4桁で入力してください。', ]; // ▼ バリデーション実行 $request->validate($rules, $messages); // ▼ データ整形 $zipcode = $request->zip1 . '-' . $request->zip2; $tel = implode('-', array_filter([$request->tel1, $request->tel2, $request->tel3])); $fax = implode('-', array_filter([$request->fax1, $request->fax2, $request->fax3])); // ▼ 既存レコードを取得(1レコード運用) $row = InvSetting::first(); // ▼ 画像パスを設定 $imagePath = $request->company_image_path; // ▼ フォームで新たにファイルを送信した場合のみ再保存(保険的処理) if ($request->hasFile('company_image')) { if ($imagePath && Storage::disk('public')->exists($imagePath)) { Storage::disk('public')->delete($imagePath); } $imagePath = $request->file('company_image')->store('inv', 'public'); } // ▼ レコードを新規作成 or 更新 if ($row) { $row->update([ 't_number' => $request->t_number, 't_name' => $request->t_name, 'zipcode' => $zipcode, 'adrs' => $request->adrs, 'bldg' => $request->bldg, 'tel_num' => $tel, 'fax_num' => $fax, 'company_image_path' => $imagePath, // ← hiddenの値 or 新規アップロード結果を保存 ]); } else { InvSetting::create([ 't_number' => $request->t_number, 't_name' => $request->t_name, 'zipcode' => $zipcode, 'adrs' => $request->adrs, 'bldg' => $request->bldg, 'tel_num' => $tel, 'fax_num' => $fax, 'company_image_path' => $imagePath, ]); } return back()->with('success', 'インボイス設定を登録しました。'); } /** * 社判画像アップロード(AJAX用) */ // public function upload(Request $request) // { // // ファイルがアップロードされているか確認 // if ($request->hasFile('company_image_file')) { // // 拡張子チェック & バリデーション // $request->validate([ // 'company_image_file' => 'required|image|mimes:png,jpg,jpeg|max:2048', // ], [ // 'company_image_file.image' => '画像ファイルを選択してください。', // 'company_image_file.mimes' => 'アップロード可能な形式は png, jpg, jpeg のみです。', // 'company_image_file.max' => 'ファイルサイズは2MB以下にしてください。', // ]); // // ファイル保存(public/storage/inv に格納) // $path = $request->file('company_image_file')->store('inv', 'public'); // // ファイル名を抽出 // $fileName = basename($path); // // JSONで返却(JSが受け取る) // return response()->json([ // 'file_name' => $fileName, // 'path' => $path, // ]); // } // // ファイル未選択時 // return response()->json([ // 'error' => 'ファイルが選択されていません。' // ], 400); // } public function upload(Request $request) { // ファイルがアップロードされているか確認 if ($request->hasFile('company_image_file')) { // 拡張子チェック & バリデーション $request->validate([ 'company_image_file' => 'required|image|mimes:png,jpg,jpeg|max:2048', ], [ 'company_image_file.image' => '画像ファイルを選択してください。', 'company_image_file.mimes' => 'アップロード可能な形式は png, jpg, jpeg のみです。', 'company_image_file.max' => 'ファイルサイズは2MB以下にしてください。', ]); // ファイルオブジェクト取得 $file = $request->file('company_image_file'); // 元のファイル名(例:company_logo.png) $originalName = $file->getClientOriginalName(); // 保存用に、ファイル名の重複を避けるためにユニーク名を生成(推奨) $fileName = $originalName; // public/storage/inv に保存 $path = $file->storeAs('inv', $fileName, 'public'); // JSONで返却(JS側で表示用ファイル名を使う) return response()->json([ 'file_name' => $originalName, // ユーザーが見えるファイル名 'stored_as' => $fileName, // 実際に保存されたファイル名 'path' => $path, ]); } // ファイル未選択時 return response()->json([ 'error' => 'ファイルが選択されていません。' ], 400); } }