Wishlist
A wishlist is a list of products that is not meant to be ordered. Merx’ ProductList class gives you the same list of products as the cart, without the session handling and the checkout of Cart.
Cart extends ProductList. Both hold the same ListItem objects and share methods like total() and quantity(). The difference is that Cart stores itself in the visitor’s session and can be ordered, while ProductList leaves storage to you. That makes ProductList a good starting point for a wishlist, so let’s build one on it.
Create a list
<?php
use Wagnerwagner\Merx\ProductList;
return function () {
$wishlist = new ProductList();
return [
'wishlist' => $wishlist,
];
};
Add products
add() takes the id or the UUID of a product page, an array, or a ListItem object.
// id of a product page
$wishlist->add('products/nice-shoes');
// UUID of a product page
$wishlist->add('page://L1cJEiOOQI3VzljV');
// array, to keep your own data alongside the product
$wishlist->add([
'key' => 'nice-shoes',
'page' => 'products/nice-shoes',
'data' => [
'added' => date('c'),
],
]);
The identifier is key, the product page is page, and everything else you want to store on the item belongs in data. When you leave out key, Merx uses the page’s UUID.
Store the list
ProductList does not persist itself. Assuming you have no Kirby user accounts, the visitor’s session is the simplest place to keep the list. Store it the same way the cart does, with toSessionArray() per item.
<?php
use Wagnerwagner\Merx\ListItem;
use Wagnerwagner\Merx\ProductList;
function wishlist(): ProductList
{
$data = kirby()->session()->get('wishlist', []);
return new ProductList($data);
}
function saveWishlist(ProductList $wishlist): void
{
kirby()->session()->set(
'wishlist',
$wishlist->toArray(fn (ListItem $item) => $item->toSessionArray()),
);
}
Passing the stored array back into new ProductList() turns every entry into a ListItem object again. Only the page reference is stored, not the price, so prices are read from the product page again on every request. A product that got more expensive while it sat on the wishlist shows its current price.
Show the list
<?php /** @var \Wagnerwagner\Merx\ProductList $wishlist */ ?>
<ul>
<?php foreach ($wishlist as $item): ?>
<li>
<a href="<?= $item->page?->url() ?>"><?= $item->title ?></a>
<?= $item->price ?>
<?php if ($added = $item->data['added'] ?? null): ?>
<small>added <?= date('j M Y', strtotime($added)) ?></small>
<?php endif ?>
</li>
<?php endforeach ?>
</ul>
<p>Total: <?= $wishlist->total() ?></p>
Move the list into the cart
Because both classes hold the same items, moving a wishlist into the cart is a loop over add().
foreach (wishlist() as $item) {
$site->cart()->add($item);
}