15 versions
ACPT history.
Every release of ACPT is archived here with its changelog, file size, and security scan result. Use the archive to roll back to a stable release or audit what changed between updates.
15 of 15 releases scanned clean
v2.1.9Latest
October 30, 20268.4 MBScanned
Improved
- **Fatal error at the end of the update to 2.1.8** - updating from 2.1.7 or older showed "Class ACPT\Utils\Http\ACPTApiClient not found" (or "ACPT\Utils\PHP\Session") after "Plugin updated successfully". The update did complete and the site kept working: the old version, still running until the update page finished, couldn't find its files in the new package. Updating from older versions no longer shows the error (Tickets #1444, #1446).
- #### ACPT Lite
- **Activating ACPT while ACPT Lite 2.1.0 is active crashed** - upgrading from ACPT Lite failed with "Plugin could not be activated because it triggered a fatal error": both plugins declared the same functions, and the import stopped on a Lite field group without a position (e.g. a field group on users). ACPT now activates, imports Lite's post types, taxonomies and field groups, and deactivates Lite.
October 28, 20268.4 MBScanned
Fixed
- #### Compatibility
- **Fatal error when saving a post** - on sites where another plugin loads a newer version of the webmozart/assert library (2.x, PHP 8.2+), saving a post with ACPT fields crashed with "Declaration of ACPT\Utils\PHP\Assert::string() must be compatible". ACPT no longer redeclares the library's methods, so it works with both versions (Ticket #1435).
- **Conflicts with other plugins' PHP libraries** - ACPT's PHP libraries (Twig, phpfastcache, webmozart/assert, Symfony YAML and the others) are now bundled under ACPT's own namespace, so another plugin loading a different version of the same library can no longer break ACPT, or be broken by it.
- #### Admin
- **The update was offered again after updating** - right after an update, WordPress offered the same version again. ACPT now compares against the installed version, and an up-to-date ACPT shows the auto-updates toggle (Ticket #1439).
- **"No response from the server" on the license page** - when acpt.io's answer wasn't JSON (a firewall's block page, an error page), the license page hid what the site received. It now shows the HTTP status and the page's text (Ticket #1431).
- **Saving a meta group with a nameless box crashed** - the save failed with a server error; the box is now rejected with a message. Empty field type groups are hidden in the WooCommerce product data builder.
- #### Meta fields
- **Required fields hidden by their conditions blocked the save** - a required field hidden by its own or its box's conditions stopped the browser from submitting the form, and was still validated on the server ("Expected a non-empty value."). Hidden fields are no longer required or validated; their value is still saved (Ticket #1437).
- **Repeater children named "type" or "original_name"** - they were saved but missing from `get_acpt_field()`. They are returned again (Ticket #1437).
- **Length limits counted bytes** - Min/Max length on meta and form fields rejected accented text the browser had accepted. Limits now count characters, as the browser does (Ticket #1439).
- **Date & time values in the canonical format were rejected** - the date check was inverted: a Date & time field saved as `2026-10-26 14:30:00` (from code, the REST API or an import) failed validation. It is now accepted, like every other date format the field can store.
- #### Gutenberg & Dynamic blocks
- **Saved ACPT blocks showed as unsupported** - "Your site doesn't include support for this block" appeared when the editor parsed the post before ACPT registered its blocks, and on post types registered on `init` (GeneratePress Elements, most plugin CPTs) the blocks and their styles weren't registered server-side. Both are fixed (Ticket #1441).
- **Image fields printed the alt text in dynamic block templates** - `{{ acpt_box_image }}` printed the alt text or title, so ` ` broke. Image, File and Gallery values now print their URL and still answer `.alt`, `.title`, `.id` and the other attachment properties (Ticket #1436).
- #### Integrations
- **Bricks: query filters didn't work on CCT columns** - on a post type whose fields come from a CCT, filter elements (Select, Checkbox, Range...) had no options and never narrowed the loop. They now index and filter the CCT column values (Ticket #1434).
- **WPML / Polylang: media fields showed the same attachment in every language** - the generated `wpml-config.xml` didn't list the attachment ID key of Image, Gallery, File, Video, Audio and Image slider fields. It does now, with the field's own translation settings (Ticket #1432).
- #### Internal
- **Test suite on WordPress 7.2** (no change for users) - two tests expected HTML exactly as WordPress 7.1 sanitized it. The tests now pass on both versions.
v2.1.6Unavailable
October 17, 20268.2 MBScanned
Fixed
- #### Admin
- **Datasets couldn't be edited** - since 2.1.2 every "Manage" link opened the datasets list instead of the dataset, so a dataset's items couldn't be changed. The list now lives at `#/tools/datasets`; old links to `#/tools/dataset` still work (Ticket #1420).
- **Updates could keep running the previous release's scripts** - the helper scripts loaded by the admin had no version in their URL, so a browser could keep the old ones cached after an update (and downloaded them twice). They now carry the plugin version (Ticket #1413).
- #### Meta fields
- **The Icon field was blocked by the icon service** - each search result was loaded with its own request, so after a few searches the icon service refused them and icons in later Repeater rows showed as broken and couldn't be picked. Results now load with one request per icon set and picking an icon needs no request. Saved values are unchanged (Ticket #1413).
- #### Custom Content Types
- **Table data saved from tab views was lost** - in meta groups shown as vertical or horizontal tabs, every save created a new record that wasn't linked to the post, so the data looked never saved and Bricks query loops showed nothing. Saves now update the post's record (Ticket #1416).
- **Failed table saves were silent** - when a record failed validation the post saved and the table data was lost without a message. An error notice is now shown, also in the block editor (Ticket #1416).
- **Empty optional numbers and dates blocked the save** - an empty Number, Date, Date & time or Time input failed validation for the whole record; optional columns now save as empty (NULL). Decimal numbers no longer lose their decimals (1.6 was saved as 1) (Ticket #1416).
- #### Integrations
- **Bricks: Toggle conditions on the displayed label stopped matching** - since 2.1.2 a condition comparing a Toggle field with its label (e.g. `== Pravda` on a Czech site) hid the element. It matches again (Ticket #1419).
- **Elementor Pro: a Select field shown as label crashed the editor when empty** - building a Loop Grid failed with a TypeError. An empty field now renders nothing and multi-value fields render comma separated (Ticket #1415).
August 19, 20267.8 MBScanned
Improved
- #### Performance
- **License, plugin-version and ID-field-backfill options queried on every request** - These three tracking options were stored with `autoload=no`, forcing WordPress to issue a dedicated `SELECT` for each on literally every front-end and admin request instead of folding into its single bulk options query. Now stored autoloaded, with a one-time migration that fixes the flag on sites already storing these from an earlier version.
- **Settings table queried on every request without ever hitting the plugin's cache** - Reading the settings table happens during the plugin's own bootstrap, before its file-based query cache has been initialized, so this specific read could never benefit from it no matter how warm the cache was elsewhere. It now has its own lightweight cache, invalidated whenever a setting is saved.
- **`wp_enqueue_media()` running on every wp-admin screen** - ACPT called WordPress's media-library bootstrap function unconditionally on every `admin_enqueue_scripts`, triggering a `wp_posts` query on every wp-admin page for every plugin - not just ACPT's own screens. It's now only called on screens where ACPT actually registered assets.
- **Media library "date filter" dropdown query re-run on every `wp_enqueue_media()` call** - Hooked WordPress core's `media_library_months_with_files` filter (provided by core specifically to avoid this cost, see `core.trac.wordpress.org` ticket #31071) to cache the dropdown's month/year data instead of recomputing it with an uncached `wp_posts` scan every time.
Fixed
- #### Security
- **REST API authentication** - `ACPT_Api_Auth::authenticate()` only verified that Basic Auth credentials or an API key belonged to *some* valid WordPress user, without checking any capability - any authenticated user (including a Subscriber) could call every "secured" REST v1 route. Now requires `manage_options`, matching the plugin's own AJAX proxy. Reported by Patchstack.
- **SQL injection** - WooCommerce product-data field cleanup built its `DELETE` queries by string-concatenating client-supplied IDs into a `NOT IN (...)` clause with no escaping; a crafted ID could delete every row of the field table, not just orphans. Rebuilt with prepared-statement placeholders. Reported by Patchstack.
- **Privilege escalation** - A public form submission could set a client-controlled `acpt_form_user_id`/`_post_id`/`_term_id` field to update an *existing* WordPress user/post/term instead of creating a new one, with no ownership or capability check - an anonymous "create new user" form submission could overwrite an administrator account. Added `current_user_can()` checks before any update.
- **PHP Object Injection** - Hardened all 30 `unserialize()`/`maybe_unserialize()` call sites across the plugin (form metadata, relation-field sync, box/field-rename sync, form/block/permission builders, WooCommerce and WP All Import integrations) to reject embedded objects, closing a gadget-chain risk originally reported by Patchstack against 2 of these sites.
- **Stored XSS** - The meta-field sanitizer's allowed-tags list admitted ` `, so `wp_kses`-based sanitization never actually stripped it from rich-text field output.
- #### Meta Fields
- **Site-wide crash from an invalid `save-meta-group` operator** - A `belongs` rule with a missing/empty operator could be persisted with an empty value and then crash *every* subsequent read of that structure (admin, front-end, REST, every Ability) as soon as it was re-hydrated from the database. The operator is now validated and invalid rules are rejected gracefully, both when saving and when reading a pre-existing row (Ticket #1182).
- **"Autoincrement" ID field never got a value outside wp-admin** - An ID-type meta field only ever generated its value inside the wp-admin edit-screen form; a post created via REST, the Abilities API, an import, or `wp_insert_post()` directly permanently had no value for that field. The value is now generated automatically on save regardless of how the post was created, and a one-time migration backfills every already-existing post on update (Ticket #1181).
- **`get_acpt_fields()` cross-box field collisions** - Fetching every field across a whole meta group (no specific box - the call ACPT's native Etch integration uses for `{options.acpt}`) could silently drop entire boxes' worth of data: fields were keyed by their position *within* their own box, which resets to 0 for every box, so a later box's fields overwrote an earlier box's fields at the same position (Ticket #1174).
- **Gallery field losing images on drag-reorder** - Dragging to reorder a Gallery field's images in wp-admin could silently drop entries: the preview only rendered a thumbnail for attachments that still resolved (e.g. not deleted from the media library since being selected), and reordering rebuilt the field's saved value from only the *rendered* thumbnails, discarding anything without one - occasionally emptying the field entirely. A Gallery field nested inside a Repeater/Flexible block had a second, more reliable trigger: reordering located the wrong
v2.0.66Unavailable
July 25, 20267.7 MBScanned
Improved
- **Abilities API architecture** - Unified all ~41 abilities under a shared `AbstractAbility` base class (`src/Core/Ability/`), registered consistently through both the core WordPress Abilities API and the ACFW (agent-connector-for-wp) integration, with the same exception-handling, permission checks, and audit-log wrapping applied everywhere. Brings along the crash and data-loss fixes below.
Fixed
- License page stuck unrecoverable after a site migration: when the stored activation id is no longer recognized by the license server (e.g. `Activation ID not found`), the React app silently discarded the error and always rendered the "Activate your license" screen with a dead (linkless) button, with no way to reach the "Deactivate license" action that would clear the stale local record. The fetch error is now surfaced and routes to the license details screen so it can be deactivated and re-activated normally.
- Fatal error on every request when license reconciliation can't reach acpt.io (e.g. cloned/staging domains) - the unguarded API call is now wrapped so a network failure degrades gracefully instead of fataling the whole site (Ticket #1164).
- CPT rewrite rules silently disabled when editing existing post types: the "Rewrite" toggle defaulted to unchecked for existing post types whose stored settings lacked an explicit `rewrite` key, so saving the form for any reason (e.g. just updating the front URL prefix) silently persisted `rewrite: false`, registering zero rewrite rules and 404ing the CPT - not fixable by flushing permalinks. Also hardens the `custom_rewrite`/front-URL-prefix priority check so a stale `custom_rewrite` value can no longer silently shadow the front URL prefix (regression of Ticket #1153, Ticket #1160).
- Image/media field values not saving when served from a different host (CDN, offloaded media, image accelerator, etc.) - attachment resolution now falls back to matching on the URL path alone when the host differs from the site's own upload base URL.
- Bricks Query Filter showed no checkbox options for POST_TYPE relation fields, and a cold indexer run could produce zero index rows; relational-loop dynamic data tags also resolved against the archive's queried object instead of the loop target (#1161, #1165).
- Site-wide crash (front-end, admin, REST, AJAX) from a missing/empty location-rule operator on `save-meta-group` - the operator is now validated and invalid rules are rejected gracefully.
- Partial updates across 8 ability families (Table, MetaField, FormField, DynamicBlock, TableGroup, Form, MetaBox, TableRecord) were silently deleting data the payload didn't mention - most seriously, omitting `columns` on a Table update deleted every column/index/foreign-key definition, and the next schema sync then dropped the corresponding database columns. All 8 now merge onto the existing record instead of rebuilding it from scratch.
- `save-meta-field` matched against the wrong data shape and never actually found the field being edited, so non-rename edits silently no-op'd and renames created orphan duplicates.
- ACFW's audit-logging/MCP registration always lost a boot-order race against the core Abilities API integration, so its decoration silently never applied when both were active.
- ACPT abilities were missing `meta.mcp.public`, so the official `wordpress/mcp-adapter` package (used by ACFW and other MCP host plugins) rejected every call with "not exposed via MCP" even though the ability registered fine.
Why archive
Sometimes the latest release isn't the one you need. The archive lets you pin ACPT to a known-good version, or roll back while a bug is investigated. Every release stays scanned and reachable.