getImageOrientation(); switch ($orientation) { case Imagick::ORIENTATION_BOTTOMRIGHT: // upside down $imagick->rotateimage("#000", 180); // rotate 180 degrees break; case Imagick::ORIENTATION_RIGHTTOP: // 90 degrees CW $imagick->rotateimage("#000", 90); // rotate 90 degrees CW break; case Imagick::ORIENTATION_LEFTBOTTOM: // 90 degrees CCW $imagick->rotateimage("#000", -90); // rotate 90 degrees CCW break; } // Reset orientation to normal after the correction $imagick->setImageOrientation(Imagick::ORIENTATION_TOPLEFT); } catch (ImagickException) { } } 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(string $filePath, string $fileType, int $width, int $height): bool { global $mysqli; $stmt = $mysqli->prepare("INSERT INTO Files (Path, Type, UploadedBy, UploadedAt, Width, Height) VALUES (?, ?, ?, NOW(), ?, ?)"); $stmt->bind_param("ssiii", $filePath, $fileType, $_SESSION["ID"], $width, $height); $stmt->execute(); $stat = $stmt->affected_rows > 0; $stmt->close(); return $stat; } function doImageUpload($inFile, $outFile): bool { // Create Imagick object $width = 0; $height = 0; try { $imagick = new Imagick($inFile); $imagick->setImageFormat('webp'); autoRotateImage($imagick); $imagick->stripImage(); $imagick->writeImage($outFile); $width = $imagick->getImageWidth(); $height = $imagick->getImageHeight(); $imagick->destroy(); } catch (ImagickException) { } // Check if the reencoding was successful if (file_exists($outFile)) { return saveUploadedFileInDatabase($outFile, 'image/webp', $width, $height); } else { return false; } } function listFiles($onlyMine = true): array { $output = ["Status" => "Fail"]; require_once "lib/account.php"; if (isLoggedIn()) { global $mysqli; if (!$onlyMine && !isModerator()) { $onlyMine = true; } $query = "SELECT Files.ID, Files.Path, Files.Type, Files.UploadedAt, Files.UploadedBy, Users.Nickname FROM Files INNER JOIN Users ON Files.UploadedBy = Users.ID ORDER BY UploadedAt DESC"; if ($onlyMine) { $query .= " WHERE UploadedBy = ?"; } $stmt = $mysqli->prepare($query); if ($onlyMine) { $stmt->bind_param("i", $_SESSION["ID"]); } $id = 0; $path = ""; $type = ""; $uploadedAt = ""; $uploadedByID = 0; $uploadedBy = ""; $stmt->bind_result($id, $path, $type, $uploadedAt, $uploadedByID, $uploadedBy); $stmt->execute(); // Fetch the results into the bound variables while ($stmt->fetch()) { $files[] = [ 'ID' => $id, 'Path' => $path, 'Type' => $type, 'UploadedAt' => $uploadedAt, 'UploadedByID' => $uploadedByID, '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[0] == "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("YmdHis")); $filename = makePathSafe($filename); $extension = match ($type) { 'image' => 'webp', default => 'dummy', }; if ($extension != "dummy") { $basepath = "uploads/$type/$id/$date"; mkdir($basepath, 755, true); return $basepath . "/$filename.$extension"; } else { return ""; } } function fileExists(int $fileId, bool $onlyMine = true): bool|string { if (!$fileId) { return false; } global $mysqli; if (!$onlyMine && !isModerator()) { $onlyMine = true; } $query = 'SELECT ID, Path FROM Files WHERE ID = ?' . ($onlyMine ? ' AND UploadedBy = ?' : ''); $stmtfileexists = $mysqli->prepare($query); if ($onlyMine) { $stmtfileexists->bind_param('ii', $fileId, $_SESSION['ID']); } else { $stmtfileexists->bind_param('i', $fileId); } $filePath = ""; $id = null; $stmtfileexists->bind_result($id, $filePath); $stmtfileexists->execute(); $stmtfileexists->fetch(); if ($id != null) { return $filePath; } else { return false; } } function addToGroup(int $groupId, int $fileId): array { $output = ["Status" => "Fail"]; if (!$groupId || !$fileId) { return $output; } global $mysqli; $stmtcheck = $mysqli->prepare('SELECT ID FROM FileGroups WHERE CreatorID != ? AND ID = ?'); $stmtcheck->bind_param('ii', $_SESSION['ID'], $groupId); $stmtcheck->execute(); if ($stmtcheck->affected_rows == 0) { if (fileExists($fileId, false)) { $stmtadd = $mysqli->prepare('INSERT INTO FileGroups (FileID, CreatorID, ID) VALUES (?, ?, ?)'); $stmtadd->bind_param('iii', $fileId, $_SESSION['ID'], $groupId); $stmtadd->execute(); if ($stmtadd->affected_rows > 0) { $output["Status"] = "Success"; } } } return $output; } function deleteFile(int $fileID): array { global $mysqli; $out = ["Status" => "Fail"]; if (isLoggedIn()) { $file_location = fileExists($fileID, !isAdmin()); $query = !isAdmin() ? 'DELETE FROM Files WHERE ID = ? AND UploadedBy = ?' : 'DELETE FROM Files WHERE ID = ?'; $stmtDelete = $mysqli->prepare($query); if (!isAdmin()) { $stmtDelete->bind_param('ii', $fileID, $_SESSION['ID']); } else { $stmtDelete->bind_param('i', $fileID); } $stmtDelete->execute(); if ($file_location) { if (unlink($file_location) && $stmtDelete->affected_rows > 0) { $out['Status'] = 'Success'; } } } return $out; }