"Uploader", "version" => "0.2", "author" => "Starbeamrainbowlabs", "description" => "Adds the ability to upload files to Pepperminty Wiki. Uploaded files act as pages and have the special 'File:' prefix.", "id" => "feature-upload", "code" => function() { add_action("upload", function() { global $settings, $env, $pageindex, $paths; switch($_SERVER["REQUEST_METHOD"]) { case "GET": // Send upload page if(!$settings->upload_enabled) exit(page_renderer::render("Upload Disabled - $setting->sitename", "

You can't upload anything at the moment because $settings->sitename has uploads disabled. Try contacting " . $settings->admindetails["name"] . ", your site Administrator. Go back.

")); if(!$env->is_logged_in) exit(page_renderer::render("Upload Error - $settings->sitename", "

You are not currently logged in, so you can't upload anything.

Try logging in first.

")); exit(page_renderer::render("Upload - $settings->sitename", "

Select an image below, and then type a name for it in the box. This server currently supports uploads up to " . human_filesize(get_max_upload_size()) . " in size.

$settings->sitename currently supports uploading of the following file types: " . implode(", ", $settings->upload_allowed_file_types) . ".




")); break; case "POST": // Recieve file // Make sure uploads are enabled if(!$settings->upload_enabled) { unlink($_FILES["file"]["tmp_name"]); http_response_code(412); exit(page_renderer::render("Upload failed - $settings->sitename", "

Your upload couldn't be processed because uploads are currently disabled on $settings->sitename. Go back to the main page.

")); } // Make sure that the user is logged in if(!$env->is_logged_in) { unlink($_FILES["file"]["tmp_name"]); http_response_code(401); exit(page_renderer::render("Upload failed - $settings->sitename", "

Your upload couldn't be processed because you are not logged in.

Try logging in first.")); } // Calculate the target ename, removing any characters we // are unsure about. $target_name = makepathsafe($_POST["name"]); $temp_filename = $_FILES["file"]["tmp_name"]; $mimechecker = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($mimechecker, $temp_filename); finfo_close($mimechecker); // Perform appropriate checks based on the *real* filetype switch(substr($mime_type, 0, strpos($mime_type, "/"))) { case "image": $extra_data = []; $imagesize = getimagesize($temp_filename, $extra_data); // Make sure that the image size is defined if(!is_int($imagesize[0]) or !is_int($imagesize[1])) { http_response_code(415); exit(page_renderer::render("Upload Error - $settings->sitename", "

The file that you uploaded doesn't appear to be an image. $settings->sitename currently only supports uploading images (videos coming soon). Go back to try again.

")); } break; case "video": http_response_code(501); exit(page_renderer::render("Upload Error - $settings->sitename", "

You uploaded a video, but $settings->sitename doesn't support them yet. Please try again later.

")); default: http_response_code(415); exit(page_renderer::render("Upload Error - $settings->sitename", "

You uploaded an unnknown file type which couldn't be processed. $settings->sitename thinks that the file you uploaded was a(n) '$mime_type', which isn't supported.

")); } $file_extension = system_mime_type_extension($mime_type); $new_filename = "$paths->upload_file_prefix$target_name.$file_extension"; $new_description_filename = "$new_filename.md"; if(isset($pageindex->$new_filename)) exit(page_renderer::render("Upload Error - $settings->sitename", "

A page or file has already been uploaded with the name '$new_filename'. Try deleting it first. If you do not have permission to delete things, try contacting one of the moderators.

")); if(!file_exists("Files")) mkdir("Files", 0664); if(!move_uploaded_file($temp_filename, $env->storage_prefix . $new_filename)) { http_response_code(409); exit(page_renderer::render("Upload Error - $settings->sitename", "

The file you uploaded was valid, but $settings->sitename couldn't verify that it was tampered with during the upload process. This probably means that $settings->sitename has been attacked. Please contact " . $settings->admindetails . ", your $settings->sitename Administrator.

")); } $description = $_POST["description"]; // Escape the raw html in the provided description if the setting is enabled if($settings->clean_raw_html) $description = htmlentities($description, ENT_QUOTES); file_put_contents($env->storage_prefix . $new_description_filename, $description); // Construct a new entry for the pageindex $entry = new stdClass(); // Point to the description's filepath since this property // should point to a markdown file $entry->filename = $new_description_filename; $entry->size = strlen($description); $entry->lastmodified = time(); $entry->lasteditor = $env->user; $entry->uploadedfile = true; $entry->uploadedfilepath = $new_filename; $entry->uploadedfilemime = $mime_type; // Add the new entry to the pageindex // Assign the new entry to the image's filepath as that // should be the page name. $pageindex->$new_filename = $entry; // Save the pageindex file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT)); header("location: ?action=view&page=$new_filename&upload=success"); break; } }); add_action("preview", function() { global $settings, $env, $pageindex; $filepath = $env->storage_prefix . $pageindex->{$env->page}->uploadedfilepath; $mime_type = $pageindex->{$env->page}->uploadedfilemime; if(isset($_GET["size"]) and $_GET["size"] == "original") { // Get the file size $filesize = filesize($filepath); // Send some headers header("content-length: $filesize"); header("content-type: $mime_type"); // Open the file and send it to the user $handle = fopen($filepath, "rb"); fpassthru($handle); fclose($handle); exit(); } // Determine the target size of the image $target_size = 512; if(isset($_GET["size"])) $target_size = intval($_GET["size"]); if($target_size < $settings->min_preview_size) $target_size = $settings->min_preview_size; if($target_size > $settings->max_preview_size) $target_size = $settings->max_preview_size; // Determine the output file type $output_mime = $settings->preview_file_type; if(isset($_GET["type"]) and in_array($_GET["type"], [ "image/png", "image/jpeg", "image/webp" ])) $output_mime = $_GET["type"]; switch(substr($mime_type, 0, strpos($mime_type, "/"))) { case "image": $image = false; switch($mime_type) { case "image/jpeg": $image = imagecreatefromjpeg($filepath); break; case "image/gif": $image = imagecreatefromgif($filepath); break; case "image/png": $image = imagecreatefrompng($filepath); break; case "image/webp": $image = imagecreatefromwebp($filepath); break; default: http_response_code(415); $image = errorimage("Unsupported image type."); break; } $raw_width = imagesx($image); $raw_height = imagesy($image); $preview_image = resize_image($image, $target_size); header("content-type: $output_mime"); switch($output_mime) { case "image/jpeg": imagejpeg($preview_image); break; case "image/png": imagepng($preview_image); break; default: case "image/webp": imagewebp($preview_image); break; } imagedestroy($preview_image); break; default: http_response_code(501); exit("Unrecognised file type."); } }); page_renderer::register_part_preprocessor(function(&$parts) { global $pageindex, $env, $settings; // Todo add the preview to the top of the page here, but only if the current action is view and we are on a page that is a file if(isset($pageindex->{$env->page}->uploadedfile) and $pageindex->{$env->page}->uploadedfile == true) { // We are looking at a page that is paired with an uploaded file $filepath = $pageindex->{$env->page}->uploadedfilepath; $mime_type = $pageindex->{$env->page}->uploadedfilemime; $dimensions = getimagesize($env->storage_prefix . $filepath); $preview_sizes = [ 256, 512, 768, 1024, 1440 ]; $preview_html = "

File Information

Name" . str_replace("File/", "", $filepath) . "
Type$mime_type
Size" . human_filesize(filesize($filepath)) . "
Original dimensions$dimensions[0] x $dimensions[1]
Uploaded by" . $pageindex->{$env->page}->lasteditor . "

Description

"; $parts["{content}"] = str_replace("", "\n$preview_html", $parts["{content}"]); } }); } ]); //// Pair of functions to calculate the actual maximum upload size supported by the server //// Lifted from Drupal by @meustrus from Stackoverflow. Link to answer: //// http://stackoverflow.com/a/25370978/1460422 // Returns a file size limit in bytes based on the PHP upload_max_filesize // and post_max_size function get_max_upload_size() { static $max_size = -1; if ($max_size < 0) { // Start with post_max_size. $max_size = parse_size(ini_get('post_max_size')); // If upload_max_size is less, then reduce. Except if upload_max_size is // zero, which indicates no limit. $upload_max = parse_size(ini_get('upload_max_filesize')); if ($upload_max > 0 && $upload_max < $max_size) { $max_size = $upload_max; } } return $max_size; } function parse_size($size) { $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size. $size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size. if ($unit) { // Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by. return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); } else { return round($size); } } function errorimage($text) { $width = 640; $height = 480; $image = imagecreatetruecolor($width, $height); imagefill($image, 0, 0, imagecolorallocate($image, 238, 232, 242)); // Set the background to #eee8f2 $fontwidth = imagefontwidth(3); imagetext($image, 3, ($width / 2) - (($fontwidth * strlen($text)) / 2), ($height / 2) - (imagefontheight(3) / 2), $text, imagecolorallocate($image, 17, 17, 17) // #111111 ); return $image; } function resize_image($image, $size) { $cur_width = imagesx($image); $cur_height = imagesy($image); if($cur_width < $size and $cur_height < $size) return $image; $width_ratio = $size / $cur_width; $height_ratio = $size / $cur_height; $ratio = min($width_ratio, $height_ratio); $new_height = floor($cur_height * $ratio); $new_width = floor($cur_width * $ratio); header("x-resize-to: $new_width x $new_height\n"); return imagescale($image, $new_width, $new_height); } ?>