Skip to content

Media: Add unit tests for pre_wp_get_image_alttext filter - #14063

Open
robelsust wants to merge 4 commits into
WordPress:trunkfrom
robelsust:feature/66248-pre-wp-get-image-alttext
Open

robelsust wants to merge 4 commits into
WordPress:trunkfrom
robelsust:feature/66248-pre-wp-get-image-alttext

Conversation

@robelsust

Copy link
Copy Markdown

Adds comprehensive unit test coverage for the pre_wp_get_image_alttext filter introduced in #66248 (PR #14024).

The tests in tests/phpunit/tests/image/alttext.php cover:

  • Short-circuiting and returning custom alt text (e.g. from an external service or database).
  • Short-circuiting with an empty string '' to turn off alt text generation as documented.
  • Falling through to standard XMP parsing when null is returned.
  • Ensuring the $file path argument is passed to the filter callback.
  • Short-circuiting without requiring file existence or DOM extension availability.

Testing:

  • vendor/bin/phpcs src/wp-admin/includes/image.php tests/phpunit/tests/image/alttext.php: passed with 0 errors and 0 warnings.
  • vendor/bin/phpunit tests/phpunit/tests/image/alttext.php: all 12 tests (17 assertions) pass cleanly on both single site and multisite.

Trac ticket: https://core.trac.wordpress.org/ticket/66248

Use of AI Tools

AI assistance: Yes
Tool(s): Antigravity
Model(s): Gemini
Used for: Drafting unit tests and test matrix for pre_wp_get_image_alttext. Code and test execution were reviewed and verified locally by robelsust.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs.

Core Committers: Use this line as a base for the props when committing in SVN:

Props therssoftware, mppellicer, siliconforks.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@puntope

puntope commented Oct 7, 2026

Copy link
Copy Markdown

The PR says it only adds tests for a filter "introduced in PR #14024". But the diff also contains the filter implementation itself.

Comment thread src/wp-admin/includes/image.php Outdated
*
* @since 7.2.0
*
* @param string|null $override_alt_text Short-circuit return value.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docblock's claims @param string|null $override_alt_text but actually can return anything.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand? Technically, yes, any filter could have anything for the first parameter (because you can't control what filters a third-party plugin or theme might be using), but I think the convention is to document the data type that should be there.

The implementation and the docblock largely follows the pattern used in other "short-circuit" filters in WordPress core. For example:

Comment thread src/wp-admin/includes/image.php Outdated
/**
* Filters whether to short-circuit the parsing of alt text from an image.
*
* Returning a non-null value will short-circuit the image parsing,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It claims: Returning a non-null value will short-circuit the image parsing, which implies the full image parsing, not just the altext

@robelsust

Copy link
Copy Markdown
Author

Thanks @mppellicer! The filter implementation from PR #14024 was included in this branch so that the unit tests could run and be verified in CI. If PR #14024 is merged first, I will gladly rebase this PR so it only contains the unit test file.

@puntope

puntope commented Oct 7, 2026

Copy link
Copy Markdown

About tests:

  • Non-string returns (e.g. false, 0, an array) are not covered.
  • Consider using @dataProviders in tests to reduce duplication.
  • Also the DIR_TESTDATA . '/images/IPTC-PhotometadataRef-Std2025.1.jpg' is duplicated.

@siliconforks

Copy link
Copy Markdown

Thanks @mppellicer! The filter implementation from PR #14024 was included in this branch so that the unit tests could run and be verified in CI. If PR #14024 is merged first, I will gladly rebase this PR so it only contains the unit test file.

I've closed PR #14024 in favor of this one so that all discussion (for either the filter itself or the tests) will be in one place.

if ( empty( $meta['title'] ) && $caption_length < 80 ) {
if ( in_array( 'title', $allowed_keys, true ) && empty( $meta['title'] ) && $caption_length < 80 ) {
// Assume the title is stored in 2:120 if it's short.
$meta['title'] = $caption;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To execute this line, you need to have both caption and title in $allowed_keys. I think you should only need title?

$description_length = strlen( $exif_usercomment );
if ( empty( $meta['title'] ) && $description_length < 80 ) {
if ( in_array( 'title', $allowed_keys, true ) && empty( $meta['title'] ) && $description_length < 80 ) {
$meta['title'] = trim( $exif_usercomment );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here as above - you need to have both caption and title in $allowed_keys. I think it should just be title.

@siliconforks

Copy link
Copy Markdown

Overall, the wp_read_image_metadata_allowed_keys filter seems fine to me. I'm not sure if we need the pre_wp_get_image_alttext filter any more, since you can accomplish the same thing with wp_read_image_metadata_allowed_keys?

@robelsust

Copy link
Copy Markdown
Author

Thanks for the thorough review and catch on the title and caption key coupling @siliconforks!

I have updated the PR accordingly:

  1. Title & Caption Decoupling in IPTC and EXIF:

    • Updated the IPTC 2#120 and EXIF UserComment logic so that allowing only title (without caption) successfully extracts the title while leaving $meta['caption'] empty.
    • Added dedicated unit tests covering independent title and caption extraction from both IPTC and EXIF in readImageMetadataAllowedKeys.php.
  2. Dropped pre_wp_get_image_alttext:

    • Removed the pre_wp_get_image_alttext filter from wp_get_image_alttext() in favor of the unified wp_read_image_metadata_allowed_keys filter as you suggested.
    • Omission of 'alt' from allowed_keys completely skips calling wp_get_image_alttext(), preventing all file read and XML parsing overhead.
    • Retained the core unit test suite for wp_get_image_alttext() in tests/phpunit/tests/image/alttext.php.

All tests pass cleanly in single site and multisite with 0 PHPCS violations. Ready for another look!

Introduces unit tests in `tests/phpunit/tests/image/alttext.php` covering short-circuiting with a custom string, disabling alt text generation with an empty string, falling through when null is returned, passing the file path argument to the callback, and bypassing file access requirements.

Follow-up to #66248 and PR WordPress#14024.
Trac ticket: https://core.trac.wordpress.org/ticket/66248
…mage_metadata()`.

Allows developers to customize or disable extraction of specific metadata fields (such as 'alt', 'caption', 'title', etc.) or disable metadata parsing entirely via a single filter, as proposed by @joedolson on Trac #66248.

Guards IPTC, XMP ('alt'), and EXIF extraction based on the filtered allowed keys to avoid redundant disk I/O and XML/DOMDocument parsing overhead when fields are not needed. Maintains the complete default 13-key return array structure to ensure strict backward compatibility for all callers.

Includes dedicated unit tests in `readImageMetadataAllowedKeys.php`.

See #66248.
…op pre_wp_get_image_alttext filter.

- Decouple 'title' from 'caption' in both IPTC and EXIF parsing within wp_read_image_metadata() so that allowing only 'title' still extracts titles stored in IPTC 2#120 or EXIF UserComment.
- Remove pre_wp_get_image_alttext filter in favor of the unified wp_read_image_metadata_allowed_keys filter.
- Add unit tests for independent title and caption extraction in readImageMetadataAllowedKeys.php.

See #66248.
@robelsust
robelsust force-pushed the feature/66248-pre-wp-get-image-alttext branch from ca1607d to 7e24989 Compare October 14, 2026 14:20
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.

3 participants