Skip to content

Changelog

What changed in each release of Wishlist, in terms of what it means for you rather than which files moved.

1.5.0 — 3 October 2026

Most Wishlisted downloads as a spreadsheet. Download CSV, on the report's filter panel, gives every product matching the filters in that panel, not only the page on screen, in the order the table is sorted. Each row has the product's id, name, model, status, stock, price and special, how many shoppers have it saved (total, customers and guests) and how many customers are waiting for stock or watching the price. It names nobody, exactly as the screen does. Anyone who can open the report can download it. See the guide.

A "Your wishlist" box for your layouts. Placed in a column or content position in Design → Layouts, it shows each shopper their own most recent saves, guest or signed in, as your theme's own product cards, with a link to their whole list. It shows nothing to a shopper who has saved nothing, sets no cookie, and shows nowhere until you place it. One new setting, Saved Products Shown (4 unless you change it, 1 to 12), decides how many cards it shows, and does nothing until the box is placed. If you run a full-page cache, read limits and guarantees first.

An update takes the box off every layout. Removing the old version, the first step of every update from this one on, makes OpenCart delete each placement of it, and Wishlist keeps no copy. Place it again in Design → Layouts after updating. Saved Products Shown is kept like every other setting.

Fixes:

  • A product you add to a customer's list from the admin arrives with both alerts off. It used to arrive with no alert record at all. The next time the customer opened their wishlist, both alerts were switched on for it, and the sweep then emailed them about a product they never chose. The admin's add now records both alerts as off and leaves an existing record alone. The price it is measured from is the one the sweep compares against, special and tax included, so a customer who later ticks Price drops is not told about a drop that never happened.
  • A guest's saves are no longer lost to the nightly tidy-up. Products saved as a guest after a sign-in, or by a guest who never opened their list page, could be deleted by the next purge. Every save now keeps the guest's record and counts as a visit, so the retention window runs from the last time the guest looked at or added to their list.
  • An alert counts as sent only when it was. If the mail step could not be loaded at all, the sweep marked every alert it was about to send as sent, and nobody got them.
  • The command-line sweep mails customers on other languages properly. It sent them the bare text keys as a subject and an unsubscribe link with no words. It now falls back to English wherever no translation ships, as the web doors already did.
  • Names with & or quotes in them read correctly rather than as &: customers' and products' in alert emails, and products' in the Download CSV spreadsheet.
  • Your own wording no longer gains a layer of & on every save, and the shared list's heading and page title show it as you typed it. Choosing another language in the wording panel no longer lands you on the login page.
  • New addresses works. On 1.4.0 the button sent you to the login page, so the scheduled jobs' secret could not be replaced from the screen.
  • 1.4.0's notes were wrong about uninstalling. Removing the extension does not take the secret: an update is an uninstall and an install, and Wishlist puts its remembered copy back so your cron lines keep working. New addresses is the one way to stop the old ones.
  • On a multi-store install, saving another storefront's tab no longer freezes settings that belong to the whole installation (guest retention, the box's limit, the per-sweep cap, the API switch and the secret) at whatever they were that day. Installing or updating no longer writes those, or any defaults, onto any storefront but the default one either. What you saved for a storefront is kept.
  • The customer record's Wishlist tab, and the two personal-data screens, say when a change did not go through, for instance after your session expired, rather than doing nothing.
  • A weekly or monthly sweep comes due a calendar week or month after the last one, measured from that sweep as OpenCart's own scheduler measures. Before, the length depended on the day it was asked, so it could run a day or an hour off.
  • The guest cookie is now HttpOnly, so no script on the page can read it.
  • An API credential whose key has been emptied by hand is refused. OpenCart's form will not save one, but an edited database row could hold one, and it admitted a caller who presented no key.

Settings, data and API. One setting is new, Saved Products Shown. The module's own on/off value (module_wishlist_status) is now switched on for every storefront by the install, because it only decides whether OpenCart draws a placed box, and placing the box is the switch; it is still on no screen. No table or column changed. The API's routes and fields are exactly as they were.

1.4.0 — 21 September 2026

Both scheduled jobs have two doors of their own, and Wishlist now supports OpenCart 4.1.0.4. That release broke OpenCart's own scheduler inside core: every scheduled job on the store dies before any extension is reached, ours and everybody else's. On it the alert sweep and the guest purge never ran, and nothing said so. An extension cannot repair that fault, but it can go around it. There are now two web addresses you can have fetched from a host's cron panel or a cron service, and two commands you can run from crontab lines if your host gives you a shell:

php extension/wishlist/wishlist.php sweep
php extension/wishlist/wishlist.php purge

Run the sweep hourly and the purge once a day, which is exactly what the two scheduled jobs did. Both run the same work OpenCart's scheduler ran, so nothing about the alerts or the retention window changes, only what starts them. One way is enough; do not set up two. The lines to paste are in install, and the settings screen shows your store's own two addresses, with a button that gives you new ones if you ever need them.

Those addresses are guarded by a secret. One secret covers both of them. It is generated when the extension is installed, it is never shown on a form you can type into, and it survives an update with its value intact, so an address you pasted into a cron service a year ago keeps working across releases. Pressing New addresses stops the old ones immediately, which is why it asks you to confirm. Removing the extension takes the secret with the rest of its settings, so the addresses stop opening anything on a store that no longer has Wishlist; putting the extension back gives you new ones to paste. It is a different value from the key your unsubscribe links are signed with, which is never regenerated and has no button.

The settings screen says what your release has broken, and stops promising what it cannot deliver. On 4.1.0.4 it names the release, says neither scheduled job can fire on it, and points at the two doors that work. It no longer lists OpenCart's scheduler among your options as though it were one.

Removing a saved product works on 4.1.0.4. That release renamed a method inside OpenCart's own wishlist model, which Wishlist calls when a signed-in customer takes something off their list. On that release the Remove button answered with a PHP notice instead of doing anything. Wishlist now asks the store which name it has. This was found by running the full install-to-uninstall pass on that release for the first time. A release has to pass that before it is listed as tested.

1.3.0 — 21 September 2026

  • Wishlist now publishes what it holds about a person, column by column, with what removes each one. Every column of its five tables is on what this holds about a person. It holds less than any other extension that holds anything: no name, no address, no telephone number. A guest is a token in a cookie and nothing else.
  • The one cookie, wishlist_guest, set on a guest's first save and never on a browse, is published with its lifetime, which is your own guest retention setting in days. It is the only cookie any of our extensions sets, and the page is what you copy into your cookie notice.
  • Customers > Personal Data answers what Wishlist holds about one person and erases them from the same screen, alongside every other extension on the store that answers the same question. It takes an account's email address or a guest's own token, because a guest has no address to be found by.
  • Remove everything held about a person, linked from the settings screen, is new: the guests, what they saved, the share links and the alerts, all of it, without uninstalling.
  • Nothing changed about the erasure you already had. Deleting a customer in admin has always taken their alerts and their share link with them, on both OpenCart releases. The new screen runs the same act rather than a second one, so there is one answer to what goes when a customer goes.
  • Two new settings, both defaulting to what Wishlist already did. Sweep Runs lets the alert sweep act daily, weekly or monthly rather than every time the hourly job wakes it; Cooldown Per Product makes the 24 hours before the same product can mail the same person again something you can set, from one hour to fourteen days. See send alerts less often.
  • The alert switches are now saved per storefront. They were always read per store by the sweep, but the settings screen had no store picker and saved the default store's answer only. On a multi-store install it now has a Shopfront picker, and the two alert switches, the cooldown and the wording are kept for each storefront. The rest stay one answer for the whole installation, set on the default storefront.
  • Nothing about your data changes on upgrade, and no existing setting moved.

1.2.0 — 11 September 2026

Three sentences a shopper reads are now yours to write, one language at a time. The heading on a shared list page, the line an alert email opens with, and the wording on the unsubscribe link in its footer. They live together under Wording on the settings screen, behind a language picker: each language is saved on its own, and a box left empty uses Wishlist's own wording, shown in the box in grey so you can tell inherited from written.

Your existing shared list title is kept, and it is filed under your storefront's default language. That box used to have no language at all. The only page it appears on is a storefront page, so after the upgrade the heading is in the wording panel under your default language. Nothing else was moved or reworded. If your storefront runs in more than one language, the others read Wishlist's own heading until you write yours in them too. The Shared List Title field is gone from where it was; the same words are in the wording panel.

A guest wishlist now lasts as long as you have said to keep it, rather than a year. The cookie that tells a returning guest's browser apart was issued for a fixed 365 days, while Guest Wishlist Retention accepts anything from 1 to 3650. On a store that had raised that setting past a year the saved rows were kept and the cookie naming them was not, so a guest coming back after twelve months was shown an empty list while their products sat in the database. The cookie is now issued for whatever that setting says and re-issued on every visit, so the window closes only on a browser that has stopped coming back. If your retention is 365 days or less (it is, unless you raised it), nothing here is different for you. Browsers cap a cookie at around 400 days on their own, and no store can lift that ceiling.

Nothing else a shopper touches changed. The wishlist itself, the sign-in merge, the share link, Add all to cart, the alerts, the sweep, the unsubscribe, the API and Most Wishlisted all behave exactly as they did in 1.1.0.

Wishlist also gains the machinery for serving a translation of its own strings once one exists: it now works out which of the languages it ships your store should be served, rather than assuming your language code is spelled the way our directories are. It ships English and only English, so with one language shipped that question has one answer and a single-language store is shown nothing extra. Alert emails are still written in the language on the customer's own record, which is what that machinery had to be careful not to take away. See Limits and guarantees.

1.1.0 — 9 September 2026

Nothing in the storefront changed. The wishlist itself, the guest cookie, the sign-in merge, the share link, Add all to cart, the alert emails, the sweep, the unsubscribe and Most Wishlisted all behave exactly as they did in 1.0.0. This release adds one thing beside them and changes nothing that was already there.

Wishlist now answers a JSON API, for a system that keeps your own records (an ERP, a merchandising tool, a buying spreadsheet somebody automated) rather than for a browser. It answers two questions:

  • Who asked to hear about a product. One alert at a time, or the whole list walked page by page, filtered by product, by customer, by store, by which of the two alerts they wanted, or by when they asked. Each row carries the price and stock figures the alert is measured against.
  • What is saved and not bought. How many people have a product on a list right now, split into those with an account and those without. These are the same two figures Most Wishlisted shows, for a system rather than a person. It is the only thing the API says about guest lists, and it is deliberately all it says.

It is off until you switch it on, and while it is off every route answers as though the extension had no API at all. The switch is in a new API section on the settings screen, beside the base address, the versions being answered, a link to System → Users → API and a warning if there is no credential that could call it yet.

That switch is deliberately independent of the module's own status. You can switch Wishlist off in the storefront and the API keeps answering. What your shoppers have saved is your own record, and a storefront switch should not hide it from the system that holds your data.

Before you hand the address to anybody, note four things:

  • The API only ever reads. Nothing can add a product to somebody's list, switch an alert on, or unsubscribe them. Those are the shopper's acts, done on their own page.
  • No guest list and no share link is readable through it, and none ever will be. A guest list is keyed on a random token handed to that shopper in a URL, and holding the token is permission to read and share the list, so publishing one would be publishing a key, not a name. Nothing identifying is stored about a guest to publish instead. The demand figures are the aggregate over those same lists, and they name nobody.
  • The credential is OpenCart's own API user, and it is not scoped to this extension. One is enough to read every extension's API on the store and core's own order API besides, across every storefront in the installation. Restrict it by IP address under System → Users → API, and treat it the way you would treat an admin login.
  • Deleting is the only erasure signal. Deleting a customer deletes their alert rows, unsubscribing deletes them, and a shopper removing the product deletes the one. Nothing is left behind to read. If you have synchronised alerts into your own system, reconcile against the full list rather than waiting for a deletion notice that is never coming.

One column was added to the alerts table, and it is the only database change in this release: an id of its own, so a page of the API can pick up exactly where the last one stopped. It is added in place on upgrade, and no row is touched.

The API's own page is the API, and it is generated from what the extension actually answers rather than written beside it.

Everything each version promises stays answerable for at least twenty-four months after a replacement ships. See the API promise.

1.0.0 — 4 September 2026

The first public release. There is no previous version, so nothing below is a change; this entry is the baseline every later one is measured against.

What ships: a wishlist that works for shoppers with no account and survives the browser closing, merged into their account the moment they sign in; a share link per list, showing the saved products and nothing at all about the owner, revoked the moment it is replaced; Add all to cart, from the shopper's own list and from a shared one, naming line by line whatever could not go in and why; price-drop and back-in-stock emails for logged-in customers, switched on by saving a product and narrowed or switched off only from the shopper's own page, never from the admin; a one-click unsubscribe that works with no session and stays off afterwards; Reports → Most Wishlisted, a row per saved product split into customers and guests, with how many are waiting on stock and how many are watching the price; and a Wishlist tab on the customer record, which shows what one customer asked to hear about and cannot switch it on. Your theme is untouched: no template to edit and no core file changed. What it does not do is the shorter list, and the one worth reading first.

It runs on OpenCart 4.0.2.0 through 4.1.0.3 (all eight releases) and refuses to install below 4.0.2.0 rather than half-working there. On 4.1.0.4 it warns and installs anyway: that release cannot run any scheduled task at all, for any extension on the store, so the alert sweep and the nightly guest purge never fire while everything a shopper touches carries on working. See requirements and install.

What an update keeps

  • No wishlist, share link or alert subscription is lost. Nothing this extension does drops a table.
  • Share links and unsubscribe links keep working, because neither the share tokens nor the key the unsubscribe links are signed with is regenerated.
  • Both scheduled jobs are re-created enabled, so one you had switched off in Extensions → Cron Jobs comes back on.
  • The Wishlist box comes off every layout, so place it again in Design → Layouts. How many products it shows is kept.
  • Edited language files and templates are overwritten, exactly as an edited OpenCart language file is. Keep a copy of anything you change.

Your settings come back, with the exceptions below. An update is an uninstall and then an install, and OpenCart deletes an extension's settings at the uninstall step. Wishlist keeps its own copy of them and puts them back afterwards. They are one set for the whole installation rather than one per store, apart from module_wishlist_status, module_wishlist_price_alert, module_wishlist_stock_alert, module_wishlist_copy and module_wishlist_alert_cooldown, which each store keeps its own of.

These are asked for again rather than put back:

  • module_wishlist_status — Nothing to keep: every install switches it on again for every store, and no screen offers a control for it. Placing the "Your wishlist" box in Design > Layouts is the switch, and an update takes those placements off.
  • module_wishlist_diary_verbose_until — Detailed logging comes back off after an update, the way a fresh install does. An upgrade is an uninstall and a reinstall, and putting a diagnostic window back is how a store ends up verbose months after the support exchange that asked for it ended.

A setting a release adds does not change what your store does. Its default is what Wishlist did before the setting existed, so an update never asks you to go and set something to get back the behaviour you already had.

What this cannot tell you is whether a release changed how a setting behaves, as against whether it survives. Nothing derives that from the code, so it is written by hand: a release that changes an answer you relied on says so in its own entry above, as its own paragraph and never among what is new.