Repository navigation
3.3.9 - #1360
Open
gabrielcld2 wants to merge 131 commits into
Open
3.3.9#1360gabrielcld2 wants to merge 131 commits into
gabrielcld2 wants to merge 131 commits into
Conversation
gabrielcld2
commented
Nov 5, 2026
Collaborator
- Report failed DAM imports instead of claiming success #1358
- Keep DAM transformations and overlays when recreating a delivery relation #1352
- fix(delivery): track Cloudinary src URLs back to their attachment #1344
- test(e2e): Add global image transformations spec #1343
- test(e2e): Add breakpoints and lazy load spec #1342
- Fix PHP deprecation warnings (null array offsets, output handler output, object cache key) #1340
- ci: Fix Composer cache and speed up lint #1330
- fix(sync): Break the sync loop that can overload a server (#1301) #1328
- Fix undefined array key “id” warning in filter_image_block_render_block #1321
- fix(sync): auto-regenerate thumbnail sizes left stale after an image edit #1314
The tester forced Cloudinary into the update list without checking the installed version, and self-deactivated via a hard-coded folder name that often did not match, so it could keep re-injecting the update forever. Compare against the installed version, drop a previously injected update once it is installed, use plugin_basename() for deactivation, and give the tester zip a top-level folder.
…e-loop Fix update tester offering an already-installed version
Bumps [@codemirror/state](https://github.com/codemirror/state) from 6.7.4 to 6.7.5. - [Changelog](https://github.com/codemirror/state/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/state/commits) --- updated-dependencies: - dependency-name: "@codemirror/state" dependency-version: 6.7.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [dotenv](https://github.com/motdotla/dotenv) from 17.4.2 to 18.0.2. - [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) - [Commits](motdotla/dotenv@v17.4.2...v18.0.2) --- updated-dependencies: - dependency-name: dotenv dependency-version: 18.0.2 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
…as the last word WordPress applies its own filter after image_downsize() has already resolved, and CDN/ image-optimization plugins commonly target it directly -- so a competing plugin, or filter ordering on image_downsize, could leave a local URL in place with no second chance to correct it. The new filter is a cheap guard: it bows out immediately if the URL is already a Cloudinary URL, and otherwise reuses the same deliverable/re-entrancy checks as filter_downsize(), so it only does work in the rare case something else missed. Also extracts the shared save-state/ re-entrancy guard (in_downsize, content_save_pre, is_saving_metadata, video exclusion) into Media::is_replacement_paused(), reused by filter_downsize(), the new filter, and attachment_url() (WPP-1183).
…de blind spot image_downsize()/wp_get_attachment_image_src() are exercised by ordinary front-end theme code (e.g. the_post_thumbnail()), not just wp-admin screens -- manual QA confirmed a featured image rendered by Twenty Twenty-Five's front-end template hit the filter, so scoping correction to Utils::is_admin() (admin screens only) left the front end exposed to the same "something overwrote the URL after image_downsize()" problem this hook was added to guard against. Registers both filters unconditionally instead of inside add_live_url_filters()'s admin-only set; that method's other filters are untouched. Also fixes a bug the broadened testing surfaced: wp_get_attachment_image_src() passes the caller's $icon argument straight through to the filter regardless of whether a real image was actually found (it just means "fall back to a mime icon if none is found"), but filter_attachment_image_src() treated $icon as "this is a fallback icon" and bowed out unconditionally. WP_Media_List_Table's list-mode thumbnail column always calls with icon=true, even for real synced images, which silently blocked correction there while grid mode (driven by image_downsize() instead) worked fine. Dropping the $icon check is safe: the existing is_deliverable()/cloudinary_id() checks already leave a genuine icon fallback alone, since an unsynced/non-deliverable attachment has no cloudinary_id to correct it to (WPP-1183).
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.14 to 2.2.16. - [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-version: 2.2.16 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [php-stubs/woocommerce-stubs](https://github.com/php-stubs/woocommerce-stubs) from 11.1.0 to 11.1.2. - [Commits](php-stubs/woocommerce-stubs@v11.1.0...v11.1.2) --- updated-dependencies: - dependency-name: php-stubs/woocommerce-stubs dependency-version: 11.1.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Moving the docblock above the if statement (rather than immediately before the apply_filters() call it documents) broke PHPStan's parsing of the @PARAM tag, caught by composer phpstan ahead of opening the PR. Keeps the same relative position as before, just inside the inverted condition.
…placement_paused() call Addresses a readability nit from PR review: the bool was unexplained at the call site, requiring a trip to the method signature to know what it toggles.
…lop/codemirror/state-6.7.5 chore(deps): bump @codemirror/state from 6.7.4 to 6.7.5
…lop/dotenv-18.0.2 chore(deps-dev): bump dotenv from 17.4.2 to 18.0.2
…php-stubs/woocommerce-stubs-11.1.2 chore(deps-dev): bump php-stubs/woocommerce-stubs from 11.1.0 to 11.1.2
…phpstan/phpstan-2.2.16 chore(deps-dev): bump phpstan/phpstan from 2.2.14 to 2.2.16
Bumps [eslint](https://github.com/eslint/eslint) from 10.10.0 to 10.11.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](eslint/eslint@v10.10.0...v10.11.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.11.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [cssnano](https://github.com/cssnano/cssnano) from 9.0.4 to 9.1.2. - [Release notes](https://github.com/cssnano/cssnano/releases) - [Commits](https://github.com/cssnano/cssnano/compare/cssnano@9.0.4...cssnano@9.1.2) --- updated-dependencies: - dependency-name: cssnano dependency-version: 9.0.5 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
…lop/eslint-10.11.0 chore(deps-dev): bump eslint from 10.10.0 to 10.11.0
…lop/cssnano-9.0.5 chore(deps-dev): bump cssnano from 9.0.4 to 9.1.2
The project has no TypeScript and eslint.config.js does not use @typescript-eslint/eslint-plugin directly. @wordpress/eslint-plugin already brings it in through typescript-eslint, with a matching parser version. The direct entry made Dependabot bump only the plugin, which broke npm ci with a peer conflict on @typescript-eslint/parser (#1292).
…nt-plugin chore(deps): Remove unused typescript-eslint plugin
… filter Utils::is_saving_metadata() checked did_action(), which is cumulative for the whole request: any post/term/user meta write earlier in the request (a view counter, a session plugin, etc.) would leave it true for the rest of the page once filter_attachment_image_src()/filter_downsize() started running on the front end, permanently blocking correction. Switches to doing_action() to detect a write actually in progress. It has a single caller in the plugin (Media::is_replacement_paused()), so this is a contained fix. filter_attachment_image_src() also treated every deliverable+synced attachment as correctable, but Delivery::is_deliverable() returns true for any non-image, non-video type -- so a synced non-image attachment (audio, zip, docx, ...) requested with icon=true (as WP_Media_List_Table always does) would have its generic mime icon replaced with the raw asset's Cloudinary URL, breaking the resulting <img> tag. Scopes correction to wp_attachment_is_image() || is_preview_only(), matching the preview-capable-formats carve-out filter_downsize() already uses. Test changes: added coverage for both fixes, including a regression test for an unrelated earlier meta write no longer blocking correction. Also fixed several existing tests that were passing for the wrong reason -- they relied on wp_attachment_is()/wp_attachment_is_image(), which return false unconditionally without a real _wp_attached_file postmeta regardless of post_mime_type, and a couple never set stub_cloudinary_url, so the asserted "stays unchanged" outcome held even with the check they meant to cover disabled. Every bow-out path was mutation-tested (temporarily disabled, confirmed the test fails, restored) rather than assumed correct.
Publish a post with a Cloudinary Gallery block and assert the front end renders exactly N images, that every src/srcset is served from res.cloudinary.com/<cloud_name>/, and that switching the layout from expanded to classic in the editor and saving changes the rendered widget markup. Move expectCloudinaryUrl() to utils/delivery.js so the image and gallery delivery specs share one assertion.
…achment-image-src fix: hook wp_get_attachment_image_src to keep Cloudinary URLs as the last word
…nary-e2e test(e2e): Add Gallery block front-end delivery spec
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.16 to 2.2.17. - [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-version: 2.2.17 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [eslint](https://github.com/eslint/eslint) from 10.11.0 to 10.12.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](eslint/eslint@v10.11.0...v10.12.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.12.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [globals](https://github.com/sindresorhus/globals) from 17.12.0 to 17.13.0. - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](sindresorhus/globals@v17.12.0...v17.13.0) --- updated-dependencies: - dependency-name: globals dependency-version: 17.13.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@codemirror/state](https://github.com/codemirror/state) from 6.7.5 to 6.7.6. - [Changelog](https://github.com/codemirror/state/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/state/commits) --- updated-dependencies: - dependency-name: "@codemirror/state" dependency-version: 6.7.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
…e-delivery fix(delivery): track Cloudinary src URLs back to their attachment
…livery relation An asset inserted from the DAM with a crop or effects stages those transformations in post meta until it gets a delivery relation. create_size_relation() moves them into the new row and deletes the post meta, but create_delivery() then restored the transformations it had captured before the row existed (none). The restore goes through a relationship save deferred to shutdown, so it overwrote the migrated value with null and the transformations were lost for good. The capture also came from Relate::get_transformations(), which is memoized per request, so recreating the relation again in the same request kept capturing the stale value. Recreating an existing relation also baked its overlays into the transformations column, as the capture merged them in, and dropped the overlay columns. Capture the transformations and overlays from the relationship data instead, each in its own column, and write them with the new relation itself rather than restoring them afterwards. Transformations staged in post meta still take precedence.
The revert test saved webp/60 and then auto/auto before any render, so it passed even if the plugin ignored the settings. Render and check webp/60 first, then revert and check f_auto/q_auto on the same image. f_ and q_ are added at render time, not at sync time, so upload and sync one image in beforeAll instead of one per test. Record each ID as soon as it exists so a partial setup is still cleaned up.
test(e2e): Add global image transformations spec
…ions Keep DAM transformations and overlays when recreating a delivery relation
…668061d89d1468be7 [Snyk] Upgrade human-format from 1.2.1 to 1.4.0
…lop/dotenv-18.0.9 chore(deps-dev): bump dotenv from 18.0.8 to 18.0.9
…lop/chart.js-4.6.1 chore(deps): bump chart.js from 4.5.1 to 4.6.1
…lop/webpack-5.112.2 chore(deps-dev): bump webpack from 5.112.0 to 5.112.2
…lop/npm-run-all2-9.0.4 chore(deps-dev): bump npm-run-all2 from 9.0.3 to 9.0.4
…phpstan/phpstan-2.3.2 chore(deps-dev): bump phpstan/phpstan from 2.3.1 to 2.3.2
…30933cd2f0dea414e [Snyk] Upgrade @codemirror/state from 6.7.4 to 6.7.6
…55196520238cc469b [Snyk] Upgrade @codemirror/state from 6.7.4 to 6.7.6
…lop/wordpress-c9a6458842 chore(deps-dev): bump the wordpress group across 1 directory with 13 updates
Cloudinary transformation segments such as w_800,h_600 contain commas, so splitting srcset on every comma broke each candidate into pieces. Parse candidates by their trailing descriptor instead and expose the descriptor through parseSrcset().
Cover the responsive breakpoints and lazy load delivery settings on a synced image: - min/max/step produce the matching srcset width entries - lazy load renders the SVG placeholder, data attributes and the CLDLB loader config with the blur placeholder - turning either setting off removes its markup
The regex only ended a candidate at a comma followed by whitespace or at the end of the string, and quietly returned what it had so far when it did not match. Valid input such as "a.jpg 1x,b.jpg 2x" gave an empty list, which made srcset checks pass without checking anything. Read a URL as a run of non-whitespace characters, as the HTML spec does, so commas inside Cloudinary URLs still stay part of the URL.
- Move saveSettings() and readSettings() to tests/e2e/utils/settings.js and base64-encode the JSON, so a quote in a value cannot break the PHP string. - Match the breakpoint w_ parameter exactly. - Check that every width left after breakpoints are off is a registered image size. - Stop the CLDLB regex at the end of the line. - Explain why the lazy load test also turns breakpoints off.
download_asset() returns a WP_Error when the download fails, but import_asset() only caught exceptions, so the error was dropped and the REST endpoint answered with success. The editor got a broken attachment with no file, and handle_failed_download() never ran. - import_asset() now returns the download error, so the attachment is deleted and the error is sent to the media modal. - handle_failed_download() logs the attachment ID, public_id and error to the plugin debug log and the PHP error log. - download_asset() deletes the file it primed for the download when the request fails or the response isn't a 200, instead of leaving an empty file in the uploads folder.
The endpoint only required the upload_files capability and used the posted attachment ID as is. Now that a failed download deletes the attachment, any user able to upload files could delete any attachment by posting its ID with a URL that can't be downloaded. - The endpoint now requires the attachment to exist and the user to be able to edit it. - A failed download only deletes an attachment that has no file yet and that the user can delete. - The logged public_id is read from the stored meta, instead of one generated when it's missing. - The error, which can come from a remote response header, is sanitized before it's logged or returned. - The primed file is also removed when an exception is thrown during the download.
Deleting the attachment of a failed import also ran the delete sync, which sends a destroy request for the asset on Cloudinary: a new import already counts as synced before its file is downloaded. The request currently fails because the attachment has no resource type yet, but the source asset the user picked must never be at risk. The cleanup now deletes the attachment in WordPress only. The exception cleanup in download_asset() also uses a flag to know whether the primed file became the attachment's file, instead of comparing paths that a filter can rewrite.
The DAM page called the asset download endpoint after every insert, including assets already in the Media Library, which have no attachment to download into. The endpoint now rejects that request, and with no error handler the import progress never cleared. A failed download was also shown as a success. - Only call the download endpoint for new assets, as the media modal does. - Show the error when the download fails or the request is rejected. - Always clear the import progress.
…lazy-load-e2e test(e2e): Add breakpoints and lazy load spec
…orts Report failed DAM imports instead of claiming success
3.3.9 (develop to uat)
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.