SettingAdminController.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. /*
  4. * SettingAdminController — настройки сайта в административной панели.
  5. *
  6. * Маршруты: GET /admin/settings (форма), POST /admin/settings (сохранение)
  7. * Хранит: контакты, соцсети, копирайт, слоган, логотипы,
  8. * Яндекс.Метрика, Google Analytics, Open Graph.
  9. * Логотипы/OG-изображение загружаются как файлы, путь сохраняется в settings.
  10. * После сохранения сбрасывается кеш настроек.
  11. */
  12. use App\Http\Controllers\Controller;
  13. use App\Models\Setting;
  14. use Illuminate\Http\RedirectResponse;
  15. use Illuminate\Http\Request;
  16. use Illuminate\View\View;
  17. class SettingAdminController extends Controller
  18. {
  19. private const TEXT_KEYS = [
  20. // Контакты
  21. 'phone', 'email', 'working_hours',
  22. // Соцсети
  23. 'telegram', 'youtube', 'vk',
  24. // Подвал
  25. 'footer_slogan', 'copyright',
  26. // Аналитика
  27. 'yandex_metrika', 'google_analytics',
  28. // Open Graph
  29. 'og_site_name', 'og_description', 'og_locale',
  30. // Режим сайта (хранятся как '1'/'0')
  31. 'site_maintenance', 'site_noindex',
  32. ];
  33. private const LOGO_KEYS = ['logo_header', 'logo_footer'];
  34. public function index(): View
  35. {
  36. $settings = Setting::all();
  37. return view('admin.settings.index', compact('settings'));
  38. }
  39. public function update(Request $request): RedirectResponse
  40. {
  41. $request->validate([
  42. 'phone' => 'nullable|string|max:30',
  43. 'email' => 'nullable|email|max:100',
  44. 'telegram' => 'nullable|url|max:255',
  45. 'youtube' => 'nullable|url|max:255',
  46. 'vk' => 'nullable|url|max:255',
  47. 'footer_slogan' => 'nullable|string|max:255',
  48. 'copyright' => 'nullable|string|max:255',
  49. 'working_hours' => 'nullable|string|max:500',
  50. // Аналитика
  51. 'yandex_metrika' => 'nullable|digits_between:6,12',
  52. 'google_analytics' => 'nullable|string|max:30',
  53. // Open Graph
  54. 'og_site_name' => 'nullable|string|max:100',
  55. 'og_description' => 'nullable|string|max:300',
  56. 'og_locale' => 'nullable|string|max:10',
  57. // Режим сайта
  58. 'site_maintenance' => 'nullable|in:0,1',
  59. 'site_noindex' => 'nullable|in:0,1',
  60. // Файлы
  61. 'logo_header' => 'nullable|image|mimes:png,jpg,svg,webp|max:512',
  62. 'logo_footer' => 'nullable|image|mimes:png,jpg,svg,webp|max:512',
  63. 'og_image' => 'nullable|image|mimes:jpg,jpeg,png,webp|max:2048',
  64. ]);
  65. // Сохраняем текстовые поля
  66. foreach (self::TEXT_KEYS as $key) {
  67. Setting::set($key, $request->input($key));
  68. }
  69. // Загружаем логотипы — заменяем файл и сохраняем путь в settings
  70. foreach (self::LOGO_KEYS as $key) {
  71. if ($request->hasFile($key) && $request->file($key)->isValid()) {
  72. $ext = $request->file($key)->getClientOriginalExtension();
  73. $filename = $key.'.'.$ext;
  74. $request->file($key)->move(public_path('images/logos'), $filename);
  75. Setting::set($key, 'images/logos/'.$filename);
  76. }
  77. }
  78. // OG-изображение: 1200×630, сохраняется в public/images/og/
  79. if ($request->hasFile('og_image') && $request->file('og_image')->isValid()) {
  80. $ext = $request->file('og_image')->getClientOriginalExtension();
  81. $request->file('og_image')->move(public_path('images/og'), 'og_image.'.$ext);
  82. Setting::set('og_image', 'images/og/og_image.'.$ext);
  83. }
  84. return redirect()->route('admin.settings.index')
  85. ->with('success', 'Настройки сохранены.');
  86. }
  87. }