Appearance
Wishlist
Flow ID: CF-17 | Module(s): eshop, Product domain | Complexity: Low
Business Overview
Logged-in customers save products for future purchase. Items added/removed via AJAX or REST, with automatic sync to Advisable AI bookmarks and Facebook Conversion API for retargeting.
What customers experience:
- Click a heart icon on any product listing or detail page to save it
- View saved products on
/customer/wishlist(paginated, 36 per page) - Remove individual items or clear the entire wishlist
- Toggle add/remove via AJAX with instant UI feedback (icon swap, toast notification)
Key business behaviors:
- Requires login (redirects to homepage if not authenticated)
- One entry per customer-product pair (duplicates silently ignored)
- Syncs with AI bookmarks on add/remove (deferred task)
- Facebook
AddToWishlistevent fired server-side on add via Meta Conversions API - Google GA4
add_to_wishlistevent fired client-side viaecomnTag - Paginated display (36 per page) with product code parsing
- Loyalty points calculated on wishlist page via
calcLoyalty()hook
API Reference
REST Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /rest/product/wishlist | Customer JWT | List wishlist items (filterable by id, customerId, productId) |
| GET | /rest/product/wishlist/{id} | Customer JWT | Get single wishlist entry |
| GET | /rest/product/wishlist/item | Customer JWT | Get entry by filter |
| POST | /rest/product/wishlist | Customer JWT | Add product (customer ID from JWT) |
| POST | /rest/product/wishlist/{id} | Customer JWT | Update entry |
| DELETE | /rest/product/wishlist/{id} | Customer JWT | Remove (verifies ownership via resourceContext->getUserId()) |
Filters: id, customerId, productId Sorts: id, customerId, productId Relations: customer, product
Legacy AJAX
| Method | Path | Description |
|---|---|---|
| POST (AJAX) | /customer/wishlistAction/add/{productId} | Add product — fires Facebook CAPI + AI bookmark |
| POST (AJAX) | /customer/wishlistAction/remove/{productId} | Remove product — removes AI bookmark |
| GET/POST | /customer/wishlist_add/{productId} | Add product (older endpoint) |
| GET/POST | /customer/wishlist_remove/{productId} | Remove product (older endpoint) |
| GET/POST | /customer/wishlist_remove_all | Clear entire wishlist |
Storefront Pages
| URL | Description |
|---|---|
/customer/wishlist/{offset} | Paginated wishlist display (36/page) |
Code Flow
Step 1: Add to Wishlist (AJAX via wishlistAction)
File: ecommercen/eshop/controllers/Adv_customer.php (line ~1131)
- Guard: Must be AJAX request with valid session (
customer_id) - Duplicate check:
getCustomerProductIds($customerId)— skip if already in list - Insert:
wishlist_model->add_record({customer_id, product_id}) - Facebook CAPI:
reportWishlistFacebookConversion($productId, 1)— deferred task - AI bookmark:
bookmarkToAdvisableAI($productId)— deferred task - Response: JSON
{status: 'success'}
Step 2: Facebook Conversion API Event
File: ecommercen/eshop/controllers/Adv_customer.php (line ~1163)
- Guard: Check
FACEBOOK_CONVERSION.ENABLEDregistry setting - Product data: Fetch product name and calculated final price from
product_model - Customer data: Fetch from
customer_modelby session ID - Build payload:
content_ids(with tracking prefix),content_name,content_type=product,currency,value - Dispatch: Deferred task via
FacebookConversionService->dispatchEvent(EventType::ADD_TO_WISHLIST, ...)
Step 3: Remove from Wishlist
File: ecommercen/eshop/controllers/Adv_customer.php (line ~1081)
- Delete:
wishlist_model->remove($customerId, $productId) - AI unbookmark:
removeBookmarkFromAdvisableAI($productId)— deferred task - Response:
OK(text) or JSON depending on endpoint used
Step 4: Display Wishlist Page
File: ecommercen/eshop/controllers/Adv_customer.php (line ~955)
- Auth check: Redirect to homepage if no
customer_idin session - Fetch products:
wishlist_model->get_products_with_paths($customerId, 36, $offset)— joins with product model for full product data - Count:
countProductsWithPaths({customer_id})for pagination - Hook:
wishListExtra()— callscalcLoyalty()by default - Render: Product grid with pagination, product code parsing
Step 5: Client-Side Behavior
File: assets/main/js/components/wishlist-actions.js
- Click handler:
.wishlist_actionelements withdata-action,data-product_id,data-view_form - AJAX POST: To
/customer/wishlistAction/{action}/{productId}with optional AI recommendation ID - GA4 event: On add, fires
ecomnTag.add_to_wishlist_GA4()with product data from Vue state - UI toggle: Swaps action data attribute, changes icon (heart/heart-broken), shows toast notification
Domain Layer
| Component | Path |
|---|---|
| REST Controller | src/Rest/Product/Controllers/Wishlist.php |
| Service | src/Domains/Product/Wishlist/Service.php |
| WriteService | src/Domains/Product/Wishlist/WriteService.php |
| Validator | src/Domains/Product/Wishlist/Validator.php |
| WriteData | src/Domains/Product/Wishlist/WriteData.php |
| Entity | src/Domains/Product/Wishlist/Repository/Entity.php |
| Repository | src/Domains/Product/Wishlist/Repository/Repository.php |
| WriteRepository | src/Domains/Product/Wishlist/Repository/WriteRepository.php |
| Legacy Model | ecommercen/eshop/models/Adv_wishlist_model.php |
| JS Component | assets/main/js/components/wishlist-actions.js |
Dual path: Legacy AJAX for storefront + REST for headless/admin.
Data Model
wishlist
| Column | Type | Description |
|---|---|---|
id | int (PK, AI) | Wishlist entry ID |
customer_id | int (FK) | Customer who saved the product |
product_id | int (FK) | Saved product reference |
No timestamps on this table.
Client Extension Points
wishListExtra()hook: Override to add loyalty, upsell data (default callscalcLoyalty())- Facebook tracking: Override
reportWishlistFacebookConversion()for custom event data - AI sync: Override
bookmarkToAdvisableAI()/removeBookmarkFromAdvisableAI()methods - GA4 tracking: Client-side via
ecomnTag.add_to_wishlist_GA4()inwishlist-actions.js - View:
{client_views}/customer/wishlist/— templates for wishlist page - REST ownership:
destroy()in Wishlist controller verifiescustomer_idmatches JWT user
Related Flows
- CF-02 Product Detail — wishlist button on PDP
- CF-01 Product Browsing — wishlist button on product listings
- CF-10 Customer Auth — requires login to use wishlist
- CF-11 Customer Account — wishlist page in customer account
- CF-34 AI Recommendations — syncs with AI bookmarks on add/remove
- IN-07 Facebook Catalog & CAPI —
AddToWishlistserver event via Meta Conversions API - SY-27 Deferred Task Runner — Facebook CAPI and AI bookmark events dispatched as deferred tasks