:: **Zploit** v1.0 | Current Path: **/home/kreativepixelz/www/kreative_crm/**
:: Editing File: portfolio.php
<?php include 'header.php'; // ensure this sets up $conn and session // Page variables $page_title = "Portfolio"; include 'breadcrumb.php'; include 'menu.php'; $selected_section = isset($_GET['section_id']) ? intval($_GET['section_id']) : 0; /** Helpers **/ /* Return sanitized, URL-encoded path for browser use */ function safe_url($relative_path) { $parts = explode('/', $relative_path); foreach ($parts as $i => $p) $parts[$i] = rawurlencode($p); return implode('/', $parts); } /* Try to extract YouTube video ID from various URL formats: - https://www.youtube.com/watch?v=ID - https://youtu.be/ID - https://www.youtube.com/shorts/ID returns ID or empty string */ function get_youtube_id($url) { if (!$url) return ''; $url = trim($url); // 1) yt short path if (preg_match('#(?:youtube\.com/(?:shorts|embed)/|youtu\.be/)([A-Za-z0-9_-]{8,})#', $url, $m)) { return $m[1]; } // 2) watch?v= if (strpos($url, 'youtube.com') !== false && strpos($url, 'v=') !== false) { parse_str(parse_url($url, PHP_URL_QUERY) ?: '', $params); if (!empty($params['v'])) return $params['v']; } // 3) fallback: attempt to parse path last segment $parts = parse_url($url, PHP_URL_PATH); if ($parts) { $last = basename($parts); if (preg_match('/^[A-Za-z0-9_-]{8,}$/', $last)) return $last; } return ''; } /* Placeholder thumbnail URL (use an image in your project or CDN) */ $placeholder_thumb = 'assets/img/video_placeholder.png'; // make sure this file exists (create if not) /* PDF thumbnail generator (optional) omitted here; keep previous logic if you have Imagick enabled */ ?> <!-- Styling: fixed-size unified thumbnails --> <style> .preview-thumb { width: 200px; /* fixed width */ height: 140px; /* fixed height */ object-fit: cover; /* crop to fit box */ border-radius: 6px; border: 1px solid #ddd; transition: transform 0.25s ease, box-shadow 0.25s ease; cursor: pointer; display: block; margin: 0 auto; } .preview-thumb:hover { transform: scale(1.08); box-shadow: 0 10px 30px rgba(0,0,0,0.14); z-index: 10; } /* PDF container uses same width so PDF iframe and image align */ .pdf-container { text-align: center; padding: 10px 0; min-width: 220px; } .pdf-preview { width: 200px; height: 250px; margin: 0 auto; border-radius:6px; overflow:hidden; border:1px solid #e6e6e6; display:flex; align-items:center; justify-content:center; background:#fff; } .pdf-frame { width:100%; height:100%; border:none; } /* small btn spacing */ .view-pdf-btn { margin-top:10px; display:inline-block; } /* responsive */ @media (max-width:768px){ .preview-thumb { width:140px; height:100px; } .pdf-preview{ width:140px; height:190px; } } </style> <div class="page-body"> <div class="container-fluid"> <div class="row"><div class="col-sm-12"><div class="card"> <!-- Header --> <div class="row align-items-center"> <div class="col-sm-3"> <div class="card-header pb-0 card-no-border"><h2>Portfolio Management</h2></div> </div> <div class="col-sm-6"> <div class="card-header pb-0 card-no-border"> <div class="d-flex align-items-center"> <p class="mb-0 font-13 text-nowrap me-2">Work Section:</p> <select class="form-select" style="width:auto;" onchange="window.location.href = this.value ? 'portfolio.php?section_id='+this.value : 'portfolio.php';"> <option value="">All Sections</option> <?php $sectionResult = mysqli_query($conn, "SELECT * FROM work_sections ORDER BY section_name ASC"); while ($section = mysqli_fetch_assoc($sectionResult)) { $sel = ($selected_section == $section['id']) ? 'selected' : ''; echo "<option value='".intval($section['id'])."' $sel>" . htmlspecialchars($section['section_name']) . "</option>"; } ?> </select> <?php if ($selected_section>0): ?> <a href="portfolio.php" class="btn btn-sm btn-outline-secondary ms-2">Clear Filter</a> <?php endif; ?> </div> </div> </div> <div class="col-sm-3 text-end"> <div class="card-header pb-0 card-no-border"> <a href="portfolio_add.php" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> Add New Portfolio</a> </div> </div> </div> <div class="card-body"> <?php if (isset($_GET['msg'])): ?> <div class="alert alert-info"><?= htmlspecialchars($_GET['msg']); ?></div> <?php endif; ?> <div class="input-group mb-3 mt-3"> <input type="text" class="form-control" id="searchInput" placeholder="Search Portfolio..."> </div> <div class="dt-ext table-responsive"> <table class="display" id="export-button"> <thead> <tr><th>#</th><th>Work Section</th><th>Preview</th><th>Website Link</th><th>Action</th></tr> </thead> <tbody> <?php $sr_no = 1; $where = $selected_section > 0 ? "WHERE p.work_section_id = $selected_section" : ""; $sql = "SELECT p.*, w.section_name FROM portfolio_photos p LEFT JOIN work_sections w ON p.work_section_id = w.id $where ORDER BY p.id DESC"; $res = mysqli_query($conn, $sql); if ($res && mysqli_num_rows($res) > 0) { while ($row = mysqli_fetch_assoc($res)) { $section_name = strtolower(trim($row['section_name'] ?? '')); $folder_name = preg_replace('/[^a-z0-9]+/', '_', $section_name); $img_name = $row['img_name']; $ext = strtolower(pathinfo($img_name, PATHINFO_EXTENSION)); $file_rel = "uploads/portfolio/$folder_name/" . $img_name; $file_fs = __DIR__ . "/$file_rel"; echo "<tr>"; echo "<td class='text-center'>{$sr_no}</td>"; echo "<td>" . htmlspecialchars($row['section_name']) . "</td>"; /* --- VIDEO SECTION --- */ if ($section_name === 'video production') { $video_link = trim($row['video_link']); $thumb_fs_jpg = __DIR__ . "/uploads/portfolio/$folder_name/thumbs/" . pathinfo($img_name, PATHINFO_FILENAME) . ".jpg"; $thumb_fs_png = __DIR__ . "/uploads/portfolio/$folder_name/thumbs/" . pathinfo($img_name, PATHINFO_FILENAME) . ".png"; // Try YouTube ID $yt_id = get_youtube_id($video_link); $thumb_url = ''; $video_open_url = ''; if ($yt_id) { // use YouTube embed and thumbnail $thumb_url = "https://img.youtube.com/vi/{$yt_id}/hqdefault.jpg"; $video_open_url = "https://www.youtube.com/watch?v={$yt_id}"; // show consistent preview image (uses preview-thumb class) echo "<td><div class='pdf-container'>"; echo "<a href='".htmlspecialchars($video_open_url)."' target='_blank'><img src='".htmlspecialchars($thumb_url)."' class='preview-thumb' alt='YouTube Thumbnail'></a>"; echo "</div></td>"; } else { // Not a YouTube link. Possibly an uploaded mp4 or other host. // Prefer local thumbs if present, else placeholder if (file_exists($thumb_fs_jpg)) { $thumb_url = safe_url("uploads/portfolio/$folder_name/thumbs/" . pathinfo($img_name, PATHINFO_FILENAME) . ".jpg"); } elseif (file_exists($thumb_fs_png)) { $thumb_url = safe_url("uploads/portfolio/$folder_name/thumbs/" . pathinfo($img_name, PATHINFO_FILENAME) . ".png"); } else { // If it's a local mp4, try to use a generic placeholder or generate thumbs offline $thumb_url = $placeholder_thumb; } // If video_link is a direct mp4 URL, open it; else open file_rel if ($video_link && (stripos($video_link, '.mp4') !== false || stripos($video_link, 'http') === 0)) { $video_open_url = htmlspecialchars($video_link); } else { $video_open_url = safe_url($file_rel); } echo "<td><div class='pdf-container'>"; echo "<a href='{$video_open_url}' target='_blank'><img src='".htmlspecialchars($thumb_url)."' class='preview-thumb' alt='Video Thumbnail'></a>"; echo "</div></td>"; } } /* --- PDF PREVIEW --- */ else if ($ext === 'pdf') { $thumb_fs_jpg = __DIR__ . "/uploads/portfolio/$folder_name/thumbs/" . pathinfo($img_name, PATHINFO_FILENAME) . ".jpg"; $thumb_fs_png = __DIR__ . "/uploads/portfolio/$folder_name/thumbs/" . pathinfo($img_name, PATHINFO_FILENAME) . ".png"; $file_url = safe_url($file_rel); echo "<td><div class='pdf-container'>"; if (file_exists($thumb_fs_jpg)) { echo "<a href='{$file_url}' target='_blank'><img src='".safe_url("uploads/portfolio/$folder_name/thumbs/".pathinfo($img_name, PATHINFO_FILENAME).".jpg")."' class='preview-thumb' alt='PDF Thumb'></a>"; } elseif (file_exists($thumb_fs_png)) { echo "<a href='{$file_url}' target='_blank'><img src='".safe_url("uploads/portfolio/$folder_name/thumbs/".pathinfo($img_name, PATHINFO_FILENAME).".png")."' class='preview-thumb' alt='PDF Thumb'></a>"; } else { echo "<div class='pdf-preview'><iframe src='{$file_url}#toolbar=0&navpanes=0&scrollbar=1' class='pdf-frame'></iframe></div>"; } echo "<a href='{$file_url}' target='_blank' class='btn btn-outline-primary btn-sm view-pdf-btn'><i class='fa fa-file-pdf'></i> View PDF</a>"; echo "</div></td>"; } /* --- IMAGE PREVIEW --- */ else if (in_array($ext, ['jpg','jpeg','png','gif','webp'])) { if (file_exists($file_fs)) { echo "<td><a href='".safe_url($file_rel)."' target='_blank'><img src='".safe_url($file_rel)."' class='preview-thumb' alt='Image'></a></td>"; } else { echo "<td><span class='text-muted'>Missing</span></td>"; } } /* --- FALLBACK --- */ else { echo "<td><span class='text-muted'>No Preview</span></td>"; } /* Website Link column */ echo "<td>"; if (!empty($row['website_link'])) { echo "<a href='".htmlspecialchars($row['website_link'])."' target='_blank' class='btn btn-outline-primary btn-sm'><i class='fa fa-globe'></i> View</a>"; } else { echo "<span class='text-muted'>N/A</span>"; } echo "</td>"; /* Actions */ echo "<td class='text-center'>"; if (!empty($row['video_link'])) { echo "<a href='".htmlspecialchars($row['video_link'])."' target='_blank' class='btn btn-info btn-sm me-1'><i class='fa fa-eye'></i> View</a>"; } elseif (file_exists($file_fs) || !empty($file_rel)) { echo "<a href='".safe_url($file_rel)."' target='_blank' class='btn btn-info btn-sm me-1'><i class='fa fa-eye'></i> View</a>"; } echo "<a href='portfolio_edit.php?id=".intval($row['id'])."' class='btn btn-warning btn-sm me-1'><i class='fa fa-edit'></i> Edit</a>"; echo "<a href='portfolio_share.php?id=".intval($row['id'])."' class='btn btn-primary btn-sm me-1'><i class='fa fa-share'></i> Share</a>"; if (isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin') { echo "<a href='portfolio_delete.php?id=".intval($row['id'])."' class='btn btn-danger btn-sm' onclick=\"return confirm('Are you sure you want to delete this portfolio?');\"><i class='fa fa-trash'></i> Delete</a>"; } echo "</td>"; echo "</tr>"; $sr_no++; } } else { echo "<tr><td colspan='5' class='text-center text-muted'>No portfolio entries found</td></tr>"; } ?> </tbody> </table> </div> </div> </div></div></div> </div> </div> <script> document.getElementById("searchInput").addEventListener("keyup", function(){ const v = this.value.toLowerCase(); document.querySelectorAll("#export-button tbody tr").forEach(r=>{ r.style.display = r.innerText.toLowerCase().includes(v) ? "" : "none"; }); }); </script> <?php include 'footer.php'; ?>