FILE SHARING SYSTEM
Introduction
The File Sharing System is a secure web-based platform that enables users to upload, store, manage, and share files with others. The system provides both user and admin interfaces with features like file upload/download, folder organization, sharing permissions, and file management. Users can create accounts, upload files, organize them in folders, share files with other users or via public links, and track their file activities. Administrators can manage all files, users, monitor system usage, and maintain security settings.
Project Features
User Features:
- User Registration and Login System
- File Upload (Multiple files supported)
- Folder Creation and Management
- File/Folder Organization (Move, Copy, Rename, Delete)
- File Sharing Options:
- Share with specific users
- Generate public shareable links
- Set password protection for shared links
- Set expiry dates for shared links
- Download Files
- File Preview for images, PDFs, text files
- Search Files and Folders
- Recent Files View
- Storage Usage Statistics
- User Profile Management
- File Version History
- Trash/Recycle Bin (Restore deleted files)
Admin Features:
- Admin Login Dashboard
- User Management (View, Add, Edit, Delete Users)
- File Management (View all files, Delete inappropriate files)
- Storage Monitoring (Total storage used per user)
- System Settings Configuration
- File Type Restrictions
- Maximum Upload Size Settings
- View System Logs
- Manage File Sharing Links
- Generate Reports
Project File Structure
file-sharing-system/ │ ├── assets/ │ ├── css/ │ │ ├── style.css │ │ ├── admin-style.css │ │ └── responsive.css │ ├── js/ │ │ ├── main.js │ │ ├── file-manager.js │ │ ├── upload.js │ │ └── admin.js │ └── images/ │ ├── icons/ │ └── avatars/ │ ├── uploads/ │ ├── user_files/ │ │ └── [user_id]/ │ ├── temp/ │ └── thumbnails/ │ ├── database/ │ └── file_sharing_system.sql │ ├── includes/ │ ├── config.php │ ├── db_connection.php │ ├── functions.php │ ├── session.php │ ├── auth.php │ └── file_functions.php │ ├── admin/ │ ├── index.php │ ├── login.php │ ├── logout.php │ ├── dashboard.php │ ├── users.php │ ├── add-user.php │ ├── edit-user.php │ ├── delete-user.php │ ├── files.php │ ├── view-file.php │ ├── delete-file.php │ ├── settings.php │ ├── logs.php │ ├── reports.php │ └── profile.php │ ├── user/ │ ├── index.php │ ├── register.php │ ├── login.php │ ├── logout.php │ ├── dashboard.php │ ├── my-files.php │ ├── upload.php │ ├── create-folder.php │ ├── file-details.php │ ├── download.php │ ├── delete.php │ ├── restore.php │ ├── share.php │ ├── shared-with-me.php │ ├── shared-links.php │ ├── trash.php │ ├── search.php │ ├── profile.php │ └── settings.php │ ├── shared/ │ ├── index.php │ └── access.php │ ├── api/ │ ├── upload.php │ ├── delete.php │ ├── rename.php │ ├── move.php │ └── get-files.php │ ├── index.php ├── 404.php ├── .htaccess └── robots.txt
Database Schema (file_sharing_system.sql)
-- Create Database
CREATE DATABASE IF NOT EXISTS file_sharing_system;
USE file_sharing_system;
-- Table: users
CREATE TABLE users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
full_name VARCHAR(100),
avatar VARCHAR(255),
role ENUM('user', 'admin') DEFAULT 'user',
storage_quota BIGINT DEFAULT 1073741824, -- 1GB default
storage_used BIGINT DEFAULT 0,
is_active BOOLEAN DEFAULT TRUE,
last_login DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Insert default admin
INSERT INTO users (username, email, password, full_name, role, storage_quota)
VALUES ('admin', '[email protected]', MD5('Admin@123'), 'System Administrator', 'admin', 5368709120);
-- Table: folders
CREATE TABLE folders (
folder_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
parent_folder_id INT DEFAULT NULL,
folder_name VARCHAR(255) NOT NULL,
folder_path TEXT,
is_public BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE,
FOREIGN KEY (parent_folder_id) REFERENCES folders(folder_id) ON DELETE CASCADE,
INDEX idx_user_folders (user_id, parent_folder_id)
);
-- Table: files
CREATE TABLE files (
file_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
folder_id INT,
file_name VARCHAR(255) NOT NULL,
original_name VARCHAR(255) NOT NULL,
file_extension VARCHAR(50),
file_size BIGINT NOT NULL,
file_path VARCHAR(500) NOT NULL,
file_type VARCHAR(100),
mime_type VARCHAR(100),
is_public BOOLEAN DEFAULT FALSE,
download_count INT DEFAULT 0,
last_downloaded DATETIME,
is_deleted BOOLEAN DEFAULT FALSE,
deleted_at DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE,
FOREIGN KEY (folder_id) REFERENCES folders(folder_id) ON DELETE SET NULL,
INDEX idx_user_files (user_id, folder_id, is_deleted),
INDEX idx_file_search (file_name, file_extension)
);
-- Table: file_versions
CREATE TABLE file_versions (
version_id INT PRIMARY KEY AUTO_INCREMENT,
file_id INT NOT NULL,
version_number INT NOT NULL,
file_name VARCHAR(255) NOT NULL,
file_size BIGINT NOT NULL,
file_path VARCHAR(500) NOT NULL,
created_by INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (file_id) REFERENCES files(file_id) ON DELETE CASCADE,
FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL
);
-- Table: shared_links
CREATE TABLE shared_links (
link_id INT PRIMARY KEY AUTO_INCREMENT,
file_id INT,
folder_id INT,
share_token VARCHAR(100) UNIQUE NOT NULL,
share_password VARCHAR(255),
access_limit INT DEFAULT NULL,
access_count INT DEFAULT 0,
expiry_date DATETIME,
allow_download BOOLEAN DEFAULT TRUE,
created_by INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (file_id) REFERENCES files(file_id) ON DELETE CASCADE,
FOREIGN KEY (folder_id) REFERENCES folders(folder_id) ON DELETE CASCADE,
FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE CASCADE,
CHECK (file_id IS NOT NULL OR folder_id IS NOT NULL)
);
-- Table: shared_with_users
CREATE TABLE shared_with_users (
share_id INT PRIMARY KEY AUTO_INCREMENT,
file_id INT,
folder_id INT,
shared_with_user_id INT NOT NULL,
shared_by_user_id INT NOT NULL,
permission ENUM('view', 'download', 'edit') DEFAULT 'view',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (file_id) REFERENCES files(file_id) ON DELETE CASCADE,
FOREIGN KEY (folder_id) REFERENCES folders(folder_id) ON DELETE CASCADE,
FOREIGN KEY (shared_with_user_id) REFERENCES users(user_id) ON DELETE CASCADE,
FOREIGN KEY (shared_by_user_id) REFERENCES users(user_id) ON DELETE CASCADE,
CHECK (file_id IS NOT NULL OR folder_id IS NOT NULL),
UNIQUE KEY unique_share (file_id, folder_id, shared_with_user_id)
);
-- Table: file_activities
CREATE TABLE file_activities (
activity_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
file_id INT,
folder_id INT,
activity_type ENUM('upload', 'download', 'delete', 'restore', 'rename', 'move', 'share', 'view') NOT NULL,
ip_address VARCHAR(45),
user_agent TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE,
FOREIGN KEY (file_id) REFERENCES files(file_id) ON DELETE SET NULL,
FOREIGN KEY (folder_id) REFERENCES folders(folder_id) ON DELETE SET NULL
);
-- Table: system_settings
CREATE TABLE system_settings (
setting_id INT PRIMARY KEY AUTO_INCREMENT,
setting_key VARCHAR(100) UNIQUE NOT NULL,
setting_value TEXT,
setting_description TEXT,
updated_by INT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Insert default settings
INSERT INTO system_settings (setting_key, setting_value, setting_description) VALUES
('max_upload_size', '10485760', 'Maximum file upload size in bytes (10MB)'),
('allowed_file_types', 'jpg,jpeg,png,gif,pdf,doc,docx,xls,xlsx,txt,zip', 'Comma separated list of allowed file extensions'),
('default_storage_quota', '1073741824', 'Default storage quota for new users (1GB)'),
('maintenance_mode', '0', 'System maintenance mode (0=off, 1=on)'),
('site_name', 'FileShare Pro', 'Website name'),
('site_url', 'http://localhost/file-sharing-system/', 'Website URL');
-- Table: login_logs
CREATE TABLE login_logs (
log_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
username VARCHAR(50),
login_status ENUM('success', 'failed') NOT NULL,
ip_address VARCHAR(45),
user_agent TEXT,
login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE SET NULL
);
Core PHP Files
1. includes/config.php
<?php
// Database configuration
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'file_sharing_system');
// Application configuration
define('SITE_NAME', 'FileShare Pro');
define('SITE_URL', 'http://localhost/file-sharing-system/');
define('ADMIN_URL', SITE_URL . 'admin/');
define('USER_URL', SITE_URL . 'user/');
define('UPLOAD_DIR', $_SERVER['DOCUMENT_ROOT'] . '/file-sharing-system/uploads/');
define('USER_FILES_DIR', UPLOAD_DIR . 'user_files/');
define('TEMP_DIR', UPLOAD_DIR . 'temp/');
define('THUMBNAIL_DIR', UPLOAD_DIR . 'thumbnails/');
// File settings
define('MAX_FILE_SIZE', 10485760); // 10MB
define('ALLOWED_EXTENSIONS', 'jpg,jpeg,png,gif,pdf,doc,docx,xls,xlsx,txt,zip,rar');
define('DEFAULT_STORAGE_QUOTA', 1073741824); // 1GB
// Security settings
define('SESSION_TIMEOUT', 3600); // 1 hour
define('ENABLE_SSL', false);
define('HASH_COST', 10);
// Start session if not started
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
// Error reporting (disable in production)
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Timezone setting
date_default_timezone_set('UTC');
?>
2. includes/db_connection.php
<?php
require_once 'config.php';
class Database {
private $connection;
private static $instance = null;
private function __construct() {
$this->connect();
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new Database();
}
return self::$instance;
}
private function connect() {
$this->connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($this->connection->connect_error) {
die("Connection failed: " . $this->connection->connect_error);
}
$this->connection->set_charset("utf8mb4");
}
public function getConnection() {
return $this->connection;
}
public function escapeString($string) {
return $this->connection->real_escape_string(trim($string));
}
public function prepare($sql) {
return $this->connection->prepare($sql);
}
public function query($sql) {
return $this->connection->query($sql);
}
public function getLastInsertId() {
return $this->connection->insert_id;
}
public function affectedRows() {
return $this->connection->affected_rows;
}
public function beginTransaction() {
$this->connection->begin_transaction();
}
public function commit() {
$this->connection->commit();
}
public function rollback() {
$this->connection->rollback();
}
public function __destruct() {
if ($this->connection) {
$this->connection->close();
}
}
}
// Global database instance
$db = Database::getInstance();
$conn = $db->getConnection();
?>
3. includes/functions.php
<?php
require_once 'db_connection.php';
// Redirect to specified page
function redirect($url) {
header("Location: $url");
exit();
}
// Check if user is logged in
function isLoggedIn() {
return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
}
// Check if admin is logged in
function isAdmin() {
return isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin';
}
// Get current user ID
function getCurrentUserId() {
return $_SESSION['user_id'] ?? 0;
}
// Format file size
function formatFileSize($bytes) {
if ($bytes === 0) return '0 Bytes';
$k = 1024;
$sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
$i = floor(log($bytes) / log($k));
return round($bytes / pow($k, $i), 2) . ' ' . $sizes[$i];
}
// Get file icon based on extension
function getFileIcon($extension) {
$icons = [
'pdf' => 'fa-file-pdf',
'doc' => 'fa-file-word',
'docx' => 'fa-file-word',
'xls' => 'fa-file-excel',
'xlsx' => 'fa-file-excel',
'jpg' => 'fa-file-image',
'jpeg' => 'fa-file-image',
'png' => 'fa-file-image',
'gif' => 'fa-file-image',
'txt' => 'fa-file-alt',
'zip' => 'fa-file-archive',
'rar' => 'fa-file-archive',
'mp3' => 'fa-file-audio',
'mp4' => 'fa-file-video',
'html' => 'fa-file-code',
'css' => 'fa-file-code',
'js' => 'fa-file-code'
];
return $icons[strtolower($extension)] ?? 'fa-file';
}
// Generate unique filename
function generateUniqueFilename($original_name) {
$extension = pathinfo($original_name, PATHINFO_EXTENSION);
return uniqid() . '_' . time() . '.' . $extension;
}
// Get user storage usage
function getUserStorageUsage($user_id) {
global $conn;
$sql = "SELECT SUM(file_size) as total FROM files WHERE user_id = ? AND is_deleted = 0";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
return $row['total'] ?? 0;
}
// Update user storage used
function updateUserStorageUsed($user_id) {
global $conn;
$storage_used = getUserStorageUsage($user_id);
$sql = "UPDATE users SET storage_used = ? WHERE user_id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ii", $storage_used, $user_id);
return $stmt->execute();
}
// Check if user has enough storage
function hasEnoughStorage($user_id, $file_size) {
global $conn;
$sql = "SELECT storage_quota, storage_used FROM users WHERE user_id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
return ($user['storage_used'] + $file_size) <= $user['storage_quota'];
}
// Validate file extension
function isValidFileExtension($filename) {
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$allowed = explode(',', ALLOWED_EXTENSIONS);
return in_array($extension, $allowed);
}
// Generate share token
function generateShareToken() {
return bin2hex(random_bytes(32));
}
// Log user activity
function logActivity($user_id, $file_id, $folder_id, $activity_type) {
global $conn;
$ip_address = $_SERVER['REMOTE_ADDR'] ?? '';
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$sql = "INSERT INTO file_activities (user_id, file_id, folder_id, activity_type, ip_address, user_agent)
VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param("iiisss", $user_id, $file_id, $folder_id, $activity_type, $ip_address, $user_agent);
return $stmt->execute();
}
// Get folder path breadcrumbs
function getFolderPath($folder_id) {
global $conn;
$path = [];
$current_id = $folder_id;
while ($current_id) {
$sql = "SELECT folder_id, folder_name, parent_folder_id FROM folders WHERE folder_id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $current_id);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
array_unshift($path, $row);
$current_id = $row['parent_folder_id'];
} else {
break;
}
}
return $path;
}
// Sanitize filename
function sanitizeFilename($filename) {
// Remove any path information
$filename = basename($filename);
// Replace spaces with underscores
$filename = str_replace(' ', '_', $filename);
// Remove any non-alphanumeric characters except dots and underscores
$filename = preg_replace('/[^a-zA-Z0-9._-]/', '', $filename);
return $filename;
}
// Create thumbnail for image
function createThumbnail($source_path, $destination_path, $max_width = 200, $max_height = 200) {
list($width, $height, $type) = getimagesize($source_path);
$ratio = min($max_width / $width, $max_height / $height);
$new_width = $width * $ratio;
$new_height = $height * $ratio;
$thumb = imagecreatetruecolor($new_width, $new_height);
switch ($type) {
case IMAGETYPE_JPEG:
$source = imagecreatefromjpeg($source_path);
break;
case IMAGETYPE_PNG:
$source = imagecreatefrompng($source_path);
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
break;
case IMAGETYPE_GIF:
$source = imagecreatefromgif($source_path);
break;
default:
return false;
}
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
switch ($type) {
case IMAGETYPE_JPEG:
imagejpeg($thumb, $destination_path, 80);
break;
case IMAGETYPE_PNG:
imagepng($thumb, $destination_path, 8);
break;
case IMAGETYPE_GIF:
imagegif($thumb, $destination_path);
break;
}
imagedestroy($source);
imagedestroy($thumb);
return true;
}
// Get file preview URL
function getPreviewUrl($file) {
$extension = strtolower($file['file_extension']);
$previewable = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'txt'];
if (in_array($extension, $previewable)) {
return SITE_URL . 'user/preview.php?id=' . $file['file_id'];
}
return '#';
}
// Check if file is image
function isImage($extension) {
$image_extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
return in_array(strtolower($extension), $image_extensions);
}
// Delete file from server
function deleteFileFromServer($file_path) {
if (file_exists($file_path) && is_file($file_path)) {
return unlink($file_path);
}
return false;
}
// Get system setting
function getSetting($key, $default = null) {
global $conn;
$sql = "SELECT setting_value FROM system_settings WHERE setting_key = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $key);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
return $row['setting_value'];
}
return $default;
}
// Update system setting
function updateSetting($key, $value) {
global $conn;
$sql = "UPDATE system_settings SET setting_value = ?, updated_by = ?, updated_at = NOW() WHERE setting_key = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("sis", $value, $_SESSION['admin_id'], $key);
return $stmt->execute();
}
// Generate CSRF token
function generateCSRFToken() {
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
// Verify CSRF token
function verifyCSRFToken($token) {
return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}
// Clean old temp files
function cleanTempFiles($hours = 24) {
$temp_dir = TEMP_DIR;
$expiry_time = time() - ($hours * 3600);
$files = glob($temp_dir . '*');
foreach ($files as $file) {
if (is_file($file) && filemtime($file) < $expiry_time) {
unlink($file);
}
}
}
?>
4. includes/file_functions.php
<?php
require_once 'functions.php';
class FileManager {
private $conn;
private $user_id;
public function __construct($user_id) {
global $conn;
$this->conn = $conn;
$this->user_id = $user_id;
}
// Upload file
public function uploadFile($file, $folder_id = null, $description = '') {
if (!isset($file['error']) || is_array($file['error'])) {
return ['success' => false, 'message' => 'Invalid file parameters'];
}
// Check for upload errors
switch ($file['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
return ['success' => false, 'message' => 'File too large'];
default:
return ['success' => false, 'message' => 'Unknown upload error'];
}
// Check file size
if ($file['size'] > MAX_FILE_SIZE) {
return ['success' => false, 'message' => 'File exceeds maximum size limit'];
}
// Check file extension
$original_name = $file['name'];
if (!isValidFileExtension($original_name)) {
return ['success' => false, 'message' => 'File type not allowed'];
}
// Check storage space
if (!hasEnoughStorage($this->user_id, $file['size'])) {
return ['success' => false, 'message' => 'Insufficient storage space'];
}
// Generate unique filename
$extension = pathinfo($original_name, PATHINFO_EXTENSION);
$file_name = generateUniqueFilename($original_name);
// Create user directory if not exists
$user_dir = USER_FILES_DIR . $this->user_id . '/';
if (!file_exists($user_dir)) {
mkdir($user_dir, 0755, true);
}
// Set folder path based on folder_id
if ($folder_id) {
$folder_path = $this->getFolderPath($folder_id);
$upload_dir = $user_dir . $folder_path . '/';
if (!file_exists($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
} else {
$upload_dir = $user_dir;
}
$file_path = $upload_dir . $file_name;
// Move uploaded file
if (!move_uploaded_file($file['tmp_name'], $file_path)) {
return ['success' => false, 'message' => 'Failed to save file'];
}
// Get file mime type
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $file_path);
finfo_close($finfo);
// Insert into database
$sql = "INSERT INTO files (user_id, folder_id, file_name, original_name, file_extension,
file_size, file_path, mime_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $this->conn->prepare($sql);
$relative_path = 'uploads/user_files/' . $this->user_id . '/' . ($folder_path ? $folder_path . '/' : '') . $file_name;
$stmt->bind_param("iisssiss",
$this->user_id,
$folder_id,
$file_name,
$original_name,
$extension,
$file['size'],
$relative_path,
$mime_type
);
if ($stmt->execute()) {
$file_id = $this->conn->insert_id;
// Create thumbnail for images
if (isImage($extension)) {
$this->createFileThumbnail($file_id, $file_path);
}
// Update user storage used
updateUserStorageUsed($this->user_id);
// Log activity
logActivity($this->user_id, $file_id, $folder_id, 'upload');
return [
'success' => true,
'file_id' => $file_id,
'message' => 'File uploaded successfully'
];
} else {
// Delete file if database insert fails
unlink($file_path);
return ['success' => false, 'message' => 'Database error'];
}
}
// Create folder
public function createFolder($folder_name, $parent_folder_id = null) {
$folder_name = sanitizeFilename($folder_name);
// Check if folder already exists
$sql = "SELECT folder_id FROM folders WHERE user_id = ? AND parent_folder_id " .
($parent_folder_id ? "= ?" : "IS NULL") . " AND folder_name = ?";
$stmt = $this->conn->prepare($sql);
if ($parent_folder_id) {
$stmt->bind_param("iis", $this->user_id, $parent_folder_id, $folder_name);
} else {
$stmt->bind_param("is", $this->user_id, $folder_name);
}
$stmt->execute();
if ($stmt->get_result()->num_rows > 0) {
return ['success' => false, 'message' => 'Folder already exists'];
}
// Create folder in database
$sql = "INSERT INTO folders (user_id, parent_folder_id, folder_name) VALUES (?, ?, ?)";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("iis", $this->user_id, $parent_folder_id, $folder_name);
if ($stmt->execute()) {
$folder_id = $this->conn->insert_id;
// Create physical folder
$this->createPhysicalFolder($folder_id);
logActivity($this->user_id, null, $folder_id, 'create_folder');
return ['success' => true, 'folder_id' => $folder_id];
}
return ['success' => false, 'message' => 'Failed to create folder'];
}
// Get files in folder
public function getFiles($folder_id = null) {
$sql = "SELECT f.*,
(SELECT COUNT(*) FROM file_versions WHERE file_id = f.file_id) as version_count
FROM files f
WHERE f.user_id = ? AND f.folder_id " .
($folder_id ? "= ?" : "IS NULL") . " AND f.is_deleted = 0
ORDER BY f.created_at DESC";
$stmt = $this->conn->prepare($sql);
if ($folder_id) {
$stmt->bind_param("ii", $this->user_id, $folder_id);
} else {
$stmt->bind_param("i", $this->user_id);
}
$stmt->execute();
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
}
// Get folders
public function getFolders($parent_folder_id = null) {
$sql = "SELECT * FROM folders WHERE user_id = ? AND parent_folder_id " .
($parent_folder_id ? "= ?" : "IS NULL") . "
ORDER BY folder_name";
$stmt = $this->conn->prepare($sql);
if ($parent_folder_id) {
$stmt->bind_param("ii", $this->user_id, $parent_folder_id);
} else {
$stmt->bind_param("i", $this->user_id);
}
$stmt->execute();
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
}
// Delete file (move to trash)
public function deleteFile($file_id) {
$sql = "UPDATE files SET is_deleted = 1, deleted_at = NOW()
WHERE file_id = ? AND user_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("ii", $file_id, $this->user_id);
if ($stmt->execute() && $stmt->affected_rows > 0) {
logActivity($this->user_id, $file_id, null, 'delete');
return true;
}
return false;
}
// Permanently delete file
public function permanentDeleteFile($file_id) {
// Get file info
$sql = "SELECT * FROM files WHERE file_id = ? AND user_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("ii", $file_id, $this->user_id);
$stmt->execute();
$file = $stmt->get_result()->fetch_assoc();
if (!$file) {
return false;
}
// Delete physical file
$file_path = $_SERVER['DOCUMENT_ROOT'] . '/file-sharing-system/' . $file['file_path'];
if (file_exists($file_path)) {
unlink($file_path);
}
// Delete thumbnail
$thumbnail_path = THUMBNAIL_DIR . $file_id . '.jpg';
if (file_exists($thumbnail_path)) {
unlink($thumbnail_path);
}
// Delete from database
$sql = "DELETE FROM files WHERE file_id = ? AND user_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("ii", $file_id, $this->user_id);
if ($stmt->execute()) {
updateUserStorageUsed($this->user_id);
return true;
}
return false;
}
// Restore file from trash
public function restoreFile($file_id) {
$sql = "UPDATE files SET is_deleted = 0, deleted_at = NULL
WHERE file_id = ? AND user_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("ii", $file_id, $this->user_id);
if ($stmt->execute() && $stmt->affected_rows > 0) {
logActivity($this->user_id, $file_id, null, 'restore');
return true;
}
return false;
}
// Get trash files
public function getTrashFiles() {
$sql = "SELECT * FROM files WHERE user_id = ? AND is_deleted = 1 ORDER BY deleted_at DESC";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("i", $this->user_id);
$stmt->execute();
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
}
// Share file with user
public function shareWithUser($file_id, $shared_with_user_id, $permission = 'view') {
// Check if file belongs to user
$sql = "SELECT * FROM files WHERE file_id = ? AND user_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("ii", $file_id, $this->user_id);
$stmt->execute();
if ($stmt->get_result()->num_rows === 0) {
return false;
}
// Check if already shared
$sql = "SELECT * FROM shared_with_users WHERE file_id = ? AND shared_with_user_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("ii", $file_id, $shared_with_user_id);
$stmt->execute();
if ($stmt->get_result()->num_rows > 0) {
// Update existing share
$sql = "UPDATE shared_with_users SET permission = ? WHERE file_id = ? AND shared_with_user_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("sii", $permission, $file_id, $shared_with_user_id);
} else {
// Create new share
$sql = "INSERT INTO shared_with_users (file_id, shared_with_user_id, shared_by_user_id, permission)
VALUES (?, ?, ?, ?)";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("iiis", $file_id, $shared_with_user_id, $this->user_id, $permission);
}
if ($stmt->execute()) {
logActivity($this->user_id, $file_id, null, 'share');
return true;
}
return false;
}
// Generate share link
public function generateShareLink($file_id, $expiry_days = 7, $password = null, $allow_download = true) {
// Check if file belongs to user
$sql = "SELECT * FROM files WHERE file_id = ? AND user_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("ii", $file_id, $this->user_id);
$stmt->execute();
if ($stmt->get_result()->num_rows === 0) {
return false;
}
$token = generateShareToken();
$expiry_date = $expiry_days ? date('Y-m-d H:i:s', strtotime("+$expiry_days days")) : null;
$hashed_password = $password ? password_hash($password, PASSWORD_DEFAULT) : null;
$sql = "INSERT INTO shared_links (file_id, share_token, share_password, expiry_date, allow_download, created_by)
VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("isssii", $file_id, $token, $hashed_password, $expiry_date, $allow_download, $this->user_id);
if ($stmt->execute()) {
return SITE_URL . 'shared/?token=' . $token;
}
return false;
}
// Get shared files
public function getSharedWithMe() {
$sql = "SELECT f.*, sw.permission, u.username as shared_by_username,
u.full_name as shared_by_name, sw.created_at as shared_at
FROM shared_with_users sw
JOIN files f ON sw.file_id = f.file_id
JOIN users u ON sw.shared_by_user_id = u.user_id
WHERE sw.shared_with_user_id = ? AND f.is_deleted = 0
ORDER BY sw.created_at DESC";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("i", $this->user_id);
$stmt->execute();
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
}
// Helper function to create physical folder
private function createPhysicalFolder($folder_id) {
$folder_path = $this->getFolderPhysicalPath($folder_id);
if (!file_exists($folder_path)) {
mkdir($folder_path, 0755, true);
}
}
// Helper function to get folder physical path
private function getFolderPhysicalPath($folder_id) {
$path_parts = [];
$current_id = $folder_id;
while ($current_id) {
$sql = "SELECT folder_id, folder_name, parent_folder_id FROM folders WHERE folder_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("i", $current_id);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
array_unshift($path_parts, $row['folder_name']);
$current_id = $row['parent_folder_id'];
} else {
break;
}
}
$user_dir = USER_FILES_DIR . $this->user_id . '/';
return $user_dir . implode('/', $path_parts);
}
// Helper function to get folder path for breadcrumbs
private function getFolderPath($folder_id) {
$path_parts = [];
$current_id = $folder_id;
while ($current_id) {
$sql = "SELECT folder_id, folder_name, parent_folder_id FROM folders WHERE folder_id = ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("i", $current_id);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
array_unshift($path_parts, $row['folder_name']);
$current_id = $row['parent_folder_id'];
} else {
break;
}
}
return implode('/', $path_parts);
}
// Helper function to create file thumbnail
private function createFileThumbnail($file_id, $file_path) {
$thumbnail_dir = THUMBNAIL_DIR;
if (!file_exists($thumbnail_dir)) {
mkdir($thumbnail_dir, 0755, true);
}
$thumbnail_path = $thumbnail_dir . $file_id . '.jpg';
createThumbnail($file_path, $thumbnail_path);
}
}
?>
5. index.php (Landing Page)
<?php
require_once 'includes/config.php';
require_once 'includes/functions.php';
// Redirect to user dashboard if logged in
if (isLoggedIn()) {
redirect('user/dashboard.php');
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo SITE_NAME; ?> - Secure File Sharing Platform</title>
<link rel="stylesheet" href="assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="container">
<div class="nav-brand">
<a href="index.php">
<i class="fas fa-cloud-upload-alt"></i>
<?php echo SITE_NAME; ?>
</a>
</div>
<ul class="nav-menu">
<li><a href="#features">Features</a></li>
<li><a href="#pricing">Pricing</a></li>
<li><a href="#about">About</a></li>
<li><a href="user/login.php">Login</a></li>
<li><a href="user/register.php" class="btn-register">Sign Up Free</a></li>
</ul>
</div>
</nav>
<!-- Hero Section -->
<section class="hero">
<div class="container">
<div class="hero-content">
<h1>Secure File Sharing Made Simple</h1>
<p>Upload, store, and share your files with complete security and control.
Access your files from anywhere, anytime.</p>
<div class="hero-buttons">
<a href="user/register.php" class="btn btn-primary">Get Started Free</a>
<a href="#features" class="btn btn-secondary">Learn More</a>
</div>
<div class="hero-stats">
<div class="stat">
<span class="stat-number">1M+</span>
<span class="stat-label">Users</span>
</div>
<div class="stat">
<span class="stat-number">10M+</span>
<span class="stat-label">Files Shared</span>
</div>
<div class="stat">
<span class="stat-number">99.9%</span>
<span class="stat-label">Uptime</span>
</div>
</div>
</div>
<div class="hero-image">
<img src="assets/images/hero-illustration.svg" alt="File Sharing Illustration">
</div>
</div>
</section>
<!-- Features Section -->
<section id="features" class="features">
<div class="container">
<h2 class="section-title">Why Choose <?php echo SITE_NAME; ?>?</h2>
<div class="features-grid">
<div class="feature-card">
<i class="fas fa-shield-alt"></i>
<h3>Secure Storage</h3>
<p>Your files are encrypted and stored securely with enterprise-grade protection.</p>
</div>
<div class="feature-card">
<i class="fas fa-share-alt"></i>
<h3>Easy Sharing</h3>
<p>Share files with anyone via secure links or direct user sharing.</p>
</div>
<div class="feature-card">
<i class="fas fa-cloud-upload-alt"></i>
<h3>Large File Support</h3>
<p>Upload files up to 10GB with our premium plans.</p>
</div>
<div class="feature-card">
<i class="fas fa-clock"></i>
<h3>Version History</h3>
<p>Keep track of file changes with automatic version control.</p>
</div>
<div class="feature-card">
<i class="fas fa-mobile-alt"></i>
<h3>Mobile Access</h3>
<p>Access your files from any device with our responsive design.</p>
</div>
<div class="feature-card">
<i class="fas fa-chart-line"></i>
<h3>Analytics</h3>
<p>Track file downloads and sharing activity.</p>
</div>
</div>
</div>
</section>
<!-- How It Works -->
<section class="how-it-works">
<div class="container">
<h2 class="section-title">How It Works</h2>
<div class="steps">
<div class="step">
<div class="step-number">1</div>
<i class="fas fa-user-plus"></i>
<h3>Create Account</h3>
<p>Sign up for free and get 1GB storage instantly</p>
</div>
<div class="step">
<div class="step-number">2</div>
<i class="fas fa-upload"></i>
<h3>Upload Files</h3>
<p>Drag and drop your files or use our uploader</p>
</div>
<div class="step">
<div class="step-number">3</div>
<i class="fas fa-share"></i>
<h3>Share Securely</h3>
<p>Generate shareable links or invite specific users</p>
</div>
</div>
</div>
</section>
<!-- Pricing Section -->
<section id="pricing" class="pricing">
<div class="container">
<h2 class="section-title">Simple, Transparent Pricing</h2>
<div class="pricing-grid">
<div class="pricing-card">
<h3>Free</h3>
<div class="price">$0<span>/month</span></div>
<ul>
<li><i class="fas fa-check"></i> 1GB Storage</li>
<li><i class="fas fa-check"></i> 100MB File Size Limit</li>
<li><i class="fas fa-check"></i> Basic Sharing</li>
<li><i class="fas fa-check"></i> 30-Day Version History</li>
</ul>
<a href="user/register.php" class="btn btn-outline">Get Started</a>
</div>
<div class="pricing-card popular">
<div class="popular-badge">Most Popular</div>
<h3>Pro</h3>
<div class="price">$9.99<span>/month</span></div>
<ul>
<li><i class="fas fa-check"></i> 100GB Storage</li>
<li><i class="fas fa-check"></i> 5GB File Size Limit</li>
<li><i class="fas fa-check"></i> Advanced Sharing Options</li>
<li><i class="fas fa-check"></i> Password Protection</li>
<li><i class="fas fa-check"></i> 1-Year Version History</li>
</ul>
<a href="user/register.php?plan=pro" class="btn btn-primary">Choose Pro</a>
</div>
<div class="pricing-card">
<h3>Business</h3>
<div class="price">$29.99<span>/month</span></div>
<ul>
<li><i class="fas fa-check"></i> 1TB Storage</li>
<li><i class="fas fa-check"></i> 10GB File Size Limit</li>
<li><i class="fas fa-check"></i> Team Collaboration</li>
<li><i class="fas fa-check"></i> Advanced Analytics</li>
<li><i class="fas fa-check"></i> Unlimited Version History</li>
</ul>
<a href="user/register.php?plan=business" class="btn btn-outline">Contact Sales</a>
</div>
</div>
</div>
</section>
<!-- Testimonials -->
<section class="testimonials">
<div class="container">
<h2 class="section-title">What Our Users Say</h2>
<div class="testimonial-grid">
<div class="testimonial-card">
<div class="testimonial-content">
<i class="fas fa-quote-left"></i>
<p>Best file sharing platform I've used. The security features are top-notch!</p>
</div>
<div class="testimonial-author">
<img src="assets/images/user1.jpg" alt="User">
<div>
<h4>John Doe</h4>
<p>Small Business Owner</p>
</div>
</div>
</div>
<div class="testimonial-card">
<div class="testimonial-content">
<i class="fas fa-quote-left"></i>
<p>Perfect for team collaboration. Sharing files with colleagues is seamless.</p>
</div>
<div class="testimonial-author">
<img src="assets/images/user2.jpg" alt="User">
<div>
<h4>Jane Smith</h4>
<p>Project Manager</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- CTA Section -->
<section class="cta">
<div class="container">
<h2>Ready to get started?</h2>
<p>Join millions of users who trust us with their files</p>
<a href="user/register.php" class="btn btn-primary btn-large">Create Free Account</a>
</div>
</section>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-section">
<h4><?php echo SITE_NAME; ?></h4>
<p>Secure file sharing for everyone</p>
</div>
<div class="footer-section">
<h4>Quick Links</h4>
<ul>
<li><a href="#features">Features</a></li>
<li><a href="#pricing">Pricing</a></li>
<li><a href="#about">About Us</a></li>
<li><a href="contact.php">Contact</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Legal</h4>
<ul>
<li><a href="privacy.php">Privacy Policy</a></li>
<li><a href="terms.php">Terms of Service</a></li>
<li><a href="security.php">Security</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Follow Us</h4>
<div class="social-links">
<a href="#"><i class="fab fa-facebook"></i></a>
<a href="#"><i class="fab fa-twitter"></i></a>
<a href="#"><i class="fab fa-linkedin"></i></a>
<a href="#"><i class="fab fa-github"></i></a>
</div>
</div>
</div>
<div class="footer-bottom">
<p>© <?php echo date('Y'); ?> <?php echo SITE_NAME; ?>. All rights reserved.</p>
</div>
</div>
</footer>
<script src="assets/js/main.js"></script>
</body>
</html>
6. user/dashboard.php
<?php
require_once '../includes/config.php';
require_once '../includes/functions.php';
require_once '../includes/file_functions.php';
// Check login
if (!isLoggedIn()) {
redirect('login.php');
}
$user_id = $_SESSION['user_id'];
$fileManager = new FileManager($user_id);
// Get user info
$sql = "SELECT * FROM users WHERE user_id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();
// Get recent files
$recent_files = $fileManager->getFiles(null);
$recent_files = array_slice($recent_files, 0, 5);
// Get folders
$folders = $fileManager->getFolders(null);
// Get storage usage
$storage_used_percent = ($user['storage_used'] / $user['storage_quota']) * 100;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
<!-- User Navigation -->
<nav class="user-nav">
<div class="container">
<div class="nav-brand">
<a href="dashboard.php">
<i class="fas fa-cloud-upload-alt"></i>
<?php echo SITE_NAME; ?>
</a>
</div>
<div class="nav-search">
<form action="search.php" method="GET">
<input type="text" name="q" placeholder="Search files...">
<button type="submit"><i class="fas fa-search"></i></button>
</form>
</div>
<ul class="nav-menu">
<li><a href="dashboard.php" class="active"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li>
<li><a href="my-files.php"><i class="fas fa-folder"></i> My Files</a></li>
<li><a href="shared-with-me.php"><i class="fas fa-share-alt"></i> Shared</a></li>
<li><a href="trash.php"><i class="fas fa-trash"></i> Trash</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle">
<img src="<?php echo $user['avatar'] ?? '../assets/images/default-avatar.png'; ?>" alt="Avatar">
<?php echo htmlspecialchars($user['username']); ?>
</a>
<ul class="dropdown-menu">
<li><a href="profile.php"><i class="fas fa-user"></i> Profile</a></li>
<li><a href="settings.php"><i class="fas fa-cog"></i> Settings</a></li>
<li><a href="logout.php"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<!-- Main Content -->
<div class="dashboard-container">
<div class="container">
<!-- Welcome Section -->
<div class="welcome-section">
<h1>Welcome back, <?php echo htmlspecialchars($user['full_name'] ?: $user['username']); ?>!</h1>
<div class="quick-actions">
<a href="upload.php" class="action-btn">
<i class="fas fa-cloud-upload-alt"></i>
Upload Files
</a>
<a href="create-folder.php" class="action-btn">
<i class="fas fa-folder-plus"></i>
New Folder
</a>
</div>
</div>
<!-- Storage Stats -->
<div class="storage-stats">
<div class="storage-info">
<h3>Storage Usage</h3>
<div class="storage-bar">
<div class="storage-progress" style="width: <?php echo $storage_used_percent; ?>%"></div>
</div>
<div class="storage-details">
<span><?php echo formatFileSize($user['storage_used']); ?> used</span>
<span>of <?php echo formatFileSize($user['storage_quota']); ?></span>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<i class="fas fa-file"></i>
<div class="stat-info">
<span class="stat-label">Total Files</span>
<span class="stat-value"><?php echo count($recent_files); ?></span>
</div>
</div>
<div class="stat-card">
<i class="fas fa-folder"></i>
<div class="stat-info">
<span class="stat-label">Folders</span>
<span class="stat-value"><?php echo count($folders); ?></span>
</div>
</div>
<div class="stat-card">
<i class="fas fa-share-alt"></i>
<div class="stat-info">
<span class="stat-label">Shared</span>
<span class="stat-value">0</span>
</div>
</div>
</div>
</div>
<!-- Quick Access Folders -->
<div class="quick-access">
<h2>Quick Access</h2>
<div class="folders-grid">
<?php foreach ($folders as $folder): ?>
<a href="my-files.php?folder=<?php echo $folder['folder_id']; ?>" class="folder-card">
<i class="fas fa-folder"></i>
<span><?php echo htmlspecialchars($folder['folder_name']); ?></span>
</a>
<?php endforeach; ?>
<a href="my-files.php" class="folder-card view-all">
<i class="fas fa-arrow-right"></i>
<span>View All</span>
</a>
</div>
</div>
<!-- Recent Files -->
<div class="recent-files">
<div class="section-header">
<h2>Recent Files</h2>
<a href="my-files.php" class="view-all-link">View All <i class="fas fa-arrow-right"></i></a>
</div>
<div class="files-list">
<table class="files-table">
<thead>
<tr>
<th>Name</th>
<th>Size</th>
<th>Modified</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($recent_files as $file): ?>
<tr>
<td>
<i class="fas <?php echo getFileIcon($file['file_extension']); ?>"></i>
<a href="file-details.php?id=<?php echo $file['file_id']; ?>">
<?php echo htmlspecialchars($file['original_name']); ?>
</a>
</td>
<td><?php echo formatFileSize($file['file_size']); ?></td>
<td><?php echo date('M d, Y', strtotime($file['updated_at'])); ?></td>
<td>
<div class="action-buttons">
<a href="download.php?id=<?php echo $file['file_id']; ?>" class="btn-icon" title="Download">
<i class="fas fa-download"></i>
</a>
<a href="share.php?id=<?php echo $file['file_id']; ?>" class="btn-icon" title="Share">
<i class="fas fa-share-alt"></i>
</a>
<a href="delete.php?id=<?php echo $file['file_id']; ?>" class="btn-icon text-danger"
onclick="return confirm('Move to trash?')" title="Delete">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($recent_files)): ?>
<tr>
<td colspan="4" class="text-center">No files yet. <a href="upload.php">Upload your first file</a></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Upload Modal -->
<div id="uploadModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h2>Upload Files</h2>
<form action="../api/upload.php" method="POST" enctype="multipart/form-data" id="uploadForm">
<div class="dropzone" id="dropzone">
<i class="fas fa-cloud-upload-alt"></i>
<p>Drag & drop files here or click to browse</p>
<input type="file" name="files[]" id="fileInput" multiple style="display: none;">
</div>
<div id="fileList" class="file-list"></div>
<button type="submit" class="btn btn-primary">Upload Files</button>
</form>
</div>
</div>
<script src="../assets/js/main.js"></script>
<script src="../assets/js/upload.js"></script>
<script>
// Initialize upload modal
document.querySelector('.action-btn[href="upload.php"]').addEventListener('click', function(e) {
e.preventDefault();
document.getElementById('uploadModal').style.display = 'block';
});
// Close modal
document.querySelector('.close').addEventListener('click', function() {
document.getElementById('uploadModal').style.display = 'none';
});
</script>
</body>
</html>
7. assets/css/style.css
/* Reset and Base Styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary-color: #4361ee;
--secondary-color: #3f37c9;
--success-color: #4cc9f0;
--danger-color: #f72585;
--warning-color: #f8961e;
--dark-color: #1e1b4b;
--light-color: #f8f9fa;
--gray-color: #6c757d;
--border-color: #dee2e6;
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
background-color: #fafafa;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* Typography */
h1, h2, h3, h4, h5, h6 {
font-weight: 600;
line-height: 1.2;
margin-bottom: 1rem;
color: var(--dark-color);
}
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.75rem; }
h4 { font-size: 1.5rem; }
h5 { font-size: 1.25rem; }
h6 { font-size: 1rem; }
p {
margin-bottom: 1rem;
}
a {
color: var(--primary-color);
text-decoration: none;
transition: var(--transition);
}
a:hover {
color: var(--secondary-color);
}
/* Buttons */
.btn {
display: inline-block;
padding: 12px 24px;
border-radius: 8px;
font-weight: 500;
text-align: center;
cursor: pointer;
transition: var(--transition);
border: none;
font-size: 1rem;
}
.btn-primary {
background: var(--primary-color);
color: white;
}
.btn-primary:hover {
background: var(--secondary-color);
transform: translateY(-2px);
box-shadow: var(--shadow);
}
.btn-secondary {
background: white;
color: var(--primary-color);
border: 2px solid var(--primary-color);
}
.btn-secondary:hover {
background: var(--primary-color);
color: white;
}
.btn-danger {
background: var(--danger-color);
color: white;
}
.btn-danger:hover {
background: #d1146b;
}
.btn-large {
padding: 16px 32px;
font-size: 1.1rem;
}
.btn-small {
padding: 8px 16px;
font-size: 0.875rem;
}
/* Navigation */
.navbar {
background: white;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
position: sticky;
top: 0;
z-index: 1000;
}
.navbar .container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 20px;
}
.nav-brand a {
font-size: 1.5rem;
font-weight: 700;
color: var(--primary-color);
}
.nav-brand i {
margin-right: 8px;
color: var(--primary-color);
}
.nav-menu {
display: flex;
list-style: none;
align-items: center;
gap: 2rem;
}
.nav-menu a {
color: var(--dark-color);
font-weight: 500;
}
.nav-menu a:hover,
.nav-menu a.active {
color: var(--primary-color);
}
.btn-register {
background: var(--primary-color);
color: white !important;
padding: 10px 20px;
border-radius: 8px;
}
.btn-register:hover {
background: var(--secondary-color);
}
/* Hero Section */
.hero {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 100px 0;
position: relative;
overflow: hidden;
}
.hero .container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
align-items: center;
}
.hero-content h1 {
font-size: 3rem;
color: white;
margin-bottom: 1.5rem;
}
.hero-content p {
font-size: 1.2rem;
margin-bottom: 2rem;
opacity: 0.9;
}
.hero-buttons {
display: flex;
gap: 1rem;
margin-bottom: 3rem;
}
.hero-stats {
display: flex;
gap: 3rem;
}
.stat {
display: flex;
flex-direction: column;
}
.stat-number {
font-size: 2rem;
font-weight: 700;
}
.stat-label {
opacity: 0.8;
font-size: 0.9rem;
}
.hero-image img {
width: 100%;
animation: float 6s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
/* Features Section */
.features {
padding: 80px 0;
background: white;
}
.section-title {
text-align: center;
font-size: 2.5rem;
margin-bottom: 3rem;
position: relative;
}
.section-title:after {
content: '';
display: block;
width: 80px;
height: 4px;
background: var(--primary-color);
margin: 1rem auto 0;
border-radius: 2px;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.feature-card {
padding: 2rem;
text-align: center;
background: white;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
transition: var(--transition);
}
.feature-card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 40px rgba(0,0,0,0.15);
}
.feature-card i {
font-size: 3rem;
color: var(--primary-color);
margin-bottom: 1.5rem;
}
.feature-card h3 {
margin-bottom: 1rem;
}
.feature-card p {
color: var(--gray-color);
line-height: 1.6;
}
/* How It Works */
.how-it-works {
padding: 80px 0;
background: var(--light-color);
}
.steps {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
max-width: 900px;
margin: 0 auto;
}
.step {
text-align: center;
position: relative;
}
.step-number {
width: 50px;
height: 50px;
background: var(--primary-color);
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
font-weight: bold;
margin: 0 auto 1.5rem;
}
.step i {
font-size: 2.5rem;
color: var(--primary-color);
margin-bottom: 1rem;
}
.step h3 {
margin-bottom: 0.5rem;
}
.step p {
color: var(--gray-color);
}
/* Pricing Section */
.pricing {
padding: 80px 0;
background: white;
}
.pricing-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
max-width: 1000px;
margin: 0 auto;
}
.pricing-card {
background: white;
border-radius: 10px;
padding: 2rem;
text-align: center;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
position: relative;
transition: var(--transition);
}
.pricing-card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 40px rgba(0,0,0,0.15);
}
.pricing-card.popular {
border: 2px solid var(--primary-color);
transform: scale(1.05);
}
.popular-badge {
position: absolute;
top: -12px;
left: 50%;
transform: translateX(-50%);
background: var(--primary-color);
color: white;
padding: 4px 16px;
border-radius: 20px;
font-size: 0.875rem;
font-weight: 500;
}
.price {
font-size: 3rem;
font-weight: 700;
color: var(--dark-color);
margin: 1.5rem 0;
}
.price span {
font-size: 1rem;
color: var(--gray-color);
font-weight: normal;
}
.pricing-card ul {
list-style: none;
margin-bottom: 2rem;
text-align: left;
}
.pricing-card li {
margin-bottom: 0.75rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.pricing-card li i {
color: var(--success-color);
}
.btn-outline {
background: transparent;
color: var(--primary-color);
border: 2px solid var(--primary-color);
}
.btn-outline:hover {
background: var(--primary-color);
color: white;
}
/* Testimonials */
.testimonials {
padding: 80px 0;
background: var(--light-color);
}
.testimonial-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
max-width: 800px;
margin: 0 auto;
}
.testimonial-card {
background: white;
border-radius: 10px;
padding: 2rem;
box-shadow: var(--shadow);
}
.testimonial-content {
margin-bottom: 1.5rem;
position: relative;
}
.testimonial-content i {
color: var(--primary-color);
font-size: 2rem;
opacity: 0.2;
position: absolute;
top: -10px;
left: -10px;
}
.testimonial-content p {
position: relative;
z-index: 1;
font-style: italic;
}
.testimonial-author {
display: flex;
align-items: center;
gap: 1rem;
}
.testimonial-author img {
width: 60px;
height: 60px;
border-radius: 50%;
object-fit: cover;
}
.testimonial-author h4 {
margin-bottom: 0.25rem;
}
.testimonial-author p {
color: var(--gray-color);
font-size: 0.875rem;
}
/* CTA Section */
.cta {
padding: 100px 0;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
color: white;
text-align: center;
}
.cta h2 {
font-size: 2.5rem;
color: white;
margin-bottom: 1rem;
}
.cta p {
font-size: 1.2rem;
margin-bottom: 2rem;
opacity: 0.9;
}
.cta .btn {
background: white;
color: var(--primary-color);
}
.cta .btn:hover {
background: var(--light-color);
transform: translateY(-2px);
}
/* Footer */
.footer {
background: var(--dark-color);
color: white;
padding: 4rem 0 2rem;
}
.footer-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 2rem;
margin-bottom: 3rem;
}
.footer-section h4 {
color: white;
margin-bottom: 1.5rem;
position: relative;
}
.footer-section h4:after {
content: '';
display: block;
width: 50px;
height: 2px;
background: var(--primary-color);
margin-top: 0.5rem;
}
.footer-section ul {
list-style: none;
}
.footer-section li {
margin-bottom: 0.75rem;
}
.footer-section a {
color: rgba(255,255,255,0.8);
transition: var(--transition);
}
.footer-section a:hover {
color: white;
padding-left: 5px;
}
.social-links {
display: flex;
gap: 1rem;
}
.social-links a {
width: 40px;
height: 40px;
background: rgba(255,255,255,0.1);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: var(--transition);
}
.social-links a:hover {
background: var(--primary-color);
transform: translateY(-3px);
}
.footer-bottom {
text-align: center;
padding-top: 2rem;
border-top: 1px solid rgba(255,255,255,0.1);
color: rgba(255,255,255,0.6);
}
/* User Dashboard Styles */
.user-nav {
background: white;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
position: sticky;
top: 0;
z-index: 1000;
}
.user-nav .container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem 20px;
}
.nav-search {
flex: 1;
max-width: 500px;
margin: 0 2rem;
}
.nav-search form {
display: flex;
position: relative;
}
.nav-search input {
width: 100%;
padding: 10px 16px;
border: 1px solid var(--border-color);
border-radius: 8px;
font-size: 0.95rem;
transition: var(--transition);
}
.nav-search input:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.1);
}
.nav-search button {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: var(--gray-color);
cursor: pointer;
}
.dropdown {
position: relative;
}
.dropdown-toggle {
display: flex;
align-items: center;
gap: 8px;
}
.dropdown-toggle img {
width: 32px;
height: 32px;
border-radius: 50%;
object-fit: cover;
}
.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
background: white;
border-radius: 8px;
box-shadow: 0 10px 30px rgba(0,0,0,0.15);
min-width: 200px;
display: none;
z-index: 1000;
}
.dropdown:hover .dropdown-menu {
display: block;
}
.dropdown-menu li {
list-style: none;
}
.dropdown-menu a {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 16px;
color: var(--dark-color);
transition: var(--transition);
}
.dropdown-menu a:hover {
background: var(--light-color);
color: var(--primary-color);
}
/* Dashboard Container */
.dashboard-container {
padding: 2rem 0;
}
.welcome-section {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
.welcome-section h1 {
margin-bottom: 0;
}
.quick-actions {
display: flex;
gap: 1rem;
}
.action-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
background: var(--primary-color);
color: white;
border-radius: 8px;
transition: var(--transition);
}
.action-btn:hover {
background: var(--secondary-color);
transform: translateY(-2px);
color: white;
}
/* Storage Stats */
.storage-stats {
background: white;
border-radius: 10px;
padding: 2rem;
margin-bottom: 2rem;
box-shadow: var(--shadow);
display: grid;
grid-template-columns: 2fr 1fr;
gap: 2rem;
}
.storage-info h3 {
margin-bottom: 1rem;
}
.storage-bar {
height: 10px;
background: var(--light-color);
border-radius: 5px;
overflow: hidden;
margin-bottom: 0.5rem;
}
.storage-progress {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
border-radius: 5px;
transition: width 0.3s ease;
}
.storage-details {
display: flex;
justify-content: space-between;
color: var(--gray-color);
font-size: 0.9rem;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.stat-card {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
background: var(--light-color);
border-radius: 8px;
}
.stat-card i {
font-size: 2rem;
color: var(--primary-color);
}
.stat-info {
display: flex;
flex-direction: column;
}
.stat-label {
font-size: 0.875rem;
color: var(--gray-color);
}
.stat-value {
font-size: 1.5rem;
font-weight: 700;
color: var(--dark-color);
}
/* Quick Access */
.quick-access {
margin-bottom: 2rem;
}
.quick-access h2 {
margin-bottom: 1rem;
}
.folders-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 1rem;
}
.folder-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 1.5rem;
background: white;
border-radius: 8px;
box-shadow: var(--shadow);
transition: var(--transition);
color: var(--dark-color);
}
.folder-card:hover {
transform: translateY(-3px);
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
color: var(--primary-color);
}
.folder-card i {
font-size: 2.5rem;
margin-bottom: 0.5rem;
color: var(--primary-color);
}
.folder-card.view-all {
background: var(--light-color);
}
.folder-card.view-all i {
color: var(--gray-color);
}
/* Recent Files */
.recent-files {
background: white;
border-radius: 10px;
padding: 2rem;
box-shadow: var(--shadow);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
}
.section-header h2 {
margin-bottom: 0;
}
.view-all-link {
color: var(--primary-color);
font-weight: 500;
}
.files-table {
width: 100%;
border-collapse: collapse;
}
.files-table th {
text-align: left;
padding: 1rem;
border-bottom: 2px solid var(--border-color);
color: var(--gray-color);
font-weight: 600;
font-size: 0.9rem;
}
.files-table td {
padding: 1rem;
border-bottom: 1px solid var(--border-color);
}
.files-table tr:hover {
background: var(--light-color);
}
.files-table i {
margin-right: 10px;
color: var(--gray-color);
}
.action-buttons {
display: flex;
gap: 0.5rem;
}
.btn-icon {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
background: var(--light-color);
color: var(--gray-color);
transition: var(--transition);
}
.btn-icon:hover {
background: var(--primary-color);
color: white;
}
.btn-icon.text-danger:hover {
background: var(--danger-color);
}
.text-center {
text-align: center;
}
.text-danger {
color: var(--danger-color);
}
/* Modal */
.modal {
display: none;
position: fixed;
z-index: 2000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
.modal-content {
background-color: white;
margin: 10% auto;
padding: 2rem;
border-radius: 10px;
width: 90%;
max-width: 600px;
position: relative;
animation: slideDown 0.3s ease;
}
@keyframes slideDown {
from {
transform: translateY(-30px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.close {
position: absolute;
right: 20px;
top: 15px;
font-size: 28px;
font-weight: bold;
color: var(--gray-color);
cursor: pointer;
}
.close:hover {
color: var(--danger-color);
}
/* Dropzone */
.dropzone {
border: 2px dashed var(--border-color);
border-radius: 8px;
padding: 2rem;
text-align: center;
margin: 1rem 0;
cursor: pointer;
transition: var(--transition);
}
.dropzone:hover,
.dropzone.dragover {
border-color: var(--primary-color);
background: rgba(67, 97, 238, 0.05);
}
.dropzone i {
font-size: 3rem;
color: var(--primary-color);
margin-bottom: 1rem;
}
.file-list {
margin: 1rem 0;
max-height: 200px;
overflow-y: auto;
}
.file-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5rem;
background: var(--light-color);
margin-bottom: 0.5rem;
border-radius: 4px;
}
/* Responsive Design */
@media (max-width: 768px) {
h1 { font-size: 2rem; }
h2 { font-size: 1.75rem; }
.hero .container {
grid-template-columns: 1fr;
text-align: center;
}
.hero-buttons {
justify-content: center;
}
.hero-stats {
justify-content: center;
}
.steps {
grid-template-columns: 1fr;
}
.pricing-grid {
grid-template-columns: 1fr;
}
.pricing-card.popular {
transform: scale(1);
}
.storage-stats {
grid-template-columns: 1fr;
}
.stats-grid {
grid-template-columns: 1fr;
}
.user-nav .container {
flex-direction: column;
gap: 1rem;
}
.nav-search {
max-width: 100%;
margin: 0;
}
}
8. assets/js/upload.js
class FileUploader {
constructor() {
this.dropzone = document.getElementById('dropzone');
this.fileInput = document.getElementById('fileInput');
this.fileList = document.getElementById('fileList');
this.uploadForm = document.getElementById('uploadForm');
this.files = [];
this.init();
}
init() {
// Click on dropzone to open file dialog
this.dropzone.addEventListener('click', () => {
this.fileInput.click();
});
// Handle drag & drop
this.dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
this.dropzone.classList.add('dragover');
});
this.dropzone.addEventListener('dragleave', () => {
this.dropzone.classList.remove('dragover');
});
this.dropzone.addEventListener('drop', (e) => {
e.preventDefault();
this.dropzone.classList.remove('dragover');
this.handleFiles(e.dataTransfer.files);
});
// Handle file input change
this.fileInput.addEventListener('change', (e) => {
this.handleFiles(e.target.files);
});
// Handle form submission
this.uploadForm.addEventListener('submit', (e) => {
e.preventDefault();
this.uploadFiles();
});
}
handleFiles(files) {
for (let file of files) {
// Check file size (10MB limit)
if (file.size > 10 * 1024 * 1024) {
this.showNotification(`File ${file.name} is too large. Max size: 10MB`, 'error');
continue;
}
// Check if file already in list
if (!this.files.find(f => f.name === file.name && f.size === file.size)) {
this.files.push(file);
}
}
this.updateFileList();
}
updateFileList() {
this.fileList.innerHTML = '';
this.files.forEach((file, index) => {
const fileItem = document.createElement('div');
fileItem.className = 'file-item';
fileItem.innerHTML = `
<div>
<i class="fas fa-file"></i>
<span>${file.name}</span>
<small>(${this.formatFileSize(file.size)})</small>
</div>
<button type="button" class="btn-icon remove-file" data-index="${index}">
<i class="fas fa-times"></i>
</button>
`;
this.fileList.appendChild(fileItem);
});
// Add remove functionality
document.querySelectorAll('.remove-file').forEach(btn => {
btn.addEventListener('click', (e) => {
const index = e.target.closest('.remove-file').dataset.index;
this.files.splice(index, 1);
this.updateFileList();
});
});
}
formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
uploadFiles() {
if (this.files.length === 0) {
this.showNotification('Please select files to upload', 'warning');
return;
}
const formData = new FormData();
this.files.forEach(file => {
formData.append('files[]', file);
});
// Show loading
const submitBtn = this.uploadForm.querySelector('button[type="submit"]');
const originalText = submitBtn.textContent;
submitBtn.textContent = 'Uploading...';
submitBtn.disabled = true;
fetch('../api/upload.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
this.showNotification('Files uploaded successfully!', 'success');
this.files = [];
this.updateFileList();
// Refresh page after 2 seconds
setTimeout(() => {
location.reload();
}, 2000);
} else {
this.showNotification(data.message || 'Upload failed', 'error');
}
})
.catch(error => {
this.showNotification('Error uploading files', 'error');
console.error('Upload error:', error);
})
.finally(() => {
submitBtn.textContent = originalText;
submitBtn.disabled = false;
});
}
showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.className = `notification notification-${type}`;
notification.textContent = message;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
padding: 15px 25px;
background: ${type === 'success' ? '#4cc9f0' : type === 'error' ? '#f72585' : '#4361ee'};
color: white;
border-radius: 8px;
z-index: 9999;
animation: slideIn 0.3s ease;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
`;
document.body.appendChild(notification);
setTimeout(() => {
notification.remove();
}, 3000);
}
}
// Initialize uploader when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
new FileUploader();
});
9. api/upload.php
<?php
require_once '../includes/config.php';
require_once '../includes/functions.php';
require_once '../includes/file_functions.php';
header('Content-Type: application/json');
// Check if user is logged in
if (!isLoggedIn()) {
echo json_encode(['success' => false, 'message' => 'Not authenticated']);
exit();
}
// Check if files were uploaded
if (empty($_FILES['files'])) {
echo json_encode(['success' => false, 'message' => 'No files uploaded']);
exit();
}
$user_id = $_SESSION['user_id'];
$fileManager = new FileManager($user_id);
$uploaded_files = [];
$errors = [];
// Handle multiple file uploads
$files = $_FILES['files'];
$file_count = count($files['name']);
for ($i = 0; $i < $file_count; $i++) {
$file = [
'name' => $files['name'][$i],
'type' => $files['type'][$i],
'tmp_name' => $files['tmp_name'][$i],
'error' => $files['error'][$i],
'size' => $files['size'][$i]
];
$result = $fileManager->uploadFile($file);
if ($result['success']) {
$uploaded_files[] = $result;
} else {
$errors[] = $result['message'];
}
}
echo json_encode([
'success' => count($uploaded_files) > 0,
'uploaded' => $uploaded_files,
'errors' => $errors,
'message' => count($uploaded_files) . ' files uploaded successfully'
]);
?>
How to Use This Project - Step by Step Guide
Step 1: System Requirements
- XAMPP/WAMP/MAMP (PHP 7.4+)
- MySQL 5.7+
- Web browser (Chrome, Firefox, etc.)
- 2GB RAM minimum
- 500MB free disk space
Step 2: Installation
- Download and Extract
# Navigate to htdocs (XAMPP) or www (WAMP) cd C:\xampp\htdocs\ # Create project folder mkdir file-sharing-system # Extract all files into this folder
- Database Setup
- Open phpMyAdmin (http://localhost/phpmyadmin)
- Create new database:
file_sharing_system - Import
database/file_sharing_system.sql - Verify tables are created (users, folders, files, etc.)
- Configure Project
- Open
includes/config.php - Update database credentials if needed:
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', ''); // Add password if set
define('DB_NAME', 'file_sharing_system');
- Set Folder Permissions
# Create required directories mkdir uploads mkdir uploads/user_files mkdir uploads/temp mkdir uploads/thumbnails # Set permissions (Linux/Mac) chmod -R 755 uploads/ # Windows: Ensure write permissions for these folders
Step 3: Initial Configuration
- Default Admin Account
- Username: admin
- Password: Admin@123
- Email: [email protected]
- System Settings
- Login as admin
- Go to Settings page
- Configure:
- Maximum file size
- Allowed file types
- Default storage quota
- Site name and URL
Step 4: Testing the System
User Side Testing:
- User Registration
- Go to homepage
- Click "Sign Up Free"
- Fill registration form
- Submit and verify email
- User Login
- Use registered credentials
- Access dashboard
- View storage stats
- Upload Files
- Click "Upload Files"
- Drag & drop files or browse
- Select multiple files
- Click upload
- Verify files appear in list
- Create Folders
- Click "New Folder"
- Enter folder name
- Verify folder created
- Navigate into folder
- File Management
- Rename files/folders
- Move files between folders
- Delete files (to trash)
- Restore from trash
- Permanent delete
- File Sharing
- Select a file
- Click "Share"
- Choose sharing method:
- Share with specific user
- Generate public link
- Set password (optional)
- Set expiry date
- Copy share link
- Download Files
- Click download icon
- Verify file downloads
- Check download count
- Search Functionality
- Use search bar
- Search by filename
- Filter results
Admin Side Testing:
- Admin Login
- Go to
/admin/login.php - Use admin credentials
- User Management
- View all users
- Add new users
- Edit user details
- Suspend/activate users
- Delete users
- File Management
- View all files
- Monitor storage usage
- Delete inappropriate files
- View file details
- System Settings
- Configure system parameters
- Set storage quotas
- Manage file types
- View system logs
- Reports
- Generate usage reports
- View statistics
- Export data
Step 5: Security Configuration
- .htaccess Configuration
# Protect sensitive directories <FilesMatch "\.(sql|log|ini)$"> Order allow,deny Deny from all </FilesMatch> # Disable directory browsing Options -Indexes
- PHP Configuration
- Update
php.inifor larger uploads:
upload_max_filesize = 100M post_max_size = 100M max_execution_time = 300
Step 6: Features in Detail
User Features:
- File Upload
- Multiple file upload
- Progress indicator
- Drag & drop support
- File type validation
- Size validation
- Folder Management
- Create nested folders
- Move files between folders
- Copy files
- Rename folders
- File Sharing
- Share with specific users
- Public share links
- Password protection
- Expiry dates
- Download permissions
- File Operations
- Download single/multiple
- Preview supported files
- Version history
- File comments
- Star/favorite files
- Storage Management
- Storage usage display
- Quota notifications
- Clean up old files
- Trash management
- Search & Filter
- Quick search
- Advanced filters
- Sort by date/size/name
- File type filters
Admin Features:
- User Administration
- Create/Edit/Delete users
- Set user roles
- Manage permissions
- Reset passwords
- System Monitoring
- Storage overview
- Active users
- File statistics
- Bandwidth usage
- Security Management
- Login attempts
- Activity logs
- IP blocking
- File scanning
- Configuration
- File type restrictions
- Size limits
- Storage quotas
- Email settings
Step 7: Troubleshooting
Common Issues and Solutions:
- Upload Fails
- Check PHP upload limits
- Verify folder permissions
- Check disk space
- Check file type restrictions
- Login Issues
- Clear browser cache
- Check session configuration
- Verify database connection
- Check user activation status
- File Not Downloading
- Check file permissions
- Verify file exists on server
- Check .htaccess configuration
- Browser cache issues
- Slow Performance
- Optimize database queries
- Implement file caching
- Use CDN for files
- Compress images
Step 8: Deployment to Production
- Server Requirements
- PHP 7.4 or higher
- MySQL 5.7 or higher
- Apache/Nginx web server
- SSL certificate
- 20GB+ storage space
- Security Hardening
- Enable HTTPS
- Set secure file permissions
- Implement rate limiting
- Enable firewall
- Regular backups
- Update PHP and MySQL
- Performance Optimization
- Enable PHP opcache
- Configure MySQL caching
- Use Redis for sessions
- Implement file compression
- CDN integration
- Monitoring Setup
- Server monitoring
- Error logging
- Usage analytics
- Backup monitoring
- Security alerts
Step 9: Backup Strategy
- Database Backup
# Automated daily backup mysqldump -u root -p file_sharing_system > backup_$(date +%Y%m%d).sql
- File Backup
# Backup uploads directory tar -czf uploads_backup_$(date +%Y%m%d).tar.gz uploads/
- Configuration Backup
- Backup config files
- Save .htaccess rules
- Document settings
Step 10: Customization Options
- Branding
- Update logo in navigation
- Change color scheme in CSS
- Modify email templates
- Customize error pages
- Functionality
- Add payment integration
- Implement file preview for more types
- Add social login
- Create API endpoints
- Mobile app development
- Integration
- Google Drive integration
- Dropbox integration
- Email notifications
- Slack/webhook alerts
Security Features Implemented
- Authentication & Authorization
- Password hashing
- Session management
- CSRF protection
- Role-based access control
- File Security
- File type validation
- Virus scanning (optional)
- Secure file storage
- Access control per file
- Data Protection
- SQL injection prevention
- XSS protection
- Input sanitization
- Secure headers
- Monitoring
- Activity logging
- Failed login tracking
- File access logs
- Admin alerts
Future Enhancements
- Version 2.0 Features
- Real-time collaboration
- File encryption
- Mobile apps (iOS/Android)
- Desktop sync client
- Advanced search with OCR
- File locking for editing
- Team workspaces
- API for developers
- Enterprise Features
- LDAP/Active Directory integration
- Compliance reporting
- Data loss prevention
- Advanced analytics
- Workflow automation
- E-signature integration
- Performance Improvements
- Distributed storage
- CDN integration
- Load balancing
- Database sharding
- Elasticsearch integration
This comprehensive File Sharing System provides a robust foundation for a secure file management platform. The modular architecture allows for easy customization and scaling based on specific requirements. Both user and admin interfaces are intuitive and feature-rich, making it suitable for personal use, small businesses, or enterprise deployment.