Here is a workaround that I decided to use thanks to a suggestion on WordPress.org forums. I added a new column to the media library list view that displays the results of the WP_Query for each media attachment.
This lets wp-admin users see if a post is attached to an ACF image field or not. I am still preventing attachment deletion using similar code as in the original question, but instead of giving wp-admin users a notification or modal that the attachment can be deleted on triggering the 'delete_attachment'
hook, users can see in the list view if the media is attached to any ACF image field -> which explains if it is able to be deleted or not.
In the code below, $query
represents the same data as in my original question (see above $query = new WP_Query($args)
), just refactored that bit into a new function wp_query_metaquery_check_acf_image_field_usage( $attachment_id )
.
add_filter('manage_media_columns', function($columns) {
// Remove the default 'comments' column
unset($columns['comments']);
// Add the custom column 'ACF Image field usage' under column key 'acf_image_field_usage'
return array_merge($columns, ['acf_image_field_usage' => __('ACF Image field usage', 'textdomain')]);
});
add_action('manage_media_custom_column', function($column_key, $attachment_id) {
if ($column_key == 'acf_image_field_usage') {
$query = wp_query_metaquery_check_acf_image_field_usage( $attachment_id );
// If 0 posts were found in the meta_query
if (count($query->posts) === 0) {
echo '<span style="color:inherit;">'; _e("None", 'textdomain');
echo '</span>';
// If 1 or more posts were found in the meta_query
} else if (count($query->posts) > 0) {
// Loop through meta query results to log each discovered post containing the attachment
for ($i = 0; $i < count($query->posts); $i++) {
echo '<span style="color:inherit;">'; _e($query->posts[$i]->ID . ' - ' . $query->posts[$i]->post_title, 'textdomain');
echo '</span>';
echo '<br>';
}
}
}
}, 10, 2);