=== Dynamic QR Redirects ===
Contributors: innersitesolutions
Tags: qr code, redirect, dynamic qr code, google reviews, short link
Requires at least: 5.8
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Print one QR code, change where it points any time. Dynamic QR redirects with a built-in QR generator, scan counter, and cache-safe forwarding.

== Description ==

**Dynamic QR Redirects** turns any WordPress page into a *dynamic* QR-code link: the printed QR code encodes a stable URL on **your own site** (like `yoursite.com/leave-a-review`), and you choose — and can change at any time — where that URL actually sends people. No reprints, no third-party link shortener, no subscription.

Perfect for:

* **"Leave us a Google review" stickers** — repoint the QR code if your review link changes.
* **Menus, flyers, table tents, business cards** — printed once, updated forever.
* **Event posters** — send scanners to this month's schedule, then next month's.
* **Product packaging** — point at the current manual, promo, or support page.

= Why not a QR/link-shortener service? =

Free QR services love to expire your codes or move them behind a paywall — and then your printed stickers break. With this plugin the URL is on your own domain, under your control, forever, for free.

= Features =

* **Built-in QR code generator** — view and download a print-ready PNG for every redirect right from wp-admin. No external service is contacted; codes are generated in your browser.
* **Scan counter** — see total scans and the most recent scan time for each redirect. No cookies, no personal data.
* **Printed variants** — generate a separate QR code per placement (sticker, menu, poster…) and see which one gets scanned, per variant, right in the list. Variant tokens are permanent, so printed codes never break.
* **Campaign tagging** — optionally append `utm_source=qr`, `utm_medium=offline`, and a per-redirect `utm_campaign` (plus `utm_content` for variants) at scan time, so Google Analytics on the destination site attributes the traffic. Hand-written UTM tags in your destination URL are never overwritten.
* **Instant redirects** — fires on `template_redirect` before any theme HTML renders. Choose 302 (recommended, always changeable) or 301 per redirect.
* **Cache-safe** — sends no-cache headers and purges LiteSpeed Cache, WP Super Cache, W3 Total Cache, and WP Rocket when you change a destination, so updates take effect immediately.
* **Two ways to manage** — a simple **Tools → QR Redirects** screen (list, inline edit, add, remove, copy link, show QR), or a **QR Redirect** box in the page editor sidebar to convert any existing page.
* **Clean uninstall** — deleting the plugin removes all of its data; your pages remain as normal pages.
* **Lightweight** — no settings pages full of upsells, no external requests, no tracking.

QR generation uses the bundled [qrcode-generator](https://github.com/kazuhikoarase/qrcode-generator) JavaScript library by Kazuhiko Arase (MIT license, GPL-compatible).

== Installation ==

1. Install and activate the plugin from **Plugins → Add New**, or upload the zip via **Plugins → Add New → Upload Plugin**.
2. Go to **Tools → QR Redirects**.
3. Add a redirect: pick a short slug (e.g. `leave-a-review`) and a destination URL.
4. Click **Show QR → Download PNG** and send that image to print.
5. Whenever the destination needs to change, update the URL — the printed code keeps working.

== Frequently Asked Questions ==

= Where do I get the QR code image? =

It's built in. On **Tools → QR Redirects**, click **Show QR** on any row, then **Download PNG**. The code is generated locally in your browser — nothing is sent to any external service.

= Can I turn an existing page into a redirect? =

Yes. Edit the page and use the **QR Redirect** box in the sidebar: enter a destination URL and update the page. Clear the field to make it a normal page again.

= Should I use 301 or 302? =

Use **302** (the default) unless the destination will truly never change. Browsers aggressively cache 301 redirects, so a later destination change may not reach repeat visitors.

= Does it work with caching plugins? =

Yes. The redirecting pages send no-cache headers, and the plugin purges LiteSpeed Cache, WP Super Cache, W3 Total Cache, and WP Rocket automatically when a destination changes. Other caches are covered by standard WordPress cache cleaning, and a `dqrr_flush_cache` action is provided for custom setups.

= What does the scan counter store? =

Only two numbers per redirect: a total hit count and the timestamp of the most recent scan. No IP addresses, no cookies, no personal data — nothing that implicates GDPR. Scans by logged-in users who can edit pages are not counted. You can disable counting entirely with `add_filter( 'dqrr_count_hits', '__return_false' );`.

= How do I track which sticker or flyer someone scanned? =

Open **Show QR** for the redirect and add a **printed variant** for each placement (e.g. `window`, `menu`, `flyer`). Each variant gets its own QR code (same redirect, plus `?v=token`) and its own scan count in the list. Unknown or mistyped tokens are ignored, so random query strings can't pollute your counts. Variants can't be renamed once created — the token is baked into the printed code — but you can remove ones you no longer print (removal only stops per-variant counting; the printed code itself keeps redirecting).

= How does the Google Analytics / UTM tagging work? =

Enable **Campaign tagging** on a redirect and every scan is forwarded with `utm_source=qr`, `utm_medium=offline`, `utm_campaign=<slug>` — plus `utm_content=<variant>` when a printed variant was scanned. Tags are added at redirect time, so they apply to codes you printed *before* enabling the option, and they never overwrite UTM parameters already present in your destination URL. Developers can customize the tags with the `dqrr_utm_args` filter.

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

The pages remain and simply stop redirecting (they'll render as normal, empty pages). Deleting the plugin also removes all stored destinations and counters.

= Does it redirect posts too? =

Redirects are pages only, by design — pages are exempt from feeds, archives, and blog listings, which keeps redirect URLs clean and predictable.

== Screenshots ==

1. Tools → QR Redirects: all redirects with inline destination editing, scan counts, and QR preview/download.
2. Downloadable print-ready QR code PNG.
3. The QR Redirect box in the page editor sidebar.

== Changelog ==

= 1.1.0 =
* New: **Printed variants** — per-placement QR codes (`?v=token`) with per-variant scan counts. Tokens are permanent so printed codes never break; unknown tokens are ignored.
* New: **Campaign tagging** — optional per-redirect UTM tagging (`utm_source=qr`, `utm_medium=offline`, `utm_campaign=<slug>`, `utm_content=<variant>`), applied at scan time and never overwriting hand-written UTM parameters. Customizable via the `dqrr_utm_args` filter.
* UI: variant management (add/remove with confirmation) inside the QR panel, campaign-tagging checkbox, and per-variant scan breakdown in the Tools list.
* Uninstall now also removes the new variant and tagging meta.

= 1.0.0 =
* Initial WordPress.org release.
* Built-in QR code preview and print-ready PNG download (bundled MIT-licensed qrcode-generator library — no external requests).
* Scan counter with last-scan timestamp per redirect.
* Per-redirect 301/302 choice (302 default).
* Copy-link buttons, redirect-removal confirmation, "Manage Redirects" link on the Plugins screen.
* Cache purging for LiteSpeed Cache, WP Super Cache, W3 Total Cache, and WP Rocket.
* Full internationalization, uninstall cleanup, and automatic migration from the pre-release "ISS QR Redirects" build.

== Upgrade Notice ==

= 1.1.0 =
Adds printed variants (per-placement QR codes with per-variant scan counts) and optional UTM campaign tagging. Existing redirects and printed codes are unaffected.

= 1.0.0 =
First public release.
