forked from Adleraci/adlerka.top
		
	
		
			
				
	
	
		
			189 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
function makePathSafe($userInput): string
 | 
						|
{
 | 
						|
    // Keep only alphanumeric characters, underscores, and hyphens
 | 
						|
    $safeString = preg_replace('/[^\w\-]/', '', $userInput);
 | 
						|
 | 
						|
    // Ensure no path traversal
 | 
						|
    $safeString = str_replace('..', '_', $safeString);
 | 
						|
 | 
						|
    // Trim leading/trailing underscores
 | 
						|
    $safeString = trim($safeString, '_');
 | 
						|
 | 
						|
    // Replace directory separator characters with underscores
 | 
						|
    $safeString = str_replace(['/', '\\'], '_', $safeString);
 | 
						|
 | 
						|
    // Limit length for safety
 | 
						|
    return substr($safeString, 0, 255);
 | 
						|
}
 | 
						|
 | 
						|
function getIncomingFiles(): array
 | 
						|
{
 | 
						|
    $files = $_FILES;
 | 
						|
    $files2 = [];
 | 
						|
    foreach ($files as $infoArr) {
 | 
						|
        $filesByInput = [];
 | 
						|
        foreach ($infoArr as $key => $valueArr) {
 | 
						|
            if (is_array($valueArr)) { // file input "multiple"
 | 
						|
                foreach ($valueArr as $i => $value) {
 | 
						|
                    $filesByInput[$i][$key] = $value;
 | 
						|
                }
 | 
						|
            } else { // -> string, normal file input
 | 
						|
                $filesByInput[] = $infoArr;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        $files2 = array_merge($files2, $filesByInput);
 | 
						|
    }
 | 
						|
    $files3 = [];
 | 
						|
    foreach ($files2 as $file) { // let's filter empty & errors
 | 
						|
        if (!$file['error']) $files3[] = $file;
 | 
						|
    }
 | 
						|
    return $files3;
 | 
						|
}
 | 
						|
 | 
						|
function saveUploadedFileInDatabase($filePath, $fileType):bool
 | 
						|
{
 | 
						|
    global $mysqli;
 | 
						|
    $stmt = $mysqli->prepare("INSERT INTO Files (Path, Type, UploadedBy, UploadedAt) VALUES (?, ?, ?, NOW())");
 | 
						|
    $stmt->bind_param("ssi", $filePath, $fileType, $_SESSION["ID"]);
 | 
						|
    $stmt->execute();
 | 
						|
    $stat = $stmt->affected_rows > 0;
 | 
						|
    $stmt->close();
 | 
						|
    return $stat;
 | 
						|
}
 | 
						|
 | 
						|
function doImageUpload($inFile, $outFile): bool
 | 
						|
{
 | 
						|
    // Create Imagick object
 | 
						|
    try {
 | 
						|
        $imagick = new Imagick($inFile);
 | 
						|
    } catch (ImagickException $e) {
 | 
						|
    }
 | 
						|
 | 
						|
    // Set the desired format for reencoding (WebP)
 | 
						|
    try {
 | 
						|
        $imagick->setImageFormat('webp');
 | 
						|
    } catch (ImagickException $e) {
 | 
						|
    }
 | 
						|
 | 
						|
    // Remove non-essential metadata
 | 
						|
    try {
 | 
						|
        $imagick->stripImage();
 | 
						|
    } catch (ImagickException $e) {
 | 
						|
    }
 | 
						|
 | 
						|
    // Write the reencoded image to the output file
 | 
						|
    try {
 | 
						|
        $imagick->writeImage($outFile);
 | 
						|
    } catch (ImagickException $e) {
 | 
						|
    }
 | 
						|
 | 
						|
    // Destroy the Imagick object to free up resources
 | 
						|
    $imagick->destroy();
 | 
						|
 | 
						|
    // Check if the reencoding was successful
 | 
						|
    if (file_exists($outFile)) {
 | 
						|
        return saveUploadedFileInDatabase($outFile, 'image/webp');
 | 
						|
    } else {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
function listFiles($onlyMine = true):array
 | 
						|
{
 | 
						|
    $output = ["Status" => "Fail"];
 | 
						|
    require_once "lib/account.php";
 | 
						|
    if(($onlyMine && isLoggedIn()) || (!$onlyMine && isModerator())) {
 | 
						|
        global $mysqli;
 | 
						|
        $query = "SELECT ID, Path, Type, UploadedAt, UploadedBy FROM Files";
 | 
						|
 | 
						|
        if($onlyMine){
 | 
						|
            $query .= " WHERE UploadedBy = ?";
 | 
						|
        }
 | 
						|
 | 
						|
        $stmt = $mysqli->prepare($query);
 | 
						|
        if($onlyMine) {
 | 
						|
            $stmt->bind_param("i", $_SESSION["ID"]);
 | 
						|
        }
 | 
						|
 | 
						|
        $id = 0;
 | 
						|
        $path = "";
 | 
						|
        $type = "";
 | 
						|
        $uploadedAt = "";
 | 
						|
        $uploadedBy = 0;
 | 
						|
 | 
						|
        $stmt->bind_result($id, $path, $type, $uploadedAt, $uploadedBy);
 | 
						|
 | 
						|
        $stmt->execute();
 | 
						|
 | 
						|
        // Fetch the results into the bound variables
 | 
						|
        while ($stmt->fetch()) {
 | 
						|
            $files[] = [
 | 
						|
                'ID' => $id,
 | 
						|
                'Path' => $path,
 | 
						|
                'Type' => $type,
 | 
						|
                'UploadedAt' => $uploadedAt,
 | 
						|
                'UploadedBy' => $uploadedBy,
 | 
						|
            ];
 | 
						|
        }
 | 
						|
 | 
						|
        // Check if any results were fetched
 | 
						|
        if (!empty($files)) {
 | 
						|
            $output["Status"] = "Success";
 | 
						|
            $output["Files"] = $files;
 | 
						|
        }
 | 
						|
 | 
						|
        $stmt->close();
 | 
						|
    }
 | 
						|
 | 
						|
    return $output;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
function parseIncomingFiles(): array
 | 
						|
{
 | 
						|
    $incomingFiles = getIncomingFiles();
 | 
						|
    $success = true;
 | 
						|
 | 
						|
    foreach ($incomingFiles as $incomingFile) {
 | 
						|
        if ($incomingFile["error"] == 0 && is_file($incomingFile["tmp_name"])) {
 | 
						|
            $type = explode("/", $incomingFile["type"]);
 | 
						|
            if ($type == "image") {
 | 
						|
                $imgFname = pathinfo($incomingFile["name"], PATHINFO_FILENAME);
 | 
						|
                $uploadPath = getUploadPath("image", $imgFname);
 | 
						|
                if (!empty($uploadPath)) {
 | 
						|
                    if (!doImageUpload($incomingFile["tmp_name"], $uploadPath)) {
 | 
						|
                        $success = false;
 | 
						|
                    }
 | 
						|
                } else {
 | 
						|
                    $success = false;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    $output = ["Status" => "Fail"];
 | 
						|
    if($success){
 | 
						|
        $output["Status"] = "Success";
 | 
						|
    }
 | 
						|
    return $output;
 | 
						|
}
 | 
						|
 | 
						|
function getUploadPath($type = "unknown", $filename = "hehe"): string
 | 
						|
{
 | 
						|
    $type = makePathSafe($type);
 | 
						|
    $id = makePathSafe($_SESSION["ID"]);
 | 
						|
    $date = makePathSafe(date("Y/m/d"));
 | 
						|
    $filename = makePathSafe($filename);
 | 
						|
    $extension = match ($type) {
 | 
						|
        'image' => 'webp',
 | 
						|
        default => 'dummy',
 | 
						|
    };
 | 
						|
    if($extension != "dummy") {
 | 
						|
        return "uploads/$type/$id/$date/$filename.$extension";
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        return "";
 | 
						|
    }
 | 
						|
} |