=== ID Popup === Contributors: indesignmedia Tags: popup plugin, responsive popup, roadblock, woocommerce popup Requires at least: 5.6 Tested up to: 6.7 Stable tag: 1.5 Requires PHP: 7.4 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Professional WordPress popup plugin — display responsive image popups with advanced display rules, WooCommerce support, and flexible scheduling. == Description == **ID Popup** is a powerful, lightweight WordPress plugin for displaying fully customizable and responsive image popups on your website. Built on a **Custom Post Type** architecture, you can create and manage **unlimited independent popups**, each with their own settings, display rules, and scheduling. Whether you're running a flash sale, announcing a new product, or displaying a promotional banner, ID Popup gives you complete control over when, where, and to whom your popups appear. ### Key Features **Multiple Popups** * Create unlimited independent popups, each with their own individual settings. * Manage all popups from a dedicated **Popups** menu in the WordPress admin. **Smart Display Rules** * Show on the **Entire Website**, **Home Page Only**, **All Pages**, or **All Single Posts**. * Target **Specific Page(s)** or **Specific Post(s)** using a live-search Select2 picker. * **WooCommerce Support**: Display on **All Product Pages** or target **Specific Product Page(s)** — only shown when WooCommerce is active. **Responsive Image Support** * Upload separate images for **Desktop** and **Mobile** devices via the native WordPress Media Library. * If no mobile image is set, the popup is automatically **suppressed on mobile devices**. * If no desktop image is set, the popup is automatically **suppressed on desktop devices**. * Remove images with a single click using the built-in remove (×) button. **Popup Scheduling** * Set independent **Start Date & Time** and **End Date & Time** for each popup. * Each date bound is evaluated independently — set only a start date, only an end date, or both. **Appearance & Behavior** * Configurable **Delay Before Opening** (default: 3 seconds). * Auto-close timer — set to 0 to disable auto-close entirely (default: 15 seconds). * Customizable **Overlay Color** and **Overlay Opacity**. * Linkable popup image with **Target URL** (opens in a new tab, with `rel="noopener noreferrer"`). * **Desktop Max Width** control in pixels (default: 900px). **Native WordPress Integration** * Built on WordPress **Custom Post Type** — no custom database tables. * Uses the native **WordPress Media Uploader** — no third-party upload dependencies. * **Select2** live search for selecting specific pages, posts, or products. * Automatic one-time **data migration** from older single-setting versions. ### 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** * Download the plugin ZIP file. * Go to **Plugins > Add New > Upload Plugin** in your WordPress admin. * Select the `id-popup.zip` file and click **Install Now**. 2. **Activate the Plugin** * Click **Activate** after installation. 3. **Create Your First Popup** * Navigate to **Popups > Add New** in the WordPress admin sidebar. * Give your popup a title, upload images, configure display rules and scheduling, then click **Publish**. 4. **Adding More Popups** * Go to **Popups > Add New** again. Each popup is fully independent with its own settings. == Frequently Asked Questions == = Can I create multiple popups? = Yes! Version 1.4 introduced a full **Custom Post Type** architecture. You can create unlimited independent popups, each with its own images, display rules, and schedule, all managed from the **Popups** menu in your admin sidebar. = Can I use different images for desktop and mobile? = Yes. You can upload separate images for desktop and mobile in the **Media Setup** section of each popup. If one is missing, the popup is automatically hidden on that device type — no broken images, no empty containers. = Can I schedule the popup to appear only on specific dates? = Yes. Set a **Start Date & Time** and/or **End Date & Time** for each popup. Each boundary is evaluated independently — you can have an end-date-only popup that phases out on a deadline without requiring a start date. = Can I target specific pages, posts, or WooCommerce products? = Yes. Use the **Display Rules** dropdown to select **Specific Page(s)**, **Specific Post(s)**, or (if WooCommerce is active) **Specific Product Page(s)**. A live Select2 search lets you search and choose items by name without needing to know their IDs. = Does it work with WooCommerce? = Yes. When WooCommerce is active, two additional display rules appear in the dropdown: **All Product Pages** and **Specific Product Page(s)**, allowing you to target your WooCommerce store with surgical precision. = How does Auto Close work? = The **Auto Close After (s)** field sets a timer in seconds after which the popup automatically closes. Set it to **0** to disable auto-close entirely and keep the popup open until the user manually closes it. = What happens if I had the old single-settings version installed? = The plugin automatically detects and migrates your old settings into a new popup post called "Default Popup" on the first admin load after upgrading. No data is lost. == Changelog == = 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()` — 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` — eliminates any possibility of string injection 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 popup on any WooCommerce single product page. * Added **Specific Product Page(s)** display rule — target individual WooCommerce products by name using the Select2 search interface. * WooCommerce rules are only rendered in the admin dropdown when WooCommerce is active (`class_exists('WooCommerce')`). * AJAX search handler now supports `product` post type when `specific_products` rule is selected. **Select2 Improvements** * Placeholder text dynamically updates based on selected display rule: "Search pages…", "Search posts…", or "Search products…". * Select2 search field now appears for `specific_products` rule in addition to `specific_pages` and `specific_posts`. **Display Rule Precision** * "All Single Posts" now uses `is_singular('post')` instead of `is_single()` — correctly excludes custom post types and WooCommerce products. * "Specific Post(s)" rule now uses `is_singular('post')` + `get_queried_object_id()` matching — consistent with the specific pages and products pattern. * "Specific Page(s)" now 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. * Added dedicated **Popups** menu item in the WordPress admin sidebar with a custom dashicon. * Three separate native WordPress Meta Boxes replace the single settings form: **Media Setup**, **Display Rules & Scheduling**, and **Appearance & Behavior**. * Meta box headers styled with the plugin's red theme using CSS targeting native WP postbox elements. * Added 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 now 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 simultaneous 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 — more robust, survives media library reorganization. * Image URLs are dynamically resolved at render time using `wp_get_attachment_image_url()`. * Added `attachment_url_to_postid()` fallback for any legacy string URL values still in the database. * Added live image previews in the admin for both desktop and mobile images. * Added remove (×) 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 (hidden by default). **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 == = 1.5 = Minor update to readme description and tags for repository compatibility. = 1.4 = = 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. **Popup List** — The Popups admin screen showing all created popups with status. 2. **Media Setup** — Upload desktop and mobile images using the WordPress Media Library with live preview and remove button. 3. **Display Rules** — Dropdown with all targeting options including WooCommerce product rules. 4. **Appearance & Behavior** — Configure delay, overlay, auto-close, and target URL. 5. **Live Popup** — Example of the popup displayed on the frontend with overlay. == Support == For assistance, documentation, or to report bugs, visit the [ID Popup Support Page](https://indesignmedia.net/contact-us/). For further documentation and usage guides, please visit 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 as per the terms of the license. The full license can be found here: [GPLv2 License](https://www.gnu.org/licenses/gpl-2.0.html)