Skip to main content

💾 Downloads

Frontpage Demo:
downloadAnsicht.png

Download-Ordner können einfach über TVs integriert werden.

<?php
# V 2025-12-22 (mit absolut URLs) - minimal modernisiert

# Parameter
$strSORT = $modx->getOption('SORT', $scriptProperties, 'asc');  # asc oder desc
$dir     = trim($modx->getOption('dir', $scriptProperties, ""), '/');
$style   = $modx->getOption('style', $scriptProperties, 'legacy');  # legacy oder bs5

# Pfade vorbereiten
$fsDir  = MODX_BASE_PATH . $dir;                                           # Dateisystem-Pfad
$urlDir = rtrim(MODX_BASE_URL, '/') . '/' . $dir;                          # URL-Pfad (immer mit führendem /)

# erlaubte Extensions (kleingeschrieben, ohne Punkt)
$allowedExt = [
    'pdf','ics','deb','zip','gif','png','jpg','jpeg','xz','zst','gz'
];

if (is_dir($fsDir)) {
    $open_dir = opendir($fsDir);

    $output = array();   // legacy
    $files  = array();   // bs5

    while ($file = readdir($open_dir)) {

        if ($file != "." && $file != "..") {

            # Extension sauber prüfen (case-insensitive)
            $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
            if (!in_array($ext, $allowedExt, true)) {
                continue;
            }

            # Dateigröße aus dem Dateisystem
            $size = ceil(filesize($fsDir . "/" . $file) / 1024);

            # HTML-sicher ausgeben
            $fileEsc = htmlspecialchars($file, ENT_QUOTES, 'UTF-8');

            if ($style === 'bs5') {
                # Bootstrap-Variante
                $files[$file] = array(
                    'file' => $file,
                    'fileEsc' => $fileEsc,
                    'size' => $size,
                    'ext'  => $ext,
                );

            } else {
                # Legacy-Ausgabe
                $o  = "<ul style=\"list-style-type:square;\">";
                $o .= "<li><a href=\"{$urlDir}/{$file}\" target=\"_blank\" rel=\"noopener noreferrer\"> {$fileEsc}</a>";
                $o .= "&nbsp;&nbsp;&nbsp;[" . $size . " KB]</li>";
                $o .= "</ul>";
                $output[$file] = $o;
            }
        }
    }

    closedir($open_dir);

    # Bootstrap-Ausgabe
    if ($style === 'bs5') {

        if ($strSORT == "asc") {
            ksort($files);
        } else {
            krsort($files);
        }

        $html   = array();
        $html[] = '<div class="download card file-list-card my-4">';
        $html[] = '  <div class="card-header py-2">Downloads</div>';
        $html[] = '  <ul class="list-group list-group-flush small mb-0">';

        foreach ($files as $fileName => $data) {
            $file    = $data['file'];
            $fileEsc = $data['fileEsc'];
            $size    = $data['size'];
            $ext     = $data['ext'];

            # Icon minimal nach Typ (fallback: generic file)
            $icon = 'bi bi-file-earmark me-2';
            if ($ext === 'pdf') {
                $icon = 'bi bi-file-earmark-pdf me-2';
            } elseif ($ext === 'zip' || $ext === 'gz' || $ext === 'xz' || $ext === 'zst') {
                $icon = 'bi bi-file-earmark-zip me-2';
            } elseif ($ext === 'png' || $ext === 'jpg' || $ext === 'jpeg' || $ext === 'gif') {
                $icon = 'bi bi-file-earmark-image me-2';
            } elseif ($ext === 'ics') {
                $icon = 'bi bi-calendar-event me-2';
            }

            $html[] = '    <li class="list-group-item d-flex justify-content-between align-items-center">';
            $html[] = '      <a href="' . $urlDir . '/' . rawurlencode($file) . '" target="_blank" rel="noopener noreferrer" class="file-link text-decoration-none">';
            $html[] = '        <i class="' . $icon . '"></i> ' . $fileEsc;
            $html[] = '      </a>';
            $html[] = '      <span class="badge bg-secondary">' . $size . ' KB</span>';
            $html[] = '    </li>';
        }

        $html[] = '  </ul>';
        $html[] = '</div>';

        return implode("\n", $html);

    } else {

        if ($strSORT == "asc") {
            ksort($output);
        } else {
            krsort($output);
        }

        return implode('', $output);
    }
}

return "Das Verzeichnis \"" . htmlspecialchars($dir, ENT_QUOTES, 'UTF-8') . "\" existiert nicht!";
<style>
.download.card.file-list-card {
    max-width: 520px;
    margin: 2rem 0;
    box-shadow: 0 4px 12px rgba(0,0,0,0.10);
}

.file-list-card .card-header {
    background-color: #f8f9fa;
    font-weight: 600;
    font-size: 0.95rem;
}

.file-list-card .list-group-item {
    padding: 0.35rem 0.75rem;
}

.file-list-card .file-link {
    display: inline-flex;
    align-items: center;
}

.file-list-card .file-link:hover {
    text-decoration: underline;
}

.file-list-card .badge {
    font-size: 0.75rem;
    font-weight: 400;
}
</style>