{"id":227396,"date":"2025-07-07T02:56:57","date_gmt":"2025-07-07T02:56:57","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/inpipe-by-seresa\/"},"modified":"2026-03-12T06:04:51","modified_gmt":"2026-03-12T06:04:51","slug":"inpipe-by-seresa","status":"publish","type":"plugin","link":"https:\/\/tg.wordpress.org\/plugins\/inpipe-by-seresa\/","author":23226096,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.1.1","stable_tag":"1.1.1","tested":"6.9.4","requires":"6.4","requires_php":"8.3","requires_plugins":null,"header_name":"inPIPE by Seresa","header_author":"Seresa.io","header_description":"Captures, stores, and decodes UTM parameters for enhanced results in Google Analytics, Facebook Ads, and other platforms. Integrates with the dataLayer and supports standard and encoded UTM codes.","assets_banners_color":"","last_updated":"2026-03-12 06:04:51","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/seresa.io\/wordpress-plugin","header_author_uri":"https:\/\/seresa.io","rating":5,"author_block_rating":0,"active_installs":0,"downloads":850,"num_ratings":1,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"seresa8","date":"2025-07-07 02:56:24"},"1.0.1":{"tag":"1.0.1","author":"seresa8","date":"2025-07-21 09:35:40"},"1.0.2":{"tag":"1.0.2","author":"seresa8","date":"2025-11-21 07:29:37"},"1.0.3":{"tag":"1.0.3","author":"seresa8","date":"2025-12-03 05:09:15"},"1.0.4":{"tag":"1.0.4","author":"seresa8","date":"2026-01-05 08:29:17"},"1.0.5":{"tag":"1.0.5","author":"seresa8","date":"2026-01-07 08:42:49"},"1.0.6":{"tag":"1.0.6","author":"seresa8","date":"2026-01-09 06:40:38"},"1.0.7":{"tag":"1.0.7","author":"seresa8","date":"2026-01-14 06:43:12"},"1.0.8":{"tag":"1.0.8","author":"seresa8","date":"2026-01-15 03:43:41"},"1.0.9":{"tag":"1.0.9","author":"seresa8","date":"2026-01-20 09:00:54"},"1.1.0":{"tag":"1.1.0","author":"seresa8","date":"2026-01-30 02:50:29"},"1.1.1":{"tag":"1.1.1","author":"seresa8","date":"2026-03-12 06:04:51"}},"upgrade_notice":[],"ratings":{"1":0,"2":0,"3":0,"4":0,"5":1},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3323178,"resolution":"128x128","location":"assets","locale":""}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","1.0.8","1.0.9","1.1.0","1.1.1"],"block_files":[],"assets_screenshots":[],"screenshots":[],"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[244594,43896,219244,244593,25969],"plugin_category":[],"plugin_contributors":[244595],"plugin_business_model":[],"class_list":["post-227396","plugin","type-plugin","status-publish","hentry","plugin_tags-ad-blocker-bypass","plugin_tags-datalayer","plugin_tags-server-side-tracking","plugin_tags-utm-encoding","plugin_tags-utm-tracking","plugin_contributors-seresa8","plugin_committers-seresa8"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/inpipe-by-seresa\/assets\/icon-128x128.png?rev=3323178","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>inPIPE by Seresa allows you to generate, store, and manage UTM parameters\u2014both plain and coded. The plugin automatically decodes coded UTM query strings when visitors land on your website, pushing the full UTM data to the dataLayer. This helps bypass ad blockers and improves tracking in Google Analytics, Facebook Ads, and other platforms.<\/p>\n\n<ul>\n<li>Generate &amp; manage UTM query strings with ease  <\/li>\n<li>Supports both <strong>plain and coded UTM parameters<\/strong>  <\/li>\n<li>Decodes coded UTM links on-site and sends data to the dataLayer  <\/li>\n<li>Reduces tracking disruptions caused by ad blockers  <\/li>\n<li>Works with GA4, GTM, Facebook Ads &amp; more  <\/li>\n<\/ul>\n\n<p><strong>Use WP inPIPE for more reliable UTM tracking and better data collection!<\/strong><\/p>\n\n<h3>Features<\/h3>\n\n<ul>\n<li>Generate and store UTM query string URLs based on user input  <\/li>\n<li>Encode UTM parameters to enhance tracking accuracy  <\/li>\n<li>Decode UTM query strings on site visits and push the original UTM data to the dataLayer  <\/li>\n<li>Potentially bypass ad blockers to ensure accurate data collection<\/li>\n<\/ul>\n\n<h3>Configuration<\/h3>\n\n<ul>\n<li>Navigate to <strong>Admin Dashboard &gt; inPIPE<\/strong> to manage plugin settings.<\/li>\n<li>Enable automatic UTM processing in the settings panel.<\/li>\n<li>Use the <strong>UTM Coder<\/strong> to create, edit, or delete UTM query strings.<\/li>\n<\/ul>\n\n<h3>External Services<\/h3>\n\n<p>This plugin connects to external services hosted by Seresa.io for the following purposes:<\/p>\n\n<p><strong>Subscription Verification &amp; Premium Package Downloads<\/strong>\n   - <strong>Service:<\/strong> The plugin uses the API at [https:\/\/sub.seresa.app] to verify premium subscriptions and to download premium packages or updates.\n   - <strong>When:<\/strong>\n     - Subscription verification occurs when you attempt to access premium features or validate your license.\n     - Package downloads occur when you install or update premium components from within the plugin.\n   - <strong>Data Sent:<\/strong>\n     - The plugin sends your license key, site URL, and (if applicable) the requested package identifier to the API.\n   - <strong>Purpose:<\/strong>\n     - To verify your entitlement to premium features and to deliver premium package files securely.\n   - <strong>Terms of Service:<\/strong> [https:\/\/seresa.io\/terms]\n   - <strong>Privacy Policy:<\/strong> [https:\/\/seresa.io\/privacy]<\/p>\n\n<p><strong>Other Hosted Services<\/strong>\n   - See below for additional premium features that may rely on external event processing (e.g., Transmute Engine).<\/p>\n\n<ol>\n<li><p>Subscription Verification<\/p>\n\n<ul>\n<li>What: The plugin connects to https:\/\/sub.seresa.app\/premium-downloader\/v1\/verify-subscription to validate subscription codes<\/li>\n<li>When: This occurs only when a user enters a subscription code in the admin panel to activate premium features<\/li>\n<li>Data sent: Subscription code entered by the user, site URL, and WordPress version<\/li>\n<li>Purpose: To verify the validity of subscription purchases and enable premium features<\/li>\n<li>Provider: Seresa.io - <a href=\"https:\/\/seresa.io\/terms\">Terms of Service<\/a> and <a href=\"https:\/\/seresa.io\/privacy\">Privacy Policy<\/a><\/li>\n<\/ul><\/li>\n<li><p>Package Installation<\/p>\n\n<ul>\n<li>What: The plugin connects to https:\/\/sub.seresa.app\/premium-downloader\/v1\/download to download premium components<\/li>\n<li>When: This occurs only after subscription verification when the user initiates the installation of premium features<\/li>\n<li>Data sent: Verified subscription code, site URL, WordPress version, and PHP version<\/li>\n<li>Purpose: To securely download and install authorized premium components<\/li>\n<li>Provider: Seresa.io - <a href=\"https:\/\/seresa.io\/terms\">Terms of Service<\/a> and <a href=\"https:\/\/seresa.io\/privacy\">Privacy Policy<\/a><\/li>\n<\/ul><\/li>\n<li><p>Transmute Engine (Premium Feature)<\/p>\n\n<ul>\n<li>What: Premium users' event data is processed through Transmute Engine, a server-side event processing service<\/li>\n<li>When: When events are triggered on your website (page views, clicks, form submissions, etc.)<\/li>\n<li>Data sent: Event data, UTM parameters, and tracking information<\/li>\n<li>Purpose: To process and route event data to your configured third-party services<\/li>\n<li>How it works: Transmute Engine acts as a first-party server to your website, temporarily processing data without permanent storage, and forwarding it to your specified endpoints<\/li>\n<li>Provider: Seresa.io - <a href=\"https:\/\/seresa.io\/terms\">Terms of Service<\/a> and <a href=\"https:\/\/seresa.io\/privacy\">Privacy Policy<\/a><\/li>\n<\/ul><\/li>\n<\/ol>\n\n<p>No data is shared with third parties beyond Seresa.io, and all connections use secure HTTPS encryption. Users can choose not to use premium features, in which case no external connections will be made.<\/p>\n\n<h3>Third-Party Libraries<\/h3>\n\n<p>This plugin uses the following third-party libraries:<\/p>\n\n<ol>\n<li><p>Vue.js<\/p>\n\n<ul>\n<li>What: A progressive JavaScript framework for building user interfaces<\/li>\n<li>Website: https:\/\/vuejs.org\/<\/li>\n<li>License: MIT License - https:\/\/github.com\/vuejs\/vue\/blob\/main\/LICENSE<\/li>\n<\/ul><\/li>\n<li><p>Vue Toastification<\/p>\n\n<ul>\n<li>What: Toast notification library for Vue.js<\/li>\n<li>Website: https:\/\/github.com\/Maronato\/vue-toastification<\/li>\n<li>License: MIT License<\/li>\n<\/ul><\/li>\n<li><p>Lucide Icons<\/p>\n\n<ul>\n<li>What: Beautiful &amp; consistent icon toolkit for Vue.js<\/li>\n<li>Website: https:\/\/lucide.dev\/<\/li>\n<li>License: ISC License - https:\/\/github.com\/lucide-icons\/lucide\/blob\/main\/LICENSE<\/li>\n<\/ul><\/li>\n<li><p>Axios<\/p>\n\n<ul>\n<li>What: Promise-based HTTP client for JavaScript<\/li>\n<li>Website: https:\/\/axios-http.com\/<\/li>\n<li>License: MIT License<\/li>\n<\/ul><\/li>\n<li><p>Pinia<\/p>\n\n<ul>\n<li>What: State management library for Vue.js<\/li>\n<li>Website: https:\/\/pinia.vuejs.org\/<\/li>\n<li>License: MIT License<\/li>\n<\/ul><\/li>\n<li><p>Vue I18n<\/p>\n\n<ul>\n<li>What: Internationalization plugin for Vue.js<\/li>\n<li>Website: https:\/\/vue-i18n.intlify.dev\/<\/li>\n<li>License: MIT License<\/li>\n<\/ul><\/li>\n<li><p>Tailwind CSS<\/p>\n\n<ul>\n<li>What: Utility-first CSS framework<\/li>\n<li>Website: https:\/\/tailwindcss.com\/<\/li>\n<li>License: MIT License<\/li>\n<\/ul><\/li>\n<li><p>WordPress JavaScript Libraries<\/p>\n\n<ul>\n<li>What: Official WordPress JavaScript libraries (@wordpress\/api-fetch, @wordpress\/components, @wordpress\/element, @wordpress\/i18n)<\/li>\n<li>Website: https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/<\/li>\n<li>License: GPL-2.0+ License<\/li>\n<\/ul><\/li>\n<\/ol>\n\n<p>All third-party libraries used are compatible with the GPL-2.0+ license of this plugin.<\/p>\n\n<h3>Build Tools and Source Code Access<\/h3>\n\n<p>This plugin uses modern frontend tools (Vue.js, Vite, Axios) to build its admin interface. The full, human-readable source code is included directly within the plugin package under the \/src directory.<\/p>\n\n<p>Included source code:\n    \u2022   \/src\/ contains all original Vue 3 components, Pinia store, and JavaScript modules\n    \u2022   \/dist\/ contains the compiled production build\n    \u2022   \/src\/README.md contains full build instructions and configuration references<\/p>\n\n<p>Build Toolchain:\n    \u2022   Vue.js 3\n    \u2022   Vite\n    \u2022   Tailwind CSS\n    \u2022   PostCSS\n    \u2022   Vitest\n    \u2022   Grunt<\/p>\n\n<p>To rebuild the admin interface from source:\n    1.  Navigate to the \/src directory\n    2.  Run npm install\n    3.  Run npm run build:free or npm run build:premium to compile assets to \/dist<\/p>\n\n<p>This ensures full compliance with WordPress.org\u2019s guidelines requiring human-readable source code for all minified or bundled assets.<\/p>\n\n<p>For detailed developer instructions, see \/src\/README.md.<\/p>\n\n<h3>License<\/h3>\n\n<p>This plugin is licensed under the GNU General Public License v2.0 or later.<br \/>\nFor more details, visit: https:\/\/www.gnu.org\/licenses\/gpl-2.0.html<\/p>\n\n<h3>Support<\/h3>\n\n<p>For <strong>free users<\/strong>: Report issues on our GitHub page:<br \/>\n\ud83d\udd17 <a href=\"https:\/\/github.com\/seresa8\/inPIPE-by-Seresa-issues\/issues\">GitHub Issues<\/a><\/p>\n\n<p>For <strong>general inquiries<\/strong>, contact us at <a href=\"mailto:support@seresa.io\">support@seresa.io<\/a>.<\/p>\n\n<p>For <strong>premium users<\/strong>: Get priority support at \ud83d\udd17 <a href=\"https:\/\/seresa.io\/support\">seresa.io\/support<\/a>.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to your WordPress plugin directory (<code>wp-content\/plugins\/<\/code>).  <\/li>\n<li>Activate the plugin through the <strong>Plugins &gt; Installed Plugins<\/strong> menu in WordPress.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"can%20i%20use%20this%20plugin%20just%20to%20generate%20utm%20parameter%20query%20strings%3F\"><h3>Can I use this plugin just to generate UTM parameter query strings?<\/h3><\/dt>\n<dd><p>Yes! The plugin allows you to easily generate <strong>UTM parameter query strings<\/strong> for your marketing campaigns. You can create both <strong>plain and coded UTM query strings<\/strong> with simple click options. If you only need to generate and use UTM parameters without decoding, you can do so without enabling the decoding feature.<\/p><\/dd>\n<dt id=\"can%20i%20use%20plain%20utm%20parameters%20instead%20of%20coded%20ones%3F\"><h3>Can I use plain UTM parameters instead of coded ones?<\/h3><\/dt>\n<dd><p>Yes! The plugin supports both <strong>plain and coded UTM parameters<\/strong>. If you don\u2019t enable decoding, your standard UTM parameters will work as usual. If you want extra protection against ad blockers, you can enable decoding in the plugin settings.<\/p><\/dd>\n<dt id=\"how%20do%20i%20enable%20coded%20utm%20decoding%3F\"><h3>How do I enable coded UTM decoding?<\/h3><\/dt>\n<dd><p>Go to <strong>Settings &gt; WP inPIPE<\/strong> and turn on the option for <strong>Coded UTM Processing<\/strong>. When enabled, the plugin will detect and decode coded UTM query strings, replacing them with the full UTM parameters in the URL bar and pushing them to the dataLayer.<\/p><\/dd>\n<dt id=\"how%20does%20this%20help%20with%20google%20tag%20manager%20%28gtm%29%3F\"><h3>How does this help with Google Tag Manager (GTM)?<\/h3><\/dt>\n<dd><p>By pushing <strong>decoded UTM parameters<\/strong> directly into the <strong>dataLayer<\/strong>, Web GTM can receive the data without requiring extra configurations to extract and manage UTM values. This simplifies tracking setup and ensures cleaner data in your analytics.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.1.1 - 2026-02-12<\/h4>\n\n<p><strong>UTM Import, Dropdown Options Management, Edit UX Overhaul, Validation &amp; Security Enhancements<\/strong><\/p>\n\n<h4>NEW FEATURES<\/h4>\n\n<ul>\n<li><p><strong>Quick Import UTM<\/strong>: Paste any URL containing UTM parameters and auto-fill the form<\/p>\n\n<ul>\n<li>Supports full URLs, query-only strings, bare parameters, and URLs without protocol<\/li>\n<li>Six-step validation chain: empty check, 512-char length cap, multiple URL detection, dangerous protocol blocking, URL parsing with fallbacks, and UTM parameter extraction<\/li>\n<li>Extracts standard UTM parameters (source, medium, campaign, term, content, id)<\/li>\n<li>Now also picks up all non-standard query parameters as custom parameters (up to 3), not just <code>utm_*<\/code> prefixed ones<\/li>\n<li>Domain validation: rejects URLs that don't match the site domain<\/li>\n<li>Warning toast when custom parameters exceed the limit, showing how many were skipped<\/li>\n<li>Landing path extracted from URL and auto-confirmed<\/li>\n<li>Import UTM button in card header next to Reset All<\/li>\n<\/ul><\/li>\n<li><p><strong>UTM Dropdown Options Management<\/strong>: Custom dropdown values for all six UTM parameter fields<\/p>\n\n<ul>\n<li>New <code>inpipe_utm_options<\/code> database table with seeded defaults and user-added values<\/li>\n<li>Add custom values inline via dropdown input (auto-saved to server immediately)<\/li>\n<li>Delete any option (including defaults) via delete icon in dropdown<\/li>\n<li>Options loaded from server on mount via <code>InPipe_UTM_Options_Manager<\/code> with 24-hour object caching<\/li>\n<li>Toast feedback on add (\"{value} added\") and delete (\"{value} removed\")<\/li>\n<\/ul><\/li>\n<li><p><strong>Landing Page Path Confirmation<\/strong>: Confirm-before-edit workflow for the landing page path<\/p>\n\n<ul>\n<li>Three-state field: editable input with checkmark \u2192 confirmed display \u2192 live query preview<\/li>\n<li>Five-layer path validation: query characters (<code>?#&amp;=<\/code>), UTM parameter patterns, character allowlist, path traversal\/dot abuse, consecutive slashes<\/li>\n<li>UTM params lock overlay when path is typed but not confirmed (prevents editing UTM fields until path is confirmed)<\/li>\n<li>Users can skip the path entirely and go straight to UTM params<\/li>\n<\/ul><\/li>\n<li><p><strong>Live UTM Query Preview<\/strong>: Real-time preview of the URL being built inside the landing page field<\/p>\n\n<ul>\n<li>Shows <code>page\/subpage?utm_source=google&amp;utm_medium=cpc&amp;custom_key=value<\/code> as params are selected<\/li>\n<li>Replaces the editable input once any UTM parameter has a value<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>UTM EDIT UX OVERHAUL<\/h4>\n\n<ul>\n<li><strong>Editing State Indicator<\/strong>: Blue banner below card header when editing a stored UTM\n\n<ul>\n<li>Shows pencil icon, \"Editing UTM:\" label, and the UTM ID in a monospace badge<\/li>\n<li>Cancel button to exit edit mode and clear the form<\/li>\n<\/ul><\/li>\n<li><strong>Save Button Context<\/strong>: Button changes from \"Save UTM\" to \"Update UTM\" with pencil icon when editing<\/li>\n<li><strong>Active UTM Highlight<\/strong>: Stored UTM item being edited gets a blue border and tint<\/li>\n<li><strong>Saved UTM Highlight<\/strong>: Newly saved or updated UTM gets a primary-color highlight with 3-second fade-out animation, auto-scrolls into view<\/li>\n<li><strong>Auto-Copy on Save<\/strong>: Coded URL is automatically copied to clipboard after saving\n\n<ul>\n<li>Toast message: \"UTM saved \u2014 coded URL copied to clipboard!\"<\/li>\n<li>Graceful fallback if clipboard access is denied<\/li>\n<\/ul><\/li>\n<li><strong>Param Value Indicators<\/strong>: UTM parameter cards show primary-color border when they have a value<\/li>\n<li><strong>Scroll Behavior<\/strong>: Edit and import scroll to the top of the UTM Parameters card; save scrolls to the highlighted stored UTM<\/li>\n<\/ul>\n\n<h4>EDIT BUG FIXES<\/h4>\n\n<ul>\n<li><strong>Fixed hasUnsavedChanges<\/strong>: Now compares against a snapshot of the loaded UTM values instead of static empty defaults<\/li>\n<li><strong>Fixed Coded URL Regeneration<\/strong>: Editing a UTM no longer generates a new random coded URL value on every keystroke \u2014 preserves the original coded URL so shared links aren't broken<\/li>\n<li><strong>Fixed Watcher During Edit Load<\/strong>: Added <code>isLoadingEdit<\/code> guard to prevent the deep watcher from firing multiple times while populating the form during edit<\/li>\n<li><strong>Fixed Custom Params Shallow Copy<\/strong>: Edit now deep-copies custom parameters to prevent mutation of stored UTM data<\/li>\n<\/ul>\n\n<h4>SECURITY ENHANCEMENTS<\/h4>\n\n<ul>\n<li><p><strong>Allowlist-Based Sanitization<\/strong>: Replaced blocklist <code>sanitizeUtmValue()<\/code> with normalize-and-allowlist approach<\/p>\n\n<ul>\n<li>NFKC normalization collapses fullwidth characters (e.g., <code>\uff47\uff4f\uff4f\uff47\uff4c\uff45<\/code> \u2192 <code>google<\/code>)<\/li>\n<li>Strips zero-width characters, directional overrides, and BOM marks<\/li>\n<li>Allowlist filter: only <code>a-z<\/code>, <code>0-9<\/code>, <code>_<\/code>, <code>-<\/code>, <code>.<\/code>, space survive<\/li>\n<li>Blocks emoji, non-standard whitespace, control characters, and all non-Latin input<\/li>\n<\/ul><\/li>\n<li><p><strong>Strict Custom Key Sanitization<\/strong>: New <code>sanitizeCustomKey()<\/code> function for custom parameter keys<\/p>\n\n<ul>\n<li>Only <code>a-z<\/code>, <code>0-9<\/code>, <code>_<\/code>, <code>-<\/code> allowed (no spaces or periods)<\/li>\n<\/ul><\/li>\n<li><p><strong>Custom Parameter Input Validation<\/strong>: Blur-based validation for custom parameter keys and values<\/p>\n\n<ul>\n<li>Key validation: rejects invalid characters, standard UTM name collisions, <code>utm_<\/code> prefix, and duplicate keys<\/li>\n<li>Value validation: rejects query-breaking and injection characters<\/li>\n<li>Immediate feedback via warning toasts \u2014 invalid input is rejected and field is cleared on blur<\/li>\n<li>Uppercase input silently normalized to lowercase on blur (e.g., <code>TEST<\/code> \u2192 <code>test<\/code>)<\/li>\n<li>Save-time sanitization via <code>sanitizeCustomKey()<\/code> \/ <code>sanitizeUtmValue()<\/code> as final safety net<\/li>\n<\/ul><\/li>\n<li><p><strong>Dropdown Value Sanitization<\/strong>: <code>handleAddFromDropdown()<\/code> sanitizes via allowlist before setting v-model<\/p>\n\n<ul>\n<li>Strict equality check rejects any input altered by sanitization (e.g., <code>&lt;script&gt;alert(1)&lt;\/script&gt;<\/code> \u2192 rejected)<\/li>\n<li>Dirty value guard in watcher silently clears pre-existing dirty options on selection<\/li>\n<\/ul><\/li>\n<li><p><strong>Landing Page Path Hardening<\/strong>: Five-layer validation for the landing page path<\/p>\n\n<ul>\n<li>Layer 3: Character allowlist \u2014 only <code>a-z<\/code>, <code>0-9<\/code>, <code>-<\/code>, <code>_<\/code>, <code>.<\/code>, <code>\/<\/code> allowed (rejects commas, spaces, special chars)<\/li>\n<li>Layer 4: Path traversal protection \u2014 blocks <code>..\/<\/code>, <code>.\/<\/code>, leading\/trailing dots, <code>\/.<\/code> patterns<\/li>\n<li>Layer 5: Malformed path detection \u2014 blocks consecutive slashes (<code>\/\/<\/code>)<\/li>\n<\/ul><\/li>\n<li><p><strong>Import Domain Validation<\/strong>: Imported URLs are validated against the site domain \u2014 mismatched domains are rejected with a clear error message<\/p><\/li>\n<\/ul>\n\n<h4>IMPROVEMENTS<\/h4>\n\n<ul>\n<li><p><strong>inPipeBaseSelect Component<\/strong>: Complete rebuild with custom dropdown mode<\/p>\n\n<ul>\n<li>Custom dropdown with deletable options, inline custom value input, keyboard navigation<\/li>\n<li>ARIA combobox\/listbox roles for accessibility<\/li>\n<li>Click-outside close, escape key handling, arrow key navigation with highlighted index<\/li>\n<li>Falls back to native <code>&lt;select&gt;<\/code> when <code>deletableOptions<\/code> is not provided<\/li>\n<\/ul><\/li>\n<li><p><strong>Coded URL Landing Path<\/strong>: Both full URL and coded URL now include the landing page path<\/p><\/li>\n<li><strong>Placeholder Update<\/strong>: Landing page placeholder changed to <code>page\/subpage<\/code><\/li>\n<li><strong>Emoji to Lucide Icons<\/strong>: Replaced all emoji icons in UTM Coder with Lucide icon components (Download, RefreshCcw, Pencil, Trash2, Save, Copy, Check, Loader, Plus, Zap, CircleAlert, Rocket)<\/li>\n<li><strong>Stored UTMs Spacing Fix<\/strong>: Fixed <code>space-y<\/code> (Tailwind-only utility) not working in plain CSS \u2014 replaced with flexbox gap for proper spacing between stored UTM items and URL rows<\/li>\n<\/ul>\n\n<h4>NEW FILES<\/h4>\n\n<ul>\n<li><code>includes\/core\/class-inpipe-utm-options-manager.php<\/code> \u2014 UTM dropdown options CRUD with WordPress object caching<\/li>\n<\/ul>\n\n<h4>TECHNICAL<\/h4>\n\n<ul>\n<li>Bumped <code>INPIPE_DB_VERSION<\/code> from <code>1.0.0<\/code> to <code>1.1.0<\/code> to trigger database upgrade for users updating from v1.1.0 \u2014 ensures <code>inpipe_utm_options<\/code> table is created via <code>dbDelta<\/code><\/li>\n<li>Added <code>inpipe_utm_options<\/code> table: <code>id<\/code>, <code>field_name<\/code>, <code>option_value<\/code>, <code>is_default<\/code>, <code>created_at<\/code>, <code>updated_at<\/code> with unique index on <code>(field_name, option_value)<\/code><\/li>\n<li>Added <code>inpipe_seed_utm_options()<\/code> function in <code>install.php<\/code> with INSERT IGNORE for idempotent re-activation<\/li>\n<li>Added 3 new REST API endpoints: <code>inpipe-utm-options-fetch<\/code>, <code>inpipe-utm-options-save<\/code>, <code>inpipe-utm-options-delete<\/code><\/li>\n<li>Added <code>handle_utm_options_fetch()<\/code>, <code>handle_utm_options_save()<\/code>, <code>handle_utm_options_delete()<\/code> to <code>InPipe_API_Endpoints_Free<\/code><\/li>\n<li>Added <code>UTM_OPTIONS_FETCH<\/code>, <code>UTM_OPTIONS_SAVE<\/code>, <code>UTM_OPTIONS_DELETE<\/code> to frontend <code>API_ENDPOINTS<\/code><\/li>\n<li>Removed Gorilla tracking script from free build in <code>vite.config.js<\/code> (premium-only)<\/li>\n<li>Table added to <code>inpipe_cleanup_tables()<\/code> for proper uninstall cleanup<\/li>\n<li>Added <code>editSnapshot<\/code>, <code>editingCodedValue<\/code>, <code>isLoadingEdit<\/code>, <code>highlightedUtmId<\/code>, <code>utmParamsCard<\/code> reactive refs to UTM Coder component<\/li>\n<\/ul>\n\n\n\n<h4>1.1.0 - 2026-01-29<\/h4>\n\n<p><strong>Gorilla Food REST API Endpoint, Cache-Busting &amp; Hourly Usage Sync<\/strong><\/p>\n\n<h4>NEW FEATURES<\/h4>\n\n<ul>\n<li><strong>Hourly Usage Data Sync<\/strong>: <code>inpipe_sync_subscription_data<\/code> now fetches fresh usage data from Subscriber App API\n\n<ul>\n<li>Automatically updates <code>inpipe_usage_data<\/code> option with events_used_this_month, allowance, etc.<\/li>\n<li>Updates <code>inpipe_last_webhook<\/code> timestamp so \"Synced at\" reflects actual sync time<\/li>\n<li>No longer relies solely on Stripe webhook push - now actively pulls data hourly<\/li>\n<\/ul><\/li>\n<li><strong>Gorilla Food REST API Endpoint<\/strong>: Added <code>\/wp-json\/inpipe\/v1\/gorilla-food<\/code> endpoint for Safari ITP bypass on cached pages\n\n<ul>\n<li>Called by JavaScript when no <code>gorilla_food<\/code> cookie exists<\/li>\n<li>Sets server-side cookie via PHP (bypasses Safari 7-day ITP limitation)<\/li>\n<li>REST API endpoints bypass FastCGI page cache, ensuring PHP always executes<\/li>\n<li>Returns <code>gorilla_food<\/code> visitor ID and <code>is_new_user<\/code> boolean<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>IMPROVEMENTS<\/h4>\n\n<ul>\n<li><p><strong>Gorilla Food Cookie Optimization<\/strong>: Cookie now only set for new users<\/p>\n\n<ul>\n<li>Prevents polluting page cache with Set-Cookie headers<\/li>\n<li>Returning users already have the cookie - no need to re-set<\/li>\n<li>Improves cache efficiency on high-traffic sites<\/li>\n<\/ul><\/li>\n<li><p><strong>Cache-Busting Page Reload<\/strong>: Improved page refresh after premium installation<\/p>\n\n<ul>\n<li>Replaced <code>window.location.reload()<\/code> with cache-busting URL approach<\/li>\n<li>Adds <code>_inpipe_refresh<\/code> timestamp parameter to force fresh HTML<\/li>\n<li>Ensures premium CSS\/JS loads correctly without manual hard refresh<\/li>\n<li>Applied to both successful installation and timeout recovery flows<\/li>\n<\/ul><\/li>\n<li><p><strong>Renamed Frontend Tracking Script<\/strong>: Renamed tracking script to \"Gorilla\" for consistency<\/p>\n\n<ul>\n<li>Script handle changed from <code>inpipe-tracking<\/code> to <code>inpipe-gorilla<\/code><\/li>\n<li>Script file renamed from <code>tracking.js<\/code> to <code>gorilla.js<\/code><\/li>\n<li>Backwards-compatible: <code>window.initInPipeTracker<\/code> aliased to <code>window.initGorilla<\/code><\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>TECHNICAL<\/h4>\n\n<ul>\n<li>Added <code>handle_gorilla_food()<\/code> method to <code>InPipe_API_Endpoints_Free<\/code> class<\/li>\n<li>Registered new public REST route <code>\/inpipe\/v1\/gorilla-food<\/code> with <code>__return_true<\/code> permission<\/li>\n<li>Updated <code>set_cookie()<\/code> in <code>InPipe_Gorilla_Food_Manager<\/code> to skip returning users<\/li>\n<li>Simplified cookie path to <code>\/<\/code> for broader compatibility<\/li>\n<li>Changed error logging to use <code>inpipe_debug_log()<\/code> helper<\/li>\n<li>Removed redundant <code>log_error()<\/code> private method from Gorilla Food Manager<\/li>\n<li>Updated <code>inPipeSubscriptionComponent.vue<\/code> reload logic with URL cache-busting<\/li>\n<li>Renamed <code>wp_enqueue_script<\/code> handle from <code>inpipe-tracking<\/code> to <code>inpipe-gorilla<\/code><\/li>\n<li>Updated <code>wp_localize_script<\/code> to use new <code>inpipe-gorilla<\/code> handle<\/li>\n<\/ul>\n\n\n\n<h4>1.0.9 - 2026-01-20<\/h4>\n\n<p><strong>Server-Side Cookie for Safari ITP Bypass (gorilla_food)<\/strong><\/p>\n\n<h4>FIXES<\/h4>\n\n<ul>\n<li>Fixed duplicate error message display on subscription activation page\n\n<ul>\n<li>Removed redundant error display from <code>inPipeBaseInput<\/code> <code>:error<\/code> prop<\/li>\n<li>Error now only shows once in the styled red-bordered box<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>NEW FEATURES<\/h4>\n\n<ul>\n<li><p><strong>Gorilla Food Cookie System<\/strong>: Implemented server-side cookie system to bypass Safari ITP 7-day JavaScript cookie limitation<\/p>\n\n<ul>\n<li>Server-side PHP <code>setcookie()<\/code> creates HTTP cookie that Safari treats as first-party<\/li>\n<li>400-day cookie expiration (maximum browser-allowed duration)<\/li>\n<li>Unique 35-character visitor ID format: <code>XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX<\/code><\/li>\n<li>Uses 58-character set excluding confusing characters (O, o, l, 0)<\/li>\n<\/ul><\/li>\n<li><p><strong>Visitor Identification<\/strong>: New <code>gorilla_food<\/code> cookie provides persistent visitor identification<\/p>\n\n<ul>\n<li>Survives Safari ITP cookie restrictions that limit JavaScript cookies to 7 days<\/li>\n<li>Cookie refreshed on every page load to maintain freshness<\/li>\n<li>Bot detection to skip cookie setting for crawlers<\/li>\n<\/ul><\/li>\n<li><p><strong>dataLayer Integration<\/strong>: Gorilla food value automatically pushed to dataLayer<\/p>\n\n<ul>\n<li><code>gorilla_food<\/code> - The unique visitor identifier<\/li>\n<li><code>is_new_user<\/code> - Boolean indicating if this is a new visitor (cookie just created)<\/li>\n<li>Available at priority 1 in <code>wp_head<\/code> for all tracking scripts<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>NEW FILES<\/h4>\n\n<ul>\n<li><code>includes\/core\/cookie\/index.php<\/code> - Directory protection<\/li>\n<li><code>includes\/core\/cookie\/inpipe-gorilla-food-functions.php<\/code> - Core generation functions and constants<\/li>\n<li><code>includes\/core\/cookie\/class-inpipe-gorilla-food-manager.php<\/code> - Cookie management class<\/li>\n<li><code>includes\/core\/cookie\/class-inpipe-gorilla-food-integration.php<\/code> - WordPress hooks and dataLayer output<\/li>\n<\/ul>\n\n<h4>TECHNICAL<\/h4>\n\n<ul>\n<li>Added <code>INPIPE_COOKIE_NAME<\/code> constant (<code>gorilla_food<\/code>)<\/li>\n<li>Added <code>INPIPE_COOKIE_EXPIRY<\/code> constant (400 days)<\/li>\n<li>Added <code>INPIPE_COOKIE_ID_LENGTH<\/code> constant (35 characters)<\/li>\n<li>Added <code>inpipe_generate_gorilla_food()<\/code> function<\/li>\n<li>Added <code>inpipe_generate_random_string()<\/code> function<\/li>\n<li>Added <code>inpipe_validate_gorilla_food()<\/code> function<\/li>\n<li>Added <code>InPipe_Gorilla_Food_Manager<\/code> class<\/li>\n<li>Added <code>InPipe_Gorilla_Food_Integration<\/code> class with static access methods<\/li>\n<li>Bootstrap runs at <code>plugins_loaded<\/code> priority 5<\/li>\n<li>Cookie set at <code>init<\/code> priority 1 (before headers sent)<\/li>\n<li>dataLayer output at <code>wp_head<\/code> priority 1<\/li>\n<\/ul>\n\n<h4>PREMIUM INTEGRATION<\/h4>\n\n<ul>\n<li>Premium plugin's tracking.js now reads <code>gorilla_food<\/code> from dataLayer<\/li>\n<li>All events include <code>gorilla_food<\/code> and <code>is_new_user<\/code> fields<\/li>\n<li>PHP-collected events also include gorilla_food via <code>InPipe_Gorilla_Food_Integration::get_gorilla_food()<\/code><\/li>\n<li>Added <code>inpipe_premium_build_event()<\/code> helper function for building events with gorilla_food<\/li>\n<\/ul>\n\n\n\n<h4>1.0.8 - 2026-01-15<\/h4>\n\n<p><strong>Redis Stale Cache Recovery<\/strong><\/p>\n\n<h4>NEW FEATURES<\/h4>\n\n<ul>\n<li>Added <code>refresh_settings()<\/code> method to Settings Manager for Redis stale cache recovery\n\n<ul>\n<li>Force-reloads settings from database bypassing object cache<\/li>\n<li>Used by Connections Manager when <code>client_id<\/code> appears empty due to stale Redis cache<\/li>\n<li>Used by Usage Webhook Sender when <code>subscription_key<\/code>\/<code>subscription_status<\/code> appear empty<\/li>\n<li>Prevents \"Valid client ID not found\" error on Redis-enabled servers (e.g., Cloudways)<\/li>\n<li>Ensures usage webhooks are scheduled and sent correctly even with stale cache<\/li>\n<\/ul><\/li>\n<\/ul>\n\n\n\n<h4>1.0.7 - 2026-01-13<\/h4>\n\n<p><strong>Auto-Disable Event Tracking for Expired Subscriptions<\/strong><\/p>\n\n<h4>NEW FEATURES<\/h4>\n\n<ul>\n<li><strong>Automatic Event Tracking Disable<\/strong>: Event tracking is now automatically disabled when subscription is not active\n\n<ul>\n<li>Catches cases where subscription expired while site was offline<\/li>\n<li>Runs on plugin initialization and when subscription status changes<\/li>\n<li>Only <code>active<\/code> and <code>trialing<\/code> subscriptions can have event tracking enabled<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>IMPROVEMENTS<\/h4>\n\n<ul>\n<li><strong>Subscription Data Always Available<\/strong>: Subscription data is now always included in admin settings, not just for active premium users\n\n<ul>\n<li>Enables proper display of expired\/cancelled subscription status in UI<\/li>\n<li>Allows users to see their subscription status even after it expires<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>UI ENHANCEMENTS<\/h4>\n\n<ul>\n<li><strong>Toggle Component Disabled State<\/strong>: Added disabled prop support to base toggle component\n\n<ul>\n<li>Visual feedback with reduced opacity and grayscale filter<\/li>\n<li>Prevents interaction when disabled<\/li>\n<li>Proper ARIA accessibility attributes<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>BUG FIXES<\/h4>\n\n<ul>\n<li><strong>Fixed Auto-Refresh After Premium Upgrade<\/strong>: Page now correctly auto-refreshes after successful premium installation\n\n<ul>\n<li>Backend was missing <code>safe_to_refresh<\/code> and <code>require_refresh<\/code> flags in API response<\/li>\n<li>Frontend condition was always false, preventing the reload from triggering<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>CODE CLEANUP<\/h4>\n\n<ul>\n<li>Removed dead code from Settings Manager:\n\n<ul>\n<li>Removed unused <code>$is_premium<\/code> property<\/li>\n<li>Removed unused <code>validate_license()<\/code> method (~75 lines)<\/li>\n<li>Premium status now fully handled by <code>InPipe_Status_Manager<\/code><\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>TECHNICAL<\/h4>\n\n<ul>\n<li>Added <code>maybe_disable_event_tracking()<\/code> method to <code>InPipe_Status_Manager<\/code><\/li>\n<li>Updated <code>on_subscription_changed()<\/code> to auto-disable tracking when subscription becomes inactive<\/li>\n<li>Modified <code>get_vue_admin_settings()<\/code> to always include subscription data<\/li>\n<li>Enhanced <code>inPipeBaseToggle.vue<\/code> with disabled state styling and handling<\/li>\n<li>Fixed <code>handle_premium_install()<\/code> response to include refresh flags<\/li>\n<li>Updated <code>class-inpipe-settings-manager.php<\/code> - Removed stale-cache check, dead code cleanup<\/li>\n<\/ul>\n\n\n\n<h4>1.0.6 - 2026-01-08<\/h4>\n\n<p><strong>Redis Object Cache Compatibility Fix<\/strong><\/p>\n\n<h4>BUG FIXES<\/h4>\n\n<ul>\n<li><strong>Fixed WordPress Hooks Not Registering on Redis Cache Hit<\/strong>: Hooks were incorrectly placed inside cache check blocks, causing them to not register when object cache returned a hit\n\n<ul>\n<li>WordPress hooks are request-specific and must be registered on every request<\/li>\n<li>Cache was preventing <code>add_action()<\/code> and <code>add_filter()<\/code> calls from executing on cached requests<\/li>\n<li>Fixes cron jobs not firing, REST API endpoints not registering, and event tracking not working on Redis\/Memcached hosting<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>AFFECTED FILES<\/h4>\n\n<ul>\n<li><code>class-inpipe-utm-decoder.php<\/code> - Fixed <code>init_hooks()<\/code> method<\/li>\n<li><code>class-inpipe-premium-event-collector.php<\/code> - Fixed <code>register_wordpress_hooks()<\/code>, <code>register_pattern_based_hooks()<\/code>, and <code>initialize_form_protection()<\/code> methods<\/li>\n<\/ul>\n\n<h4>TECHNICAL<\/h4>\n\n<ul>\n<li>Moved all <code>add_action()<\/code> and <code>add_filter()<\/code> calls outside of cache check if-blocks<\/li>\n<li>Cache is now only used for debug logging purposes (first-init detection)<\/li>\n<li>WordPress automatically deduplicates identical hook registrations, making this pattern safe<\/li>\n<li>Compatible with all object cache backends: Redis, Memcached, APCu, and default (no cache)<\/li>\n<\/ul>\n\n\n\n<h4>1.0.5 - 2026-01-06<\/h4>\n\n<p><strong>Trial Subscription Support &amp; REST API Fix<\/strong><\/p>\n\n<h4>NEW FEATURES<\/h4>\n\n<ul>\n<li><strong>Trial Subscription Status Support<\/strong>: Added full support for <code>trialing<\/code> subscription status from Stripe\n\n<ul>\n<li>Trial users now properly recognized as premium users with access to all features<\/li>\n<li>Premium UI components display correctly during trial period<\/li>\n<li>Event tracking enabled for trial subscriptions<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>UI ENHANCEMENTS<\/h4>\n\n<ul>\n<li><strong>Trial Status Display<\/strong>: Added \"Trial Active\" status display in subscription management\n\n<ul>\n<li>New blue badge styling for trial status (<code>.badge-trialing<\/code>)<\/li>\n<li>Status indicator shows \"Trial Active\" instead of \"Unknown\"<\/li>\n<li>Consistent visual styling across all subscription status displays<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>BUG FIXES<\/h4>\n\n<ul>\n<li><strong>Fixed REST API 404 Errors on Cached Servers<\/strong>: Removed incorrect route caching that caused 404 errors on servers with persistent object cache (Redis\/Memcached)\n\n<ul>\n<li>Routes must be registered on every <code>rest_api_init<\/code> call; caching was preventing registration<\/li>\n<li>Fixes <code>\/wp-json\/inpipe\/v1\/*<\/code> endpoints returning 404 on cached hosting environments<\/li>\n<\/ul><\/li>\n<li><strong>Fixed Premium Detection for Trials<\/strong>: Trial subscriptions now correctly detected as valid premium subscriptions\n\n<ul>\n<li>Updated <code>isValid()<\/code> method to accept <code>trialing<\/code> status<\/li>\n<li>Updated <code>inpipe_has_premium_subscription()<\/code> SQL query to include <code>trialing<\/code><\/li>\n<li>Fixed <code>is_active<\/code> checks in API endpoints to recognize trial subscriptions<\/li>\n<\/ul><\/li>\n<li><strong>Fixed Subscription Warning Banner<\/strong>: Trial users no longer see incorrect subscription warning messages<\/li>\n<li><strong>Fixed Event Tracking for Trials<\/strong>: Event tracking now properly schedules for trial subscriptions<\/li>\n<\/ul>\n\n<h4>TECHNICAL<\/h4>\n\n<ul>\n<li>Updated <code>class-inpipe-status-manager.php<\/code> with trialing status support<\/li>\n<li>Updated <code>class-inpipe-api-endpoints-free.php<\/code> with trialing status checks and removed route caching<\/li>\n<li>Added <code>@since 1.0.5<\/code> documentation tags to all modified methods<\/li>\n<\/ul>\n\n\n\n<h4>1.0.4 - 2025-12-16<\/h4>\n\n<p><strong>Subscription Type Fix &amp; Webhook Improvements<\/strong><\/p>\n\n<h4>BUG FIXES<\/h4>\n\n<ul>\n<li><strong>Fixed Subscription Type Mapping<\/strong>: Subscription type now correctly reads from API response\n\n<ul>\n<li>Changed from <code>metadata_plan_name<\/code> to <code>plan_name<\/code> field to match actual API response<\/li>\n<li>Fixes issue where <code>subscription_type<\/code> was defaulting to \"free\" after premium upgrade<\/li>\n<li>Supported plan types: Trial, Entry, Premium, Professional, Enterprise<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>IMPROVEMENTS<\/h4>\n\n<ul>\n<li><strong>Simplified Webhook Handler<\/strong>: Refactored <code>handle_subscription_webhook()<\/code> to use action hook pattern\n\n<ul>\n<li>Now delegates webhook processing to Premium plugin via <code>inpipe_process_webhook<\/code> action hook<\/li>\n<li>Cleaner separation between Free and Premium plugin responsibilities<\/li>\n<li>Premium plugin hooks in with: <code>add_action('inpipe_process_webhook', [$this, 'process_webhook'], 10, 3)<\/code><\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>1.0.3 - 2025-12-01<\/h4>\n\n<p><strong>CRITICAL Uninstall Fix + Security Improvements + UI Fixes<\/strong><\/p>\n\n<h4>BUG FIXES<\/h4>\n\n<ul>\n<li><strong>Fixed Subscription Code Whitespace<\/strong>: Subscription codes with leading\/trailing spaces now validate correctly\n\n<ul>\n<li>Added trim() to subscription code input before validation and API submission<\/li>\n<li>Prevents \"Invalid subscription code format\" error when users paste codes with extra whitespace<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>UI ENHANCEMENTS<\/h4>\n\n<ul>\n<li><strong>Mobile Responsive Buttons<\/strong>: Fixed upgrade buttons in Settings component for mobile view\n\n<ul>\n<li>Buttons now stack vertically and take full width on screens 768px and below<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>CRITICAL BUG FIX<\/h4>\n\n<ul>\n<li><strong>Fixed Uninstall Table Removal<\/strong>: Resolved critical bug where plugin tables without wp_ prefix were not being removed during uninstallation\n\n<ul>\n<li><strong>The Issue<\/strong>: Tables like <code>inpipe_premium_test<\/code> (without wp_ prefix) were not being deleted<\/li>\n<li><strong>Root Cause<\/strong>: Code was incorrectly stripping and re-adding the WordPress prefix to ALL table names<\/li>\n<li><strong>The Fix<\/strong>: Now uses full table names directly from database without prefix manipulation<\/li>\n<li><strong>Impact<\/strong>: All inpipe tables are now properly removed, regardless of prefix pattern<\/li>\n<li><strong>Tested<\/strong>: Verified working with wp_inpipe_*, inpipe_*, and <em><\/em><em>inpipe<\/em> patterns in Docker WordPress environment<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>SECURITY ENHANCEMENTS<\/h4>\n\n<ul>\n<li><strong>Added SQL Injection Protection<\/strong>: Implemented multi-layer security for table DROP operations\n\n<ul>\n<li>Layer 1: Regex validation (alphanumeric + underscore only)<\/li>\n<li>Layer 2: Must contain 'inpipe' string<\/li>\n<li>Layer 3: esc_sql() sanitization before query<\/li>\n<li>Layer 4: Tables only from trusted SHOW TABLES source<\/li>\n<li>Layer 5: Verification with prepared statements<\/li>\n<li><strong>Result<\/strong>: All 12 security validation tests passed<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>TABLES NOW PROPERLY REMOVED<\/h4>\n\n<ul>\n<li>wp_inpipe_* (standard FREE tables)<\/li>\n<li>wp_inpipe_premium_* (PREMIUM with wp_ prefix)<\/li>\n<li>inpipe_premium_* (PREMIUM without wp_ prefix) - <strong>NOW FIXED!<\/strong><\/li>\n<li><em><\/em><em>inpipe<\/em> (backup\/custom tables)<\/li>\n<li>All variations (mixed case, numbers, various prefixes)<\/li>\n<\/ul>\n\n<h4>DOCUMENTATION<\/h4>\n\n<ul>\n<li><strong>Updated File Headers<\/strong>: Added @since 1.0.3 documentation to uninstall.php<\/li>\n<li><strong>Added Test Results<\/strong>: Comprehensive Docker test results documented<\/li>\n<li><strong>Added Security Summary<\/strong>: Full security validation documentation<\/li>\n<\/ul>\n\n\n\n<h4>1.0.3 (Previous) - 2025-11-27<\/h4>\n\n<p><strong>UI Improvements, Component Enhancements &amp; Subscription API Fix<\/strong><\/p>\n\n<h4>BUG FIXES<\/h4>\n\n<ul>\n<li><strong>Fixed Subscription Data Mapping<\/strong>: Corrected API response field mapping in subscription verification process\n\n<ul>\n<li><code>subscription_type<\/code> now correctly reads from <code>metadata_plan_name<\/code> (e.g., \"Trial\", \"Pro\", \"Business\")<\/li>\n<li><code>plan_type<\/code> now correctly reads from <code>plan<\/code> field (e.g., \"Monthly\", \"Yearly\")<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>UI ENHANCEMENTS<\/h4>\n\n<ul>\n<li><strong>Enhanced Loading Spinner<\/strong>: Added professional loading spinner with smooth animation for Vue admin app loading state<\/li>\n<li><strong>Improved Loading Container<\/strong>: Better styled loading container with centered layout and visual feedback<\/li>\n<li><strong>Button Disabled States<\/strong>: Added proper disabled button styling with visual feedback for better UX<\/li>\n<\/ul>\n\n<h4>COMPONENT UPDATES<\/h4>\n\n<ul>\n<li><strong>Base Button Component<\/strong>: Added loading spinner animation and disabled state styling<\/li>\n<li><strong>Vue Admin Controller<\/strong>: Enhanced render_admin_app with inline CSS for loading states<\/li>\n<li><strong>Settings Component<\/strong>: UI cleanups and improved layout<\/li>\n<li><strong>Subscription Component<\/strong>: Streamlined interface and better visual hierarchy<\/li>\n<li><strong>Translation Updates<\/strong>: Enhanced Vue translations for better internationalization<\/li>\n<\/ul>\n\n<h4>TECHNICAL<\/h4>\n\n<ul>\n<li>Merged upstream changes with local improvements<\/li>\n<li>Resolved merge conflicts in Vue admin and button components<\/li>\n<li>Updated doc blocks with @since 1.0.3 tags<\/li>\n<\/ul>\n\n<h4>1.0.2 - 2025-11-20<\/h4>\n\n<p><strong>Bug Fixes, Uninstall Improvements &amp; UI Updates<\/strong><\/p>\n\n<h4>BUG FIXES<\/h4>\n\n<ul>\n<li><strong>Fixed Premium Upgrade File Issue<\/strong>: Resolved file handling error during premium package installation and upgrade process<\/li>\n<li><strong>Fixed Incomplete Uninstall After Failed Premium Upgrade<\/strong>: Plugin now properly removes ALL database tables with <code>inpipe_<\/code> prefix during uninstall, preventing orphaned premium tables from breaking WordPress admin after failed upgrades<\/li>\n<li><strong>Fixed Auto-Refresh After Premium Upgrade<\/strong>: Replaced deprecated <code>window.location.reload(true)<\/code> with cache-busting URL approach to ensure premium features display immediately after upgrade without requiring manual hard refresh<\/li>\n<\/ul>\n\n<h4>UI &amp; MESSAGING UPDATES<\/h4>\n\n<ul>\n<li><strong>Updated Upgrade Messaging<\/strong>: Changed all \"Upgrade to Premium\" messaging to promote \"Premium Transmute Engine\u2122 service for WordPress\"<\/li>\n<li><strong>Enhanced Service Description<\/strong>: Added detailed messaging about seamlessly sending event data to multiple endpoints (GA4, Google Ads, Facebook Ads, Klaviyo, Big Query) processed server-side<\/li>\n<li><strong>Updated Call-to-Action Buttons<\/strong>: Changed upgrade CTAs to \"Learn More\" and \"Free Trial\" buttons with new URLs pointing to Transmute Engine pages<\/li>\n<li><strong>Improved Link Structure<\/strong>: Made \"Get a free trial today\" a clickable link in settings component<\/li>\n<li><strong>Terminology Updates<\/strong>: Changed all references from \"endPIPEs\" to \"outPIPEs\" throughout the interface<\/li>\n<li><strong>Removed Premium Feature Cards<\/strong>: Streamlined subscription component by removing individual feature cards in favor of focused upgrade messaging<\/li>\n<li><strong>Updated Support URLs<\/strong>: Changed documentation and support links to point to support.seresa.io and Seresa YouTube channel<\/li>\n<li><strong>Consistent Header Sizing<\/strong>: Standardized header sizes across Settings and Subscription components for better visual hierarchy<\/li>\n<li><strong>Optimized Button Layout<\/strong>: Compressed upgrade buttons to left-aligned layout for better visual flow<\/li>\n<li><strong>Refined Description Styling<\/strong>: Adjusted upgrade description text sizing for better readability<\/li>\n<\/ul>\n\n<h4>IMPROVEMENTS<\/h4>\n\n<ul>\n<li><strong>Simplified Uninstall Logic<\/strong>: Removed complex conditional cleanup logic - uninstall now unconditionally removes ALL tables starting with <code>inpipe_<\/code> prefix regardless of detection state<\/li>\n<li><strong>Enhanced Cleanup Reliability<\/strong>: Uninstall process no longer relies on premium detection; uses pure prefix-based table discovery to ensure complete cleanup in all scenarios<\/li>\n<li><strong>Improved WordPress Core Options Cleanup<\/strong>: Automatically removes inPIPE references from WordPress core options (<code>uninstall_plugins<\/code>, <code>recently_activated<\/code>, <code>cron<\/code>, <code>_site_transient_update_plugins<\/code>) during uninstallation<\/li>\n<li><strong>Modern Browser Compatibility<\/strong>: Updated page reload mechanism to work reliably across all modern browsers by using timestamp-based cache-busting instead of deprecated reload methods<\/li>\n<li><strong>Enhanced Premium Integration<\/strong>: Improved premium loader functionality and status manager for better premium feature detection and handling<\/li>\n<li><strong>Improved Vue Admin Interface<\/strong>: Enhanced Vue admin component with improved caching, settings management, and connection handling<\/li>\n<li><strong>Enhanced Form Components<\/strong>: Significantly improved base input component with 200+ lines of new functionality for better user input handling and validation<\/li>\n<li><strong>Updated Translation System<\/strong>: Refined Vue translations for better internationalization support with new Transmute Engine\u2122 messaging<\/li>\n<li><strong>API Endpoint Refinements<\/strong>: Improved API endpoint handling and initialization for more reliable premium integration<\/li>\n<li><strong>Button Component Enhancement<\/strong>: Added new functionality to base button component for improved user interactions<\/li>\n<li><strong>Settings Component Updates<\/strong>: Enhanced settings component with improved configuration handling and upgrade messaging<\/li>\n<\/ul>\n\n<h4>TECHNICAL ENHANCEMENTS<\/h4>\n\n<ul>\n<li>Updated 10 core files including API endpoints, status manager, Vue admin controller, and Vue components<\/li>\n<li>Added 374 new lines of functionality with 71 lines of optimization<\/li>\n<li>Improved premium loader class implementation<\/li>\n<li>Enhanced API initialization logic<\/li>\n<\/ul>\n\n<h4>1.0.1 - 2025-07-17<\/h4>\n\n<p><strong>Major Enhancement: Unified Premium Detection System<\/strong><\/p>\n\n<h4>NEW FEATURES<\/h4>\n\n<ul>\n<li><strong>Status Manager Integration<\/strong>: Implemented centralized premium detection system for consistent plugin behavior<\/li>\n<li><strong>Enhanced Uninstall Safety<\/strong>: Added intelligent premium detection during uninstallation with robust fallback mechanisms<\/li>\n<li><strong>Improved API Reliability<\/strong>: Unified premium detection across all API endpoints and initialization<\/li>\n<\/ul>\n\n<h4>IMPROVEMENTS<\/h4>\n\n<ul>\n<li><strong>Premium Detection Consolidation<\/strong>: Replaced 13+ scattered premium detection points with single unified system\n\n<ul>\n<li>API Endpoints Free: 5 detection points \u2192 1 unified Status Manager call (80% complexity reduction)<\/li>\n<li>API Initialization: 3 detection points \u2192 unified premium detection<\/li>\n<li>Smart Uninstaller: Enhanced with Status Manager integration plus 4 robust fallback methods<\/li>\n<\/ul><\/li>\n<li><strong>Enhanced Error Handling<\/strong>: Added comprehensive safety checks and graceful degradation across all components<\/li>\n<li><strong>Debug Logging<\/strong>: Improved debugging capabilities with detailed Status Manager integration logging<\/li>\n<li><strong>Code Maintainability<\/strong>: Centralized premium logic reduces maintenance overhead and improves consistency<\/li>\n<\/ul>\n\n<h4>TECHNICAL ENHANCEMENTS<\/h4>\n\n<ul>\n<li><strong>API Endpoints<\/strong>: Updated <code>handle_subscription_webhook()<\/code>, <code>handle_premium_integration()<\/code>, <code>handle_premium_install()<\/code>, and <code>handle_premium_install_status()<\/code> methods with unified premium detection<\/li>\n<li><strong>Backup System<\/strong>: Enhanced backup creation and restoration with Status Manager integration<\/li>\n<li><strong>Uninstall Process<\/strong>: Added <code>is_uninstall_context_safe()<\/code> method for secure Status Manager usage during plugin removal<\/li>\n<li><strong>WordPress Standards<\/strong>: Maintained full compliance with WordPress coding standards and best practices<\/li>\n<\/ul>\n\n<h4>SECURITY &amp; RELIABILITY<\/h4>\n\n<ul>\n<li><strong>Uninstall Context Safety<\/strong>: Added pre-flight checks before Status Manager usage during uninstallation<\/li>\n<li><strong>Database Validation<\/strong>: Enhanced database connection verification and WordPress function availability checks<\/li>\n<li><strong>Graceful Degradation<\/strong>: Improved fallback mechanisms when Status Manager unavailable<\/li>\n<li><strong>Exception Handling<\/strong>: Comprehensive error handling prevents fatal errors during premium detection<\/li>\n<\/ul>\n\n<h4>COMPATIBILITY<\/h4>\n\n<ul>\n<li><strong>Backward Compatibility<\/strong>: All existing functionality preserved with zero breaking changes<\/li>\n<li><strong>WordPress Core<\/strong>: Fully compatible with WordPress 5.0+ requirements<\/li>\n<li><strong>PHP Compatibility<\/strong>: Maintains PHP 7.4+ compatibility with improved error handling<\/li>\n<li><strong>Performance<\/strong>: Enhanced premium detection with minimal performance overhead<\/li>\n<\/ul>\n\n<h4>DEVELOPER NOTES<\/h4>\n\n<ul>\n<li><strong>Class Documentation<\/strong>: Updated DocBlocks with @since 1.0.1 tags for all modified methods<\/li>\n<li><strong>API Preservation<\/strong>: 100% API functionality maintained - all endpoints continue to work identically<\/li>\n<li><strong>Hook Integration<\/strong>: All WordPress action and filter hooks preserved without modifications<\/li>\n<li><strong>Debug Support<\/strong>: Enhanced debugging capabilities for troubleshooting premium detection issues<\/li>\n<\/ul>\n\n<h4>FILES UPDATED<\/h4>\n\n<ul>\n<li><code>uninstall.php<\/code> \u2013 Stripped constructor and 4 internal methods: smart uninstaller setup and safety validation<\/li>\n<li><code>inpipe-by-seresa.php<\/code> \u2013 Removed 15 init, activation, component loading, and logging functions<\/li>\n<li><code>includes\/core\/class-inpipe-vue-admin.php<\/code> \u2013 Stripped Vue admin controller constructor and 4 methods for cached settings and connections<\/li>\n<li><code>includes\/core\/class-inpipe-status-manager.php<\/code> \u2013 Removed 21 premium detection, validation, and mode management methods<\/li>\n<li><code>includes\/core\/class-inpipe-settings-manager.php<\/code> \u2013 Stripped constructor and <code>load_settings<\/code> logic<\/li>\n<li><code>includes\/core\/class-inpipe-feature-manager.php<\/code> \u2013 Stripped <code>InPipe_Feature_Manager<\/code> core feature loader<\/li>\n<li><code>includes\/free\/premium-upgrade\/class-inpipe-simple-subscription-verifier.php<\/code> \u2013 Removed <code>verify_with_server<\/code><\/li>\n<li><code>includes\/free\/premium-upgrade\/class-inpipe-premium-integrator.php<\/code> \u2013 Removed <code>integrate_package<\/code> and <code>rollback_integration<\/code><\/li>\n<li><code>includes\/free\/premium-upgrade\/class-inpipe-package-installer.php<\/code> \u2013 Stripped 6 installer and package handling methods<\/li>\n<li><code>includes\/free\/premium-upgrade\/class-inpipe-backup-manager.php<\/code> \u2013 Stripped constructor and <code>ensure_wp_constants<\/code><\/li>\n<li><code>includes\/core\/api\/inpipe-api-init.php<\/code> \u2013 Stripped <code>inpipe_init_api_endpoints<\/code><\/li>\n<li><code>includes\/core\/api\/class-inpipe-api-endpoints-free.php<\/code> \u2013 Stripped 8 methods covering public UTM validation, premium integration, webhook handling, backup, and install status<\/li>\n<\/ul>\n\n<h4>UPGRADE NOTES<\/h4>\n\n<ul>\n<li><strong>Automatic Enhancement<\/strong>: Existing installations automatically benefit from improved premium detection<\/li>\n<li><strong>No Configuration Required<\/strong>: Changes are transparent to end users<\/li>\n<li><strong>Plugin Stability<\/strong>: Enhanced reliability for both free and premium installations<\/li>\n<li><strong>Debugging Improvements<\/strong>: Better error reporting and diagnostic capabilities<\/li>\n<\/ul>\n\n<h4>1.0.0 - 2025-07-07<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Generate, store, and decode UTM parameters for enhanced tracking in Google Analytics, Facebook Ads, and other platforms with dataLayer integration.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/227396","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=227396"}],"author":[{"embeddable":true,"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/seresa8"}],"wp:attachment":[{"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=227396"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=227396"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=227396"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=227396"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=227396"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/tg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=227396"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}