mirror of
https://github.com/godotengine/godot-question2answer.git
synced 2026-01-01 01:48:37 +03:00
This project lived only on the server without version control. This is now the starting point for the repository.
212 lines
6.9 KiB
PHP
212 lines
6.9 KiB
PHP
<?php
|
|
/*
|
|
Question2Answer by Gideon Greenspan and contributors
|
|
http://www.question2answer.org/
|
|
|
|
Description: Application-level file upload functionality
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
More about this license: http://www.question2answer.org/license.php
|
|
*/
|
|
|
|
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
|
|
header('Location: ../../');
|
|
exit;
|
|
}
|
|
|
|
|
|
/**
|
|
* Return the maximum size of file that can be uploaded, based on database and PHP limits
|
|
*/
|
|
function qa_get_max_upload_size()
|
|
{
|
|
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
|
|
|
|
$mindb = 16777215; // from MEDIUMBLOB column type
|
|
|
|
$minphp = trim(ini_get('upload_max_filesize'));
|
|
$minphp = convert_to_bytes(substr($minphp, -1), $minphp);
|
|
|
|
return min($mindb, $minphp);
|
|
}
|
|
|
|
|
|
/**
|
|
* Move an uploaded image or other file into blob storage. Pass the $localfilename where the file is currently stored
|
|
* (temporarily) and the $sourcefilename of the file on the user's computer (if using PHP's usual file upload
|
|
* mechanism, these are obtained from $_FILES[..]['tmp_name'] and $_FILES[..]['name'] fields respectively). To apply a
|
|
* maximum file size (in bytes) beyond the general one, use $maxfilesize, otherwise set it to null. Set $onlyimage to
|
|
* true if only image uploads (PNG, GIF, JPEG) are allowed. To apply a maximum width or height (in pixels) to uploaded
|
|
* images, set $imagemaxwidth and $imagemaxheight. The function returns an array which may contain the following elements:
|
|
*
|
|
* 'error' => a string containing an error, if one occurred
|
|
* 'format' => the format (file extension) of the blob created (all scaled images end up as 'jpg')
|
|
* 'width' => if an image, the width in pixels of the blob created (after possible scaling)
|
|
* 'height' => if an image, the height in pixels of the blob created (after possible scaling)
|
|
* 'blobid' => the blobid that was created (if there was no error)
|
|
* 'bloburl' => the url that can be used to view/download the created blob (if there was no error)
|
|
* @param $localfilename
|
|
* @param $sourcefilename
|
|
* @param $maxfilesize
|
|
* @param bool $onlyimage
|
|
* @param $imagemaxwidth
|
|
* @param $imagemaxheight
|
|
* @return array
|
|
*/
|
|
function qa_upload_file($localfilename, $sourcefilename, $maxfilesize = null, $onlyimage = false, $imagemaxwidth = null, $imagemaxheight = null)
|
|
{
|
|
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
|
|
|
|
$result = array();
|
|
|
|
// Check per-user upload limits
|
|
|
|
require_once QA_INCLUDE_DIR . 'app/users.php';
|
|
require_once QA_INCLUDE_DIR . 'app/limits.php';
|
|
|
|
switch (qa_user_permit_error(null, QA_LIMIT_UPLOADS)) {
|
|
case 'limit':
|
|
$result['error'] = qa_lang('main/upload_limit');
|
|
return $result;
|
|
|
|
case false:
|
|
qa_limits_increment(qa_get_logged_in_userid(), QA_LIMIT_UPLOADS);
|
|
break;
|
|
|
|
default:
|
|
$result['error'] = qa_lang('users/no_permission');
|
|
return $result;
|
|
}
|
|
|
|
// Check the uploaded file is not too large
|
|
|
|
$filesize = filesize($localfilename);
|
|
if (isset($maxfilesize))
|
|
$maxfilesize = min($maxfilesize, qa_get_max_upload_size());
|
|
else
|
|
$maxfilesize = qa_get_max_upload_size();
|
|
|
|
if ($filesize <= 0 || $filesize > $maxfilesize) { // if file was too big for PHP, $filesize will be zero
|
|
$result['error'] = qa_lang_sub('main/max_upload_size_x', qa_format_number($maxfilesize / pow(1024, 2), 1) . 'MB');
|
|
return $result;
|
|
}
|
|
|
|
// Find out what type of source file was uploaded and if appropriate, check it's an image and get preliminary size measure
|
|
|
|
$pathinfo = pathinfo($sourcefilename);
|
|
$format = strtolower(@$pathinfo['extension']);
|
|
$isimage = in_array($format, array('png', 'gif', 'jpeg', 'jpg')); // allowed image extensions
|
|
|
|
if ($isimage) {
|
|
$imagesize = @getimagesize($localfilename);
|
|
|
|
if (is_array($imagesize)) {
|
|
$result['width'] = $imagesize[0];
|
|
$result['height'] = $imagesize[1];
|
|
|
|
switch ($imagesize['2']) { // reassign format based on actual content, if we can
|
|
case IMAGETYPE_GIF:
|
|
$format = 'gif';
|
|
break;
|
|
|
|
case IMAGETYPE_JPEG:
|
|
$format = 'jpg';
|
|
break;
|
|
|
|
case IMAGETYPE_PNG:
|
|
$format = 'png';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$result['format'] = $format;
|
|
|
|
if ($onlyimage) {
|
|
if (!$isimage || !is_array($imagesize)) {
|
|
$result['error'] = qa_lang_sub('main/image_not_read', 'GIF, JPG, PNG');
|
|
return $result;
|
|
}
|
|
}
|
|
|
|
// Read in the raw file contents
|
|
|
|
$content = file_get_contents($localfilename);
|
|
|
|
// If appropriate, get more accurate image size and apply constraints to it
|
|
|
|
require_once QA_INCLUDE_DIR . 'util/image.php';
|
|
|
|
if ($isimage && qa_has_gd_image()) {
|
|
$image = @imagecreatefromstring($content);
|
|
|
|
if (is_resource($image)) {
|
|
$result['width'] = $width = imagesx($image);
|
|
$result['height'] = $height = imagesy($image);
|
|
|
|
if (isset($imagemaxwidth) || isset($imagemaxheight)) {
|
|
if (qa_image_constrain(
|
|
$width, $height,
|
|
isset($imagemaxwidth) ? $imagemaxwidth : $width,
|
|
isset($imagemaxheight) ? $imagemaxheight : $height
|
|
)) {
|
|
qa_gd_image_resize($image, $width, $height);
|
|
|
|
if (is_resource($image)) {
|
|
$content = qa_gd_image_jpeg($image);
|
|
$result['format'] = $format = 'jpg';
|
|
$result['width'] = $width;
|
|
$result['height'] = $height;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_resource($image)) // might have been lost
|
|
imagedestroy($image);
|
|
}
|
|
}
|
|
|
|
// Create the blob and return
|
|
|
|
require_once QA_INCLUDE_DIR . 'app/blobs.php';
|
|
|
|
$userid = qa_get_logged_in_userid();
|
|
$cookieid = isset($userid) ? qa_cookie_get() : qa_cookie_get_create();
|
|
$result['blobid'] = qa_create_blob($content, $format, $sourcefilename, $userid, $cookieid, qa_remote_ip_address());
|
|
|
|
if (!isset($result['blobid'])) {
|
|
$result['error'] = qa_lang('main/general_error');
|
|
return $result;
|
|
}
|
|
|
|
$result['bloburl'] = qa_get_blob_url($result['blobid'], true);
|
|
|
|
return $result;
|
|
}
|
|
|
|
|
|
/**
|
|
* In response to a file upload, move the first uploaded file into blob storage. Other parameters are as for qa_upload_file(...)
|
|
* @param $maxfilesize
|
|
* @param bool $onlyimage
|
|
* @param $imagemaxwidth
|
|
* @param $imagemaxheight
|
|
* @return array
|
|
*/
|
|
function qa_upload_file_one($maxfilesize = null, $onlyimage = false, $imagemaxwidth = null, $imagemaxheight = null)
|
|
{
|
|
$file = reset($_FILES);
|
|
|
|
return qa_upload_file($file['tmp_name'], $file['name'], $maxfilesize, $onlyimage, $imagemaxwidth, $imagemaxheight);
|
|
}
|