Modulsammlung icon indicating copy to clipboard operation
Modulsammlung copied to clipboard

Slice hijacker MFORM 2025

Open cukabeka opened this issue 10 months ago • 1 comments

Feature description / Feature Beschreibung Ich habe es nicht als PR, weil ich nicht weiß ob hier richtig und wo. Ich habe Thomas' SliceHijacker mal für aktuelle REDAXO Versionen angepasst. Ist das in der Modulsammlung willkommen? Ist eines meiner Lieblingsmodule :)

INPUT

<?php
//------------------------------------------------------------------------------------------
// Get a Slice 
// 2.0 - 2/2025 cukabeka
// 1.0 - 17.04.2017 Thomas Skerbis
// Basiert auf Slice-HiJacker Redaxo 4.3.2
// von: Mirco Brandes/Gerald Rusche GERUWEB
// Nach REDAXO 5 konvertiert 2017 - Thomas Skerbis
// Auf MFORM aktualisiert und für REX 5.15+ angepasst - cukabeka 2025
//-------------------------------------------------------------------------------------------

/* INSTALL: Presave-Aktion manuell beim Modul hinzufügen

<?php
if ($this->getValue(2) == '0') {
   // Der Block wird nicht gespeichert
   $this->save = false;
   // Meldung ausgeben
   $this->messages[] = 'Bitte noch einen Slice/Block auswaehlen';   
}
?>

*/

function cleanSliceOutput($content) {
    // Alle Formularelemente entfernen (input, select, textarea, button, form)
    $content = preg_replace('/<(input|select|textarea|button|form)[^>]*>/i', '', $content);
    $content = preg_replace('/<\/(select|textarea|button|form)>/i', '', $content);
    
    // required-Attribute entfernen
    $content = preg_replace('/\srequired=["\']?required["\']?/i', '', $content);
    
    // Bootstrap-HTML anpassen, um sich in einen Container einzufügen
    $content = preg_replace('/<div class="card[^>]*">/', '<div class="card mb-3" style="background: transparent; border: none;">', $content);
    $content = preg_replace('/<div class="card-body[^>]*">/', '<div class="card-body" style="background: transparent;">', $content);
    
    return $content;
}

// MFORM-Instanz erstellen
use FriendsOfRedaxo\MForm;
?>

<?php
$mform = new MForm();

// Info-Box
$mform->addHtml('<div class="alert alert-info">
    <p>Mit diesem Block können Inhalte anderer Artikel eingebunden werden.</p>
    <p><strong>Achtung:</strong> Änderungen oder Löschungen im Original wirken sich auf diesen Block aus.</p>
</div>');

// Artikel auswählen
$mform->addLinkField(1, ['label' => 'Artikel auswählen']);

// Radiobutton: Ganzen Artikel oder Slice wählen
$mform->addRadioField(2, [
    'kompletter_artikel' => 'Ganzen Artikel einbinden',
    'slice' => 'Einzelnen Slice auswählen'
], ['label' => 'Was soll eingebunden werden?']);

// --- Slice-Auswahl vorbereiten ---
$article_id = "REX_LINK[id=1 output=id]";
$clang = rex_clang::getCurrentId();

if (!empty($article_id) && $article_id > 0) {
    $slice = rex_article_slice::getFirstSliceForArticle($article_id, $clang);

    if ($slice) {
        $mform->addHtml('<div class="slice-selection mt-4">');
        
        while ($slice) {
            $slice_id = $slice->getId();
            $slice_title = "Slice-ID: $slice_id";

            // Einzelnes Radio-Element mit zugehöriger Vorschau
            $mform->addRadioField(3, [$slice_id => $slice_title], [
                'label' => '',
                'class' => 'slice-radio'
            ]);

            // Slice-Vorschau direkt nach dem Radio-Button
            $clean_slice_content = cleanSliceOutput($slice->getSlice());
            $mform->addHtml('<div class="card mb-3 ml-4">
                <div class="card-body bg-light">
                    ' . $clean_slice_content . '
                </div>
            </div>');

            $slice = $slice->getNextSlice();
        }

        $mform->addHtml('</div>');
    } else {
        $mform->addHtml('<div class="alert alert-warning">Der ausgewählte Artikel enthält keine Slices.</div>');
    }
}

echo $mform->show();
?>

<style>
/* Optionales CSS für bessere Darstellung */
.slice-selection {
    margin-left: 20px;
}
.slice-radio {
    margin-bottom: 10px;
}
.card {
    margin-bottom: 20px;
}
</style>

OUTPUT

<?php 
if ("REX_VALUE[2]" != "") {
    // Im Backend den Link zur Quelle anzeigen
    if (rex::isBackend()) {
        $master = rex_article::get("REX_LINK[id=1 output=id]");
        if ($master) {
            echo '<div class="alert alert-dismissible alert-info">
            <strong>Eingebundener Inhalt aus: </strong> 
            <a type="button" class="btn btn-primary" href="index.php?page=content&article_id=REX_LINK[id=1 output=id]&mode=edit&clang=1">';
            echo $master->getName() . '</a></div>';
        } else {
            echo '<div class="alert alert-danger">Fehler: Der verknüpfte Artikel existiert nicht.</div>';
        }
    }

    if ("REX_VALUE[2]" == "kompletter_artikel") {
        // kompletten Artikel einbinden
        $art = rex_article::get("REX_LINK[id=1]"); 

        if ($art) {
            $article = new rex_article_content($art->getId(), $art->getClang());  
            echo $article->getArticle(1);
        } else {
            echo '<div class="alert alert-danger">Fehler: Der Artikel konnte nicht geladen werden.</div>';
        }
    } else {
        // Den Slice/Block laden und anzeigen
        $slice = rex_article_slice::getArticleSliceById("REX_VALUE[3]"); 
        
        if ($slice) {
            echo $slice->getSlice();
        } else {
            echo '<div class="alert alert-warning">Fehler: Der ausgewählte Slice existiert nicht mehr.</div>';
        }
    }
} else {
    // Im Backend kurzen (Fehler-)Text ausgeben
    if (rex::isBackend()) {
        echo "<p>Noch keinen Slice/Block ausgewählt.</p>";
    }
}
?>

cukabeka avatar Feb 21 '25 22:02 cukabeka

@cukabeka ja gerne als PR

skerbis avatar Aug 16 '25 08:08 skerbis