Part 3 : Enhancing the File Manager with a File Upload Feature
In our previous tutorial Creating a Dynamic File Manager with PHP, we developed a functional file manager with features like file browsing, renaming, and deleting. Now, let’s extend its capabilities by integrating a seamless file upload feature using PHP.
Part 1 : Design a Custom File Manager Using HTML and CSS
Part 2 : Creating a Dynamic File Manager with PHP
Part 3 : Enhancing the File Manager with a File Upload Feature
Follow this video for complete guidance
Why Add File Upload?
File upload functionality is essential for any file management system. It allows users to add new files quickly without accessing the server directly. This addition makes the file manager more practical and efficient.
Full Source Code
<?php $directory = isset($_GET['dir']) ? $_GET['dir'] : 'uploads'; // Handle file upload if ($_SERVER['REQUEST_METHOD'] == 'POST') { // Handle file/folder delete if (isset($_POST['delete'])) { $itemToDelete = $_POST['delete']; $pathToDelete = "$directory/$itemToDelete"; deleteFileOrFolder($pathToDelete); } // Handle file/folder rename if (isset($_POST['rename'])) { $oldName = $_POST['oldName']; $newName = $_POST['newName']; $oldPath = "$directory/$oldName"; $newPath = "$directory/$newName"; if (renameFileOrFolder($oldPath, $newPath)) { echo "<p class='alert alert-success'>The item has been renamed.</p>"; } else { echo "<p class='alert alert-danger'>Sorry, there was an error renaming the item.</p>"; } } // Refresh the page to show changes header("Location: $_SERVER[PHP_SELF]?dir=" . urlencode($directory)); exit(); } function getFiles($directory) { $allItems = array_diff(scandir($directory), array('.', '..')); $folders = array_filter($allItems, fn($item) => is_dir("$directory/$item")); $files = array_filter($allItems, fn($item) => !is_dir("$directory/$item")); natcasesort($folders); natcasesort($files); return array_merge($folders, $files); } function buildBreadcrumb($path) { $segments = explode('/', $path); $breadcrumb = []; $currentPath = ''; foreach ($segments as $segment) { if ($segment !== '') { $currentPath .= $segment . '/'; $breadcrumb[] = "<a href=\"?dir=" . urlencode(rtrim($currentPath, '/')) . "\" class=\"breadcrumb-item\">" . htmlspecialchars($segment) . "</a>"; } } return implode(' <span class="breadcrumb-separator">/</span> ', $breadcrumb); } function deleteFileOrFolder($path) { if (is_dir($path)) { rmdir($path); // Delete empty folder } else { unlink($path); // Delete file } } function renameFileOrFolder($oldPath, $newPath) { if (rename($oldPath, $newPath)) { return true; } return false; } $files = getFiles($directory); $rootFolders = getFiles('uploads'); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Modern File Manager</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <style> body { font-family: 'Arial', sans-serif; background-color: #f7f7f7; } .container { max-width: 1200px; } .breadcrumb { background-color: transparent; padding: 0; margin-bottom: 20px; } .breadcrumb a { color: #007bff; text-decoration: none; font-weight: bold; font-size: 16px; transition: color 0.3s ease; } .breadcrumb a:hover { color: #0056b3; text-decoration: underline; } .breadcrumb i { color: #6c757d; } .breadcrumb-item { font-size: 16px; color: #6c757d; } .breadcrumb-separator { color: #6c757d; padding: 0 8px; } .sidebar { background-color: #343a40; color: #fff; padding: 20px; height: 100vh; position: fixed; top: 0; left: 0; width: 250px; } .sidebar-item { margin-bottom: 10px; cursor: pointer; font-size: 16px; } .sidebar-item:hover { background-color: #495057; padding-left: 10px; transition: padding 0.3s; } .content { margin-left: 270px; padding: 20px; } .file-item { background-color: #fff; border-radius: 5px; padding: 15px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); margin-bottom: 15px; text-align: center; } .file-item:hover { background-color: #e9ecef; } .file-icon i { font-size: 40px; color: #6c757d; margin-bottom: 10px; } .file-name { font-size: 14px; color: #495057; } .file-actions { margin-top: 10px; } #contextMenu { display: none; position: absolute; background-color: #ffffff; border: 1px solid #ccc; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); border-radius: 4px; z-index: 1000; } #contextMenu .menu-item { padding: 8px 12px; cursor: pointer; } #contextMenu .menu-item:hover { background-color: #f1f1f1; } .upload-area { width: 400px; height: 200px; border: 2px dashed #ccc; border-radius: 10px; text-align: center; line-height: 200px; margin: 50px auto; cursor: pointer; color: #333; font-size: 18px; } .upload-area.hover { background: #f0f0f0; } #fileInput { display: none; } </style> </head> <body> <div class="sidebar"> <h4 class="text-center">File Manager</h4> <hr class="text-white"> <div class="sidebar-item"> <strong>Quick Access</strong> </div> <?php foreach ($rootFolders as $folder){ ?> <?php $folderPath = "uploads/$folder"; ?> <?php if (is_dir($folderPath)){ ?> <div class="sidebar-item"> <a href="?dir=<?php echo urlencode($folderPath) ?>" class="text-white"><?php echo htmlspecialchars($folder) ?></a> </div> <?php } ?> <?php } ?> </div> <div class="content"> <div class="container"> <nav aria-label="breadcrumb"> <ol class="breadcrumb"> <li class="breadcrumb-item"><a href="?dir=uploads">Home</a></li> <?php echo buildBreadcrumb($directory); ?> </ol> </nav> <div class="upload-area" id="uploadfile">Drag & Drop Files Here</div> <input type="file" id="fileInput"> <div class="row mt-5"> <?php foreach ($files as $file){ ?> <?php $filePath = "$directory/$file"; $fileType = pathinfo($filePath, PATHINFO_EXTENSION); $iconClass = match (strtolower($fileType)) { 'png', 'jpg', 'jpeg', 'gif' => 'fa-image', 'mp3' => 'fa-play', 'mp4' => 'fa-video', 'pdf' => 'fa-file', default => is_dir($filePath) ? 'fa-folder' : 'fa-file' }; ?> <div class="col-md-2" id="file-<?php echo $file;?>"> <div class="file-item" oncontextmenu="showContextMenu(event, '<?php echo $file;?>')"> <?php if (is_dir($filePath)){ ?> <a href="?dir=<?= urlencode($filePath) ?>" class="text-decoration-none text-dark"> <?php } ?> <div class="file-icon"> <i class="fa <?php echo $iconClass;?>"></i> </div> <div class="file-name"><?php echo htmlspecialchars($file);?></div> <?php if (is_dir($filePath)){ ?> </a> <?php } ?> </div> </div> <?php } ?> </div> <div id="contextMenu" class="context-menu"> <div class="menu-item" onclick="renameItem()">Rename</div> <div class="menu-item" onclick="deleteItem()">Delete</div> </div> </div> </div> <script> function showContextMenu(event, file) { event.preventDefault(); currentItem = file; const contextMenu = document.getElementById('contextMenu'); contextMenu.style.display = 'block'; contextMenu.style.left = `${event.pageX}px`; contextMenu.style.top = `${event.pageY}px`; } function hideContextMenu() { document.getElementById('contextMenu').style.display = 'none'; } window.addEventListener('click', hideContextMenu); function deleteItem() { if (confirm('Are you sure you want to delete this item?')) { const form = document.createElement('form'); form.method = 'POST'; form.innerHTML = `<input type="hidden" name="delete" value="${currentItem}">`; document.body.appendChild(form); form.submit(); } } function renameItem() { const newName = prompt("Enter the new name:", currentItem); if (newName && newName !== currentItem) { const form = document.createElement('form'); form.method = 'POST'; form.innerHTML = ` <input type="hidden" name="rename" value="true"> <input type="hidden" name="oldName" value="${currentItem}"> <input type="hidden" name="newName" value="${newName}"> `; document.body.appendChild(form); form.submit(); } } </script> </body> </html>
How the Upload Feature Works
The upload feature allows users to upload files into the current directory of the file manager. The uploaded files are instantly visible, ensuring a smooth and intuitive experience.
- User-Friendly Upload Form: A simple file upload form is added to the interface.
- Directory Integration: Files are uploaded to the currently viewed directory.
- Instant Refresh: The page refreshes automatically to display the newly uploaded files.
Adding the Upload Functionality in PHP
We used PHP’s move_uploaded_file() function to securely handle uploaded files. The system checks if a file was uploaded and moves it to the designated directory.
Enhancing User Experience
To make file uploads more intuitive, consider:
- Progress Bar: Show upload progress in real time.
- File Type Validation: Restrict uploads to specific file types for security.
With this file upload integration, our PHP-based file manager is more powerful and functional. Users can now easily upload files to the current directory, simplifying file management tasks. Stay tuned for future updates, where we will explore advanced features like drag-and-drop uploads, file previews, and more!