CarPhotosSeeder.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <?php
  2. namespace Database\Seeders;
  3. /*
  4. * CarPhotosSeeder — скачивает демо-фотографии с Unsplash и присваивает их автомобилям.
  5. * Фото подбираются по типу кузова. Удалить можно через php artisan db:seed --class=CarPhotosSeeder reset.
  6. */
  7. use App\Models\Car;
  8. use Illuminate\Database\Seeder;
  9. use Illuminate\Support\Facades\Http;
  10. use Illuminate\Support\Facades\Storage;
  11. class CarPhotosSeeder extends Seeder
  12. {
  13. // Unsplash-фото по типу кузова — несколько штук для ротации
  14. private const PHOTOS = [
  15. 'suv' => [
  16. 'https://images.unsplash.com/photo-1617469767269-f80a3e3f13dc?w=900&q=80',
  17. 'https://images.unsplash.com/photo-1555215695-3004980ad54e?w=900&q=80',
  18. 'https://images.unsplash.com/photo-1568605117036-5fe5e7bab0b7?w=900&q=80',
  19. 'https://images.unsplash.com/photo-1617654112329-a50e7f47e065?w=900&q=80',
  20. 'https://images.unsplash.com/photo-1533473359331-0135ef1b58bf?w=900&q=80',
  21. ],
  22. 'sedan' => [
  23. 'https://images.unsplash.com/photo-1621007947382-bb3c3994e3fb?w=900&q=80',
  24. 'https://images.unsplash.com/photo-1618843479313-40f8afb4b4d8?w=900&q=80',
  25. 'https://images.unsplash.com/photo-1609752740145-6ac4be2c3947?w=900&q=80',
  26. 'https://images.unsplash.com/photo-1492144534655-ae79c964c9d7?w=900&q=80',
  27. ],
  28. 'hatchback' => [
  29. 'https://images.unsplash.com/photo-1541899481282-d53bffe3c35d?w=900&q=80',
  30. 'https://images.unsplash.com/photo-1606664515524-ed2f786a0bd6?w=900&q=80',
  31. ],
  32. 'wagon' => [
  33. 'https://images.unsplash.com/photo-1544636331-e26879cd4d9b?w=900&q=80',
  34. 'https://images.unsplash.com/photo-1549317661-bd32c8ce0db2?w=900&q=80',
  35. ],
  36. 'van' => [
  37. 'https://images.unsplash.com/photo-1519641471654-76ce0107ad1b?w=900&q=80',
  38. ],
  39. 'pickup' => [
  40. 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=900&q=80',
  41. ],
  42. 'minivan' => [
  43. 'https://images.unsplash.com/photo-1449965408869-eaa3f722e40d?w=900&q=80',
  44. ],
  45. 'default' => [
  46. 'https://images.unsplash.com/photo-1494976388531-d1058494cdd8?w=900&q=80',
  47. 'https://images.unsplash.com/photo-1533473359331-0135ef1b58bf?w=900&q=80',
  48. ],
  49. ];
  50. public function run(): void
  51. {
  52. $dir = 'cars/demo';
  53. Storage::disk('public')->makeDirectory($dir);
  54. // Скачиваем все уникальные URL один раз
  55. $urlToFile = $this->downloadAll($dir);
  56. // Счётчик ротации по каждому типу кузова
  57. $counters = [];
  58. $cars = Car::all();
  59. $updated = 0;
  60. foreach ($cars as $car) {
  61. $type = $car->body_type ?? 'default';
  62. $pool = self::PHOTOS[$type] ?? self::PHOTOS['default'];
  63. $idx = ($counters[$type] ?? 0) % count($pool);
  64. $url = $pool[$idx];
  65. $counters[$type] = $idx + 1;
  66. if (!isset($urlToFile[$url])) continue;
  67. $car->update(['photo_main' => $urlToFile[$url]]);
  68. $updated++;
  69. }
  70. $this->command->info("Фото присвоены {$updated} автомобилям.");
  71. }
  72. private function downloadAll(string $dir): array
  73. {
  74. $urlToFile = [];
  75. // Собираем все уникальные URL
  76. $allUrls = array_unique(array_merge(...array_values(self::PHOTOS)));
  77. foreach ($allUrls as $url) {
  78. $hash = md5($url);
  79. $filename = $dir . '/' . $hash . '.jpg';
  80. // Не качаем повторно если файл уже есть
  81. if (Storage::disk('public')->exists($filename)) {
  82. $this->command->line(" [skip] {$hash}.jpg");
  83. $urlToFile[$url] = $filename;
  84. continue;
  85. }
  86. $this->command->line(" [download] {$hash}.jpg ...");
  87. try {
  88. $response = Http::timeout(30)->get($url);
  89. if ($response->successful()) {
  90. Storage::disk('public')->put($filename, $response->body());
  91. $urlToFile[$url] = $filename;
  92. $this->command->line(" ✓ OK (" . round(strlen($response->body()) / 1024) . " KB)");
  93. } else {
  94. $this->command->warn(" ✗ HTTP " . $response->status());
  95. }
  96. } catch (\Exception $e) {
  97. $this->command->warn(" ✗ " . $e->getMessage());
  98. }
  99. }
  100. return $urlToFile;
  101. }
  102. }