=== ID Image Ad Popup & Roadblock ===
Contributors: indesignmedia
Tags: popup, ad popup, responsive popup, woocommerce popup, roadblock
Requires at least: 5.6
Tested up to: 7.0
Stable tag: 2.0.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Responsive image popups for WordPress with display rules, WooCommerce support, scheduling, GTM/GA4 tracking, and a modern admin UI.

== Description ==

**ID Popup** is a lightweight WordPress plugin for showing responsive image popups on your site. You can build unlimited popups, each with its own images, targeting rules, schedule, and analytics tracking.

Whether you are running a flash sale, promoting a new product, capturing leads, or showing a site-wide notice, ID Popup gives you full control over when, where, and how each popup appears.

Version 2.0.0 introduces a modernized card-and-tab admin UI, a new Tracking tab for Google Tag Manager and Google Analytics 4, a Mobile Max Width setting, a Show Logo option, and timezone-correct scheduling. All existing popups from earlier versions keep working without any changes.

### Key Features

**Multiple Popups**
* Create unlimited popups, each with its own settings.
* Manage everything from the dedicated **Popups** menu in the WordPress admin.

**Modernized Admin UI (new in 2.0.0)**
* Rounded pill-tab navigation for **Media**, **Display Rules**, **Appearance**, and **Tracking**.
* Clean white card layout for every settings section.
* Rounded buttons, consistent input styling, and modern toggle switches.
* Fully backward compatible with popups saved in earlier versions.

**Smart Display Rules**
* Show on **Entire Website**, **Home Page Only**, **All Pages**, or **All Single Posts**.
* Target **Specific Page(s)** or **Specific Post(s)** using a live search picker.
* **WooCommerce**: target **All Product Pages** or **Specific Product Page(s)** when WooCommerce is active.
* Home Page detection now works reliably with Elementor and custom template setups.

**Responsive Image Support**
* Separate images for **Desktop** and **Mobile** via the native WordPress Media Library.
* Popup is automatically suppressed on a device if no image is set for it.
* **Desktop Max Width** in pixels (default 900px).
* **Mobile Max Width** as a percentage of the viewport (new in 2.0.0, default 90%).

**Show Site Logo (new in 2.0.0)**
* Optional per-popup toggle to display your site logo (from **Customizer, Site Identity, Logo**) at the top of the popup.
* The logo is scaled responsively so it looks right on any device.

**Popup Scheduling**
* Independent **Start Date and Time** and **End Date and Time** per popup.
* Each date bound is evaluated on its own, set only a start, only an end, or both.
* **Timezone-aware (fixed in 2.0.0)**: dates are now parsed using the WordPress timezone from **Settings, General**, instead of the server timezone.

**Appearance and Behavior**
* Configurable **Delay Before Opening** (default 3 seconds).
* **Auto Close After** timer, set to 0 to disable (default 15 seconds).
* Customizable **Overlay Color** and **Overlay Opacity**.
* Linkable popup image with **Target URL** (opens in a new tab, `rel="noopener noreferrer"`).

**Analytics and Tracking (new in 2.0.0)**
* Optional per-popup **Tracking** tab, with an on/off switch and a unique **Popup ID** slug.
* When tracking is enabled, the popup link gets an HTML `id` matching your Popup ID slug, so any existing GTM click trigger or Element Visibility trigger can target it directly with zero GTM changes.
* The plugin also pushes standardized events to `window.dataLayer`:
  * `popup_view` when the popup appears.
  * `popup_click` when the popup image/link is clicked.
  * `popup_close` when the popup is closed (X, overlay, or auto-close).
* Every event carries `popup_id`, `popup_title`, and (for clicks) `link_url` and (for closes) `close_reason` and `time_shown_ms`, so you can filter and report per popup in GA4.

**Native WordPress Integration**
* Built on **Custom Post Type**, no custom database tables.
* Native **WordPress Media Uploader**, no third-party dependencies for uploads.
* Automatic one-time **data migration** from the old single-setting version.
* Clean uninstall (new in 2.0.0), a proper `uninstall.php` removes all popup posts and plugin options when you delete the plugin.

### Use Cases
* Flash sales and limited-time promotions
* New product announcements
* Email list opt-ins and lead capture
* WooCommerce product-specific upsells
* Event announcements and countdowns
* Site-wide notices and alerts

== Installation ==

1. **Upload the Plugin**
   * Go to **Plugins, Add New, Upload Plugin** in your WordPress admin.
   * Select the `id-popup.zip` file and click **Install Now**.

2. **Activate**
   * Click **Activate** after installation completes.

3. **Create Your First Popup**
   * Go to **Popups, Add New** in the WordPress admin sidebar.
   * Add a title, upload a desktop image (and optionally a mobile image), pick a display rule, then **Publish**.

4. **Optional: Enable Tracking**
   * Open the popup, click the **Tracking** tab, turn on **Enable Tracking**, and set a unique **Popup ID** slug (for example, `homepage_summer_sale`).
   * Add matching Custom Event triggers in Google Tag Manager if you want `popup_view`, `popup_click`, and `popup_close` events in GA4.

5. **Add More Popups**
   * Repeat step 3 for each popup. Each one has independent settings.

== Frequently Asked Questions ==

= Can I create multiple popups? =

Yes. Version 1.2 introduced a Custom Post Type architecture and version 2.0.0 keeps it. You can create unlimited independent popups, each with its own images, display rules, schedule, and tracking, all managed from the **Popups** menu.

= Can I use different images for desktop and mobile? =

Yes. Upload a desktop image and a mobile image in the **Media** tab. If one is missing, the popup is automatically hidden on that device so you never see broken images or empty containers.

= How does Mobile Max Width work? =

It controls the popup width on devices under 768px, as a percentage of the viewport. Default is 90%. Set a lower value if you want smaller popups on phones, or 100% for edge-to-edge.

= What does the Show Logo toggle do? =

When on, the popup displays your site logo (the one set in **Customizer, Site Identity, Logo**) above the popup image at the top-left. It uses the current logo automatically, so if you change the logo in the Customizer, the popup updates too.

= Can I schedule the popup to appear only on specific dates? =

Yes. Set a **Start Date and Time**, an **End Date and Time**, or both. Each boundary is evaluated independently, so you can run an end-date-only sunset campaign without setting a start date.

= Does the plugin honor my WordPress timezone? =

Yes. As of 2.0.0, start and end dates are compared using the WordPress timezone from **Settings, General, Timezone**. Before 2.0.0 the plugin used the server timezone, which could cause popups to fire early or late on hosts where the two differed.

= Can I target specific pages, posts, or WooCommerce products? =

Yes. Use the **Display Rules** dropdown and pick **Specific Page(s)**, **Specific Post(s)**, or (when WooCommerce is active) **Specific Product Page(s)**. A live search picker lets you find items by name without needing to know IDs.

= Does it work with WooCommerce? =

Yes. When WooCommerce is active, two extra rules appear: **All Product Pages** and **Specific Product Page(s)**.

= Does it work with Elementor and other page builders? =

Yes. The Home Page rule was improved in 2.0.0 to reliably detect the site root even on Elementor-built or custom-template homepages that bypass the standard WordPress main query.

= How do I track popup interactions in Google Analytics 4? =

Open the popup, click the **Tracking** tab, turn on **Enable Tracking**, and set a unique **Popup ID** slug. The plugin then pushes `popup_view`, `popup_click`, and `popup_close` events to the browser dataLayer, and also adds an HTML `id` matching your slug to the popup link so existing DOM-based GTM triggers work. Wire matching Custom Event triggers in GTM and register `popup_id` as a custom dimension in GA4 to see per-popup reports.

= What if I already have a GTM trigger watching a CSS ID like `#technology_popup_ad`? =

Just enter that same slug (`technology_popup_ad`) in the **Popup ID** field on the Tracking tab. The plugin will output the popup link with that HTML ID, and your existing trigger and tag will fire without any GTM changes.

= How does Auto Close work? =

**Auto Close After (s)** sets how many seconds after opening the popup automatically closes. Set it to **0** to disable auto-close entirely and keep the popup open until the visitor closes it.

= Can I have multiple popups showing on the same page? =

Yes. Every popup is rendered independently. If two published popups both match the current page and current schedule, both will show. Use scheduling and display rules to control which one appears when.

= What happens if I had the old single-settings version installed? =

The plugin automatically detects your old settings and migrates them into a new popup post called **Default Popup** on the first admin load after upgrading. No data is lost, no manual steps are needed.

= What happens when I delete the plugin? =

As of 2.0.0, the plugin ships with a proper `uninstall.php` that removes all popup posts (Custom Post Type entries and their meta) and clears the plugin's own options. If you only **Deactivate** the plugin, your data stays intact.

= Is it compatible with popups from earlier versions? =

Yes. Version 2.0.0 preserves every option key, meta key, hook, and shortcode from previous versions. Your existing popups keep their settings and keep working without any manual changes.

== Changelog ==

= 2.0.0 =
*Released: August 2026*

**New Features**
* **Mobile Max Width (%)** setting per popup, controls popup width on devices under 768px as a percentage of the viewport (default 90%).
* **Show Logo** toggle, displays the site logo from **Customizer, Site Identity, Logo** at the top of the popup, sized responsively.
* **Tracking tab** for Google Tag Manager and Google Analytics 4 integration:
  * Per-popup **Enable Tracking** switch and unique **Popup ID** slug.
  * When enabled, the popup link renders with an HTML `id` matching your slug (works with existing DOM-based GTM click and Element Visibility triggers).
  * Standardized events pushed to `window.dataLayer`: `popup_view`, `popup_click`, `popup_close`.
  * Event parameters: `popup_id`, `popup_title`, `link_url`, `close_reason` (button, overlay, auto), `time_shown_ms`.

**Modernized Admin UI**
* New pill-tab navigation on the popup edit screen (Media, Display Rules, Appearance, Tracking).
* Clean white card layout for every settings section, with rounded corners.
* Consistent rounded pill buttons, unified input styling, modern toggle switches, and a matching Publish button.
* Fully backward compatible: all existing option keys, meta keys, hooks, and shortcodes are preserved.

**Timezone Correctness**
* Scheduling now honors the WordPress timezone from **Settings, General**, instead of the server timezone. Start and end dates compare correctly across all hosting environments.

**Improved Home Page Detection**
* The **Home Page Only** rule now matches WordPress `is_front_page()` and `is_home()`, plus a URL-path fallback, so page builders and custom templates that bypass main-query conditionals (Elementor, custom themes) still resolve the site root correctly.

**Bug Fixes**
* Close button position stays anchored to the popup image top-right corner whether or not the site logo is enabled.
* Close button glyph is now visually centered inside its circle across browsers (Arial fallback plus zero line-height eliminates cross-browser glyph drift).

**Housekeeping**
* Added `uninstall.php` that removes all popup posts and plugin options on plugin deletion (multisite-safe).
* Bumped **Tested up to** to 7.0.

= 1.5 =
*Released: March 2026*
* Updated short description and tags.
* Synchronised plugin version with stable tag.

= 1.4 =

**Security Hardening**
* Added `wp_die()` after `wp_send_json_error()` in AJAX handler to prevent continued execution after unauthorized access.
* Whitelisted the `type` parameter in the AJAX search handler against known post types, unknown types are rejected with `wp_die()`.
* Switched `popup_link` sanitization from `sanitize_text_field()` to `esc_url_raw()`, the correct WordPress standard for URL fields stored in the database.
* Added strict allowlist validation for `display_rules` using `in_array()` with type checking.
* Cast all `specific_ids` to integers using `intval`, eliminating string injection risk through ID fields.
* Applied `esc_html()` to post titles and `absint()` to IDs in AJAX JSON responses.
* Applied `esc_attr()` to `desktop_max_width` in inline style output.

**Bug Fixes**
* Fixed auto-close value of `0` not working. `parseInt(0) || 15000` was incorrectly evaluating to `15000`. Now uses `isNaN()` check so `0` correctly disables auto-close.
* Fixed mobile skip logic. `data()` returns a string but was compared with `=== 0` (integer). Wrapped with `parseInt()` for correct type coercion.
* Fixed scheduling logic. Previously required both start AND end dates to evaluate, now each date boundary is checked independently.
* Removed dead `$preview_style` PHP variable that was computed but never used.

**Performance**
* Added `no_found_rows: true` and `update_post_term_cache: false` to the frontend `WP_Query` to skip unnecessary database queries.
* Popup HTML is now skipped in PHP entirely if neither desktop nor mobile images are set.

= 1.3 =
*Released: March 2026*

**New: WooCommerce Display Rules**
* Added **All Product Pages** display rule, shows the popup on any WooCommerce single product page.
* Added **Specific Product Page(s)** display rule, target individual products by name using the Select2 search interface.
* WooCommerce rules only appear in the admin dropdown when WooCommerce is active (`class_exists('WooCommerce')`).
* AJAX search handler supports `product` post type when `specific_products` rule is selected.

**Select2 Improvements**
* Placeholder text updates based on the selected rule: "Search pages...", "Search posts...", or "Search products...".
* Search field also appears for `specific_products` rule.

**Display Rule Precision**
* **All Single Posts** now uses `is_singular('post')` instead of `is_single()`, correctly excluding custom post types and WooCommerce products.
* **Specific Post(s)** uses `is_singular('post')` + `get_queried_object_id()` matching, consistent with the specific pages and products pattern.
* **Specific Page(s)** uses `get_queried_object_id()` for ID matching instead of passing an array to `is_page()`.

= 1.2 =
*Released: March 2026*

**Multiple Popups Architecture (Major Feature)**
* Migrated from a single WordPress Options API settings page to a **Custom Post Type** (`id_popup`).
* Each popup is now an independent WordPress post with its own title, settings, and lifecycle.
* Dedicated **Popups** menu item in the WordPress admin sidebar with a custom dashicon.
* Three separate WordPress Meta Boxes replace the single settings form: **Media Setup**, **Display Rules and Scheduling**, and **Appearance and Behavior**.
* Meta box headers styled with the plugin's red theme.
* Automatic one-time data migration from the old `id_popup_settings` option into a new "Default Popup" post, no data loss on upgrade.

**Frontend Multi-Popup Support**
* Frontend uses `WP_Query` to loop all published `id_popup` posts.
* Each popup evaluated independently for scheduling and display rules.
* HTML output switched from singleton IDs (`#id-popup`) to classes (`.id-popup-container`, `.id-popup-overlay`) to support multiple popups on one page.
* Per-popup delay and auto-close timings passed via `data-delay` and `data-autoclose` attributes, no global JS variables.

**Image Handling**
* Each popup independently skips rendering if no image is configured for the current device type.
* Device detection (`data-has-desktop`, `data-has-mobile`) evaluated fresh per popup per page load.

= 1.1 =
*Released: March 2026*

**WordPress Media Library Integration**
* Replaced plain URL input fields with the native **WordPress Media Uploader**.
* Plugin now stores WordPress Attachment IDs instead of raw image URLs.
* Image URLs resolved at render time using `wp_get_attachment_image_url()`.
* Added `attachment_url_to_postid()` fallback for legacy string URL values.
* Added live image previews in the admin for both desktop and mobile images.
* Added remove (x) button on image thumbnails, clears the attachment ID and hides the preview without a page reload.

**Display Rules Expansion**
* Added **All Pages** display rule.
* Added **All Single Posts** display rule.
* Added **Specific Page(s)** display rule with Select2 live search.
* Added **Specific Post(s)** display rule with Select2 live search.
* "Specific Page/Post" field dynamically shows/hides based on the selected rule.

**Select2 Integration**
* Integrated Select2 library for the specific page/post ID selection.
* AJAX-powered live search for pages and posts.
* Selected items displayed as removable pill tags.
* Automatically clears selections when an incompatible display rule is chosen.

**Field Defaults**
* Desktop Max Width defaults to 900px.
* Auto Close defaults to 15 seconds.
* Delay Before Opening defaults to 3 seconds.
* Target URL defaults to `#`.

= 1.0 =
*Released: 2024*

* Initial release.
* Responsive popup image support for desktop and mobile.
* Popup scheduling with start and end dates.
* Display location control: entire site, homepage, or single post.
* Overlay color and opacity controls.
* Linkable popup image.
* Auto-close timer.
* Popup delay setting.

== Upgrade Notice ==

= 2.0.0 =
Major feature and UI release. New Tracking tab (GTM and GA4 dataLayer), Mobile Max Width, Show Logo, timezone-aware scheduling, modernized card-and-pill-tab admin UI, and a proper uninstall cleanup. Fully backward compatible with popups from earlier versions.

= 1.5 =
Minor update to readme description and tags for repository compatibility.

= 1.4 =
Security hardening and bug fixes. Please update.

= 1.2 =
Major architecture upgrade introducing multiple popup support via Custom Post Type. Your existing settings are automatically migrated to a new "Default Popup" post on first admin load, no manual steps required.

== Screenshots ==

1. **Media Tab**, upload desktop and mobile images from the WordPress Media Library, set Desktop and Mobile Max Width, and toggle Show Logo.
2. **Display Rules Tab**, choose where the popup appears, target specific pages, posts, or WooCommerce products, and set start and end dates.
3. **Appearance Tab**, configure delay, auto-close timer, target URL, overlay color, and overlay opacity.
4. **Tracking Tab**, enable per-popup tracking for Google Tag Manager and Google Analytics 4 with a unique Popup ID slug.
5. **Example Popup**, the popup as it appears on the frontend, with optional site logo, responsive image, and close button.

== Support ==

For help, documentation, or bug reports, visit the [ID Popup Support Page](https://indesignmedia.net/contact-us/).

Further documentation and usage guides are available at our [official documentation](https://indesignmedia.net/plugins/id-popup).

== License ==

ID Popup is licensed under the **GPLv2** or later. You can freely redistribute and modify it under the terms of the license.

The full license text is available here: [GPLv2 License](https://www.gnu.org/licenses/gpl-2.0.html)
