0) { $sql_folder = mysqli_query($mysqli, "SELECT folder_name, parent_folder FROM folders WHERE folder_id = $breadcrumb_folder_id AND folder_client_id = $client_id"); if ($row_folder = mysqli_fetch_assoc($sql_folder)) { $folder_name = escapeHtml($row_folder['folder_name']); $parent_folder = intval($row_folder['parent_folder']); array_unshift($folder_path, [ 'folder_id' => $breadcrumb_folder_id, 'folder_name' => $folder_name ]); $breadcrumb_folder_id = $parent_folder; } else { break; } } // --------------------------------------------- // Helper: unified folder tree (no folder_location) // --------------------------------------------- function isAncestorFolder($folder_id, $current_folder_id, $client_id) { global $mysqli; if ($current_folder_id == 0) { return false; } if ($current_folder_id == $folder_id) { return true; } $result = mysqli_query($mysqli, "SELECT parent_folder FROM folders WHERE folder_id = $current_folder_id AND folder_client_id = $client_id"); if ($row = mysqli_fetch_assoc($result)) { $parent_folder_id = intval($row['parent_folder']); return isAncestorFolder($folder_id, $parent_folder_id, $client_id); } else { return false; } } function displayFolders($parent_folder_id, $client_id, $indent = 0, $render_root = false) { global $mysqli, $get_folder_id, $session_user_role, $archive_query, $archived, $num_root_items, $folders_expanded, $view, $type_filter; // Always render root (only once) if ($parent_folder_id == 0 && $indent == 0) { echo ''; } $sql_folders = mysqli_query( $mysqli, "SELECT folder_id, folder_name FROM folders WHERE parent_folder = $parent_folder_id AND folder_client_id = $client_id ORDER BY folder_name ASC" ); while ($row = mysqli_fetch_assoc($sql_folders)) { $folder_id = intval($row['folder_id']); $folder_name = escapeHtml($row['folder_name']); $row_files = mysqli_fetch_assoc(mysqli_query( $mysqli, "SELECT COUNT('file_id') AS num FROM files WHERE file_folder_id = $folder_id AND file_client_id = $client_id AND file_$archive_query" )); $num_files = intval($row_files['num']); $row_docs = mysqli_fetch_assoc(mysqli_query( $mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_folder_id = $folder_id AND document_client_id = $client_id AND document_$archive_query" )); $num_docs = intval($row_docs['num']); $num_total = $num_files + $num_docs; $subfolder_result = mysqli_query( $mysqli, "SELECT COUNT(*) AS count FROM folders WHERE parent_folder = $folder_id AND folder_client_id = $client_id" ); $subfolder_count = intval(mysqli_fetch_assoc($subfolder_result)['count']); // Active or ancestor of active folder = on active path $on_active_path = ($get_folder_id == $folder_id) || isAncestorFolder($folder_id, $get_folder_id, $client_id); // Option C: indent with padding (no AdminLTE sidebar CSS required) // Tune these numbers if you want tighter/looser indent $indent_px = 12 * $indent; // 12px per level echo ''; } } // --------------------------------------------- // DATA LOAD // view=1 (grid) - every file in the folder, thumbnail or file-type icon // view=0 (list) loads ALL files+documents, merges, sorts in PHP // --------------------------------------------- $items = []; $num_rows = [0]; // Both views decide previewability from this, so it is set before the branch - // it used to be assigned inside the grid arm only, which left the list arm // passing null to in_array() $inline_viewable_mime_types = getInlineViewableMimeTypes(); if ($view == 1) { /* * GRID VIEW: files AND documents, same as the list view beside it. * * This used to be a single files-only query with SQL_CALC_FOUND_ROWS and a * LIMIT. Two sources cannot be paginated by one LIMIT, so it now mirrors * exactly what the list view does: fetch both unpaginated, merge, sort by * name, and slice in PHP. That also fixes the grid quietly omitting every * created document - they were only ever visible in list view. */ $safe_q = mysqli_real_escape_string($mysqli, $q); if ($get_folder_id == 0 && isset($_GET["q"])) { $file_folder_snippet = ""; // search across all folders $doc_folder_snippet = ""; } else { $file_folder_snippet = "AND file_folder_id = $folder_id"; $doc_folder_snippet = "AND document_folder_id = $folder_id"; } $file_search_snippet = ""; $doc_search_snippet = ""; if (!empty($q)) { $file_search_snippet = "AND (file_name LIKE '%$safe_q%' OR file_ext LIKE '%$safe_q%' OR file_description LIKE '%$safe_q%')"; $doc_search_snippet = "AND (MATCH(document_content_raw) AGAINST ('$safe_q') OR document_name LIKE '%$safe_q%')"; } // Skipped outright when the type filter excludes them $sql_grid_files = false; if ($type_filter !== 'document') { $sql_grid_files = mysqli_query( $mysqli, "SELECT files.*, users.user_name FROM files LEFT JOIN users ON file_created_by = user_id WHERE file_client_id = $client_id AND file_$archive_query $file_folder_snippet $file_search_snippet" ); } $sql_grid_documents = false; if ($type_filter !== 'file') { $sql_grid_documents = mysqli_query( $mysqli, "SELECT documents.*, users.user_name FROM documents LEFT JOIN users ON document_created_by = user_id WHERE document_client_id = $client_id AND document_$archive_query $doc_folder_snippet $doc_search_snippet" ); } while ($sql_grid_files && ($row = mysqli_fetch_assoc($sql_grid_files))) { $row['grid_kind'] = 'file'; $items[] = $row; } while ($sql_grid_documents && ($row = mysqli_fetch_assoc($sql_grid_documents))) { $row['grid_kind'] = 'document'; $items[] = $row; } usort($items, function ($a, $b) { $a_name = strtolower($a['grid_kind'] === 'file' ? $a['file_name'] : $a['document_name']); $b_name = strtolower($b['grid_kind'] === 'file' ? $b['file_name'] : $b['document_name']); return strcmp($a_name, $b_name); }); $num_rows = [count($items)]; $items = array_slice($items, $record_from, $record_to); } else { // -------- LIST VIEW: build unified items[] -------- // Folder filter if ($get_folder_id == 0 && isset($_GET["q"])) { $file_folder_snippet = ""; // search across all folders $doc_folder_snippet = ""; } else { $file_folder_snippet = "AND file_folder_id = $folder_id"; $doc_folder_snippet = "AND document_folder_id = $folder_id"; } // Search filters $safe_q = mysqli_real_escape_string($mysqli, $q); $file_search_snippet = ""; if (!empty($q)) { $file_search_snippet = "AND (file_name LIKE '%$safe_q%' OR file_ext LIKE '%$safe_q%' OR file_description LIKE '%$safe_q%')"; } $doc_search_snippet = ""; if (!empty($q)) { $doc_search_snippet = "AND (MATCH(document_content_raw) AGAINST ('$safe_q') OR document_name LIKE '%$safe_q%')"; } // Files query (NO limit - we'll paginate in PHP). Skipped outright when the // type filter excludes files, rather than fetching rows to throw away. $sql_files = false; if ($type_filter !== 'document') { $sql_files = mysqli_query( $mysqli, "SELECT files.*, users.user_name FROM files LEFT JOIN users ON file_created_by = user_id WHERE file_client_id = $client_id AND file_$archive_query $file_folder_snippet $file_search_snippet" ); } // Documents query (NO limit - paginate in PHP) $sql_documents = false; if ($type_filter !== 'file') { $sql_documents = mysqli_query( $mysqli, "SELECT documents.*, users.user_name FROM documents LEFT JOIN users ON document_created_by = user_id WHERE document_client_id = $client_id AND document_$archive_query $doc_folder_snippet $doc_search_snippet" ); } // Normalize FILES into $items while ($sql_files && ($row = mysqli_fetch_assoc($sql_files))) { $file_id = intval($row['file_id']); $file_name = escapeHtml($row['file_name']); $file_description = escapeHtml($row['file_description']); $file_reference_name= escapeHtml($row['file_reference_name']); $file_ext = escapeHtml($row['file_ext']); $file_size = intval($row['file_size']); $file_mime_type = escapeHtml($row['file_mime_type']); $file_uploaded_by = escapeHtml($row['user_name']); $file_created_at = escapeHtml($row['file_created_at']); $file_archived_at = $row['file_archived_at']; // determine icon if ($file_ext == 'pdf') { $file_icon = "file-pdf"; } elseif (in_array($file_ext, ['gz','tar','zip','7z','rar'])) { $file_icon = "file-archive"; } elseif (in_array($file_ext, ['txt','md'])) { $file_icon = "file-alt"; } elseif ($file_ext == 'msg') { $file_icon = "envelope"; } elseif (in_array($file_ext, ['doc','docx','odt'])) { $file_icon = "file-word"; } elseif (in_array($file_ext, ['xls','xlsx','ods'])) { $file_icon = "file-excel"; } elseif (in_array($file_ext, ['pptx','odp'])) { $file_icon = "file-powerpoint"; } elseif (in_array($file_ext, ['mp3','wav','ogg'])) { $file_icon = "file-audio"; } elseif (in_array($file_ext, ['mov','mp4','av1'])) { $file_icon = "file-video"; } elseif (in_array($file_ext, ['jpg','jpeg','png','gif','webp','bmp','tif'])) { $file_icon = "file-image"; } else { $file_icon = "file"; } $items[] = [ 'kind' => 'file', 'id' => $file_id, 'name' => $file_name, 'description' => $file_description, 'reference_name' => $file_reference_name, 'icon' => $file_icon, 'ext' => $file_ext, 'mime' => $file_mime_type, 'size' => $file_size, 'created_at' => $file_created_at, 'created_by' => $file_uploaded_by, 'archived_at' => $file_archived_at, ]; } // Normalize DOCUMENTS into $items while ($sql_documents && ($row = mysqli_fetch_assoc($sql_documents))) { $document_id = intval($row['document_id']); $document_name = escapeHtml($row['document_name']); $document_description = escapeHtml($row['document_description']); $document_created_by_name = escapeHtml($row['user_name']); $document_created_at = $row['document_created_at']; $document_updated_at = $row['document_updated_at']; $document_archived_at = $row['document_archived_at']; $items[] = [ 'kind' => 'document', 'id' => $document_id, 'name' => $document_name, 'description' => $document_description, 'mime' => 'Document', 'size' => null, 'updated_at' => $document_updated_at, 'created_by' => $document_created_by_name, 'archived_at' => $document_archived_at, ]; } // Sort combined items $sort = isset($_GET['sort']) ? $_GET['sort'] : 'name'; $order = isset($_GET['order']) ? $_GET['order'] : 'ASC'; usort($items, function($a, $b) use ($sort, $order) { $direction = ($order === 'DESC') ? -1 : 1; if ($sort == 'created') { $valA = strtotime($a['created_at']); $valB = strtotime($b['created_at']); } elseif ($sort == 'type') { $valA = strtolower($a['mime']); $valB = strtolower($b['mime']); } elseif ($sort == 'size') { $valA = (int)($a['size'] ?? 0); $valB = (int)($b['size'] ?? 0); } else { // default: name $valA = strtolower($a['name']); $valB = strtolower($b['name']); } if ($valA == $valB) { return 0; } return ($valA < $valB) ? -1 * $direction : 1 * $direction; }); // Total items (for pagination footer) $total_items = count($items); $num_rows = [$total_items]; // Apply pagination slice $items = array_slice($items, $record_from, $record_to); } // --------------------------------------------- // Root folder count (for "/" badge) // --------------------------------------------- $row_root_files = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('file_id') AS num FROM files WHERE file_folder_id = 0 AND file_client_id = $client_id AND file_$archive_query")); $row_root_docs = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_folder_id = 0 AND document_client_id = $client_id AND document_$archive_query")); $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num']); ?>

Files

Folders



No files in this folder. No documents in this folder. Nothing in this folder.

$file_id, 'name' => $file_name, 'kind' => $file_preview_kind, 'icon' => $file_icon, 'ext' => strtoupper($file_ext), 'size' => $file_size_human, 'excerpt' => $file_excerpt, 'preview' => $file_open_url, 'download' => $file_download_url, 'action' => ($item_kind === 'document') ? 'Open full page' : 'Download' ]; ?>
"> NOW() AND item_type = 'File' AND item_related_id = $file_id LIMIT 1" ); $file_shared = (mysqli_num_rows($sql_shared) > 0); if ($file_shared) { $row_shared = mysqli_fetch_assoc($sql_shared); $item_recipient = escapeHtml($row_shared['item_recipient']); $item_expire_at_human = timeAgo($row_shared['item_expire_at']); } ?> $file_id, 'name' => basename($file_name), 'kind' => ($file_mime_type === 'application/pdf') ? 'pdf' : (($file_mime_type === 'text/plain' || $file_mime_type === 'application/json') ? 'text' : 'image'), 'icon' => $file_icon, 'ext' => strtoupper($file_ext), 'size' => $file_size_human, 'excerpt' => '', 'preview' => "file.php?file_id=$file_id&action=view", 'download' => "file.php?file_id=$file_id", 'action' => 'Download' ]; } ?> NOW() AND item_type = 'Document' AND item_related_id = $document_id LIMIT 1" ); $doc_shared = (mysqli_num_rows($sql_shared) > 0); if ($doc_shared) { $row_shared = mysqli_fetch_assoc($sql_shared); $item_recipient = escapeHtml($row_shared['item_recipient']); $item_expire_at_human = timeAgo($row_shared['item_expire_at']); } ?>
Name Type Size Updated Action
= 0) { ?>


Shared


Document -
Shared