Files
3dealer/app/Http/Controllers/WishlistController.php
T

73 lines
2.2 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Catalog\ProductCard;
use App\Services\Wishlist;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\View\View;
use Lunar\Models\Product;
use Modules\Core\Catalog\Services\ProductService;
class WishlistController extends Controller
{
public function __construct(
private readonly Wishlist $wishlist,
) {}
/**
* The account's wishlist page.
*/
public function index(string $locale, ProductService $products): View
{
return view('account.wishlist', ['products' => $this->products($products)]);
}
/**
* The same list for a guest, from their cookie. Logged-in users are sent
* to the account version.
*/
public function guest(string $locale, ProductService $products): View|RedirectResponse
{
if (auth()->check()) {
return redirect()->route('account.wishlist');
}
return view('wishlist.guest', ['products' => $this->products($products)]);
}
/**
* Adds or removes a product, for guests and logged-in shoppers alike. The
* heart button's Stimulus controller asks for JSON; without JS the form
* posts normally and comes back to the same page.
*/
public function toggle(string $locale, Request $request, int $productId): JsonResponse|RedirectResponse
{
abort_unless(Product::whereKey($productId)->exists(), 404);
$active = $this->wishlist->toggle($productId);
if ($request->expectsJson()) {
return response()->json(['active' => $active]);
}
return back();
}
/**
* Product cards for the current wishlist, newest first. Products no longer
* in the search index (deleted, unpublished) are simply skipped.
*/
private function products(ProductService $products): Collection
{
return collect($this->wishlist->ids())
->map(fn (int $id) => $products->getById($id))
->filter()
->map(fn (array $product) => ['id' => $product['id'], ...ProductCard::fromIndexed($product)])
->values();
}
}