Tul xxx Tul
User / IP
:
216.73.216.146
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
comidarapidafran2
/
admin
/
Viewing: gallery.php
<?php include '../components/connect.php'; session_start(); $admin_id = $_SESSION['admin_id'] ?? null; if(!$admin_id){ header('location:admin_login.php'); exit(); } $message = []; $galleryDir = realpath(__DIR__ . '/../assets/img/galeria'); if($galleryDir === false || strpos($galleryDir, realpath(__DIR__ . '/..')) !== 0){ $message[] = 'No se pudo acceder al directorio de la galería.'; } else { if(!is_dir($galleryDir)){ mkdir($galleryDir, 0775, true); } } function gallery_generate_unique_filename(string $originalName): string { $extension = strtolower(pathinfo($originalName, PATHINFO_EXTENSION)); $base = strtolower(pathinfo($originalName, PATHINFO_FILENAME)); $base = preg_replace('/[^a-z0-9]+/i', '-', $base) ?: 'galeria'; $unique = uniqid($base . '-', true); return $extension ? $unique . '.' . $extension : $unique; } $allowedExtensions = ['jpg','jpeg','png','webp','gif','avif']; $maxFileSize = 20 * 1024 * 1024; // 20MB function gallery_format_bytes(int $bytes): string { if ($bytes <= 0) return '0 B'; $units = ['B','KB','MB','GB','TB']; $power = (int)floor(log($bytes, 1024)); $power = min($power, count($units) - 1); $value = $bytes / (1024 ** $power); return number_format($value, $power >= 2 ? 2 : 1, ',', '.') . ' ' . $units[$power]; } if(isset($_POST['add_image']) && $galleryDir){ if(!isset($_FILES['gallery_image']) || $_FILES['gallery_image']['error'] !== UPLOAD_ERR_OK){ $message[] = 'Selecciona una imagen válida para subir.'; } else { $file = $_FILES['gallery_image']; $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if(!in_array($extension, $allowedExtensions, true)){ $message[] = 'Formato no permitido. Usa JPG, PNG, WEBP, GIF o AVIF.'; } elseif($file['size'] > $maxFileSize){ $message[] = 'La imagen supera el tamaño máximo (20 MB).'; } else { $uniqueName = gallery_generate_unique_filename($file['name']); $targetPath = $galleryDir . DIRECTORY_SEPARATOR . $uniqueName; if(move_uploaded_file($file['tmp_name'], $targetPath)){ $message[] = 'Imagen agregada a la galería.'; } else { $message[] = 'No se pudo guardar la imagen.'; } } } } if(isset($_POST['delete_image']) && $galleryDir){ $imageName = isset($_POST['image_name']) ? basename($_POST['image_name']) : ''; if($imageName){ $targetPath = $galleryDir . DIRECTORY_SEPARATOR . $imageName; $realTarget = realpath($targetPath); if($realTarget && strpos($realTarget, $galleryDir) === 0 && file_exists($realTarget)){ if(unlink($realTarget)){ $_SESSION['gallery_flash'][] = 'Imagen eliminada de la galería.'; } else { $_SESSION['gallery_flash'][] = 'No se pudo eliminar la imagen.'; } } else { $_SESSION['gallery_flash'][] = 'Imagen no válida.'; } } header('Location: gallery.php'); exit(); } $galleryItems = []; if($galleryDir && is_dir($galleryDir)){ $files = glob($galleryDir . DIRECTORY_SEPARATOR . '*.{jpg,jpeg,png,webp,gif,avif,JPG,JPEG,PNG,WEBP,GIF,AVIF}', GLOB_BRACE); foreach($files as $path){ if(!is_file($path)) continue; $galleryItems[] = [ 'name' => basename($path), 'path' => $path, 'url' => '../assets/img/galeria/' . basename($path), 'size' => filesize($path), 'mtime' => filemtime($path) ]; } usort($galleryItems, function($a, $b){ return $b['mtime'] <=> $a['mtime']; }); } $galleryCount = count($galleryItems); $gallerySizeBytes = 0; foreach($galleryItems as $it){ $gallerySizeBytes += (int)($it['size'] ?? 0); } $gallerySizeFormatted = gallery_format_bytes($gallerySizeBytes); $pageMessages = []; if(isset($_SESSION['gallery_flash']) && is_array($_SESSION['gallery_flash'])){ $pageMessages = array_merge($pageMessages, $_SESSION['gallery_flash']); unset($_SESSION['gallery_flash']); } if(is_array($message) && !empty($message)){ $pageMessages = array_merge($pageMessages, $message); } $message = []; $businessName = getBusinessName($conn); $businessLogoVersion = getBusinessLogoVersion($conn); $iconHref = '../icon.php?size=64' . ($businessLogoVersion !== '' ? '&v=' . rawurlencode($businessLogoVersion) : ''); ?> <!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Administrar Galería | <?= htmlspecialchars($businessName); ?></title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="icon" href="<?= htmlspecialchars($iconHref); ?>" type="image/png"> <link rel="stylesheet" href="../css/admin_style.css"> <style> .gallery-wrapper { padding: 2rem 1.5rem 3rem; max-width: 1200px; margin: 0 auto; } .gallery-stats { display: flex; flex-wrap: wrap; gap: .8rem; margin-bottom: 1.4rem; } .stat-pill { display: inline-flex; align-items: center; gap: .55rem; padding: .65rem 1rem; border-radius: 999px; font-weight: 900; font-size: 1rem; border: 1px solid rgba(226, 232, 240, 0.85); background: rgba(255,255,255,0.85); color: #0f172a; box-shadow: 0 10px 24px rgba(15, 23, 42, 0.10); backdrop-filter: blur(6px); } .stat-pill i { color: #0ea5e9; } .upload-card { background: #fff; border-radius: 16px; box-shadow: 0 10px 26px rgba(0,0,0,0.08); padding: 1.8rem; margin-bottom: 2rem; border: 1px solid rgba(0,0,0,0.04); } .upload-card h2 { margin-top: 0; font-size: 1.4rem; font-weight: 700; color: #333; } .dropzone { display: flex; align-items: center; justify-content: center; flex-direction: column; border: 2px dashed rgba(179,0,0,0.25); border-radius: 14px; padding: 2.5rem 1rem; background: rgba(255,0,0,0.02); transition: border-color .2s ease, background .2s ease; } .dropzone.is-dragover { border-color: rgba(14,165,233,0.6); background: rgba(14,165,233,0.08); } .dropzone i { font-size: 2.5rem; color: var(--color-primary, #b30000); margin-bottom: 1rem; } .dropzone strong { color: #111; } .dropzone span { margin-top: 0.4rem; color: #666; font-size: 0.95rem; } .dropzone input[type="file"] { margin-top: 1.2rem; } .file-selected { margin-top: 1rem; display: none; align-items: center; gap: .6rem; padding: .65rem .85rem; border-radius: 12px; background: rgba(255,255,255,0.9); border: 1px solid rgba(226, 232, 240, 0.85); font-weight: 800; color: #0f172a; max-width: 760px; } .file-selected img { width: 48px; height: 48px; border-radius: 12px; object-fit: cover; border: 1px solid rgba(15,23,42,0.08); background: #fff; } .btn-primary { margin-top: 1.2rem; background: linear-gradient(120deg, var(--color-primary, #b30000), #ff4d4d); border: none; color: #fff; padding: 0.75rem 1.8rem; border-radius: 999px; font-size: 1rem; font-weight: 700; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; } .btn-primary:hover { transform: translateY(-1px); box-shadow: 0 12px 24px rgba(179,0,0,0.22); } .gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, 240px); gap: 1.5rem; justify-content: center; } .gallery-card { background: #fff; border-radius: 18px; overflow: hidden; box-shadow: 0 12px 28px rgba(0,0,0,0.08); border: 1px solid rgba(0,0,0,0.05); display: flex; flex-direction: column; position: relative; } .gallery-card .thumb { position: relative; width: 100%; padding-bottom: 75%; overflow: hidden; background: linear-gradient(120deg, rgba(148, 163, 184, 0.22), rgba(226, 232, 240, 0.55)); } .gallery-card .thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: transform 0.3s ease; } .gallery-card .thumb img.is-loaded { opacity: 1; transition: opacity 0.25s ease, transform 0.3s ease; } .gallery-card:hover .thumb img { transform: scale(1.05); } .gallery-meta { padding: 0.95rem 1rem 1.1rem 1rem; display: flex; justify-content: center; } .gallery-actions { display: flex; gap: 0.6rem; justify-content: center; } .gallery-actions .view-btn, .gallery-actions .delete-btn { border: none; padding: 0.48rem 1.05rem; border-radius: 999px; font-weight: 700; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; font-size: 0.9rem; display: inline-flex; align-items: center; gap: .45rem; } .gallery-actions .view-btn { background: linear-gradient(135deg, #0ea5e9, #2563eb); color: #fff; box-shadow: 0 10px 22px rgba(37,99,235,0.22); } .gallery-actions .view-btn:hover { transform: translateY(-1px); box-shadow: 0 14px 28px rgba(37,99,235,0.26); } .gallery-actions .delete-btn { background: rgba(255, 255, 255, 0.85); color: #0f172a; border: 1px solid rgba(148, 163, 184, 0.55); box-shadow: 0 10px 24px rgba(15, 23, 42, 0.10); backdrop-filter: blur(6px); } .gallery-actions .delete-btn:hover { background: linear-gradient(135deg, #ef4444, #b91c1c); color: #fff; transform: translateY(-1px); border-color: transparent; box-shadow: 0 12px 26px rgba(239, 68, 68, 0.20); } .empty-gallery { text-align: center; padding: 3rem 1rem; background: #fff; border-radius: 18px; border: 1px dashed rgba(0,0,0,0.08); color: #666; font-size: 1.1rem; } .gallery-preview-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.7); display: flex; justify-content: center; align-items: center; opacity: 0; visibility: hidden; transition: opacity 0.25s ease, visibility 0.25s ease; z-index: 9999; padding: 1.5rem; } .gallery-preview-modal.show { opacity: 1; visibility: visible; } .gallery-preview-modal .modal-content { position: relative; max-width: min(640px, 78vw); max-height: min(78vh, 520px); border-radius: 16px; overflow: hidden; box-shadow: 0 24px 48px rgba(0,0,0,0.32); background: #000; display: flex; align-items: center; justify-content: center; } .gallery-preview-modal img { display: block; width: 100%; height: auto; max-height: calc(78vh - 32px); object-fit: contain; background: #000; } .gallery-preview-modal .modal-close { position: absolute; top: 12px; right: 12px; width: 34px; height: 34px; border-radius: 50%; border: none; background: rgba(0,0,0,0.65); color: #fff; font-size: 20px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.2s ease; } .gallery-preview-modal .modal-close:hover { background: rgba(0,0,0,0.85); } .gallery-preview-modal .modal-overlay { position: absolute; inset: 0; background: transparent; } .messages { margin-bottom: 1.2rem; } .messages .alert { padding: 0.9rem 1.2rem; border-radius: 12px; background: #fff7e6; border: 1px solid rgba(255,170,43,0.35); color: #8a4b00; margin-bottom: 0.6rem; font-weight: 600; } @media (max-width: 575.98px) { .upload-card { padding: 1.4rem; } .gallery-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); justify-content: stretch; } } @media (max-width: 360px) { .gallery-grid { grid-template-columns: 1fr; } } body.gallery-page { --color-primary: #0ea5e9; --color-success: #22c55e; --color-warning: #f59e0b; --color-danger: #ef4444; background: linear-gradient(135deg, #f5f9ff 0%, #fff7f3 100%); min-height: 100vh; } body.gallery-page .upload-card, body.gallery-page .gallery-card, body.gallery-page .empty-gallery { background: rgba(255, 255, 255, 0.86); border: 1px solid rgba(226, 232, 240, 0.85); box-shadow: 0 18px 42px rgba(17, 24, 39, 0.10); backdrop-filter: blur(10px); } body.gallery-page .btn-primary { background: linear-gradient(135deg, #0ea5e9, #2563eb); box-shadow: 0 12px 26px rgba(37, 99, 235, 0.22); } body.gallery-page .btn-primary:hover { filter: brightness(1.02); box-shadow: 0 14px 30px rgba(37, 99, 235, 0.26); } body.gallery-page .dropzone { border-color: rgba(37,99,235,0.28); background: rgba(14,165,233,0.06); } body.gallery-page .dropzone i { color: #0ea5e9; } body.gallery-page .gallery-preview-modal { background: rgba(17,24,39,0.55); backdrop-filter: blur(6px); } </style> </head> <body class="admin-panel gallery-page"> <?php // Asegurar que $message sea un arreglo antes de incluir el header if(!isset($message) || !is_array($message)){ $message = []; } include '../components/admin_header.php'; ?> <section class="page-heading"> <h1 class="section-title">Galería</h1> </section> <section class="gallery-wrapper"> <?php if(!empty($pageMessages)): ?> <div class="messages"> <?php foreach($pageMessages as $msg): ?> <div class="alert"><?= htmlspecialchars($msg); ?></div> <?php endforeach; ?> </div> <?php endif; ?> <div class="gallery-stats"> <div class="stat-pill"><i class="fas fa-images"></i> <?= number_format((int)$galleryCount, 0, ',', '.'); ?> imagen(es)</div> <div class="stat-pill"><i class="fas fa-database"></i> <?= htmlspecialchars($gallerySizeFormatted); ?></div> </div> <div class="upload-card"> <h2>Agregar nueva imagen</h2> <form method="POST" enctype="multipart/form-data"> <div class="dropzone"> <i class="fas fa-cloud-upload-alt"></i> <strong>Selecciona la imagen que quieres añadir</strong> <span>Formatos permitidos: JPG, PNG, WEBP, GIF o AVIF · Máximo 20 MB</span> <input type="file" name="gallery_image" accept="image/*" required> <div class="file-selected" id="fileSelected"> <img id="fileSelectedThumb" alt="Vista previa" /> <span id="fileSelectedName"></span> </div> </div> <button type="submit" name="add_image" class="btn-primary"><i class="fas fa-upload"></i> Subir imagen</button> </form> </div> <?php if(empty($galleryItems)): ?> <div class="empty-gallery"> Aún no has agregado imágenes a la galería. </div> <?php else: ?> <div class="gallery-grid"> <?php foreach($galleryItems as $item): ?> <div class="gallery-card"> <div class="thumb"> <img class="gallery-thumb-img" src="<?= htmlspecialchars($item['url']); ?>" alt="Imagen de galería" loading="lazy" decoding="async"> </div> <div class="gallery-meta"> <div class="gallery-actions"> <button type="button" class="view-btn" data-image="<?= htmlspecialchars($item['url']); ?>"><i class="fas fa-eye"></i> Ver</button> <form method="POST" class="delete-image-form"> <input type="hidden" name="delete_image" value="1"> <input type="hidden" name="image_name" value="<?= htmlspecialchars($item['name']); ?>"> <button type="submit" name="delete_image" class="delete-btn"><i class="fas fa-trash"></i> Eliminar</button> </form> </div> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> </section> <div class="gallery-preview-modal" id="gallery-preview-modal" aria-hidden="true"> <div class="modal-overlay" data-dismiss="modal"></div> <div class="modal-content"> <button class="modal-close" type="button" data-dismiss="modal" aria-label="Cerrar vista">×</button> <img src="" alt="Vista previa" id="gallery-preview-image"> </div> </div> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> document.addEventListener('DOMContentLoaded', () => { const pageMessages = <?= json_encode($pageMessages, JSON_UNESCAPED_UNICODE); ?>; if(window.Swal && Array.isArray(pageMessages) && pageMessages.length){ const toasts = pageMessages.slice(0, 4); toasts.forEach((msg, idx) => { const text = String(msg || ''); const lc = text.toLowerCase(); const icon = (lc.includes('agregada') || lc.includes('eliminada') || lc.includes('guard')) ? 'success' : (lc.includes('no se pudo') || lc.includes('error') || lc.includes('no válida') ? 'error' : 'info'); setTimeout(() => { Swal.fire({ toast:true, position:'top-end', icon, title:text, showConfirmButton:false, timer:2200, timerProgressBar:true }); }, idx * 350); }); } const modal = document.getElementById('gallery-preview-modal'); const previewImage = document.getElementById('gallery-preview-image'); const viewButtons = document.querySelectorAll('.view-btn'); const deleteForms = document.querySelectorAll('form.delete-image-form'); const dropzone = document.querySelector('.dropzone'); const fileInput = dropzone ? dropzone.querySelector('input[type="file"]') : null; const fileSelected = document.getElementById('fileSelected'); const fileSelectedName = document.getElementById('fileSelectedName'); const fileSelectedThumb = document.getElementById('fileSelectedThumb'); document.querySelectorAll('img.gallery-thumb-img').forEach(img => { if(img.complete && img.naturalWidth > 0){ img.classList.add('is-loaded'); } else { img.addEventListener('load', () => img.classList.add('is-loaded'), { once: true }); img.addEventListener('error', () => img.classList.add('is-loaded'), { once: true }); } }); const openModal = (src) => { if(!modal || !previewImage) return; previewImage.src = src; modal.classList.add('show'); modal.setAttribute('aria-hidden', 'false'); }; const closeModal = () => { if(!modal || !previewImage) return; modal.classList.remove('show'); modal.setAttribute('aria-hidden', 'true'); previewImage.src = ''; }; deleteForms.forEach(form => { form.addEventListener('submit', (e) => { if(!window.Swal) return; e.preventDefault(); Swal.fire({ title: '¿Eliminar imagen?', text: 'Esta acción no se puede deshacer.', icon: 'warning', showCancelButton: true, confirmButtonText: 'Sí, eliminar', cancelButtonText: 'Cancelar', confirmButtonColor: '#ef4444', cancelButtonColor: '#6b7280' }).then(res => { if(res.isConfirmed){ form.submit(); } }); }); }); function renderSelectedFile(file){ if(!fileSelected || !fileSelectedName || !fileSelectedThumb) return; if(!file){ fileSelected.style.display = 'none'; fileSelectedName.textContent = ''; fileSelectedThumb.removeAttribute('src'); return; } fileSelectedName.textContent = file.name; fileSelected.style.display = 'flex'; if(file.type && file.type.startsWith('image/')){ const reader = new FileReader(); reader.onload = () => { fileSelectedThumb.src = String(reader.result || ''); }; reader.readAsDataURL(file); } } if(dropzone && fileInput){ dropzone.addEventListener('click', (e) => { const target = e.target; if(target && target.tagName && String(target.tagName).toLowerCase() === 'input') return; fileInput.click(); }); ['dragenter','dragover'].forEach(evt => { dropzone.addEventListener(evt, (e) => { e.preventDefault(); dropzone.classList.add('is-dragover'); }); }); ['dragleave','drop'].forEach(evt => { dropzone.addEventListener(evt, (e) => { e.preventDefault(); dropzone.classList.remove('is-dragover'); }); }); dropzone.addEventListener('drop', (e) => { const files = e.dataTransfer?.files; if(files && files.length){ fileInput.files = files; renderSelectedFile(files[0]); } }); fileInput.addEventListener('change', () => { const file = fileInput.files && fileInput.files.length ? fileInput.files[0] : null; renderSelectedFile(file); }); } viewButtons.forEach(btn => { btn.addEventListener('click', () => { const src = btn.dataset.image; if(src){ openModal(src); } }); }); modal?.querySelectorAll('[data-dismiss="modal"]').forEach(el => { el.addEventListener('click', closeModal); }); document.addEventListener('keydown', (event) => { if(event.key === 'Escape'){ closeModal(); } }); }); </script> </body> </html>
Coded With 💗 by
0x6ick