getAllVariants(); if (empty($variants)) { $this->error('Keine Daten von Shopify erhalten (Details im Log).'); return self::FAILURE; } // Deduplizieren: pro Produkttitel nur einmal $products = collect($variants) ->filter(fn($v) => ! empty($v['image_urls'])) ->keyBy('product_title'); $this->info("Produkte mit Bildern in Shopify: {$products->count()}"); $downloaded = 0; $skipped = 0; foreach ($products as $title => $variant) { $product = Product::where('title', $title)->first(); if (! $product) { continue; } if (! empty($product->images) && ! $this->option('force')) { $skipped++; continue; } $paths = []; foreach ($variant['image_urls'] as $url) { $response = Http::get($url); if ($response->failed()) { $this->warn(" Bild konnte nicht geladen werden: {$url}"); continue; } $ext = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'jpg'; $filename = 'product-images/' . Str::uuid() . '.' . $ext; Storage::disk('public')->put($filename, $response->body()); $paths[] = $filename; } if (! empty($paths)) { $product->update(['images' => $paths]); $this->line(" ✓ {$title} (" . count($paths) . " Bild(er))"); $downloaded++; } } $this->info("✓ {$downloaded} Produkte mit Bildern versorgt"); if ($skipped) { $this->line(" {$skipped} übersprungen (haben bereits Bilder — nutze --force zum Überschreiben)"); } return self::SUCCESS; } }