Changelog · Free
What's new in Syncly
Every release of the free Syncly for GoHighLevel plugin: sync engine, field mapping, forms, restrictions, and dashboard improvements.
All notable changes to Syncly will be documented in this file.
1.4.41 - 2026-09-20
Added
- Added "Inbound Contact Actions" setting in Webhooks tab with three modes: Create & Update (default), Create Only, and Update Only. Admins can now control whether incoming GoHighLevel webhooks create new WordPress users, update existing users, or both.
- Bulk Sync to GHL: user meta key filter is now a searchable dropdown that lists existing user meta keys, and the meta value filter offers all stored values for the chosen key with multi-select and custom value support.
- Fixed duplicate email error when inbound webhook tries to create a WordPress user with an existing email address. The plugin now logs these as "skipped" instead of "failed" and returns the existing user ID gracefully.
- Fixed ContactCreate and ContactUpdate webhooks attempting to create users when email already exists in WordPress, even with different GoHighLevel contact IDs. Now returns existing user without error.
1.4.40 - 2026-09-09
Fixed
- Fixed
remove_tagsfailing with "Contact not found" when a contact was deleted or merged in GoHighLevel. Tag removal on a non-existent contact is now treated as idempotent (already done), and the stale contact ID is cleaned up from WordPress user meta. - Fixed
add_tagsfailing permanently when a cached contact was deleted or merged in GHL — now returns a graceful skip and cleans up stale meta. - Fixed
user_register/profile_updatefailing permanently when the provided or cached contact ID was stale — now falls through to create a new contact in GHL. - Fixed
delete_userfailing permanently when the contact was already deleted in GHL — now returns idempotent success and cleans up stale meta. - Fixed
gf_add_notefailing permanently when the contact no longer exists — now returns a graceful skip. - Fixed
UserMetaSyncleaving stale contact IDs in user meta when the GHL contact no longer exists — now cleans up on "not found". - Fixed inbound webhook sync overwriting a WordPress user's name when a duplicate contact with the same email but different GHL contact ID triggers an update. The plugin now rejects inbound updates from unrecognized contact IDs to prevent data overwrites.
- Client auto-recovery now returns immediate success for DELETE requests on non-existent contacts, even when the request body doesn't contain an email for merged-contact lookup.
- Custom Objects: added ability to create new custom object schemas directly from the WordPress admin via
CustomObjectAjaxHandler::create_custom_object_schema(). - Custom Objects: added
CustomObjectResource::get_associations_for_object()for per-object association lookup. - Custom Objects: expanded the post type list to include
show_uitypes with asyncly_supported_post_typesfilter for extensions.
- Custom Objects: background queue processing (
enable_batch_sync) and sync logging (log_sync_operations) are now always enabled for all mappings — the toggle has been removed. - Custom Objects: field mappings now include a
patternfield for transform support.
1.4.39 - 2026-08-30
Added
- Added a per-user Simple/Advanced display mode. New installs default to a beginner-friendly Simple dashboard; existing installs keep the full Advanced interface (every settings tab, Sync Logs, etc.). The choice is offered in the Setup Wizard and switchable anytime from the dashboard.
- The Setup Wizard now asks you to pick your preferred view (Simple or Advanced) before connecting, with redesigned mode cards.
- The connection screen now lists the exact GoHighLevel permissions (OAuth scopes) the plugin will request, sourced from the single
Client::OAUTH_SCOPESdefinition.
- Reordered the Setup Wizard steps so connecting to GoHighLevel is no longer a blocker — the Continue button is always available, and the connection step moved to step 3 (after the View selection).
- OAuth returns now honor the location the connection started from: the Setup Wizard returns you to the exact step you left (
step=3), and admin connections return to the Syncly dashboard instead of a generic admin URL — so reconnecting no longer abandons the wizard. OAuthHandler::get_authorization_url(),generate_state_token(), andget_state_return_url()now route the post-authorization redirect correctly.- Replaced remaining hardcoded colors in the user profile screen with the shared GHL design tokens so branding stays consistent.
1.4.38 - 2026-08-29
Fixed
- Fixed user profile tags sometimes displaying as raw tag IDs (instead of names) and being synced to GoHighLevel as IDs when the OAuth connection was temporarily unhealthy. The plugin now persists a durable tag ID → name map on every successful tag fetch and falls back to it during API outages, so profile tag names and outbound sync payloads always use the real names.
1.4.37 - 2026-08-28
Added
- Added a dismissible review-request banner on the Syncly admin dashboard that invites users to leave a review on WordPress.org after 3 days of plugin usage.
- Recorded the plugin activation date on first activation so the review request can be timed appropriately.
1.4.36 - 2026-08-28
Added
- Added the
calendars/events.writeOAuth scope for GoHighLevel calendar appointment booking, used by Syncly Pro's product auto-booking feature. - Broadened the OAuth scope set to align with the GoHighLevel marketplace draft: calendars (read/write), workflows, conversations, and conversation messages.
- Fired a new
syncly_cache_clearedaction when the dashboard "Clear Cache" button or a location/connection change purges caches, so Syncly Pro can clear its cached calendars and workflows too. - Added
ContactResource::get_by_id()(full-detail contact including tags and custom fields) andContactResource::update_custom_fields()for Syncly Pro's public REST endpoints.
- The REST API manual sync trigger now accepts
all,users,contacts, andforms; unknown types receive a 400 error. - The manual sync trigger now processes the queue immediately (the same code path as the scheduled auto-sync) and returns queue status in its response.
- Added
Client::set_api_version()/get_api_version()so API consumers can switch GHL API versions for individual requests. - Rebuilt the Webhook Setup settings screen on the GHL design-token styling.
- Removed the obsolete Campaigns scope from OAuth and scope checking.
- Added Upgrade page descriptions for two new Syncly Pro features: Auto-Book GHL Calendar and GHL Workflow Enrollment.
1.4.35 - 2026-08-28
Added
- Added reusable GHL components to the global stylesheet (globals.css): checkbox toggles, buttons (ghl-button), form inputs (ghl-input/ghl-select), and Select2 dropdown styling.
- Gravity Forms settings: the GHL field selector is now a searchable Select2 dropdown.
- Consolidated admin, frontend, and public styling onto shared GHL design tokens (colors, spacing, typography, radii, shadows) for consistent branding across every screen.
- Dashboard tab navigation now lives in dashboard.css (inline styles removed) and the active tab uses the brand accent color.
- Roles/Permissions tag toggles ("Auto-apply tags", "Remove on change") now use the branded GHL checkbox switch.
- Gravity Forms settings inputs/buttons and the conditional mapping row now use GHL component classes (ghl-input, ghl-select, ghl-button).
- Refactored enqueueing for admin columns and user profile assets through AssetsManager; global design tokens now load on every Syncly admin screen.
- "View in GHL" links in user columns and profile fields now respect the configured white-label brand setting.
1.4.34 - 2026-08-26
Added
- Added advanced bulk sync to GHL with filters: user role, sync status, and user meta key/value.
- Added advanced bulk import from GHL with filters: search query (name, email, phone), GHL tag filter, and import mode (all, new only, existing only).
- Added live user count preview when filtering bulk sync users.
- Added live contact preview when filtering bulk import contacts.
- Added silent reconnect: "Reconnect Account" button now attempts a proxy token refresh before redirecting to GHL. Users with valid tokens get a fresh 24h token instantly without leaving WordPress.
- Fixed OAuth proxy domain references from labgenz.com to synclyforgohighlevel.com in Client.php (proxy URL, redirect URI, and all docblock comments).
- Fixed token refresh to send form-encoded data instead of JSON, matching what the proxy's
/refresh-tokenendpoint expects. - Fixed plugin header Version tag to match SVN release tag.
- Updated all admin menu references from "GHL CRM" to "Syncly".
1.4.33 - 2026-08-24
Updated
- Updated service URLs to synclyforgohighlevel.com.
- Fixed release workflow to deploy WordPress.org assets only on manual dispatch.
1.4.32 - 2026-08-24
Fixed
- Fixed Gravity Forms note sometimes failing with "Contact not found" by using the in-memory contact cache instead of hitting GHL's eventually-consistent search API.
1.4.31 - 2026-08-23
Added
- Added atomic OAuth refresh locking, safe transient API retries with request correlation, and shared-client connection verification.
- Added webhook delivery deduplication, malformed-JSON rejection, and retryable failure responses.
- Added atomic queue claims, atomic rate-limit reservation, stale final-attempt recovery, and short tag-fetch failure backoff.
- Added regression coverage for API reliability, webhook validation, OAuth state binding, queue dependency waits, and log redaction.
- Fixed plugin activation and deactivation hooks so installation setup, database initialization, cleanup scheduling, and setup-wizard redirects run from the actual
syncly.phpbootstrap file. - Fixed dependency-waiting queue jobs so they return to
pendingwithout consuming a retry attempt. - Renew the queue-processing lock while a batch is actively being processed, preventing overlapping workers during slow remote API calls.
- Stopped OAuth authorization codes and state values from being written to file logs; structured log context now redacts credentials defensively.
- Require the same authenticated administrator who started OAuth to complete its callback.
- File logging is now opt-in via
SYNCLY_BRIDGE_LOGand includes IIS protection plus nginx deployment guidance. - CI now verifies the advertised PHP 7.4 minimum alongside PHP 8.1, validates Composer metadata, and runs a complete PHP syntax check.
- Deployment workflow now deploys the tagged release rather than force-resetting production to the latest
mainbranch.
1.4.27 - 2026-08-21
Added
- Added Gravity Forms integration with a dedicated per-form Syncly settings tab.
- Added field mapping, per-form tags, duplicate update behavior, source naming, configurable queue delay, spam-entry protection, optional contact timeline notes, sync history, and resend controls for Gravity Forms submissions.
- Added Syncly Pro conditional submission rules for Gravity Forms.
- Added Gravity Forms Automation to the centralized Upgrade to Pro feature list.
- Gravity Forms synchronization uses the existing asynchronous Action Scheduler queue.
1.4.26 - 2026-08-20
Added
- Redesigned the setup wizard with a cleaner layout, nicer buttons, and a bigger celebration when setup finishes.
- The setup wizard now clearly shows Pro-only integrations (WooCommerce, LearnDash, Custom Objects, Abandoned Cart Recovery, Webhooks, Login Sync) so free users know what upgrading unlocks.
- Added an optional "Help Improve Syncly" toggle in the setup wizard for sharing anonymous usage data.
- Requested the GoHighLevel
campaigns.readonlypermission during OAuth and added acampaignsscope check, enabling campaign lookups for campaign enrollment features.
- Fixed a setup wizard layout bug that could show a broken, overlapping "Back/Continue" bar on some steps.
- Fixed a bug where the setup wizard showed a "failed to save" message even when settings were saved successfully.
- Fixed a bug where a default registration tag entered in the setup wizard was not being saved.
- Removed a "Role-Based Tags" toggle from the setup wizard that had no real effect on its own; that feature is configured on its own settings page.
- Fixed the Elementor widget category and Gutenberg block category to always show the current plugin name instead of an outdated hardcoded label.
- Updated the OAuth connection proxy domain used for GoHighLevel authentication.
1.4.24 - 2026-08-13
Fixed
- Removed lingering legacy branding references from the active admin UI and runtime code paths.
- Kept the WordPress release workflow and external service documentation aligned with the current Syncly public site.
1.4.21 - 2026-08-11
Fixed
- Removed outdated Opportunities and Workflows OAuth scopes from the GoHighLevel connection flow so the plugin uses the current app permissions required by the integration.
1.4.20 - 2026-08-09
Added
- Added a Tag Rules Impact panel to the user profile screen that shows which site automations apply to that user's current GoHighLevel tags.
- Added Contact Form 7, Elementor, and Gutenberg tag automations to the Tag Rules page so every free-tier tag rule is listed in one place.
- Added Rule Safety warnings that highlight tag configurations which can unintentionally bypass content restrictions.
1.4.19 - 2026-08-09
Changed
- Added Tag Rules, a single page that shows all tag automations on the site in one place so admins can quickly review what happens when a contact has a given tag.
1.4.18 - 2026-08-09
Changed
- Refreshed the Upgrade to Pro page to highlight the latest Syncly Pro automation features for roles, memberships, subscriptions, and content access.
1.4.17 - 2026-08-09
Added
- Added support for creating a GoHighLevel tag directly from the tag selector when an entered tag does not already exist in the connected GoHighLevel account.
- Added page-view outcome tagging controls so contacts can be tagged when access to a protected page is approved or denied.
- Added bidirectional tag-to-role sync so GoHighLevel tags can automatically assign matching WordPress roles.
- Added clearer in-app Pro upsell messaging in Role Tags settings for approve/deny automation capabilities.
- Updated role/tag and membership settings flows for improved admin configuration reliability.
1.4.15 - 2026-08-07
Fixed
- Fixed a sync loop issue where updates coming from GoHighLevel could sometimes trigger the same update again in WordPress.
- This now protects user creation, profile updates, user deletion, and tag updates so they do not bounce back and forth between systems.
- Fixed the Webhooks settings buttons so Copy URL, Copy Token, Regenerate Token, and Test Webhook all work reliably again.
- The Webhooks settings page now uses the shared admin script for its button behavior, which makes it more reliable and easier to maintain.
1.4.14 - 2026-08-04
Added
- Added a GoHighLevel Tags filter to the WordPress Users table.
- Scoped the Users table tag filter to the active GoHighLevel location by querying only the location-scoped stored contact tag meta.
- Added Select2 enhancement for the Users tag filter so admins can search large tag lists without extra API requests.
1.4.13 - 2026-08-02
Fixed
- Field Mapping now persists each row's selected GHL field data type and restores it correctly after page reload instead of defaulting back to
TEXT. - Registration date mapping now syncs correctly for
DATEcustom fields by includinguser_registeredin mapped user source data and normalizing date values toY-m-dbefore sending to GoHighLevel.
- Updated custom-field type allowlists and Field Mapping type selectors to the current GoHighLevel-supported values:
TEXT,LARGE_TEXT,NUMERICAL,PHONE,MONETORY,CHECKBOX,SINGLE_OPTIONS,MULTIPLE_OPTIONS,FLOAT,TIME,DATE,TEXTBOX_LIST,FILE_UPLOAD,SIGNATURE,RADIO.
1.4.12 - 2026-08-02
Changed
- Added typed custom-field creation support (
DATE,NUMBER, andTEXT) for shared field-mapping create flows used by Syncly Pro settings. - Added deferred create-option resolution in settings save so Login Sync field selections can create missing GHL custom fields reliably on save.
- Improved user profile contact ID display resolution to prefer location-scoped contact meta and safely fall back to legacy contact keys.
1.4.11 - 2026-08-02
Changed
- Unified custom-field creation behavior so Pro settings screens now use the free plugin's existing field-mapping custom-field creation and existing-field selection flow.
- Added support in the shared field-mapping script for Pro-style standard select controls triggered by
.ghl-create-custom-field-btn. - Removed dependency on a separate Pro-only custom-field creator script to prevent duplicated logic.
1.4.10 - 2026-08-01
Changed
- Queue processing cadence now runs every 5 minutes instead of every 10 seconds to reduce constant background churn and server pressure.
- Added a one-time schedule migration that clears legacy high-frequency
syncly_process_queuejobs and re-seeds with the new cadence. - Action Scheduler loading is now conditional: Syncly loads its bundled copy only when no Action Scheduler provider is already available.
1.4.9 - 2026-07-31
Added
- Field Mapping: users can now create a brand-new GoHighLevel custom field directly from the mapping dropdown. Type a name that doesn't match any existing field and a "+ Create new GHL field: …" option appears; selecting it calls the GHL custom fields API (TEXT type), registers the returned field ID in the local cache, and selects it immediately — no page reload required.
- Field Mapping lazy dropdown search now excludes the "create" option from the standard filter loop, so it is always visible while the user is typing.
1.4.8 - 2026-07-15
Fixed
- Dropdown and tag selector styling no longer conflicts with LearnDash, WooCommerce, or other plugins, Syncly's styles now only apply inside Syncly's own admin pages.
- Releases are now automatically published to the WordPress.org plugin directory when a new version is tagged.
1.4.7 - 2026-07-11
Changed
- Security hardening: removed registration-time trust of request role input and now uses persisted user role data for role-tag sync.
- Security hardening: strengthened admin AJAX guards by enforcing capability checks alongside nonce validation.
- Security hardening: required admin capability for OAuth admin callback handling before processing query parameters.
1.4.6 - 2026-07-10
Changed
1.4.5 - 2026-07-09
Changed
1.4.1 - 2026-06-23
Removed
- Global Tags — Moved to Pro; free plugin shows an informational notice and delegates rendering/resolution via extension hooks.
- A shared plugin-name constant used everywhere the plugin's display name appears.
---
1.3.15 - 2026-06-07
Fixed
- GitHub release build — Moved staging and zipping into the runner temp directory so release artifacts are built from a clean copy instead of inside the repository tree.
- Release artifact hygiene — Prevented self-inclusion of generated
build/anddist/folders in downloadable release zips.
---
1.3.14 - 2026-06-07
Fixed
- OAuth reconnect flow — Rewired the dashboard reconnect button to start the real OAuth reauthorization flow instead of only attempting a silent token refresh.
- OAuth recovery consistency — Aligned emergency reconnect token exchange with the primary OAuth callback redirect URI to avoid intermittent reconnect failures.
- Release packaging — Excluded hidden repository files like
.githuband.gitignorefrom GitHub release artifacts and added workflow checks to enforce it.
---
1.3.13 - 2026-06-06
Fixed
- Plugin Check compliance — Fixed 7 remaining WordPress.org plugin check errors:
- Added translator comment for sprintf() with placeholders in OAuth token refresh message
- Updated Gutenberg block apiVersion from 2 to 3 for WordPress 7.0+ iframe editor compatibility
- Fixed SQL prepared statements with proper phpcs comments in sync log query
- Replaced WP 5.9+ functions (str_starts_with, str_contains) with WP 5.8-compatible alternatives (strpos)
---
1.3.12 - 2026-06-06
Changed
- API Key connection method — Hidden API Key tab in connection setup. OAuth is now the only available connection method for enhanced security and maintainability.
---
1.3.11 - 2026-06-06
Fixed
- Release workflow artifact path — Corrected build directory navigation so GitHub Actions reliably generates and validates the release zip.
---
1.3.10 - 2026-06-06
Fixed
- GitHub release artifact reliability — Release workflow now installs Composer production dependencies inside the packaged build directory and validates that vendor/autoload.php exists in the final zip.
---
1.3.9 - 2026-06-06
Changed
- WordPress.org readiness — Updated plugin metadata, plugin-check compliance, and release packaging safeguards for production zip artifacts.
- Plugin Check errors — Resolved i18n translator comments, prepared SQL usage, direct file access checks, review link policy, and release metadata mismatches.
---
1.3.8 - 2026-05-10
Fixed
- Test Link Debugger — Now reads actual field mappings from settings instead of hardcoded field names. If phone is mapped to
billing_phone, the tool will correctly read that field.
---
1.3.7 - 2026-05-10
Changed
- Test Link Debugger — Removed GHL API fallback. Test tool now reads exclusively from WordPress user meta. All contact fields must be synced to WP user profile first.
---
1.3.6 - 2026-05-10
Fixed
- Test Link Debugger — Empty fields now display as plain text
(empty)instead of HTML markup.
---
1.3.5 - 2026-05-10
Added
- Field Privacy — New "Hide Fields From Guests" setting in Personalization tab. Admin selects which contact fields to hide from campaign visitors (defaults to showing all).
- Test Link Debugger — New tool in Personalization settings to test signed campaign URLs and see exactly what contact data and fields would resolve.
- Personalization UX — Simplified field visibility logic from allowlist to denylist (hide specific fields instead of allow specific fields).
---
1.3.4 - 2026-05-10
Removed
- Personalization strict mode — Earlier plain contact-ID personalization was removed; current builds require campaign contact links with an access token before guest state is persisted.
---
1.3.3 - 2026-05-10
Changed
- Personalization safe mode only — Removed
ghl_cidauto-login behavior from runtime handling. - Personalization settings UI — Removed the "Auto-Login Matched User" option from the free plugin settings.
---
1.3.2 - 2026-05-10
Changed
- Personalization (Free) — Removed live guest contact fetch from the free plugin when a campaign contact does not map to a WordPress user.
- Personalization settings UI — Removed the "Live GHL Fetch (No WP User)" section from the free settings screen.
---
1.3.1 - 2026-05-10
Added
- Dashboard documentation shortcut — Added a direct "Documentation" quick action link in the main plugin dashboard to
http://synclyforgohighlevel.com/documentation/.
- Personalization free/pro split — Guest personalization remains available in Free for signed campaign contacts mapped to WordPress users, while advanced behaviors are now Pro-gated.
- Personalization settings UI — Pro-only controls remain visible in Free but are locked with clear "This is a PRO feature" messaging, matching the existing lock pattern used in other settings tabs.
- New Pro unlock flags — Added
ghl_crm_cid_autologin_enabledandghl_crm_cid_guest_live_fetch_enabledhooks so Pro can unlock auto-login and live guest contact fetching.
---
1.3.0 - 2026-05-10
Added
- Email campaign personalization — New
ContactIdHandlerclass handles protected contact URL parameters from email campaigns. Guest visitors get their contact ID persisted in a signed HttpOnly cookie for shortcode personalization across page loads. [ghl_user_meta]guest support — Shortcodes now resolve field values for non-logged-in visitors. If the contact maps to a WP user, WP user meta is read directly (same keys as logged-in). For contacts with no WP account, data is fetched from the GHL API and cached as a transient.- Personalization settings tab — New dedicated "Personalization" tab in the plugin settings with: enable toggle, auto-login toggle, campaign token input, strict token mode toggle, and copy link template helper.
TagManager::find_user_by_contact_id()— New method to look up a WP user by their linked GHL contact ID, with location-scoped and legacy key fallback.- Strict mode — Optional
require_ghl_cid_tokensetting. When enabled, requires a valid campaign access token in the URL before persisting guest data. - Auto-login via protected link — When enabled and a valid campaign access token is present, automatically logs in the matched WP user.
---
1.2.1 - 2026-04-10
Added
- Login Sync settings tab — Full SPA-routed settings page with custom field mapping (select2), conditional tag assignment (first-login / every-login), inactivity tag removal, and tag-based redirect rules with CPT URL picker.
- Auto-create GHL contact on login — When a logged-in user has no GHL contact, the queue processor now falls back to
user_registerto create the contact automatically. ghl_crm_login_register_payloadfilter — New filter hook allows Pro (or third-party code) to enrich the register payload with login-specific custom fields and tags in a single API call.- Login field sync — User login now updates
last_loginandlogin_countcustom fields in GHL on each login.
- WooCommerce product tags —
locationIdrejection —add_tags()was injectinglocationIdinto the POST body sent tocontacts/{id}/tags, which GHL rejects with"property locationId should not exist". Fixed by suppressing body injection for that endpoint. - MetadataService
refresh_metadata— Custom fields transient was never saved during metadata refresh; only tags were persisted. Now saves both.
- Error event logging — Errors now capture a PHP backtrace and environment details for easier remote debugging.
- Log sanitization — Context passed to the file logger now has sensitive keys redacted and inline secrets scrubbed before storage.
- Queue processor — Streamlined user action routing; dead-end sync log entries for social-media-only contacts with no email are suppressed.
---
1.2.0 - 2026-03-26
Changed — Free / Pro Feature Separation
- AI Field Suggestions — Moved to Pro; free plugin delegates via
ghl_crm_field_suggestions_resultfilter. - Sync Preview / Dry Run — Moved to Pro; free plugin delegates via
ghl_crm_preview_user_sync_resultfilter. - Public REST API Endpoints — Moved to Pro; free plugin fires
ghl_crm_register_public_rest_routesaction for Pro to register endpoints (contacts, sync, status, webhooks). - Elementor Widget Conditions — Moved to Pro; free plugin fires
ghl_crm_init_elementor_conditionsaction. - Archive & REST API Protection — Moved to Pro; free plugin fires
ghl_crm_register_advanced_restriction_hooksaction. - Restriction Override Settings — Admin bypass and allowed-tag overrides are available in the free plugin.
- Global Tags — Moved to Pro; free plugin shows an informational notice and delegates rendering/resolution via extension hooks.
- Analytics Dashboard — Chart visualizations moved to Pro via
ghl_crm_render_analytics_tabaction; free shows upgrade CTA.
- Family Relationships Settings Tab — New teaser page with greyed-out preview and upgrade CTA for the Pro family accounts feature.
- PRO Badges — Settings sidebar tabs, field mapping auto-suggest button, restriction settings, role tag global settings, sync preview, and REST API page now show PRO badges when Pro is not active.
- Upgrade CTAs — Sync Preview, REST API, Analytics, and Family Relationships pages show full upgrade banners with greyed-out feature previews.
- Telemetry Fatal Error Filter —
capture_fatal_error()now only logs errors originating fromsynclyorsyncly-prodirectories, preventing unrelated theme/plugin errors from being sent.
- FEATURES-AND-BENEFITS.md — Updated to accurately reflect the Free vs Pro feature split.
1.1.3 - 2026-03-22
Fixed
- Action Scheduler Timing Race — Scheduled OAuth token refresh was never registering because Action Scheduler initializes at
initpriority 1 while plugin components loaded at priority 0. Deferred scheduling toaction_scheduler_inithook. - Cron/CLI OAuth Timeout — Cron and WP-CLI requests now receive 15s timeout (previously got 8s frontend timeout), preventing token refresh failures on slow connections.
- Cascading Refresh Failures — Added per-request
$refresh_failed_this_requestflag to prevent retry loops within the same PHP process. - Log Flood Prevention — Added 30-second deduplication window in FileLogger to suppress identical repeated log entries.
- Scheduled Refresh Window — Widened from 2-hour to 12-hour buffer before token expiry, ensuring low-traffic sites refresh in time.
- cURL Timeout Retry — Auto-retry on cURL error 28 with 25s timeout before falling back to reconnect flow.
- Reconnect Endpoint Timeout — Bumped from 15s to 25s for more reliable proxy communication.
- Action Scheduler Guards — Added
ActionScheduler::is_initialized()checks to NotificationManager, ReportingManager, and QueueManager scheduling methods. - Token Expiry Display — Connection status now shows exact HH:MM:SS countdown instead of approximate
human_time_diff.
- Reconnect Account Button — Quick action on reports dashboard to manually trigger OAuth token refresh.
- GHL Quick Links — Direct link to GoHighLevel dashboard from reports page.
- Compound Tag Conditions — Gutenberg blocks and Elementor widgets now support AND/OR/NOT logic for tag-based content restriction.
- Elementor Widget Rename — "GHL Restricted Content" renamed to "GHL Content" for clarity.
1.1.2 - 2026-03-21
Improved
- Compatibility — Version bump for Pro add-on 1.1.2 compatibility (LearnDash sync reliability fixes).
1.1.1 - 2026-03-19
Added
- Centralized UserMetaSync Class — Extracted all post-sync user meta logic (pending tags, tag caching, GHL refresh) from
QueueManagerinto a dedicatedUserMetaSyncclass undersrc/Sync/, registered inLoadervia theghl_crm_after_sync_successhook. - Asset Auto-Minification Pipeline — Added
matthiasmullie/minifydev dependency andbuild-minify.phpscript (composer build) that generates.min.css/.min.jsfor all plugin assets. - AssetsManager .min Auto-Detection — New
maybe_use_min_file()helper inAssetsManagerautomatically serves.minassets in production and falls back to source files whenSCRIPT_DEBUGis on.
- WooCommerce Product-Tags Queue Routing —
wc_product_tagsitems were routed through a legacyghl_crm_execute_syncfilter instead of a properregister_handler()call; now registered alongsidewc_customerinWooCommerceSync::register_queue_handlers(). - Empty Tag Sync Failure — Selecting the "Loading tags…" placeholder before tag list finished loading passed an empty string
""to the API;process_customer_conversion()andprocess_product_tags()now strip empty values witharray_filter($tags, 'strlen'). - Tag Overwrite on WC Sync —
wc_customerandwc_product_tagsuser meta updates were overwriting existing tags; now fetches current tags viaget_user_tag_ids()and merges before storing. - QueueManager Dead Code Cleanup — Removed orphaned
handle_after_sync_success(),sync_contact_tags_from_ghl()methods, and legacyghl_crm_execute_syncfilter handler from QueueManager.
- Error Catching Robustness — Changed
catch (\Exception)tocatch (\Throwable)in WooCommerceSync queue handlers to also captureTypeErrorand similar fatal errors.
1.0.2 - 2026-03-18
Improved
- Version Constant Consistency — Replaced all hardcoded version strings in
add_admin_asset()/wp_enqueue_*calls withGHL_CRM_VERSIONandGHL_CRM_PRO_VERSIONconstants for single-point version management.
- User Deletion Sync (WP→GHL) — Fixed duplicate hook registration in
UserHooksand unreliable email-based contact lookup; now resolves storedcontact_idfrom user meta. - Webhook Delete Sync (GHL→WP) — Added ping-pong prevention on the delete path via
_ghl_skip_delete_syncmeta flag. - QueueProcessor Dead Code — Removed orphaned
wc_customerandformdefault handlers; addedghl_crm_queue_processor_readyhook for handler self-registration. - CF7 Submission Timing — Changed CF7Handler from hook-based to direct
register_handler()call to fix race condition. - Settings Page jQuery Crash — Applied
CSS.escape()for dynamic tag name values in jQuery selectors across all JS files. - WooCommerce Tag Overwrite —
WooCommerceSyncconvert-lead and product-tag flows now use the additiveadd_tags()(POST) endpoint instead of the destructive full-contactupdate()(PUT). - Tag Display Special Characters (Comprehensive) — Fixed single-quote breakage in
data-saved-tagsHTML attributes viaesc_attr()aroundwp_json_encode()in 10 PHP files; replaced broken Select2data:config with DOMpopulation in 4 JS files; removed destructive$select.empty()/$select.html('')calls in 4 JS files; addedCSS.escape()in 8 JS files.
1.0.1 - 2026-03-17
Added
- LearnDash Course Progress Sync — Syncs course progress (percentage, status, completed steps, total steps) to GHL custom fields via the Pro add-on. Includes a 15-minute per-user-per-course debounce to prevent API rate limit exhaustion on rapid lesson completions. Filterable via
ghl_crm_progress_debounce_seconds. - Virtual Field Resolution Filter — Added
ghl_crm_resolve_field_valuefilter inUserHooks::prepare_contact_data()so integrations can resolve computed/virtual field values (e.g.,ld_progress_percentage_{course_id}) during regular profile update syncs. - Contact Form 7 Integration — GHL CRM tab in the CF7 editor with per-form field mapping, tag assignment, and automatic submission sync on form send.
- Sync Preview / Dry Run — Preview sync operations before executing: shows create vs update action, field-by-field comparison, tag changes, conflicts, and estimated API calls.
- Email Notification System — Six notification types (connection lost, sync errors, queue backlog, rate limit, webhook failures, daily summary) with HTML email templates and configurable throttling.
- Elementor Widget Restrictions — GoHighLevel Restrictions section in the Advanced tab of all Elementor widgets with five restriction types.
- Gutenberg Restricted Content Block —
ghl-crm/restricted-contentblock with tag selection, fallback content, and customizable styling.
- Multisite Queue Safety — Queue processing lock switched from
get_transient/set_transienttoget_site_transient/set_site_transientinQueueManagerfor network-wide locking. - TagManager Documentation — Full PHPDoc blocks added to every method with logical method reordering (no logic changes).
- FEATURES-AND-BENEFITS.md — Complete rewrite based on codebase audit. Removed non-existent features, added Free vs Pro distinction, and documented all verified features with technical specifics.
- Duplicate Contact Recovery — Auto-converts POST to PUT on duplicate detection; handles deleted/merged contacts via email re-lookup and meta update.
- Ping-Pong Prevention — 30-second inbound guard transient prevents infinite sync loops between webhook inbound and profile update outbound sync.
1.0.0 - 2026-01-01
- Initial release.
Get every update automatically
One-click updates from your WordPress dashboard on every active license.