Releases: DataFlairAI/DataFlair-Toplists
Release list
v2.4.3 — Fix MySQL 1038 out-of-sort-memory on the Toplists admin list
Fixed
- Admin Toplists list page could hit MySQL error 1038 "Out of sort memory" once the table grew large enough that the default
ORDER BY last_synced DESCfilesort exceeded the host'ssort_buffer_size. Schema v1.15 adds indexes onlast_synced,name, anditem_count(ensureToplistsSortIndexes()), covering every columnToplistsQuery::ALLOWED_SORTcan hit that didn't already have one.
Verified on strike-odds.test: the Toplists admin list loads, View Details expands, Dashboard and Brands load, and the front-end casino cards still render. PHPUnit: 969 tests, 3131 assertions.
v2.4.2 — Fix oversized casino-card icons on the live front end
Fixed
- Casino-card icons (ribbon star, rating star, feature checks, and others) could render oversized on the live front end. These SVGs ship with only a viewBox, no width/height, and the containment rule for them only ever shipped in the block-editor stylesheet, which never loads on a published page. A page-level reset that expands bare
<svg>to 100% width (Tailwind Preflight and similar resets both do this) could stretch them to fill their container.
Found live during the same QA pass as 2.4.1: the ribbon star rendered full-viewport-height on a real front-end page. Ports the same rule already proven correct in assets/editor.css to the front-end stylesheet.
v2.4.1 — Fix fatal error on Roots/Acorn (Sage-based) themes
Fixed
- Fatal error rendering the toplist block/shortcode on Roots/Acorn (Sage-based) themes. The Alpine.js already-loaded detection called
strpos()directly on every queued script's->src, assuming it is always a plain string. Acorn-based themes register compiled assets with->srcas an asset value object instead, which threw aTypeErrorthe theme's Blade layer turned into a fatal error on every page rendering the block or shortcode.AlpineJsEnqueuernow coerces via__toString()when available and skips the entry otherwise instead of fataling.
Found live on a client site during QA; reproduced in an isolated regression test (same TypeError, no live site needed) before fixing.
Tests
Two new cases pin both the non-Stringable-safe-skip and the Stringable-object-still-detected paths. Full suite: 968 tests green.
v2.3.3 — API base URL label, sync guards, and the API version rewrite
Fixes the Settings tab telling admins their brand sync had nothing to call, or was still on v1, when it wasn't — the exact confusion that read as a broken sync during Sigma's first integration test. Two review passes plus a live WordPress smoke test after merge (which caught one real fatal, also fixed here) went into this release; see CHANGELOG.md for the full detail.
Fixed
- Fatal error on Tools › Tests & Diagnostics, found by a live WordPress smoke test after the code was merged, not by the 874 mocked unit tests. Verified fixed under a real WordPress 7.1 install, every admin page this release touches, logged in, clicking through.
Tested up toupdated to 7.1. - Settings › API Connection no longer implies brand sync uses v1 while V2 is selected — the tab echoed the stored base URL verbatim as "Current", reading
/api/v1even while V2 was selected and in effect. The Brands API Version row now states the exact URL brand sync calls, rewritten symmetrically in both directions so the radio is authoritative either way. - Brand and toplist sync buttons now refuse to run when the API Base URL isn't configured, instead of falling through to a hard-coded fallback host with a real bearer token.
- The admin API preview's forced-V2 rewrite works again for base URLs without a literal
/api/segment. - The 404 error message no longer shows a stale URL alongside the real one that just failed. The Dashboard health tile, Tools diagnostics, and Test Connection now all agree with Settings about whether the API is configured, and Test Connection now actually enforces v1 instead of trusting the raw stored value. The Tools › API Preview tab no longer writes an option on a plain page load.
Changed
- The
/api/vNrewrite has one owner (UrlTransformer::withApiVersion()for brand sync,forceApiVersion()for the admin preview tool).ApiBaseUrlDetector::isConfigured()is now shared everywhere that needs to know whether the API is set up.
Full changelog: https://github.com/DataFlairAI/DataFlair-Toplists/blob/main/CHANGELOG.md
v2.3.2 — keep pros/cons after toplist reorder
Fixed
- Block-level pros/cons no longer disappear after a toplist reorder
- Legacy
casino-{position}-{slug}keys resolve at any position for the brand - Gutenberg editor auto-migrates legacy keys to stable
casino-brand-{id}/ item / slug keys when casinos load
Tests
ProsConsResolverDriftTestcovers reorder survival, stable-key precedence, and sanitized-name slug matching
Upgrade
Update the plugin via WordPress → Plugins (GitHub auto-update) or install the release zip.
v2.3.0 — API contract safety
API contract note
Additive only. No existing behaviour changes for a site that installs this release. Every new safety mechanism is opt-in on both sides: a backend without the handshake or /meta endpoint behaves exactly as before, and a site running an older plugin is untouched by a backend that has them.
Why this release exists
A tenant asked for API versioning guarantees so that our backend deploys could not break their live site. Investigating that surfaced something bigger: every version before this one cleared the local tables and then fetched. If the API failed at that moment, the site went blank. That is fixed, along with three other paths that could empty a site.
What it does
Contract handshake. Every API request sends X-DataFlair-Plugin-Version, plus X-DataFlair-Expected-Contract on versioned endpoints. A backend that cannot serve the expected contract answers HTTP 409; sync pauses with a clear admin notice and the site keeps serving its last good data. State is per sync stream, so toplists and brands cannot mask each other.
Contract canary. Sync payloads are deep-validated on every page before any local write. A renamed, removed, or retyped render-critical field (offer, offerText, brand linkage, trackerLink, geo and the code / coveredCountries the geo gate matches on) stops the sync and names the field. Collective all-or-nothing checks with a minimum sample make false positives on legitimate partial data impossible; present-but-null keys are always valid.
Fail-safe sync ordering. The destructive stale-row wipe runs only after a response is fetched and validated. An empty payload against a populated site refuses the wipe. Low-budget requests skip the wipe and upsert rather than blanking the table.
Drift-resilient rendering. Card templates, ProsConsResolver and the shortcode decode boundary survive hostile retypes with zero notices under WP_DEBUG_DISPLAY.
API version awareness. Each full sync reads the backend's /api/vN/meta and raises a dismissible informational notice when the contract revision moves or a newer API version becomes available. The first reading is a silent baseline.
Declared database contract. The plugin tables are locked by a test: additive only within a major version, with the data column storing the verbatim API payload, for sites that read the tables directly instead of using the shortcode.
wp dataflair sync. The Settings page had long offered WP-CLI as a way to trigger a sync, but no such command existed. It does now, with --only=toplists|brands, a non-zero exit so a real system cron can react, and automatic backoff on API rate limits. There is still no WP-Cron, by design.
Visibility. An API Contract Check diagnostic on the Tools page, and an integration profile on the health endpoint (geo targeting, contract and revision, last sync times).
Fixes
- Card rendering no longer emits on-page notices or fatals on drifted data
- Upstream error messages are stripped, capped and escaped before reaching wp-admin
- Every contract failure now ends with an action: update the plugin, or report it
- Geo-targeting settings copy clarifies that it governs only the shortcode and block
Verification
840 tests, 2888 assertions. Verified end to end against a live staging tenant: 220 toplists across 44 pages and 542 brands across 22 pages, a forced 409 rejection with all local rows preserved, automatic recovery, rate-limit backoff, and the geo render gate unchanged across all three geo types.
See UPGRADING.md for the tenant-facing guide, including a table of every failure mode and what happens to your data.
v2.2.12 — Fix duplicate Gutenberg block registration
Fixes a duplicate init-hook registration for the Gutenberg block that could crash under WP_DEBUG on Acorn-based sites. See the 2.2.12 changelog entry in the plugin's View Details popup or README.md for the full writeup.
v2.2.11 — Scope to Pattern 1 (revert auto_geo notice)
Removed
- The auto_geo "not available in your region" notice added in 2.2.10. Scoping this release to the fixed
id/sluggeo-targeting pattern only;auto_geois being redesigned as part of a plugin-side geo-templates + page-linking feature rather than incrementally extended now.auto_geoitself (unchanged since 2.2.3) is unaffected.
Unchanged from 2.2.10
- The admin
?dataflair_geo=QA override — unrelated to auto_geo, stays.
v2.2.10 — Admin geo QA override + auto_geo unavailable notice
Added
?dataflair_geo=GBadmin QA override — a logged-in admin (manage_options) can preview any country's geo-gated content from a plain browser URL, no VPN or custom headers needed. Ignored entirely for anyone without the capability.- "These brands aren't available in your country or region" notice for unmatched
auto_geofamilies. Scoped to only theauto_geo/GeoFamilySelectorpath — fixedid/slugblocks (the common pattern of several region-locked blocks side by side on one page) stay silent as before.
v2.2.9 — Full API payload in debug table
Added
- The debug/testing accordion table (
layout=table) now surfaces the full API item payload: offer type, max bonus amount, free spins, sticky bonus, bonus expiry, currencies, offer-level geo targeting, restricted countries, game types, game providers, supported languages, brand logo thumbnail, and the tracker/campaign list. Sportsbook/poker-only fields (minimum odds, free bet value, stake returned, bet type, tournament ticket value, rakeback, free tickets) render as their own section only when populated, so casino items don't show empty rows.
Fixed
- Removed 2 dead fields with no backing API data (
Payout Time,Games Count). Product Typeread a field the API never returns; now sources from the realclassificationTypesfield.