=== Yindle Share Cart ===
Contributors: yindle
Tags: woocommerce, cart, share cart, share link, cart sharing
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 8.1
Requires Plugins: woocommerce
Stable tag: 1.0.2
License: GPL-2.0+
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Share WooCommerce carts with secure, expiring links. Recipients preview current prices and stock before choosing to replace or merge their cart.

== Description ==

Yindle Share Cart adds a **Share Cart** button to the WooCommerce cart. It
creates a link that carries only the products, variations and quantities that
were in the cart — never prices, coupons, customer details or session data.

Opening the link shows a preview built from the shop's **current** catalogue:
today's prices, today's stock, today's purchase rules. Nothing is added to the
recipient's cart until they choose **Replace my current cart** or **Merge with
my current cart** and submit the form.

All free features listed below are included and enabled. There is no paid usage
quota, expiring trial, telemetry, Yindle account requirement or forced credit
link on your storefront. Short rate limits protect the public sharing endpoint
from abuse; they do not require payment to reset.

= What it does =

* **Share Cart button** on the classic cart and the WooCommerce Cart Block.
* **Capability links.** The public link is a 64-character random capability.
  Only a purpose-separated HMAC-SHA-256 hash of it is ever stored, so a database
  copy does not hand anyone a working link.
* **Current-price preview.** Prices and availability come from live product
  objects at the moment the link is opened, not from the snapshot.
* **Deliberate replace or merge.** A GET request only ever renders the preview.
  Importing needs a WordPress nonce, an explicit mode choice and a signed
  single-use intent.
* **Guest revocation.** Creating a link also hands the sender a separate
  management capability. It can revoke the link but cannot read the cart, and
  the read capability cannot revoke anything.
* **Expiry.** 1–365 days, 30 by default, rechecked in the database on every
  request rather than relying on a cron run.
* **Atomic import.** The whole plan is validated before the cart is touched. A
  failure restores the previous cart, its coupons and its session data.
* **Stock and purchase rules.** Product existence, published state, variation
  ownership, purchasability, sold-individually, maximum quantity and combined
  merge quantities are all revalidated at import time.
* **Privacy.** Registered with WordPress's personal-data eraser, and user
  deletion removes the matching rows.
* **Classic and Blocks.** One server-side service behind both cart renderers.

= Separate Pro plugin =

Share Cart Pro by Yindle is a separate plugin available from Yindle, with named
saved carts, account management and printing. These implementations are not
included or locked inside this directory package. Existing published links and
shared data remain readable when switching editions.

= Moving from Share Cart by Yindle 1.0.1 =

The directory name is now Yindle Share Cart and its folder is `yindle-share-cart`.
This is a manual replacement: the older `share-cart-by-yindle` installation
cannot receive an automatic update across the folder change.

1. Back up your database and plugin files.
2. In WooCommerce settings, turn off **Delete data on uninstall** before
   removing the old installation. Keep it off when removing an older Pro
   installation too; older uninstall scripts do not recognize this new folder.
3. Install and activate Yindle Share Cart. If both Free copies are active, this
   directory version handles sharing and the old copy stands by. Pro takes
   precedence when it is active.
4. Verify your existing share links and settings, then deactivate the old copy.
   Delete it only after confirming deletion is disabled. Keeping it inactive is
   also safe. Do not reset capability secrets or remove shared database tables.

When this new plugin is active it protects shared data during companion
uninstallation without changing the saved deletion preference. That protection
cannot run while it is inactive. Deactivation always preserves data.

== Installation ==

1. Upload the plugin folder to `/wp-content/plugins/`, or install the ZIP under
   **Plugins → Add New → Upload Plugin**.
2. Install and activate WooCommerce 8.0 or later, then activate this plugin.
3. Configure it under **WooCommerce → Settings → Yindle Share Cart**.

If Share Cart Pro by Yindle is already active, this edition stands by and
registers nothing. The Pro edition contains every free feature.

== Frequently Asked Questions ==

= Does the link contain prices? =

No. The stored snapshot holds product IDs, variation IDs, quantities and the
selected variation attributes. Prices, coupons, totals, tax, customer details
and session data are rejected by the schema before anything is saved.

= Can a recipient's cart be changed just by opening the link? =

No. Opening the link renders a preview and changes nothing. The cart is only
modified by a POST that carries a valid nonce, an explicit replace/merge choice
and a signed single-use import intent.

= What happens if a product sold out after the link was created? =

The preview reports that the shared cart can no longer be imported, and nothing
is added. Partial imports are not possible: the plan is validated in full first.

= Does an expired licence disable anything? =

This edition has no licence client at all. In the Pro edition, a licence governs
updates and support only and never disables an installed feature.

= Is any data sent anywhere? =

Sharing and importing contact only the current shop. This edition has no
external service, telemetry, Yindle account, licence check or custom updater.
Fonts, styles, scripts and icons are bundled locally. WordPress itself can
contact WordPress.org for normal plugin updates and translations.

= Which product types are supported? =

Simple and variable WooCommerce products are supported. Extensions that add
custom cart item data need a compatible adapter. An unsupported cart is
rejected with an explanation; its extra selections are not silently discarded.

= How should I configure caching? =

Exclude the configured share URL path (by default `/cart/<share-key>/`) from
full-page and CDN caching. The plugin sends private, no-store and noindex
headers for these pages. Verify that your cache honors them with two separate
guest sessions. Treat a share URL as a secret: anyone with it can preview and
import its product selections until it expires or is revoked.

= What happens when I deactivate or delete the plugin? =

Deactivation retains data. Deleting the plugin also retains data by default.
The optional **Delete data on uninstall** setting enables permanent cleanup.
Free preserves shared data if Pro is installed or saved cart/licence data
indicates a Pro installation, even when that setting is enabled.

== Privacy ==

Share snapshots store product and variation IDs, selected attributes, quantities,
creation and expiry times, hashed link capabilities and, for signed-in creators,
their WordPress user ID. Prices, coupons, addresses, payment information and
WooCommerce session contents are not included in the shared snapshot.

The plugin uses the shop's WooCommerce session to bind import confirmation to
the current visitor and may ask WooCommerce to create its session cookie when
opening a share preview. The creator's browser stores one revocation capability
in local storage (`yindleCartManagementToken`); it is replaced by the next share
and removed when revoked or when the visitor clears site data.

Abuse prevention uses short-lived local counters keyed by a salted hash of the
visitor's session/user identity and peer IP address, with a five-minute default
window. The raw IP address is not stored by this plugin. One-use import markers
expire after one day. Shared links expire after the configured 1–365 days
(default 30); scheduled cleanup removes expired records that are not referenced
by a retained saved cart.

WordPress's personal-data eraser and user-deletion hooks remove saved-cart
relations and anonymise creator IDs. Product selections may remain when another
saved cart references them. Store owners should describe this behavior in their
shop's privacy notice.

== Third-party assets ==

Plus Jakarta Sans and Geist Mono fonts are bundled under the SIL Open Font
License 1.1. Lucide icons are bundled under the ISC license. Their notices and
source provenance are included in `assets/yindle/`. Runtime JavaScript is
human-readable and uses WordPress/WooCommerce-provided libraries.

= Translations =

This directory package uses WordPress language packs from translate.wordpress.org
for PHP and Cart Block strings. It ships no bundled translation catalogues and
needs no custom translation loader. Until a language pack is available, English
source strings remain usable. Community translations are welcome.

== Upgrade Notice ==

= 1.0.2 =
Renamed to Yindle Share Cart (`yindle-share-cart`). Follow the migration steps
before deleting the old plugin. Uses WordPress language packs; all included
sharing functionality is available without upgrades or unlocks.

= 1.0.1 =
Uses distinctive Free runtime class names. Existing carts, links, settings and
Pro compatibility are preserved.

= 1.0.0 =
Initial free release. Back up your site before changing editions; existing paid
installations should use the Pro package to retain their paid controls.

== Changelog ==

= 1.0.2 =
* Use the distinctive Yindle Share Cart name and yindle-share-cart directory.
* Remove unused saved-cart creation, issuance, account and paid styling code.
* Use standard WordPress language packs instead of bundled catalogues/loaders.
* Protect old/new edition transitions and document safe removal of older copies.
* Clarify that bundled asset provenance does not restrict modification rights.

= 1.0.1 =
* Give all nine Free runtime classes the distinctive YindleShareCart_ prefix.
* Register bundled translations at init for older supported WordPress versions.
* Compile bundled catalogues compatibly with the WordPress 6.4 translation reader.
* Link the plugin header to the verified public product page.
* Preserve shared storage, hooks and capability links; Pro files are unchanged.

= 1.0.0 =
* Initial free release of Yindle Share Cart.
* Declares WooCommerce as a plugin dependency.
* Documents local privacy, browser storage, caching and edition changes.
* Contains the complete share service: capability links, current-price preview,
  deliberate replace/merge, guest revocation, expiry, rate limiting, atomic
  import and the privacy eraser.
* Contains no licence client, no update client and no paid feature code.
