Skip to content

Refactor sproutset package - #278

Merged
marcoluzi merged 107 commits into
mainfrom
refactor
Jul 30, 2026
Merged

Refactor sproutset package#278
marcoluzi merged 107 commits into
mainfrom
refactor

Conversation

@marcoluzi

@marcoluzi marcoluzi commented Jul 30, 2026

Copy link
Copy Markdown
Member

No description provided.

marcoluzi added 30 commits July 16, 2026 11:02
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Add a real-WordPress integration lane as its own Composer project under
tests/Integration (PHPUnit 9.6 + wp-phpunit + polyfills), kept separate so
WordPress core never collides with Laravel's global helpers (both define
__()). Runs via 'composer test:integration' against the DDEV WordPress core
and a dedicated wordpress_test DB locally, and a matrix (wp 6.5 + latest)
with a MySQL service in CI. Root static-analysis/lint skip the isolated lane.
wp_get_attachment_image_src() can return false even for an image
attachment; guard it so find() honors its documented null-on-miss
contract instead of accessing offsets on false.
WpImageResolver resolves a raster attachment at a named size into a
ResolvedImage (src/width/height/alt), returning null for a missing
attachment. Binds AttachmentRepository to the WordPress implementation.
Branch on mime before the raster path: an SVG resolves with isSvg true
and null width/height/srcset, straight from its URL. Adds SVG-capable
seeding to the drift-lane harness (direct insert, since WordPress blocks
SVG uploads by default).
Raster images carry WordPress' srcset for the requested size; a size
with no candidates and SVG sources both yield null.
ResponsiveSizes is a pure helper: an explicit sizes override wins, else
auto when auto-sizing is enabled, else null. The resolver delegates to it
on the raster path.
FocalPointPosition is a pure helper mapping fractional focal coordinates
to a CSS object-position style, or null when disabled or incomplete. The
resolver applies it to both raster and SVG sources.
OnDemandSizeGenerator creates a registered size that does not yet exist,
using only front-end-safe media APIs (wp_get_image_editor, not the
admin-only intermediate-size helpers). It caps generations per request
and swallows every failure, degrading to the closest available source
rather than fataling. The resolver invokes it on the raster path.
Swaps the container's default ImageResolver from NullImageResolver to
WpImageResolver and registers OnDemandSizeGenerator as a singleton so the
per-request generation cap spans a request. NullImageResolver stays as a
boot-safe fallback. Updates the image-component and service-provider
specs for the new default binding.
marcoluzi added 27 commits July 19, 2026 20:38
…probe

Live testing on a real GD-backed WordPress showed AVIF was never
activating despite the server being able to encode it. Two independent
bugs in WpAvifSupport, both invisible to the fast lane (no WordPress
loaded), each forcing isSupported() to false:

1. Probe source PNG was grayscale+alpha. Some GD builds (e.g. 2.3.3)
   reject it in imagecreatefromstring(), so wp_get_image_editor()->load()
   failed before any AVIF encode was attempted. Swap it for a verified
   1x1 truecolor RGBA PNG (still a hardcoded byte string, so the probe
   stays GD-independent for Imagick-only builds).

2. cachedVerdict() read get_transient()'s "not found" false as a cached
   unsupported verdict, so on any site without a persistent object cache
   (the default) the probe never ran and never stored a real value —
   AVIF was dead on arrival. Cache a '1'/'0' string sentinel instead;
   a missing transient now resolves to null and re-probes.

Regression coverage:
- tests/Unit: assert the probe source is a truecolor PNG (byte check,
  environment-independent).
- tests/Integration (real WP): an absent transient re-runs the probe,
  and a stored verdict is reused without re-probing.

Spec updated to document both constraints.
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
Signed-off-by: Marco Luzi <dev@luzimarco.ch>
@marcoluzi
marcoluzi merged commit 487491a into main Jul 30, 2026
5 checks passed
@marcoluzi
marcoluzi deleted the refactor branch July 30, 2026 12:29
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.

1 participant