generated from boboko/starter
73 lines
2.2 KiB
PHP
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();
|
|
}
|
|
}
|