Releases: FriendsOfREDAXO/mblock
Releases · FriendsOfREDAXO/mblock
4.6.4
4.6.3
4.6.2
Version 4.6.2 - 2026-05-30
Bug Fixes
- Warnings bei MForm custom/core Toggle behoben: Die Replacer-Logik für
REX_MEDIALIST_SELECT_*undREX_LINKLIST_SELECT_*ersetzt den Name-Identifier jetzt null-sicher. Dadurch treten keine PHP-Deprecations mehr auf (str_replace(): Passing null to parameter #1) wennsystemIdin einzelnen Widget-HTML-Varianten noch nicht gesetzt ist. - Settings-Serialisierung gehärtet:
MBlockSettingsHelpernormalisiert Array-Werte vor dem Rendern derdata-*-Attribute. Dadurch wird die WarnungArray to string conversionvermieden.
4.6.1
- rex_select mit optgroup verursacht TypeError: In den Select-Replacern werden innerhalb von
optgroupjetzt nur noch echteoption-Elemente verarbeitet. Whitespace-Textknoten (DOMText) werden ignoriert, dadurch tritt der CrashArgument #2 ($option) must be of type DOMElement, DOMText givennicht mehr auf. Siehe Issue #227, gemeldet von @tbaddade. - Defektes Link-Beispiel repariert: Die Beispiel-Datei
base2_link_example.inienthielt beschädigte/duplizierte Startzeilen und ungültigen PHP-Code. Das Beispiel ist wieder lauffähig.
4.6.0
🚨 Bitte unbedingt bei Verwendung von MForm 9 Updatehinweise beachten kurz
MForm::useCustomLinkForClassicWidgets(true);
Erzeugt die Kompatibilität zu MForm 9
Beispiel:
/ useCustomLinkForClassicWidgets(true) sorgt dafür, dass addMediaField / addLinkField
// über das custom_link-Widget gerendert werden → kein Reindex-Problem beim Klonen.
// Das Speicherformat (REX_MEDIA_1 / REX_LINK_n) bleibt identisch.
MForm::useCustomLinkForClassicWidgets(true);
$mform = MForm::factory()
->addFieldsetArea('Team-Mitglied', MForm::factory()
Version 4.6.0 - 2026-05-07
Bug Fixes
- MForm 9 Widgets in MBlock sauber reindexiert:
custom_link,custom_medialist,custom_linklistundimglistwerden nach Add/Sort jetzt mit ihren aktuellen Widget-IDs, Popup-Callbacks und internen Referenzen neu initialisiert. Dadurch funktionieren Picker nach dem Verschieben und in neu angelegten Blöcken zuverlässig weiter. - Neue MBlocks starten mit leeren MForm-Widgets: Beim Klonen eines neuen Blocks werden MForm-Widgetzustände jetzt gezielt zurückgesetzt. Betroffen sind
custom_linksowie diemform-list-widget-Familie (medialist,linklist,imglist). Sichtbare Texte, Hidden-Values, Select-Optionen und gerenderte Listen werden nicht mehr aus dem Quellblock übernommen.
Rückwärtskompatibilität
- Kein Datenbank- oder Content-Break: Bestehende MBlock-Module, gespeicherte Inhalte und Datenstrukturen bleiben unverändert kompatibel.
- Kein harter Addon-Conflict erforderlich: MBlock selbst bleibt zu älteren MForm-Versionen lauffähig. Die Fixes in 4.5.9 fokussieren auf
custom_linkund diemform-list-widget-Familie.
4.5.8
SourceMap-Fehler (404) auf Live-Servern: Der sourceMappingURL-Kommentar in der mblock.min.js wurde entfernt, um 404-Fehler in den Browser-Entwicklertools auf Live-Servern zu vermeiden, die keine .map Dateien ausliefern. Die Map-Datei bleibt weiterhin für Entwicklungszwecke in den Sourcen erhalten. @olien
4.5.7
Bug Fixes
- REX_LINK – 3. Block überschreibt Link von Block 2:
mblock_update_rex_idshatREX_LINK_-Inputs beim Reindexieren nicht berücksichtigt, sodass alle neuen Blöcke dieselbe Link-ID aus dem Template behielten. Link-Popup-Callbacks schrieben dadurch stets in Block 2.REX_LINK_wird nun korrekt mit dem Block-Index reindexiert. - REX_LINK –
_NAME-Input nach Reindexierung nicht auffindbar (null is not an object evaluating getElementById("REX_LINK_X_NAME")): Der textuelle Anzeigefeld-Input (_NAME) bekam beim generischen Durchlauf einen andereneindexals der hidden-Input → ID-Mismatch._NAME-Inputs werden jetzt im generischen Loop übersprungen und synchron zum hidden-Input mit derselben ID-Basis aktualisiert. deleteREXLinkonclick nach Drag & Drop kaputt: Das generische Regex-Replace inmblock_update_rex_buttonshat beideleteREXLink('X')die schließende Quote entfernt → ungültiges JavaScript. Onclick-Handler werden jetzt per spezifischem Pattern korrekt mit Quotes ersetzt.- REX_LINK Buttons in Modulen ohne
rex-js-widget-link-Klasse nicht aktualisiert:closest('.rex-js-widget-link')schlug bei HTML-basierten Link-Feldern ohne diese Klasse fehl. Die Widget-Suche verwendet jetzt eine Fallback-Kette (.input-group,.rex-js-widget), die auch bei eigenen Templates greift.
4.5.6
Version 4.5.6 - 2026-02-24
Bug Fixes
- Radio-Button (Copy & Paste) – Wert nicht übernommen: Alle Radio-Inputs einer Gruppe teilen denselben
name-Attribut. Bisher wurde derformData-Eintrag bei jeder Iteration überschrieben, sodass immer das letzte (nicht ausgewählte) Radio gewann. Die Erfassung speichert jetzt pro Gruppe nur den tatsächlich gewählten Wert als neuenradio_group-Typ. - Radio-Button (Copy & Paste) –
active-Klasse als Fallback: MForm Bild-Radios und Color-Radios markieren die aktive Option zusätzlich mitclass="active"am<label>. Diese Klasse wird nun beim Erfassen als Fallback ausgewertet, fallsprop('checked')im DOM-Klon nicht gesetzt ist. - Radio-Button (Copy & Paste) – Tab-Panel-Reset: Nach dem Einfügen triggert mblock
rex:ready, wodurch Tab-Panel- und MForm-Initialisierungen alleactive-Klassen auf Labels zurücksetzen. Die Radio-Wiederherstellung wird deshalb zweistufig durchgeführt: einmal direkt beim Einfügen und nochmals nach demrex:ready/trigger('change')-Zyklus über die neuerestoreRadioGroups()-Methode.
4.5.5
Fehlerbehebungen
- CKEditor 5-Füllinhalt: Automatische Bereinigung von Ersatzinhalten für CKEditor 5 (
<p><br data-cke-filler="true"></p>) und Platzhaltern (<p class="ck-placeholder" ...>) bei der Formularübermittlung hinzugefügt. Dadurch wird verhindert, dass leere Blöcke mit unsichtbaren HTML-Artefakten gespeichert werden.
Cleanup Script for Existing Data
Use the following PHP script Example:
<?php
/**
* MBlock CKEditor 5 Filler Cleanup Script
*
* Run this script in the REDAXO PHP Console (System > Console) or via CLI
* to remove existing filler content from your database.
*/
$tables = [
'rex_article_slice' => 20, // Check value1 - value20
// Add custom YForm tables here if needed:
// 'rex_my_table' => ['description', 'text_column'],
];
$filler1 = '<p><br data-cke-filler="true"></p>';
$filler2 = '<br data-cke-filler="true">';
// JSON escaped variants (often found in MBlock data)
$filler1_json = '<p><br data-cke-filler=\"true\"><\/p>';
$filler2_json = '<br data-cke-filler=\"true\">';
echo "<h2>Cleaning CKEditor 5 Filler Content...</h2>";
foreach ($tables as $table => $columns) {
if (is_int($columns)) {
// Generate value1...valueN for slices
$cols = [];
for ($i = 1; $i <= $columns; $i++) {
$cols[] = 'value' . $i;
}
} else {
$cols = (array) $columns;
}
$sql = rex_sql::factory();
foreach ($cols as $col) {
// 1. Standard HTML replacement
$query = "UPDATE `$table` SET `$col` = REPLACE(`$col`, :filler1, '') WHERE `$col` LIKE :search1";
$sql->setQuery($query, ['filler1' => $filler1, 'search1' => '%data-cke-filler%']);
if ($sql->getRows() > 0) echo "Updated $table.$col (HTML Variant 1): " . $sql->getRows() . " rows<br>";
$query = "UPDATE `$table` SET `$col` = REPLACE(`$col`, :filler2, '') WHERE `$col` LIKE :search2";
$sql->setQuery($query, ['filler2' => $filler2, 'search2' => '%data-cke-filler%']);
if ($sql->getRows() > 0) echo "Updated $table.$col (HTML Variant 2): " . $sql->getRows() . " rows<br>";
// 2. JSON Escaped replacement (common in mblock)
$query = "UPDATE `$table` SET `$col` = REPLACE(`$col`, :filler1, '') WHERE `$col` LIKE :search1";
$sql->setQuery($query, ['filler1' => $filler1_json, 'search1' => '%data-cke-filler%']);
if ($sql->getRows() > 0) echo "Updated $table.$col (JSON Variant 1): " . $sql->getRows() . " rows<br>";
$query = "UPDATE `$table` SET `$col` = REPLACE(`$col`, :filler2, '') WHERE `$col` LIKE :search2";
$sql->setQuery($query, ['filler2' => $filler2_json, 'search2' => '%data-cke-filler%']);
if ($sql->getRows() > 0) echo "Updated $table.$col (JSON Variant 2): " . $sql->getRows() . " rows<br>";
// 3. Regex Replacement for Placeholders (PHP-based because SQL lacks REGEX replace)
// Matches: <p class="ck-placeholder" data-placeholder="..."></p>
$fetchQuery = "SELECT id, `$col` FROM `$table` WHERE `$col` LIKE '%ck-placeholder%'";
// Iterate only over rows that actually match
$iterator = rex_sql::factory()->getArray($fetchQuery);
$localUpdateCount = 0;
foreach ($iterator as $row) {
$original = $row[$col];
$current = $original;
// Regex for HTML variant
$current = preg_replace('/<p class="ck-placeholder" data-placeholder="[^"]+"><\/p>/', '', $current);
// Regex for JSON escaped variant (need to be careful with backslashes)
// Pattern: <p class=\"ck-placeholder\" data-placeholder=\"...\"><\/p>
$current = preg_replace('/<p class=\\\\"ck-placeholder\\\\" data-placeholder=\\\\"[^"]+\\\\"><\\\\\/p>/', '', $current);
if ($current !== $original) {
// Determine ID column name (usually 'id')
$idCol = 'id';
$upd = rex_sql::factory();
$upd->setTable($table);
$upd->setWhere([$idCol => $row[$idCol]]);
$upd->setValue($col, $current);
$upd->update();
$localUpdateCount++;
}
}
if ($localUpdateCount > 0) echo "Updated $table.$col (Placeholders via PHP Regex): " . $localUpdateCount . " rows<br>";
}
}
echo "<br><strong>Cleanup complete!</strong> Clear the cache manually if needed.";What's Changed
Full Changelog: 4.5.4...4.5.5