Skip to content

Fix PHP deprecation warnings (null array offsets, output handler output, object cache key) - #1340

Open
gabrielcld2 wants to merge 5 commits into
developfrom
fix/php-deprecation-warnings
Open

gabrielcld2 wants to merge 5 commits into
developfrom
fix/php-deprecation-warnings

Conversation

@gabrielcld2

@gabrielcld2 gabrielcld2 commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes recurring PHP deprecation/warning logs. There's one commit per fix.

Approach

  1. Null array offset (Relationship::get_relationship(), Delivery::get_sized(), Component::get_part()): cast the IDs to int and skip the lookup for a null part.
  2. Output produced from the String_Replace output handler: the double ob_start() isn't the cause. Errors displayed during the handler count as output. The buffers now go through output_handler(), which turns off display_errors while it runs. Errors are still logged.
  3. WP_Object_Cache::add called with a boolean key (Delivery::find_attachment_size_urls()): the loop no longer overwrites $key, so results are cached under md5( $sql ) as intended.
  4. preg_replace() given a null subject (Media::get_cloudinary_version()): the parent's version lookup now defaults to ''.
  5. WP_Object_Cache::delete called with a NULL key (Delivery::find_attachment_size_urls()): results are skipped when the contextualized ID is empty (WPML returns null for an untranslated attachment). This also stops the create_delivery( null ) and add_to_sync( null ) calls.

QA notes

  • On PHP 8.4+ with WP_DEBUG and WP_DEBUG_LOG on, browse the front end and the media library. debug.log should contain none of the messages above.
  • To reproduce all five in one request, simulate WPML returning null for an untranslated attachment:
    1. In a temporary mu-plugin, add add_filter( 'cloudinary_contextualized_post_id', '__return_null', 100 );.
    2. In the same mu-plugin, output <img src="<uploads URL>/repro/unknown.png"> in wp_footer.
    3. Add a matching postmeta row with add_post_meta( <any attachment ID>, '_wp_attached_file', 'repro/unknown.png' ).
    4. Load the front end.
  • Result on PHP 8.5: develop logs all five messages, and this branch logs none. phpstan and PHPUnit pass.

…nt parts

PHP 8.5 deprecates using null as an array offset. Relationship::get_relationship()
and Delivery::get_sized() can be called with a null ID (e.g. when the
cloudinary_contextualized_post_id filter returns null), and Component::get_part()
is called with a null part by the Opt_Level component.

Cast the IDs to int (the Relationship constructor already does so) and skip the
build parts lookup for a null part.
PHP 8.4 deprecates producing output from within a user output handler
("ob_end_flush(): Producing output from user output handler
Cloudinary\String_Replace::replace_strings is deprecated").

The double ob_start() is not the cause on its own: the deprecation fires when
an error is displayed while the handler runs (e.g. notices raised by
cloudinary_string_replace callbacks, with display_errors on), since that
display is output produced inside the handler and is discarded anyway.

Route the buffers through a dedicated output_handler() that disables
display_errors while replacing strings and restores it afterwards. Errors are
still logged. Both buffers are kept to preserve the early-flush workaround.
Delivery::find_attachment_size_urls() reused $key inside the results loop for
each attachment URL, so wp_cache_add() stored the results under the last
attachment's URL instead of md5( $sql ). When the last wp_get_attachment_url()
call failed, the key was false, triggering "WP_Object_Cache::add was called
incorrectly. Cache key must be an integer or a non-empty string, boolean given".

Use a separate variable for the attachment URL, and skip attachments without a
URL rather than mapping them under a false key.
… version

Media::get_cloudinary_version() passed the parent attachment's version meta
straight to preg_replace(). When the parent has no version meta,
get_post_meta() returns its null default, triggering "preg_replace(): Passing
null to parameter #3 ($subject) of type array|string is deprecated".

Default the meta to an empty string, which still resolves to version 1.
@gabrielcld2
gabrielcld2 marked this pull request as ready for review October 26, 2026 11:56
The cloudinary_contextualized_post_id filter can return null, e.g. WPML's
wpml_object_id for an attachment without a translation in the current
language. Delivery::find_attachment_size_urls() then carried on with a null ID,
calling create_delivery( null ), which ends in wp_cache_delete( null )
("WP_Object_Cache::delete was called incorrectly. Cache key must be an integer
or a non-empty string, NULL given"), and add_to_sync( null ).

Skip the result when the contextualized ID is empty.

This branch has not been deployed

No deployments
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.

2 participants