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.ch

Versionen

1.0.14

Für REDAXO
^5.18.0
Veröffentlicht am
22.09.2026
Require / PHP
>=8.2

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 — durch Image::picture($datei, alt: …, sizes: …) ersetzt. <typ> ist tiny (Mediapool-Auswahl) oder der in den TinyMCE-Einstellungen konfigurierte Upload-Typ. Nur src/alt werden übernommen, das umgebende <p> bleibt. Fail-open wie EditorContentScanner. sizes ist als Einstellung konfigurierbar und per TinymceImageScanner::setSizes() zur Laufzeit überschreibbar.

🤖 Generated with Claude Code

1.0.13

Für REDAXO
^5.18.0
Veröffentlicht am
04.08.2026
Require / PHP
>=8.2

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 blockierendes flock pro 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 neu X-Massif-Media: php — Cache-Hit-URLs mit diesem Header zeigen, dass der statische Fastpath (.htaccess / nginx-Snippet) nicht greift (per curl -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 failedAt ins Manifest; innerhalb von sentinel_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 im CACHE_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

Für REDAXO
^5.18.0
Veröffentlicht am
28.07.2026
Require / PHP
>=8.2

Fixed

  • Numerische Bildfilter (blur, brightness, sharpen …) funktionieren jetzt auch im Editor-Content-Scan-Pfad. Ein in Rich-Text/WYSIWYG-Inhalt getipptes REX_PIC[… filter="sepia" blur="5"] blieb als Literal auf der Seite stehen: der Scanner liefert Attributwerte als Strings, FilterParams::clamp() verlangte int|float — der resultierende TypeError wurde 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 wie Image::picture(filters: ['blur' => '5']) und String-Werte in art-JSON.

Changed

  • Explizit gesetztes sizes wird 1:1 emittiert — der auto,-Prefix wird nur noch dem Default-sizes aus den Settings vorangestellt. In Browsern mit sizes=auto-Support überschreibt der auto-Eintrag den Rest der Liste — ein explizit gesetzter Autor-Wert wurde dort still verworfen. Jetzt gewinnt der Autor-Wert; wer die Kombination will, schreibt sizes="auto, 100vw" selbst. Ohne explizites sizes bleibt das bisherige Verhalten (auto,-Prefix auf lazy-geladenen Bildern).

1.0.11

Für REDAXO
^5.18.0
Veröffentlicht am
28.07.2026
Require / PHP
>=8.2

Fixed

  • _img/.bootstrap.php ist jetzt deploy-portabel. install.php schrieb absolute Pfade der Build-Maschine (var_export) in das generierte Bootstrap — nach einem Deployment auf einen Host mit anderem absoluten Prefix (Deployer releases/N, anderer vhost-Root) schlugen Cache-Miss-Requests fatal fehl und rissen open_basedir-Warnungen. Alle Pfade werden jetzt als __DIR__-relative Ausdrücke über Install\PortablePath::export() emittiert.
  • PATH_PROVIDER-Erkennung funktionierte nie: rex::getProperty('path_provider') wird vom Core nicht gesetzt — auf Custom-Layout-Installationen (z. B. Viterex app_path_provider) fehlte der Provider-Block im Bootstrap komplett. Der live Provider wird jetzt per Reflection aus rex_path::$pathprovider gelesen.

Nach dem Update das Addon einmal reinstallieren, damit _img/.bootstrap.php neu generiert wird.

1.0.10

Für REDAXO
^5.18.0
Veröffentlicht am
27.07.2026
Require / PHP
>=8.2

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 generischen CACHE_DELETED-Clear — Dominant-Farben sind eine reine Funktion der Bildbytes, invalidiert wird weiterhin über MEDIA_UPDATED/MEDIA_DELETED, mtime und CACHE_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

Für REDAXO
^5.18.0
Veröffentlicht am
04.06.2026
Require / PHP
>=8.2

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_peeks BLOCK_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; MetadataReader verfä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×0 und Format unbekannt).

Removed

  • Vier ungenutzte use-Imports (reine Aufräumarbeit, keine Verhaltensänderung).

Vollständiges Changelog: siehe CHANGELOG.md.

1.0.8

Für REDAXO
^5.18.0
Veröffentlicht am
02.06.2026
Require / PHP
>=8.2

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. Neuer Glide\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 auf contain zu degradieren (cover und Glide's crop*-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 konfigurierte sizes-Attribut bleibt als Fallback (eager-Bilder, Preload-Links).

Vollständige Details im CHANGELOG.

1.0.7

Für REDAXO
^5.18.0
Veröffentlicht am
07.05.2026
Require / PHP
>=8.2

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 from Config::cacheGeneration() (a unix timestamp in rex_config). Bumped on every cache-clearing event: REDAXO's "Cache leeren" (CACHE_DELETED extension), 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

Für REDAXO
^5.18.0
Veröffentlicht am
07.05.2026
Require / PHP
>=8.2

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

Für REDAXO
^5.18.0
Veröffentlicht am
07.05.2026
Require / PHP
>=8.2

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

Für REDAXO
^5.18.0
Veröffentlicht am
07.05.2026
Require / PHP
>=8.2

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 for rex_var::register() and ships psr/log: ^3.0.2, both of which the addon depends on. REDAXO 5.13–5.17 fatals at boot on Call to undefined method rex_var::register().
  • psr/log pinned to ^3.0 (matches REDAXO core ≥ 5.18). When REDAXO core's psr/log constraint changes, ours has to follow in lockstep — see CLAUDE.md → Composer autoloader for why SPL chain priority can't paper over a version mismatch under rex_autoload's vendor scan.

Added

  • REX_PIC[…] / REX_VIDEO[…] now work in slice content / WYSIWYG / rich-text fields. REDAXO core's rex_var::parse() only runs on module/article templates, never on stored editor input — so a REX_PIC typed into a rich-text field used to render as literal text. New View\EditorContentScanner runs in the OUTPUT_FILTER pass and rewrites REX_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 / 0644 so they serve correctly on shared hosting (Plesk, cPanel) where PHP-FPM and Apache run as different Linux users. Combined fix in Glide\Server (Flysystem visibility = PUBLIC), Glide\Endpoint::handle (umask 0022), and install.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 approach media_negotiator/lib/Helper.php uses 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'] = true so REDAXO core proceeds into frontend.php → packages.php → addon registration.
  • Path-provider-aware bootstrap for Viterex / custom layouts. install.php resolves HTDOCS_PATH, BACKEND_FOLDER, core/boot.php, and PATH_PROVIDER via the live path provider and writes a self-contained _img/.bootstrap.php.
  • psr/log signature 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 +FollowSymLinks removed from assets/.htaccess for 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.php will chmod the existing cache/ tree to fix the legacy 0700 directories.

1.0.2-beta

Für REDAXO
^5.13.0
Veröffentlicht am
06.05.2026
Require / PHP
>=8.2

Fixed

  • Declaration of rex_logger::log() must be compatible with Psr\Log\AbstractLogger::log() fatal on older REDAXO — Composer registers its ClassLoader with prepend=true by
    default, putting our shipped psr/log v3 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
    : void return type or string|\Stringable \$message typing — fine for v1, LSP-incompatible with v3. Once any code path autoloads rex_logger, PHP runs the signature check against
    our v3 AbstractLogger, 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

Für REDAXO
^5.13.0
Veröffentlicht am
06.05.2026
Require / PHP
>=8.2

Fixed

  • REX_PIC art attribute — accept four equivalent JSON shapes (comma-separated bare variants, keyed object, single bare variant, list); REDAXO's rex_var tokenizer regex bars unescaped [/] inside REX_VAR tags so the historical list-shape art='[…]' would prevent the entire REX_PIC[…] from being recognised. Variant src is 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, so Watermark::getImage() returned null and mark/markpos/etc. did nothing. Both factories now configure LocalFilesystemAdapter(rex_path::frontend()) (correct REDAXO anchor for both media/ and assets/, works with installers like Viterex that offset the public dir to <base>/public/). New Pipeline\WatermarkResolver translates user-supplied mark values (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::translateMark applies the translation to Glide's processing params while keeping the original on Server::$activeFilterParams so the on-disk cache key still matches the URL hash.

  • rex::isDebug() typo in ImageBuilder::missingSrcMarker() and VideoBuilder::missingSrcMarker() — REDAXO's API is rex::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

Für REDAXO
^5.13.0
Veröffentlicht am
05.05.2026
Require / PHP
>=8.2

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-Negotiation
  • Image::url() als Single-URL-Escape-Hatch (Poster, OG-Tags, CSS-Backgrounds)
  • Responsives <video> mit optionalem linkPreload fü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
  • SourceInterface als 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[…] und REX_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: focuspoint Addon 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