AddOn
MASSIF Media
Beschreibung
MASSIF Media ist ein REDAXO-Addon für moderne, schnelle und responsive Medien-Auslieferung.Hilft dabei, Bilder automatisch in passenden Grössen und modernen Formaten auszuliefern — ohne dass Redakteurinnen, Redakteure oder Entwickler jedes Bild manuell vorbereiten müssen.
MASSIF Media ist ein REDAXO-Addon für moderne, schnelle und responsive Medien-Auslieferung.
Hilft dabei, Bilder automatisch in passenden Grössen und modernen Formaten auszuliefern — ohne dass Redakteurinnen, Redakteure oder Entwickler jedes Bild manuell vorbereiten müssen.
github.com/ynamite/redaxo_massif_media
Umsetzung
MASSIF Web Studio zum Profil
St. Christophstrasse 8 5400 Baden (Schweiz) www.massif.chVersionen
1.0.14
Added
- TinyMCE-Editorbilder als
<picture>. Neue Option unter Einstellungen → Allgemein → TinyMCE (Default: aus). Im Frontend-OUTPUT_FILTER(und im block_peek-Preview) wird<img src="/media/<typ>/<datei>">— das Markup, das das tinymce-Addon für eingefügte Bilder erzeugt — durchImage::picture($datei, alt: …, sizes: …)ersetzt.<typ>isttiny(Mediapool-Auswahl) oder der in den TinyMCE-Einstellungen konfigurierte Upload-Typ. Nursrc/altwerden übernommen, das umgebende<p>bleibt. Fail-open wieEditorContentScanner.sizesist als Einstellung konfigurierbar und perTinymceImageScanner::setSizes()zur Laufzeit überschreibbar.
🤖 Generated with Claude Code
1.0.13
Performance-Release: entschärft die drei Ursachen für langsame Server-Antworten auf bildreichen Seiten.
Fixed
- Cache-Endpoint: Hits streamen direkt von der Disk, Misses sind per Lock dedupliziert — keine Encode-Stampedes mehr nach „Cache leeren". Cache-Hits im PHP-Pfad instanzierten bisher den kompletten Glide-Stack und lasen die Datei voll in den Speicher; jetzt
is_file-Fastpath +readfile()-Streaming, ETag aus mtime+size,If-None-Match→304. Cache-Misses nehmen ein blockierendesflockpro Variante — N parallele Requests auf dieselbe ungecachte Variante encodieren einmal statt N× (AVIF: Sekunden CPU und je ein FPM-Worker pro Encode; nach einem Cache-Clear auf einer besuchten Seite sättigte der Encode-Sturm bisher den Worker-Pool und bremste alle Requests). Der PHP-Pfad sendet neuX-Massif-Media: php— Cache-Hit-URLs mit diesem Header zeigen, dass der statische Fastpath (.htaccess/ nginx-Snippet) nicht greift (percurl -sI <variant-url>prüfbar). 0-Byte-Cache-Dateien (broken-AVIF-Form) werden nicht mehr als leere 200 serviert. - Externe Bildquellen: Failure-Sentinel + Stale-on-Error. Eine tote externe URL blockierte bisher jeden Seiten-Render synchron für den vollen Transport-Timeout (bis zu 20 s), weil es kein Negative-Caching gab. Ein Fehlschlag schreibt jetzt
failedAtins Manifest; innerhalb vonsentinel_ttl_seconds(Default 60 s) wird nicht erneut gefetcht — ein alter Body auf der Disk wird serviert (stale-on-error, geloggt), sonst schlägt der Resolve sofort fehl. Ein erfolgreicher Fetch löscht den Sentinel.
Changed
_lqip/überlebt den generischen REDAXO-Cache-Clear. Die LQIP-Config-Werte (lqip_width/lqip_quality/lqip_blur) stecken jetzt im Cache-Key (CACHE_VERSION v3) — der Sidecar ist damit eine reine Funktion aus Bildbytes + Config und wird imCACHE_DELETED-Hook wie_color/verschont. Bisher regenerierte der erste HTML-Render nach jedem „Cache leeren" synchron pro Bild ein LQIP (voller Decode + WebP-Encode — Sekunden bei bildreichen Seiten; Lazy-Loading hilft nicht, das LQIP liegt inline im Markup). Der addon-eigene „Addon Cache jetzt leeren"-Button löscht als Escape-Hatch weiterhin alles.
Tests: neue tests/Integration/EndpointServeTest.php (Fastpath, Miss-Encode am URL-Pfad, 304, 0-Byte-Refusal, 403) plus Unit-Tests für Failure-Sentinel und LQIP-Cache-Key.
1.0.12
Fixed
- Numerische Bildfilter (
blur,brightness,sharpen…) funktionieren jetzt auch im Editor-Content-Scan-Pfad. Ein in Rich-Text/WYSIWYG-Inhalt getipptesREX_PIC[… filter="sepia" blur="5"]blieb als Literal auf der Seite stehen: der Scanner liefert Attributwerte als Strings,FilterParams::clamp()verlangteint|float— der resultierendeTypeErrorwurde vom Fail-Open-Catch geschluckt.FilterParams::normalize()konvertiert numerische Strings jetzt nach int/float und clampt sie; nicht-numerische Werte für Range-Parameter werden gedroppt. Betraf auch direkte Aufrufe wieImage::picture(filters: ['blur' => '5'])und String-Werte in art-JSON.
Changed
- Explizit gesetztes
sizeswird 1:1 emittiert — derauto,-Prefix wird nur noch dem Default-sizesaus den Settings vorangestellt. In Browsern mitsizes=auto-Support überschreibt derauto-Eintrag den Rest der Liste — ein explizit gesetzter Autor-Wert wurde dort still verworfen. Jetzt gewinnt der Autor-Wert; wer die Kombination will, schreibtsizes="auto, 100vw"selbst. Ohne explizitessizesbleibt das bisherige Verhalten (auto,-Prefix auf lazy-geladenen Bildern).
1.0.11
Fixed
_img/.bootstrap.phpist jetzt deploy-portabel.install.phpschrieb absolute Pfade der Build-Maschine (var_export) in das generierte Bootstrap — nach einem Deployment auf einen Host mit anderem absoluten Prefix (Deployerreleases/N, anderer vhost-Root) schlugen Cache-Miss-Requests fatal fehl und rissenopen_basedir-Warnungen. Alle Pfade werden jetzt als__DIR__-relative Ausdrücke überInstall\PortablePath::export()emittiert.PATH_PROVIDER-Erkennung funktionierte nie:rex::getProperty('path_provider')wird vom Core nicht gesetzt — auf Custom-Layout-Installationen (z. B. Viterexapp_path_provider) fehlte der Provider-Block im Bootstrap komplett. Der live Provider wird jetzt per Reflection ausrex_path::$pathprovidergelesen.
Nach dem Update das Addon einmal reinstallieren, damit _img/.bootstrap.php neu generiert wird.
1.0.10
Fixed
- Erster Seitenaufruf nach „Cache leeren" ist nicht mehr sekundenlang langsam (gemessen: ~5.3 s → ~0.13 s bei 40
<picture>-Elementen). Zwei Fixes in der Dominant-Color-Pipeline: (1)jpeg:size-Decode-Hint, damit libjpeg DCT-skaliert nahe Thumbnail-Grösse dekodiert statt in voller Auflösung; (2)_color/überlebt den generischenCACHE_DELETED-Clear — Dominant-Farben sind eine reine Funktion der Bildbytes, invalidiert wird weiterhin überMEDIA_UPDATED/MEDIA_DELETED, mtime undCACHE_VERSION. Der addon-eigene „Addon Cache jetzt leeren"-Button löscht als Escape-Hatch weiterhin alles inkl._color/.
Vollständiges Changelog: siehe CHANGELOG.md.
1.0.9
Fixed
- REX_PIC / REX_VIDEO in block_peek-Vorschauen werden wieder korrekt aufgelöst — keine doppelten Anführungszeichen / am ersten Leerzeichen abgeschnittenen Werte mehr.
EditorContentScanner::scan()läuft jetzt zusätzlich über block_peeksBLOCK_PEEK_OUTPUT-Extension-Point (vor der srcdoc-Maskierung). - „Metadata TTL" und „Sentinel TTL" (Tab Sicherheit & Cache) sind jetzt tatsächlich wirksam — vorher inerte Formularfelder ohne Consumer. Neue
Config::metadataTtlSeconds()/sentinelTtlSeconds()-Accessoren;MetadataReaderverfällt_meta-Sidecars nach Alter (gute Einträge: 90 Tage Backstop, fehlgeschlagene Reads: kurze Sentinel-TTL, Default 60 s, mit Retry statt Dauer-0×0). SVG bleibt korrekt ein gültiger Eintrag (Diskriminator:0×0und Format unbekannt).
Removed
- Vier ungenutzte
use-Imports (reine Aufräumarbeit, keine Verhaltensänderung).
Vollständiges Changelog: siehe CHANGELOG.md.
1.0.8
Fixed
- Scharfe Wasserzeichen. Marks werden jetzt mit Imagick-Lanczos-Resampling skaliert (statt
scaleImage()ohne Filter) und alpha-korrekt (COMPOSITE_OVER, sRGB-normalisiert) eingesetzt — auch hochauflösende Logo-PNGs kommen scharf statt matschig/treppig heraus. NeuerGlide\Watermark-Manipulator, der den Stock-Manipulator in-place ersetzt; URL-Contract unverändert, Imagick-only mit GD-Fallback, Fail-open erhalten. marks(relative Grösse) wird endlich honoriert statt stillschweigend ignoriert.marks="0.25"ergibt jetzt 25 % der Bildbreite.markfit="cover"füllt die Box korrekt, statt aufcontainzu degradieren (coverund Glide'scrop*-Tokens werden als Fill behandelt).
Changed
sizes="auto, …"auf allen<source>- und<img>-Elementen: Browser bestimmen für lazy-geladene Bilder die Render-Breite selbst; das konfiguriertesizes-Attribut bleibt als Fallback (eager-Bilder, Preload-Links).
Vollständige Details im CHANGELOG.
1.0.7
Cache-invalidation UX overhaul + AVIF minimum-dimension filter.
Fixed
-
Server cache clear now actually causes browsers to refetch. New
&g=<cache_gen>token appended to every variant URL, sourced fromConfig::cacheGeneration()(a unix timestamp inrex_config). Bumped on every cache-clearing event: REDAXO's "Cache leeren" (CACHE_DELETEDextension), the addon's "Addon Cache jetzt leeren" button, and content-affecting setting saves. Without this token, Endpoint::handle's `Cache-Control: public, max-age=31536000, immutable` directive made the browser treat variant URLs as forever-cacheable; server-side wipes were invisible at the URL layer and the request never reached the server. The previously-attributed-to-HMAC behaviour ("regenerate sign key fixes it after cache clear") was a coincidence — regenerating the key changed every URL signature, which the browser saw as new URLs and refetched. The HMAC sign and verify layer was always structurally correct. -
AVIF cache files at sub-16-pixel heights no longer broken. libavif (the AV1 codec backing both Imagick's libheif binding and GD's `imageavif()`) rejects sub-16×16 inputs with empty output, no exception. With default `image_sizes` `16,32,…` and `ratio="16:9"`, w=16 produced h=9 — encoder returned nothing, Glide wrote a 0-byte cache file, browser showed broken image. `RenderContext::buildSrcset()` now filters AVIF widths whose computed height falls below 16. Other formats keep their full width pool; browser falls through to WebP for slots where AVIF is filtered out.
Added
-
Live cache stats on the settings page. `pages/settings.security.php` calls `CacheStats::compute()` with `forceRefresh: true` on every page load. The previous 5-minute memo was actively misleading after cache changes; sub-second walk on a multi-thousand-file cache is fine for a backend-only page. The "Statistik neu berechnen" button stays for explicit re-walk after off-band filesystem operations (rsync/scp).
-
Auto-clear cache on content-affecting setting save. Changes to `KEY_FORMATS`, `KEY_QUALITY_AVIF`/`WEBP`/`JPG`, or `KEY_DEVICE_SIZES`/`KEY_IMAGE_SIZES` now wipe the addon cache and bump the cache-generation token automatically when the form is saved. Implementation: new `\Ynamite\Media\Backend\ConfigForm` subclass overrides `save()` to snapshot before/after; settings unrelated to cache content (CDN routing toggle, runtime TTLs, external-fetch behaviour, HTML markup) leave existing variants valid and skip the clear. The HMAC sign key is intentionally NOT in the auto-clear set — its regen stays user-triggered, since a regen invalidates every browser cache and third-party hotlink for content that's still semantically valid.
Install / upgrade
- Connect ZIP install via REDAXO Backend → Installer.
- Composer: `composer require ynamite/massif_media`.
- Upgrading from 1.0.4–1.0.6: `install.php` initialises the new `KEY_CACHE_GENERATION` token on first reinstall (or on first cache-clearing event); existing browser caches keep working until the next clear, at which point they're properly invalidated by the new `&g=` segment.
See CHANGELOG.md for the full diagnosis on each fix.
1.0.6
Follow-up to 1.0.5. The 1.0.5 `SafeAvifEncoder` used the minimal Imagick call pattern (`setImageFormat → setImageCompressionQuality → getImageBlob`) that `media_negotiator/lib/Helper.php::imagickConvert()` documents. On the Plesk-shipped libheif build that motivated the override, every Imagick AVIF path produces 0-byte output — including that minimal one. A second read of `rex_effect_negotiator.php` clarifies why media_negotiator's AVIF still works on those servers: `imagickConvert()` returns a `GdImage`, not bytes — its caller hands the decoded GD image to REDAXO's media pipeline, which emits AVIF via GD's `imageavif()`. So the actually-working encoder there is GD, not Imagick.
Fixed
- AVIF cache files were still 0 bytes after 1.0.5 on Plesk-shipped Imagick builds. `SafeAvifEncoder` now mirrors media_negotiator's working flow: clone the manipulated Imagick instance, render to PNG (lossless intermediate), decode via `imagecreatefromstring()`, encode AVIF via `imageavif(\$gd, null, \$quality)`. Falls through to `parent::run()` for non-AVIF formats, GD-driver hosts, missing `imageavif()`, or any PNG/decode failure. WebP and all non-AVIF paths are unchanged.
Install / upgrade
- Connect ZIP install via REDAXO Backend → Installer.
- Composer: `composer require ynamite/massif_media`.
- Existing 1.0.4 / 1.0.5 installs with 0-byte AVIF cache files: reinstall the addon — `install.php`'s chmod migration runs and the next render regenerates the AVIF variants via the new GD path. Or manually wipe `assets/addons/massif_media/cache/
/*.avif` to force regen.
See CHANGELOG.md for the full diagnosis.
1.0.5
Single-fix release for AVIF encoding on shared hosting.
Fixed
- AVIF cache files were ending up as 0 bytes on some Imagick builds (verified Plesk shared hosting with libheif). After the 1.0.4 capability detection change correctly identified those servers as AVIF-capable, the cache-miss endpoint generated empty AVIF files — browsers got broken images, request 200s with no body. Root cause: `intervention/image` v3's specialised Imagick `AvifEncoder` calls `setCompression(Imagick::COMPRESSION_ZIP)` plus the doubled `setFormat`/`setImageFormat`/`setImageCompression`/`setCompressionQuality` setters before `getImagesBlob()`. ZIP compression is meaningless for AVIF (AV1-compressed internally), but some libheif builds misinterpret the flag as an encoder hint and abort silently. New `Glide\SafeAvifEncoder` overrides the AVIF path with the minimal pattern `media_negotiator` uses successfully on the same builds: `setImageFormat('avif')` → `setImageCompressionQuality(\$q)` → `getImageBlob()` (singular). WebP works fine through Glide's default path on the affected hosts; the GD driver delegates to PHP's `imageavif()` without any property dance — both fall through to `parent::run()` unchanged.
Install / upgrade
- Connect ZIP install via REDAXO Backend → Installer.
- Composer: `composer require ynamite/massif_media`.
- Existing 1.0.4 installs with 0-byte AVIF cache files: reinstall the addon — `install.php` will chmod the existing `cache/` tree (already part of 1.0.4) and the next render will regenerate the AVIF variants via the new encoder. Or manually wipe `assets/addons/massif_media/cache/` to force a clean regen.
See CHANGELOG.md for the full diagnosis.
1.0.4
First stable release of MASSIF Media. Consolidates the 1.0.4-beta development line, the post-1.0.4-beta stability fixes (shared-hosting permissions, REX_PIC in slice content, _img bootstrap), and driver-aware AVIF/WebP capability detection.
Breaking
- Minimum REDAXO version bumped to
^5.18.0(was^5.13.0). REDAXO 5.18 is required forrex_var::register()and shipspsr/log: ^3.0.2, both of which the addon depends on. REDAXO 5.13–5.17 fatals at boot onCall to undefined method rex_var::register(). psr/logpinned to^3.0(matches REDAXO core ≥ 5.18). When REDAXO core'spsr/logconstraint changes, ours has to follow in lockstep — seeCLAUDE.md → Composer autoloaderfor why SPL chain priority can't paper over a version mismatch underrex_autoload's vendor scan.
Added
REX_PIC[…]/REX_VIDEO[…]now work in slice content / WYSIWYG / rich-text fields. REDAXO core'srex_var::parse()only runs on module/article templates, never on stored editor input — so aREX_PICtyped into a rich-text field used to render as literal text. NewView\EditorContentScannerruns in theOUTPUT_FILTERpass and rewritesREX_PIC[…]/REX_VIDEO[…]substrings in the final HTML to<picture>/<video>markup. Cheap-skips when no markers are present (~zero cost on pages without REX vars).
Fixed
- Cache directories and files now end up
0755/0644so they serve correctly on shared hosting (Plesk, cPanel) where PHP-FPM and Apache run as different Linux users. Combined fix inGlide\Server(Flysystem visibility = PUBLIC),Glide\Endpoint::handle(umask 0022), andinstall.php(recursive chmod migration for existing cache dirs). - AVIF / WebP capability detection mirrors Glide's actual driver selection (
Imagick::queryFormats()when Imagick is loaded,gd_info()otherwise). Drops the earlier 1×1 pixel encode probe — that probe produced false negatives on libheif builds that reject sub-minimum dimensions, hiding AVIF on otherwise-capable servers. Same metadata-API approachmedia_negotiator/lib/Helper.phpuses successfully across thousands of REDAXO installs. Call to undefined method rex_null_addon::boot()on direct cache-miss hits to_img/index.php. Generated bootstrap now sets\$REX['LOAD_PAGE'] = trueso REDAXO core proceeds intofrontend.php→packages.php→ addon registration.- Path-provider-aware bootstrap for Viterex / custom layouts.
install.phpresolvesHTDOCS_PATH,BACKEND_FOLDER,core/boot.php, andPATH_PROVIDERvia the live path provider and writes a self-contained_img/.bootstrap.php. psr/logsignature collision (Declaration of rex_logger::log() must be compatible with Psr\\Log\\AbstractLogger::log()). The 1.0.2-beta appended-loader hack was a misdiagnosis — the real fix is REDAXO floor + matching v3 pin.Options +FollowSymLinksremoved fromassets/.htaccessfor shared-hosting compatibility.
See CHANGELOG.md for the full diagnosis on each fix.
Install / upgrade
- Connect ZIP install via REDAXO Backend → Installer (workflow attaches the ZIP to this release automatically).
- Composer:
composer require ynamite/massif_media. - Existing installs with broken cache permissions: reinstall the addon —
install.phpwill chmod the existingcache/tree to fix the legacy 0700 directories.
1.0.2-beta
Fixed
-
Declaration of rex_logger::log() must be compatible with Psr\Log\AbstractLogger::log()fatal on older REDAXO — Composer registers itsClassLoaderwithprepend=trueby
default, putting our shippedpsr/logv3 ahead of REDAXO core's bundled version on the SPL chain. On REDAXO 5.13–5.17 (psr/log v1 in core),rex_logger::log()is declared without the
: voidreturn type orstring|\Stringable \$messagetyping — fine for v1, LSP-incompatible with v3. Once any code path autoloadsrex_logger, PHP runs the signature check against
our v3AbstractLogger, mismatch, fatal. Fix: `boot.php` re-registers the Composer loader as appended (`\$loader->unregister(); \$loader->register(false);`) so REDAXO core resolves
`Psr\Log\*` first; our loader still owns every namespace REDAXO doesn't ship. On REDAXO ≥ 5.18 (psr/log v3 in core) this is a functional no-op — the versions are identical, only
the load path differs. -
`REX_PIC[…]` / `REX_VIDEO[…]` rendered as literal text after install — REDAXO's `package_manager::install()` and `activate()` do not call `rex_delete_cache()`.
Slices and templates cached before the addon was active still contained `REX_PIC[…]` as plain text because `rex_var::parse()` ran without our vars registered. Without manual cache
clear or per-slice re-save, the frontend kept rendering literal text. Fix: `install.php` now calls `rex_delete_cache()` so the article cache regenerates with REX_PIC / REX_VIDEO
active on next render. Also fires on reinstall / update, which is the right behaviour when `getOutput()` semantics drift between releases.
See CHANGELOG for the full entry.
1.0.1-beta
Fixed
-
REX_PIC
artattribute — accept four equivalent JSON shapes (comma-separated bare variants, keyed object, single bare variant, list); REDAXO'srex_vartokenizer regex bars unescaped[/]inside REX_VAR tags so the historical list-shapeart='[…]'would prevent the entireREX_PIC[…]from being recognised. Variantsrcis now optional and auto-inherits from the parent picture. -
Watermark filters were silently ignored —
Server::create()/Server::createForExternal()didn't configure a Glide watermarks filesystem, soWatermark::getImage()returned null andmark/markpos/etc. did nothing. Both factories now configureLocalFilesystemAdapter(rex_path::frontend())(correct REDAXO anchor for bothmedia/andassets/, works with installers like Viterex that offset the public dir to<base>/public/). NewPipeline\WatermarkResolvertranslates user-suppliedmarkvalues (mediapool filename, HTTPS URL with full SSRF + TTL inheritance from the external-source pipeline, frontend-relative URL with leading slash + query strip, own Glide cache URL → routed to source) into paths the watermarks FS can read.Endpoint::translateMarkapplies the translation to Glide's processing params while keeping the original onServer::$activeFilterParamsso the on-disk cache key still matches the URL hash. -
rex::isDebug()typo inImageBuilder::missingSrcMarker()andVideoBuilder::missingSrcMarker()— REDAXO's API isrex::isDebugMode(). Production was unaffected (the marker fires only in debug); debug-mode renders with an unresolvable source 500'd. Tests passed because the stub mirrored the wrong name; stub corrected.
See CHANGELOG for the full entry.
1.0.0-beta
MASSIF Media 1.0.0-beta
Erste öffentliche Beta des eigenständigen MASSIF Media Addons für REDAXO 5 — modernes responsives <picture>/<video>-Rendering mit On-Demand-Resize, signierten Cache-URLs und
Self-contained Routing.
Ausgegliedert aus dem redaxo-massif Sammel-Addon und auf eine eigenständige Pipeline umgebaut. Koexistiert mit redaxo-massif; bestehende Ynamite\Massif\Media\… Aufrufer bleiben
unverändert — neuer Code verwendet Ynamite\Media\….
Highlights
Rendering
<picture>mit AVIF / WebP / JPG Browser-NegotiationImage::url()als Single-URL-Escape-Hatch (Poster, OG-Tags, CSS-Backgrounds)- Responsives
<video>mit optionalemlinkPreloadfür LCP-Heros - SVG / GIF Pass-through; animierte GIFs werden automatisch als animiertes WebP angeboten
- Art Direction über
<source media="…">mit Per-Variant-Crop und -Filter
Quellen
- Mediapool-Files (
rex_media) - Externe HTTPS-URLs mit SSRF-Schutz, TTL + Conditional GET, Body-Size-Cap und optionaler Host-Allowlist
SourceInterfaceals sauberer Erweiterungspunkt für eigene Quellen-Typen
Pipeline
- On-demand Resizing über
league/glide(Imagick-Driver) - HMAC-SHA256 signierte Cache-URLs gegen Disk-Filling
- Self-contained Cache-Routing über
PACKAGES_INCLUDED-Hook — funktioniert ohne addon-spezifische.htaccess- oder nginx-Config - LQIP, Dominante Farbe und Focal-Point als orthogonal kombinierbare Placeholder
- Glide-Filter-Passthrough (Brightness, Contrast, Blur, Sharpen, Watermark, …)
- Optionaler CDN-Mode (ImageKit / Cloudinary / Imgix-style Templates)
- EXIF / GPS / ICC-Profile werden vor dem Encoden gestrippt
Editoren-Integration
- Native
REX_PIC[…]undREX_VIDEO[…]rex_var-Implementierungen - Backend-Settings unter AddOns → MASSIF Media → Einstellungen (Allgemein, Placeholder, CDN, Sicherheit & Cache)
- README direkt als Backend-Dokumentations-Tab
Qualität
- PHPUnit-Suite mit Unit- und Integration-Tests
- GitHub-Actions-Workflow publisht automatisch zu my.redaxo.org bei
release: published
Requirements
- REDAXO 5.13+
- PHP 8.2+
- Imagick empfohlen (nötig für AVIF-Output, animiertes WebP und Dominante Farbe)
- Optional:
focuspointAddon für visuelle Focal-Point-Pflege
Beta-Hinweis
Funktional komplett und produktiv verifiziert. Beta-Status wegen der externen URL-Quellen-Surface (Image::picture('https://…')): erster Render fetched synchron, bei langsamen Upstreams
blockiert das die Auslieferung. Eine Queue-basierte Async-Variante ist für ein späteres Minor vorgesehen.
Vollständiges Changelog: CHANGELOG.md