Changelog — JPKCom ACF References

Versionsverlauf des WordPress-Plugins JPKCom ACF References.

Versionsverlauf von jpkcom-acf-references. Die Einträge stammen unverändert aus der README des Projekts. Eine ausführliche Anleitung mit Tipps findest du im Projekt-Guide.

1.2.1

  • Fixed: two 1.2.0 release notes described includes/references-data.php as the single home of the visibility rule — one of them saying the abilities apply the shortcode's rule "not a copy of it". That is not what shipped. jpkcom_acf_references_build_reference_query_args() is called from includes/abilities.php and from nowhere else, while includes/shortcodes.php still assembles the same clauses inline. The two agree, and that was verified by comparing the generated SQL and the returned post IDs — but agreeing is not sharing, and two implementations can drift apart the moment either is edited. The claim mattered because it was the reason to trust that the abilities cannot disagree with the site's own listing; that trust now rests on a measurement rather than on a shared function. Both notes have been corrected and marked, and the developer documentation now records that a change to the rule has to be made in both files until the shortcode is moved over. No behaviour is affected

1.2.0

  • Added: three read-only WordPress Abilities — jpkcom-acf-references/list-filters, jpkcom-acf-references/query-references and jpkcom-acf-references/get-reference — so AI assistants, MCP clients and REST automation can read your references as structured data instead of scraping the page. They are on by default for logged-in users with the read capability and can be switched off entirely with define( 'JPKCOM_ACFREFERENCES_ABILITIES', false )
  • Added: the abilities return only references your site's own listing shows, and they apply the same visibility rule the [jpkcom_acf_references_list] shortcode applies. The short description and the image gallery are returned only for a reference whose page a visitor could actually open: one that redirects to an external URL and one whose expiry date has passed both have no public detail page, so those fields are withheld and the reason is stated in the answer. This entry as originally published added "not a copy of it" about the shared rule. That was wrong — there are two implementations; see 1.2.1
  • Added: includes/references-data.php, which holds the visibility rule and the projection of a reference into plain data for the abilities. The shortcode returns exactly what it returned previously — verified by comparing the generated SQL and the returned post IDs before and after the change. This entry as originally published read as though the rule had moved out of the shortcode. It did not; see 1.2.1
  • Added: jpkcom_acf_references_ability_meta and jpkcom_acf_references_ability_capability filters, so a site can change which abilities are exposed and who may run them
  • Changed: WordPress 7.0 is now the minimum. Up to 6.9 an unexpected error inside an ability callback ended the whole request with a blank page instead of a readable message. From 7.0 WordPress catches it itself
  • Note: filtering by a value that does not exist on this site returns no references and names the value under unknown, rather than quietly returning everything. A filter that is partly recognisable still narrows by the part that was

1.1.3

  • Changed: the update manifest generator now defaults a missing Network: header to false instead of true, matching WordPress' own default. No change for this plugin, which declares Network: true explicitly
  • CI: the lint and guard workflow now also runs on pushes to main. It only covered pull requests, so a direct push with bypass rights skipped every check
  • Changed: comments, workflow step names and CI output across the repository are now English throughout, and the developer notes in CLAUDE.md were translated and trimmed. No effect on the shipped plugin

1.1.2

  • Changed: Tested up to raised to WordPress 7.1
  • Changed: the bundled updater's runtime floor now matches the plugin's own minimum. It bailed out below WordPress 6.8 while the plugin header has required 6.9 for several releases, so the check could never fire on a supported installation
  • Docs: the remaining "WordPress 6.8" requirement statements now say 6.9, matching the plugin header
  • CI: the release manifest's fallback values for requires and tested now say 6.9 and 7.1. They only apply when the README metadata cannot be read, but a stale fallback would have published a minimum the plugin no longer supports

1.1.1

  • Changed: the plugin banners (assets/banner-1544x500.avif, assets/banner-772x250.avif) are now a plain #3c4955 surface with no lettering

1.1.0

  • Changed: the three taxonomy filters of the list shortcode use tax_query instead of meta_query with LIKE over the serialised ACF values. A leading wildcard cannot use an index, so each clause scanned every meta row for that key; the term relations ACF already writes are indexed. Verified against real data: identical results in all 14 filter combinations tested
  • Fixed: on a multilingual site (WPML) the filter returned nothing in every secondary language. A shortcode carries the default-language term ID, the old clause searched for it in translations whose meta holds the translated ID, and found nothing. Measured: 0 results before, 6 after
  • Fixed: tools/check-term-sync.php could not run at all. A declare(strict_types=1) sat halfway down the file, and wp eval-file evaluates the contents — so the documented invocation ended in a fatal error every time
  • Fixed: the same script reported every translated post as drifted, because it compared raw meta against wp_get_object_terms(), which WPML rewrites to the current language
  • Changed: non-numeric values in type, filter_1 and filter_2 now produce no filter rather than one that matches nothing

1.0.9

  • Fixed: reference expiry was compared against the UTC date. WordPress sets the PHP timezone to UTC, so date( 'Y-m-d' ) returns the UTC day and expired references stayed visible for the length of the site's UTC offset after local midnight (1–2 hours for Europe/Berlin). All three comparison sites now use current_time( 'Y-m-d' )
  • Fixed: the single-reference redirect checked current_user_can( 'administrator' ), passing a role name where a capability belongs. That works only because the role is a key in the capability array, bypassing map_meta_cap and missing differently named roles with the same rights. Now checks manage_options, consistent with the sibling handlers in the same file
  • Added: tools/check-term-sync.php — a read-only checker that reports whether the serialised ACF meta values and the real taxonomy term assignments agree. Required groundwork before the shortcode filters can move from unindexed meta_query + LIKE to indexed tax_query
  • Added: tests/test-conventions.php — regression guards so neither the UTC date form nor a role-as-capability check can return unnoticed. Run in CI on every pull request

1.0.8

  • Security: update packages are now verified before installation — the verified file is handed to WordPress instead of being downloaded a second time, so the bytes that were checked are the bytes that get installed
  • Security: a missing or unfetchable SHA-256 checksum now aborts the update instead of installing unverified code (previously it silently skipped verification)
  • Security: pinned every GitHub Action to a full commit SHA and added Dependabot with a 7-day cooldown, so a moved tag can no longer change the release build
  • Security: tightened which download the updater claims, so sibling plugins cannot match each other's package
  • Fixed: sprintf() calls in the updater bound named arguments to a variadic parameter, which raises ArgumentCountError on PHP 8.3
  • Fixed: the "View Details" modal could fail with a TypeError when the manifest omitted requires_plugins
  • Performance: a failed manifest fetch is now cached for an hour instead of being retried on every admin request
  • Added: CI workflow on every pull request (PHP lint, named-argument check, YAML validation, action-pinning guard)
  • Housekeeping: removed an unused messages.mo from the release package

1.0.7

  • Fixed a leftover duplicate logo call in the reference customer partial that passed the ACF field array where an attachment ID is expected, which could render an unrelated image before every customer logo

1.0.6

  • Raised the minimum WordPress version to 6.9 and "Tested up to" to WordPress 7.0
  • Switched license metadata to the SPDX identifier GPL-2.0-or-later with the HTTPS license URI

1.0.5

  • Security: updater prefers an exact match against the manifest download_url over the slug heuristic, so a tampered manifest can no longer bypass the checksum gate
  • Security: timing-safe checksum comparison (hash_equals()) with an is_string() guard against hash_file() failures
  • Security: manifest fetch via wp_safe_remote_get() (SSRF defense-in-depth)
  • Fixed PHP warning and missing contributor names in the plugin detail popup (display_name now provided)
  • Fixed PHP warning/deprecation on wp plugin list by completing the no_update transient entry (new_version, package, tested, requires_php)

1.0.4

  • Fixed pagination layout not wrapping on small screens or with long post titles
  • Pagination items now use flex-wrap and consistent page-link styling
  • Previous/next links are hidden when no adjacent post exists
  • Improved output escaping across all templates: __()esc_html__(), get_the_title()esc_html(), get_field()esc_html(), get_the_date()esc_attr(), get_post_type_archive_link()esc_url()

1.0.3

  • Fixed updater checksum verification failing on manual ZIP uploads (local file paths mistaken for URLs)
  • Fixed release ZIP missing top-level directory, causing WordPress to not recognize plugin updates

1.0.2

  • Added check for "SitePress" class

1.0.1

  • Fix for incorrect database content caused by WPML

1.0.0

  • Initial Release