JPKCom ACF References

references-data.php

Shared data layer for references.

Holds the visibility rule and the projection of a reference into plain data. Both existed only inside the list shortcode before; the abilities need the same answers and must not restate them, because a second statement of a rule is a second rule the moment either side is touched. That is not theory: the sibling plugin jpkcom-acf-jobs shipped a "mirror image" of its own expiry rule that counted every reference whose date had been saved and cleared as expired, because MariaDB casts '' to '0000-00-00'.

Tags
author

Jean Pierre Kolb jpk@jpkc.com

license

GPL-2.0-or-later

link
https://github.com/JPKCom/jpkcom-acf-references

Table of Contents

Functions

jpkcom_acf_references_build_reference_query_args()  : array<string, mixed>
Build the WP_Query arguments that define a publicly listed reference.
jpkcom_acf_references_normalise_date()  : string|null
Normalise a stored ACF date into ISO 8601, or null when it cannot be read.
jpkcom_acf_references_plain_text()  : string
Reduce a stored value to plain text.
jpkcom_acf_references_normalise_related()  : array<int, array<string, mixed>>
Project a post-object field into id/title pairs.
jpkcom_acf_references_attachment_url()  : string|null
Resolve an attachment field to a URL, or null.
jpkcom_acf_references_normalise_gallery()  : array<int, array<string, mixed>>
Project a gallery field into url/alt records.
jpkcom_acf_references_normalise_terms()  : array<int, array<string, string>>
Read a reference's terms in one taxonomy as slug/name records.
jpkcom_acf_references_get_reference_data()  : array<string, mixed>
Project one reference into plain data, or [] when it cannot be read.

Functions

jpkcom_acf_references_build_reference_query_args()

Build the WP_Query arguments that define a publicly listed reference.

jpkcom_acf_references_build_reference_query_args([array<string, mixed> $args = [] ]) : array<string, mixed>

Extracted verbatim from the list shortcode, which was its only home. Three parts carry weight and none of them may be simplified:

  1. reference_featured EXISTS — the site treats a reference without that meta row as not listed at all. The row's VALUE is irrelevant; a stored 0 is listed, a missing row is not, and get_field() cannot tell those apart.

  2. The expiry OR group has THREE branches: at or after today, no row, and the empty string. The third is the ordinary case, not an edge case — ACF writes '' when a date is cleared rather than deleting the row, and MariaDB casts '' to '0000-00-00', which is less than any real date. A negation of only the first branch is not the complement of this group.

  3. meta_key is set for the ordering, and its own postmeta.meta_key condition lands in the WHERE clause. So a reference with no featured row is excluded TWICE, independently. Removing either one changes nothing, which is why the number of references carrying the row cannot be read off this query and needs one of its own.

current_time( 'Y-m-d' ) and not date(): WordPress sets the PHP timezone to UTC in wp-settings.php, so date() returns the UTC date and an expired reference would stay visible for the length of the site's offset past local midnight.

Parameters
$args : array<string, mixed> = []

Arguments merged over the base rule.

Tags
since
1.2.0
Return values
array<string, mixed>

WP_Query arguments.

jpkcom_acf_references_normalise_date()

Normalise a stored ACF date into ISO 8601, or null when it cannot be read.

jpkcom_acf_references_normalise_date(mixed $raw) : string|null

Never date( 'Y-m-d', strtotime( $x ) ): under strict_types a false from strtotime() makes date() throw a TypeError. The round-trip check is load-bearing rather than decorative — without it '20251340' becomes 2026-02-09 and '20259999' becomes 2033-06-07, both silently.

Wrapped in try/catch because a NUL byte in the stored value makes createFromFormat() throw a ValueError, and MySQL longtext stores NUL.

Parameters
$raw : mixed

Stored value.

Tags
since
1.2.0
Return values
string|null

Y-m-d, or null when the value is unusable.

jpkcom_acf_references_plain_text()

Reduce a stored value to plain text.

jpkcom_acf_references_plain_text(mixed $value) : string
Parameters
$value : mixed

Stored value.

Tags
since
1.2.0
Return values
string

Plain text, empty when the value is not a string.

Project a post-object field into id/title pairs.

jpkcom_acf_references_normalise_related(mixed $value) : array<int, array<string, mixed>>

Never emits a WP_Post. ACF resolves post_object fields through acf_get_posts() with post_status => 'any', so drafts and private customers genuinely arrive here — and WP_Post implements no JsonSerializable while exposing post_password, post_content and post_status as public properties. A reference linked to a password-protected customer would otherwise hand a subscriber that password in plain text.

absint() before get_post(): get_post( 0 ) returns the GLOBAL post, and absint() maps false, '', null and 'abc' all to 0. ACF returns false for an unassigned post_object, and both relation fields here allow null — without this guard a reference with no customer projects itself as its own customer.

Parameters
$value : mixed

Stored value.

since
1.2.0
Return values
array<int, array<string, mixed>>

Related records.

jpkcom_acf_references_attachment_url()

Resolve an attachment field to a URL, or null.

jpkcom_acf_references_attachment_url(mixed $value) : string|null

Accepts the three shapes ACF returns depending on return_format — id, url string, or array — and refuses anything that is not an attachment. The post-type check matters: an id pointing at a normal post would otherwise produce a permalink where the caller expects an image.

Parameters
$value : mixed

Stored value.

Tags
since
1.2.0
Return values
string|null

Attachment URL, or null.

Project a gallery field into url/alt records.

jpkcom_acf_references_normalise_gallery(mixed $value) : array<int, array<string, mixed>>

Emits only what a caller can use and nothing that identifies the attachment post itself. The alt text is read from the attachment meta rather than from ACF's formatted array, so this does not depend on the field's return_format.

Parameters
$value : mixed

Stored value.

since
1.2.0
Return values
array<int, array<string, mixed>>

Gallery images.

jpkcom_acf_references_normalise_terms()

Read a reference's terms in one taxonomy as slug/name records.

jpkcom_acf_references_normalise_terms(int $post_id, string $taxonomy) : array<int, array<string, string>>

Reads the term relationships rather than the ACF meta, for the same reason the list shortcode does: the relationships are indexed, and the two stores can drift (import, direct DB write, a WPML duplication that never ran ACF's save routine). tools/check-term-sync.php is what detects that drift.

Parameters
$post_id : int

Reference ID.

$taxonomy : string

Taxonomy slug.

Tags
since
1.2.0
Return values
array<int, array<string, string>>

Assigned terms.

jpkcom_acf_references_get_reference_data()

Project one reference into plain data, or [] when it cannot be read.

jpkcom_acf_references_get_reference_data(int $post_id[, bool $full = false ]) : array<string, mixed>

This function gates, because nothing else does. The existing readers are safe only because the shortcode hands them posts a post_type/post_status query already filtered; this one takes a bare int and inherits none of that, and the abilities above it answer to any subscriber. It therefore refuses a non-reference post type, any status but publish, a non-empty post_password and a non-positive id.

"Does not exist" and "cannot be read" return the same empty array on purpose, so the ability above cannot be used to probe which IDs exist.

$full adds the detail block. It is emitted ONLY for a reference whose detail page would actually render for an anonymous visitor: an external reference URL 307s every visitor away (redirects.php:59-77) and an expired reference 307s to the archive (redirects.php:149-206). For those the address, the gallery and the description have no public render path at all, so publishing them here would publish what the site never showed.

Parameters
$post_id : int

Reference ID.

$full : bool = false

Whether to include the detail block.

Tags
since
1.2.0
Return values
array<string, mixed>

Reference data, or [] when unreadable.

On this page

Search results