=== Vinceweb Shopping Lists ===
Contributors: vincewebdesign
Tags: shopping list, grocery list, checklist, family, shopping
Requires at least: 6.4
Tested up to: 7.1
Stable tag: 2.0.2
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Create private PIN-protected shopping lists with saved prices, quantities, store locations, shopping mode, totals, and printing.

== Description ==

Vinceweb Shopping Lists provides simple shared-device shopping lists without requiring every person to have a WordPress account.

Create separate lists for different people, protect each list with an optional PIN, and let shoppers plan and complete a trip from a phone, tablet, or desktop.

Features include:

* Multiple separate shopping-list profiles.
* Optional PIN access without a WordPress login.
* Persistent products that remain available for future trips.
* Saved price and quantity for estimating the next shop.
* Editable store-location buttons such as Fruit & Veg, Grocery, Bakery, Chilled, and Frozen.
* Custom ordering of store locations to match the route through a shop.
* Shopping mode with an "In basket" action.
* Per-shop basket, remaining, and estimated totals.
* Product and price editing while shopping.
* Catalogue-first product picker while shopping, with duplicate protection.
* Shop-specific normal and sale prices with persistent sale information.
* Shopping history, 12-month insights, and CSV export.
* Print only the items currently selected.
* Administrator-only profile and store-location management.
* Products are not deleted when an item is placed in the basket.
* No external services, tracking, advertising, or remote APIs.

Use the shortcode:

`[vinceweb_shopping_list]`

For existing installations, the previous `[my_shopping_list]` and `[mothers_shopping_list]` shortcodes remain supported as compatibility aliases.

== Installation ==

1. Upload the `vinceweb-shopping-lists` folder to `/wp-content/plugins/`, or install the ZIP through **Plugins > Add New > Upload Plugin**.
2. Activate **Vinceweb Shopping Lists**.
3. Add `[vinceweb_shopping_list]` to a WordPress page.
4. Go to **Shopping List > Shopping Locations**.
5. Create or rename the people who need their own shopping lists and optionally assign PINs.
6. Configure the store-location buttons in the order you normally walk through the shop.
7. Share the shopping-list page with the people who need it.

When upgrading from an earlier release, existing shopping products are assigned to the default **Mum** profile.

== Frequently Asked Questions ==

= Does someone need a WordPress account to use a list? =

No. A visitor can choose a shopping-list profile and enter its PIN. The plugin remembers the selected profile on that device using secure HTTP-only cookies.

= Is a PIN required? =

No. Administrators can leave a profile PIN blank. A PIN is recommended when the shopping-list page is reachable by people who should not be able to edit the list.

= Can each person have a separate list? =

Yes. Products, prices, quantities, selections, and shopping state are separated by profile.

= Can the store sections be changed? =

Yes. Administrators can edit and reorder the shared store-location buttons under **Shopping List > Shopping Locations**.

= What happens when I tap "In basket"? =

The item disappears from the active shopping screen but the product, price, quantity, and location remain stored for future trips.

= Does uninstalling delete my shopping data? =

No. Shopping data and settings are intentionally preserved to reduce the risk of accidental data loss. The plugin role and administrator capability are removed on uninstall.

= Does the plugin send data anywhere? =

No. The plugin does not use external APIs, analytics, advertising, or third-party services.

== Privacy ==

The plugin stores shopping-list profile names, hashed PINs, product names, quantities, prices, store locations, selection state, and shopping state in the local WordPress database.

When a profile is opened, the plugin sets HTTP-only cookies that remember the profile for up to 180 days. The cookies contain a profile identifier and a site-specific authentication token. PINs are stored as WordPress password hashes and are not stored in plain text.

To reduce repeated PIN guessing, failed PIN attempts are temporarily rate-limited using a short-lived transient keyed from a one-way hash of the connecting IP address.

No shopping-list information is transmitted to external services by this plugin.

== Changelog ==

= 2.0.2 =
* Renamed the public plugin to Vinceweb Shopping Lists and prepared the vinceweb-shopping-lists slug.
* Added the [vinceweb_shopping_list] shortcode while retaining previous shortcodes as compatibility aliases.
* Prefixed custom post type identifiers and added migration for existing installations.
* Moved print CSS into an enqueued static stylesheet.
* Clarified shortcode and installation documentation for WordPress.org review.

= 2.0.1 =
* Added the required translator comment for the per-shop totals string.
* Documented the intentional php://output stream close for WordPress Coding Standards.
* Retained the existing meta-query implementation; Plugin Check reports it as a performance warning rather than an error.

= 2.0.0 =
* Rebranded the public plugin name to My Shopping List.
* Added the [my_shopping_list] shortcode while retaining the original shortcode for compatibility.
* Added shop-specific normal and sale pricing with persistent sale information.
* Replaced combined trip totals with individual shop totals.
* Added catalogue-first product entry and duplicate protection.
* Added brand, size/unit, notes, and favourite/regular product fields.
* Added immutable completed-shop history for price and spend tracking.
* Added a 12-month Insights dashboard with shop spend, sale savings, and product price ranges.
* Added CSV shopping-history export.
* Preserved existing profiles, products, shops, locations, prices, cookies, and internal identifiers during upgrade.



= 1.8.3 =
* Restored the Shopping List submenus under one top-level Shopping List menu.
* Lists & People, Shops, Shopping Locations and Shopping Items are all grouped under Shopping List.
* Shopping Items no longer appears as a separate top-level menu.

= 1.8.2 =
* Moved the Shopping Items custom post type under the main Shopping List admin menu.
* Shopping Items no longer appears as a separate top-level WordPress admin menu.

= 1.8.1 =
* Consolidated all Shopping List administration into the single top-level Shopping List page.
* Removed the Lists & People, Shops and Shopping Locations submenu entries.
* Shop and location saves now return to the main Shopping List admin page.

= 1.8.0 =
* Added configurable shops above locations and aisles.
* Products can be assigned to a shop with tap-friendly buttons.
* Shopping and print lists are grouped by shop, then location/aisle.
* Added Shopping List > Shops in wp-admin.
* Existing products appear under Any shop until assigned.

= 1.7.4 =
* Fixed a fatal AJAX error in the Not in stock action caused by a call to a non-existent profile-validation method.
* Not in stock now uses the same validated item lookup as the other shopping actions.

= 1.7.3 =
* Fixed Not in stock so it correctly removes the item from the active shopping trip.
* The saved product, price, quantity, aisle and location remain available for future trips.

= 1.7.2 =
* Added a Not in stock button in shopping mode.
* Not in stock removes the item from the current trip while preserving its saved product details for future trips.

= 1.7.1 =
* Resolved WordPress Plugin Check internationalization, input sanitization, nonce-analysis, translation loading, uninstall naming, and readme warnings.

= 1.7.0 =
* Added translator comments for all translatable strings containing placeholders, resolving WordPress Plugin Check i18n errors.

= 1.6.9 =
* Added WordPress.org contributor username `vincewebdesign`.
* Prepared release metadata for WordPress.org submission testing.
* No functional changes from 1.6.8.

= 1.6.8 =
* Made named locations and aisle numbers fully independent.
* Products can now use only an aisle number, only a named location, both, or neither.
* Named locations are grouped first, standalone aisles follow numerically, and unassigned items appear last.

= 1.6.7 =
* Restored optional aisle numbers alongside named shopping locations.
* Products can have both a named location and an aisle number.
* Items are sorted by aisle number within each named location.
* Aisle numbers appear in planning, shopping mode, and print output.

= 1.6.6 =
* Fixed profile switching on sites using page caching or host-level caching.
* Shopping-list pages now send no-cache headers and define `DONOTCACHEPAGE` while rendering.
* Profile login and Switch List now use cache-busting redirects so the newly selected person's name/list is rendered immediately.

= 1.6.5 =
* Added a dedicated Shopping List menu in wp-admin.
* Moved Shopping Locations under Shopping List > Shopping Locations.
* Added Lists & People under the same Shopping List menu.
* Updated admin redirects and documentation to use the new menu location.

= 1.6.4 =
* Fixed a critical runtime fatal error caused by registering a private migration method as a WordPress `init` callback.
* Audited all registered WordPress callbacks to ensure they are public.
* Keeps the minimal safe activation flow from 1.6.3.

= 1.6.3 =
* Removed legacy-plugin deactivation from the activation hook.
* Removed all data migration work from the activation request.
* Activation now only creates the plugin role/capability.
* Added a safe legacy-build detector that shows an admin notice instead of booting two incompatible development builds together.
* Uses unique transition-release PHP identifiers.

= 1.6.2 =
* Fixed activation conflicts when older development copies of the plugin are still active.
* Uses unique internal PHP identifiers for the transition release.
* Automatically deactivates the known legacy `shipping-list` and `mothers-shopping-list-v2` copies during activation.
* Preserves all existing shopping-list data and settings.

= 1.6.1 =
* Fixed profile switching so lists without a PIN open immediately.
* Prevented PIN entry from being treated as a browser password/passkey field, avoiding unwanted fingerprint prompts.
* Improved Switch List so it clears shopping/profile query state consistently.
* Added clearer selected-profile feedback while opening a list.

= 1.6.0 =
* Prepared the plugin package and metadata for WordPress.org submission.
* Fixed PIN-authenticated AJAX actions for visitors who are not logged in to WordPress.
* Fixed printing for PIN-authenticated visitors.
* Added HTTP-only SameSite profile cookies.
* Added PIN attempt throttling.
* Preserved stable internal profile IDs when profile display names are changed.
* Added WordPress privacy-policy suggested text.
* Standardized the plugin directory slug to `mothers-shopping-list`.
* Added uninstall behavior that preserves shopping data while removing plugin roles and capabilities.
* Updated directory readme metadata and documentation.

= 1.5.0 =
* Added multiple personal shopping lists.
* Added PIN-based access without requiring a WordPress login.
* Added profile switching.
* Migrated existing products to Mum's list.

= 1.4.0 =
* Added administrator-editable store-location buttons.
* Added configurable location order.

= 1.3.0 =
* Added saved prices and quantities.
* Added estimated totals and Shopping Mode.
* Added In basket and Finish Shopping actions.

= 1.2.2 =
* Made product rows and Edit controls more compact.

= 1.2.1 =
* Changed printing to use the boxes visibly selected on screen.

== Upgrade Notice ==

= 1.7.1 =
Recommended WordPress.org submission candidate. Resolves Plugin Check errors and warnings reported against 1.7.0.

== Screenshots ==

1. Insights – view shopping history, spending information, sale savings, and product price insights.
2. Shopping List – manage your reusable shopping list, products, quantities, prices, and shopping selections.
3. Shopping Now – use the mobile-friendly shopping mode to mark items as in the basket or not in stock while you shop.
4. Shops and Aisle Locations – organise products by shop, shopping location, and aisle to make shopping easier.
