Skip to content

Ensure Icon Picker only calls wp_get_attachment_image_url with valid attachment IDs - #1033

Open
antwonw wants to merge 1 commit into
AdvancedCustomFields:masterfrom
antwonw:fix/icon-picker-non-int-attachment-id
Open

Ensure Icon Picker only calls wp_get_attachment_image_url with valid attachment IDs#1033
antwonw wants to merge 1 commit into
AdvancedCustomFields:masterfrom
antwonw:fix/icon-picker-non-int-attachment-id

Conversation

@antwonw

@antwonw antwonw commented Sep 8, 2026

Copy link
Copy Markdown

Summary of Changes

Fixes #1032

In includes/fields/class-acf-field-icon_picker.php, the template for the media_library tab unconditionally executes wp_get_attachment_image_url( $field['value']['value'], 'thumbnail' ).

When creating a new custom post type (post_type=acf-post-type) or editing any post type/taxonomy where a Dashicon or URL icon is selected, $field['value']['value'] is a string (e.g. 'dashicons-admin-post').

While the template hides the image preview container via CSS (display: none;), PHP still evaluates the function call and passes the string to WordPress core's wp_get_attachment_image_src(). Any active plugin or integration hooking into wp_get_attachment_image_src that enforces strict typing (such as WP Offload Media 3.4+) immediately crashes with a fatal TypeError:

Fatal error: Uncaught TypeError: ...::get_by_source_id(): Argument #1 ($source_id) must be of type int, string given

Proposed Solution

Harden the media library preview block in class-acf-field-icon_picker.php to verify that:

  1. The active icon type is 'media_library'.
  2. The value is not empty.
  3. The value is numeric (is_numeric()).

Only then invoke wp_get_attachment_image_url() with the integer-cast ID (int) $field['value']['value']. If these conditions are not met, $img_url safely defaults to an empty string ''.

Steps to Test

  1. Run a WordPress site on PHP 8.2+ with ACF and any plugin that hooks into wp_get_attachment_image_src expecting an integer ID (e.g. WP Offload Media 3.4+).
  2. Navigate to wp-admin/post-new.php?post_type=acf-post-type (ACF > Post Types > Add New).
  3. Without patch: The screen fails with an unhandled fatal 500 TypeError.
  4. With patch: The post type creation screen loads smoothly, displaying the default Dashicon preview.

Test Verification & Output

1. PHP Syntax Check (php -l)

$ php -l includes/fields/class-acf-field-icon_picker.php
No syntax errors detected in includes/fields/class-acf-field-icon_picker.php

2. WordPress Coding Standards Check (phpcs)

Executed with --standard=WordPress across the file:

$ phpcs --standard=WordPress includes/fields/class-acf-field-icon_picker.php
Result: 0 errors or warnings introduced on the modified lines (lines 214-226). Full compliance with tabs, Yoda conditions, and spacing.

3. Automated Scenario Unit Tests (PHP 8.5 Strict Types)

Ran automated test harness covering all field value states:

PASS: Test 1: Default post type icon (Dashicon string)
PASS: Test 2: URL icon (String URL)
PASS: Test 3: Media library icon with valid integer ID
PASS: Test 4: Media library icon with numeric string ID
PASS: Test 5: Media library icon with null/empty value

Summary: 5/5 tests passed.

Diff

diff --git a/includes/fields/class-acf-field-icon_picker.php b/includes/fields/class-acf-field-icon_picker.php
index d331bcb..c1f28ee 100644
--- a/includes/fields/class-acf-field-icon_picker.php
+++ b/includes/fields/class-acf-field-icon_picker.php
@@ -214,8 +214,13 @@ if ( ! class_exists( 'acf_field_icon_picker' ) ) :
 								>
 									<div class="acf-icon-picker-media-library-preview-img" style="<?php echo esc_attr( 'media_library' !== $field['value']['type'] ? 'display: none;' : '' ); ?>">
 										<?php
-											$img_url = wp_get_attachment_image_url( $field['value']['value'], 'thumbnail' );
-											// If the type is media_library, then we need to show the media library preview.
+										$img_url = '';
+
+										// Only fetch attachment image URL when the field type is media_library and the ID is valid.
+										if ( 'media_library' === $field['value']['type'] && ! empty( $field['value']['value'] ) && is_numeric( $field['value']['value'] ) ) {
+											$attachment_url = wp_get_attachment_image_url( (int) $field['value']['value'], 'thumbnail' );
+											$img_url        = $attachment_url ? $attachment_url : '';
+										}
 										?>
 											<img src="<?php echo esc_url( $img_url ); ?>" alt="<?php esc_attr_e( 'The currently selected image preview', 'acf' ); ?>" />
 									</div>

@antwonw
antwonw requested a review from a team as a code owner September 8, 2026 20:00
@mattgrshaw

Copy link
Copy Markdown
Member

@antwonw Thanks for the detailed report and PR! We'll look into getting this into a future release.

@antwonw antwonw changed the title Ensure Icon Picker only calls wp_get_attachment_image_url with valid attachment IDs (Fixes #1032) Ensure Icon Picker only calls wp_get_attachment_image_url with valid attachment IDs Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: class-acf-field-icon_picker.php calls wp_get_attachment_image_url() with string Dashicon slug, causing fatal TypeError on PHP 8+

2 participants