hello Friends i am using the jquery file upload plugin to upload the files.when i upload the any file then it moves into a folder successfully and also file info into database.
but now i want to response back after successfully insertion into database.
And i also have always an error that is:Error SyntaxError: Unexpected token <
the image of error look like this:
and here is the function in which i am performing database insert query and moving image into folder.
protected function handle_file_upload($uploaded_file, $name, $size, $type, $error,
$index = null, $content_range = null) {
GLOBAL $con;
$time=time();
$folder_path="../../uploads/media/";
$rand=rand();
$user_id=$_SESSION['id'];
$file = new stdClass();
$file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error,
$index, $content_range);
$file->size = $this->fix_integer_overflow(intval($size));
$file->type = $type;
if ($this->validate($uploaded_file, $file, $error, $index)) {
$this->handle_form_data($file, $index);
$upload_dir = $this->get_upload_path();
if (!is_dir($upload_dir)) {
mkdir($upload_dir, $this->options['mkdir_mode'], true);
}
$file_path = $this->get_upload_path($file->name);
$append_file = $content_range && is_file($file_path) &&
$file->size > $this->get_file_size($file_path);
if ($uploaded_file && is_uploaded_file($uploaded_file)) {
// multipart/formdata uploads (POST method uploads)
if ($append_file) {
file_put_contents(
$file_path,
fopen($uploaded_file, 'r'),
FILE_APPEND
);
} else {
//move_uploaded_file($uploaded_file, $file_path);
////
$filename = date('YmdHis',$rand).$_SESSION['id'].$name;
$file_size=$size;
$file_size=$file_size/1000;
move_uploaded_file($uploaded_file,$folder_path.$filename);
mysqli_query($con,"insert into gallery(login_id,pic,timestamp,file_size,status)values('$user_id','$filename','$time','$file_size','1')");
$gallery_id=mysqli_insert_id($con);
////
}
} else {
// Non-multipart uploads (PUT method support)
file_put_contents(
$file_path,
fopen('php://input', 'r'),
$append_file ? FILE_APPEND : 0
);
}
$file_size = $this->get_file_size($file_path, $append_file);
if ($file_size === $file->size) {
$file->url = $this->get_download_url($file->name);
if ($this->is_valid_image_file($file_path)) {
$this->handle_image_file($file_path, $file);
}
} else {
$file->size = $file_size;
if (!$content_range && $this->options['discard_aborted_uploads']) {
unlink($file_path);
$file->error = $this->get_error_message('abort');
}
}
$this->set_additional_file_properties($file);
}
return $file;
}
now from the above function i want the response gallery_id
how can i remove this error and get response after the successfull file upload.
You are the genious people please help me and ask if something not clear.
Related
I am developing a module for my client to upload and browse file in Opencart.
when I am uploading file from my back-end server I am getting the output as file.zip.xyzasdf. Where I just want to remove this .xyzasdf
Can any one suggest me how to remove sanitize from the following code...
public function upload() {
$this->load->language('catalog/download');
$json = array();
// Check user has permission
if (!$this->user->hasPermission('modify', 'catalog/download')) {
$json['error'] = $this->language->get('error_permission');
}
if (!$json) {
if (!empty($this->request->files['file']['name']) && is_file($this->request->files['file']['tmp_name'])) {
// Sanitize the filename
$filename = basename(html_entity_decode($this->request->files['file']['name'], ENT_QUOTES, 'UTF-8'));
// Validate the filename length
if ((utf8_strlen($filename) < 3) || (utf8_strlen($filename) > 128)) {
$json['error'] = $this->language->get('error_filename');
}
// Allowed file extension types
$allowed = array();
$extension_allowed = preg_replace('~\r?\n~', "\n", $this->config->get('config_file_ext_allowed'));
$filetypes = explode("\n", $extension_allowed);
foreach ($filetypes as $filetype) {
$allowed[] = trim($filetype);
}
if (!in_array(strtolower(substr(strrchr($filename, '.'), 1)), $allowed)) {
$json['error'] = $this->language->get('error_filetype');
}
// Allowed file mime types
$allowed = array();
$mime_allowed = preg_replace('~\r?\n~', "\n", $this->config->get('config_file_mime_allowed'));
$filetypes = explode("\n", $mime_allowed);
foreach ($filetypes as $filetype) {
$allowed[] = trim($filetype);
}
if (!in_array($this->request->files['file']['type'], $allowed)) {
$json['error'] = $this->language->get('error_filetype');
}
// Check to see if any PHP files are trying to be uploaded
$content = file_get_contents($this->request->files['file']['tmp_name']);
if (preg_match('/\<\?php/i', $content)) {
$json['error'] = $this->language->get('error_filetype');
}
// Return any upload error
if ($this->request->files['file']['error'] != UPLOAD_ERR_OK) {
$json['error'] = $this->language->get('error_upload_' . $this->request->files['file']['error']);
}
} else {
$json['error'] = $this->language->get('error_upload');
}
}
if (!$json) {
$file = $filename . '.' . token(32);
move_uploaded_file($this->request->files['file']['tmp_name'], DIR_FOLDER . $file);
$json['filename'] = $file;
$json['mask'] = $filename;
$json['success'] = $this->language->get('text_upload');
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
Any help would be greatly appreciated...
Thanks
Removing the random string that is added to the filename is simple. Just change
move_uploaded_file($this->request->files['file']['tmp_name'], DIR_UPLOAD . $file);
to:
move_uploaded_file($this->request->files['file']['tmp_name'], DIR_UPLOAD . $filename);
But keep in mind that this will bring problems.
OpenCart saves the random string in the database at the time of file upload, so it will later use it to identify the file.
If you delete this feature, the uploaded files in the admin panel will not be available.
I use Imagick to count the number of pages in my PDF which is uploaded by the client except that my var_dump does not return any results.
Here is my prestashop code from my ProductController.php controller for uploading files.
class ProductController extends ProductControllerCore
{
const CUSTOMIZATION_FILE_DIR = 'customizations';
protected function pictureUpload()
{
if (!($field_ids = $this->product->getCustomizationFieldIds()))
return false;
$authorized_file_fields = array();
foreach ($field_ids AS $field_id)
{
if ($field_id['type'] == Product::CUSTOMIZE_FILE)
$authorized_file_fields[(int)$field_id['id_customization_field']] = 'file' . (int)$field_id['id_customization_field'];
}
$indexes = array_flip($authorized_file_fields);
foreach ($_FILES AS $field_name => $file)
{
if (in_array($field_name, $authorized_file_fields) AND isset($file['tmp_name']) AND !empty($file['tmp_name']))
{
// If there is an upload error, let the parent handle it
if ($file['error'] != UPLOAD_ERR_OK)
continue;
// If the file is not allowed, let the parent handle it
if (!$this->isUploadTypeAllowed($file))
continue;
// Unset the PDF to prevent the parent to handle this file
unset($_FILES[$field_name]);
// Create dir
mkdir(_PS_UPLOAD_DIR_ . ProductController::CUSTOMIZATION_FILE_DIR.'/'.$this->context->cart->id, 0777, true);
// Mark the file as a custom upload
$file_name = ProductController::CUSTOMIZATION_FILE_DIR.'/'.$this->context->cart->id.'/P'. md5(uniqid(rand(), true)).'.pdf';
$doc = exec("identify -format %n $file_name");
var_dump($doc);
$tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS');
if (!move_uploaded_file($file['tmp_name'], $tmp_name))
{
$this->errors[] = Tools::displayError('An error occurred during the PDF upload.');
return false;
}
// Copy file to the upload dir
if (!copy($tmp_name, _PS_UPLOAD_DIR_.$file_name))
{
$this->errors[] = Tools::displayError('An error occurred during the PDF upload.');
return false;
}
// Chmod the new file
if (!chmod(_PS_UPLOAD_DIR_.$file_name, 0777))
{
$this->errors[] = Tools::displayError('An error occurred during the PDF upload.');
return false;
}
// Create a fake thumb to avoid error on delete, this hack avoids lots of core method override
file_put_contents(_PS_UPLOAD_DIR_ . $file_name . '_small', '');
chmod(_PS_UPLOAD_DIR_ . $file_name . '_small', 0777);
// Register the file
$this->context->cart->addPictureToProduct($this->product->id, $indexes[$field_name], Product::CUSTOMIZE_FILE, $file_name);
// Remove tmp file
unlink($tmp_name);
}
}
return parent::pictureUpload();
}
protected function isUploadTypeAllowed($file)
{
/* Detect mime content type */
$mime_type = false;
$types = array('application/pdf', 'application/zip'); // Extra mime types can be added here
if (function_exists('finfo_open'))
{
$finfo = finfo_open(FILEINFO_MIME);
$mime_type = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
}
elseif (function_exists('mime_content_type'))
{
$mime_type = mime_content_type($file['tmp_name']);
}
elseif (function_exists('exec'))
{
$mime_type = trim(exec('file -b --mime-type '.escapeshellarg($file['tmp_name'])));
}
if (empty($mime_type) || $mime_type == 'regular file')
{
$mime_type = $file['type'];
}
if (($pos = strpos($mime_type, ';')) !== false)
$mime_type = substr($mime_type, 0, $pos);
// is it allowed?
return $mime_type && in_array($mime_type, $types);
}
}
Thank you.
I searched for solution to this the better part of the day and I'm still in the dark. For a client of mine I created a simple web gallery for uploading images and I'm using valums file uploader. Till now I didn't have any problems with it on any other site I created, except miss-configuration which I solved some time ago.
So, what is the problem?
When I upload a image with filesize below 260KB it works fine. But, when I'm uploading a bigger image, it doesn't throw me back any error. I just get an empty thumbnail, because image wasn't uploaded.
When I open Chrome Console, this is what I see:
POST http://designflowstudio.com/gallery2/include/upload.php?url=uploads%2Fe558c4dfc2a0f0d60f5ebff474c97ffc&fid=7&qqfile=316267269718409738080100.jpg 403 (Forbidden) fileuploader.js:1463
POST http://designflowstudio.com/gallery2/include/upload.php?url=uploads%2Fe558c4dfc2a0f0d60f5ebff474c97ffc&fid=7&qqfile=3.jpg 403 (Forbidden) fileuploader.js:1463
On some occasions I got 413 error "Request entity too large".
Let me say that this problem really annoys me because the script works well on my local web server (apache) and on my web server. Here I can upload as may and as big images as I can find, but on the client's web server...
If anyone have time and will to help me, here is the JavaScript that I use to call the valums uploader:
function createUploader(){
var uploader = new qq.FileUploaderBasic({
debug: true,
multiple: true,
allowedExtensions: [<?php $tmp=".";foreach($allowedExt as $ext){$tmp.="'$ext', ";}echo substr($tmp,1,strlen($tmp)-3);?>],
button: document.getElementById('uploadDiv'),
action: '<?php echo$home;?>include/upload.php',
sizeLimit: <?php echo$sizeLimit;?>,
forceMultipart: true,
params: {'url':'uploads/<?php echo$g['path'];?>','fid':'<?php echo$g['id'];?>'},
onSubmit: function(id, fName){$('#upload-list').append('<div id="upload-list-'+id+'" class="gallery" rel="'+fName+'"><div class="progress'+id+'"></div>');$('.progress'+id).progressbar({value:0})},
onProgress: function(id, fName, loaded, total){
var p = 0;
p = parseFloat(loaded/total*100);
if(isNaN(p)) p = '';
$('.progress'+id).progressbar("option","value",p);
},
onComplete: function(id,fName,json){
if(json.error){
$('#upload-list-'+id).html(fName+'<br />'+json.error);
}else{
$('#upload-list-'+id)
.attr("rel",json.fname)
.html('<img class="cmd" id="deleteImg" rel="'+json.id+'" src="<?php echo$home;?>images/delete.png" title="Delete picture" /><img class="img" src="<?php echo$home;?>uploads/<?php echo$g['path'];?>/th_'+json.fname+'" /><input class="ut" type="text" name="name" value="'+json.name+'" /><input class="ud" type="text" name="desc" /><div class="cl"></div>')
.attr("id",json.id);
}
},
onError: function(id,fName,error){
console.log(id+' '+fName+' '+error);
}
});
}
window.onload = createUploader;
And here is my PHP for server processing the file:
require("config.php");
require("SimpleImage.php");
ini_set("log_errors" , "1");
ini_set("error_log" , "php-errors-upload.log");
ini_set("display_errors" , "1");
/**
* Handle file uploads via XMLHttpRequest
*/
class qqUploadedFileXhr {
/**
* Save the file to the specified path
* #return boolean TRUE on success
*/
function save($path) {
$input = fopen("php://input", "r");
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
if ($realSize != $this->getSize()){
return false;
}
$target = fopen($path, "w");
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
return true;
}
function getName() {
return $_GET['qqfile'];
}
function getSize() {
if (isset($_SERVER["CONTENT_LENGTH"])){
return (int)$_SERVER["CONTENT_LENGTH"];
} else {
throw new Exception('Getting content length is not supported.');
}
}
}
/**
* Handle file uploads via regular form post (uses the $_FILES array)
*/
class qqUploadedFileForm {
/**
* Save the file to the specified path
* #return boolean TRUE on success
*/
function save($path) {
if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
return false;
}
return true;
}
function getName() {
return $_FILES['qqfile']['name'];
}
function getSize() {
return $_FILES['qqfile']['size'];
}
}
class qqFileUploader {
private $allowedExtensions = array();
private $sizeLimit = 20485760;
private $file;
function __construct(array $allowedExtensions = array(), $sizeLimit = 20485760){
$allowedExtensions = array_map("strtolower", $allowedExtensions);
$this->allowedExtensions = $allowedExtensions;
$this->sizeLimit = $sizeLimit;
$this->checkServerSettings();
if (isset($_GET['qqfile'])) {
$this->file = new qqUploadedFileXhr();
} elseif (isset($_FILES['qqfile'])) {
$this->file = new qqUploadedFileForm();
} else {
$this->file = false;
}
}
private function checkServerSettings(){
$postSize = $this->toBytes(ini_get('post_max_size'));
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
}
}
private function toBytes($str){
$val = trim($str);
$last = strtolower($str[strlen($str)-1]);
switch($last) {
case 'g': $val *= 1024;
case 'm': $val *= 1024;
case 'k': $val *= 1024;
}
return $val;
}
/**
* Returns array('success'=>true) or array('error'=>'error message')
*/
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
chdir("../");
if(!file_exists($uploadDirectory)){
foreach(explode("/",$uploadDirectory) as $val){
if(empty($val2)){$val2=$val."/";}else{$val2.=$val."/";}
if($val<>""){if(!file_exists($val2)){mkdir($val2);}}
}
}
if (!is_writable($uploadDirectory)){
return array('error' => "Server error. Upload directory isn't writable.");
}
if (!$this->file){
return array('error' => 'No files were uploaded.');
}
$size = $this->file->getSize();
if ($size == 0) {
return array('error' => 'File is empty');
}
if ($size > $this->sizeLimit) {
return array('error' => 'File is too large');
}
$pathinfo = pathinfo($this->file->getName());
$filename = md5($pathinfo['filename'].mt_rand());
//$filename = md5(uniqid());
$ext = strtolower($pathinfo['extension']);
if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
$these = implode(', ', $this->allowedExtensions);
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
}
if(!$replaceOldFile){
/// don't overwrite previous files that were uploaded
while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
$filename .= rand(10, 99);
}
}
if ($this->file->save($uploadDirectory .'/'. $filename . '.' . $ext)){
global $sql_images;
$md=md5($filename);
$tmp=mysql_query("SELECT `order` FROM `$sql_images` WHERE `gid`='{$_REQUEST['fid']}' ORDER BY `order` DESC");
if($tmp&&mysql_num_rows($tmp)>0){$i=mysql_result($tmp,0);$i++;}else{$i=0;}
mysql_query("INSERT INTO `$sql_images` (`order`,`gid`,`name`,`path`) VALUES ('$i','{$_REQUEST['fid']}','{$pathinfo['filename']}','$filename.$ext')");
$image = new SimpleImage();
$image->load($uploadDirectory.'/'.$filename.'.'.$ext);
$image->resizeToWidth(150);
$image->save($uploadDirectory.'/th_'.$filename.'.'.$ext);
return array('success'=>true,'fname'=>$filename.".".$ext,'name'=>$pathinfo['filename'],'id'=>mysql_insert_id());
} else {
return array('error'=> 'Could not save uploaded file.' .
'The upload was cancelled, or server error encountered');
}
}
}
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
$allowedExtensions = array();
// max file size in bytes
$sizeLimit = 20*1024*1024;
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
$result = $uploader->handleUpload($_REQUEST['url']);
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
Let me say again, all the calls to MySQL, files with require() are valid. The scripts work on two other servers, but on this one, not.
Thank you for your time and will to help.
You have some configuration issues on your server if it is choking due to the content-type header. Instead of commenting out this line, to work around this messed up server, you should perhaps try to set the forceMultipart option to true, assuming your server can handle multipart-encoded requests correctly. This all assumes you are using the 2.1-SNAPSHOT version of the uploader, as the option I mentioned first appeared in this version.
I've been doing research on image file upload security for a while but can't seem to crack it. I want to add some security to the fantastic Valums Ajax Uploader by checking whether or not a file is actually an image before saving to a server. The only extensions allowed are .jpg, .png and .gif, which of course the extensions are checked but I'm looking to validate it's an image file via GD processing. I know very little about this subject so I'm taking cues from this and this post. As it stands now, I can easily save a random file with an image extension and it will be saved the server, which I want to prevent. Here is the script I've come up with thus far, which I've added to the handleUpload function in the php.php file. Unfortunately the result is that it returns an error no matter what file I upload, valid image or not. Please excuse my utter newbishness.
$newIm = #imagecreatefromjpeg($uploadDirectory . $filename . '.' . $ext);
$newIm2 = #imagecreatefrompng($uploadDirectory . $filename . '.' . $ext);
$newIm3 = #imagecreatefromgif($uploadDirectory . $filename . '.' . $ext);
if (!$newIm && !$newIm2 && !$newIm3) {
return array('error' => 'File is not an image. Please try again');
}else{
imagedestroy($newIm);
imagedestroy($newim2);
imagedestroy($newIm3);
}
Here's most of my php.php file. By the way, my files are not being submitted via a regular form but by the default uploader:
class qqUploadedFileXhr {
/**
* Save the file to the specified path
* #return boolean TRUE on success
*/
function save($path) {
$input = fopen("php://input", "r");
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
if ($realSize != $this->getSize()){
return false;
}
$target = fopen($path, "w");
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
return true;
}
function getName() {
return $_GET['qqfile'];
}
function getSize() {
if (isset($_SERVER["CONTENT_LENGTH"])){
return (int)$_SERVER["CONTENT_LENGTH"];
} else {
throw new Exception('Getting content length is not supported.');
}
}
}
/**
* Handle file uploads via regular form post (uses the $_FILES array)
*/
class qqUploadedFileForm {
/**
* Save the file to the specified path
* #return boolean TRUE on success
*/
function save($path) {
if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
return false;
}
return true;
}
function getName() {
return $_FILES['qqfile']['name'];
}
function getSize() {
return $_FILES['qqfile']['size'];
}
}
class qqFileUploader {
private $allowedExtensions = array();
private $sizeLimit = 2097152;
private $file;
function __construct(array $allowedExtensions = array(), $sizeLimit = 2097152){
$allowedExtensions = array_map("strtolower", $allowedExtensions);
$this->allowedExtensions = $allowedExtensions;
$this->sizeLimit = $sizeLimit;
$this->checkServerSettings();
if (isset($_GET['qqfile'])) {
$this->file = new qqUploadedFileXhr();
} elseif (isset($_FILES['qqfile'])) {
$this->file = new qqUploadedFileForm();
} else {
$this->file = false;
}
}
private function checkServerSettings(){
$postSize = $this->toBytes(ini_get('post_max_size'));
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
}
}
private function toBytes($str){
$val = trim($str);
$last = strtolower($str[strlen($str)-1]);
switch($last) {
case 'g': $val *= (1024 * 1024 * 1024);
case 'm': $val *= (1024 * 1024);
case 'k': $val *= 1024;
}
return $val;
}
/**
* Returns array('success'=>true) or array('error'=>'error message')
*/
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
if (!is_writable($uploadDirectory)){
return array('error' => "Server error. Upload directory isn't writable.");
}
if (!$this->file){
return array('error' => 'No files were uploaded.');
}
$size = $this->file->getSize();
if ($size == 0) {
return array('error' => 'File is empty');
}
if ($size > $this->sizeLimit) {
return array('error' => 'File is too large, please upload files that are less than 2MB');
}
$pathinfo = pathinfo($this->file->getName());
$filename = $pathinfo['filename'];
//$filename = md5(uniqid());
$ext = $pathinfo['extension'];
if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
$these = implode(', ', $this->allowedExtensions);
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
}
if(!$replaceOldFile){
/// don't overwrite previous files that were uploaded
while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
$filename .= rand(10, 99);
}
}
$newIm = #imagecreatefromjpeg($uploadDirectory . $filename . '.' . $ext);
$newIm2 = #imagecreatefrompng($uploadDirectory . $filename . '.' . $ext);
$newIm3 = #imagecreatefromgif($uploadDirectory . $filename . '.' . $ext);
if (!$newIm && !$newIm2 && !$newIm3) {
return array('error' => 'File is not an image. Please try again');
}else{
imagedestroy($newIm);
imagedestroy($newim2);
imagedestroy($newIm3);
}
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
// At this point you could use $result to do resizing of images or similar operations
if(strtolower($ext) == 'jpg' || strtolower($ext) == 'jpeg' || strtolower($ext) == 'gif' || strtolower($ext) == 'png'){
$imgSize=getimagesize($uploadDirectory . $filename . '.' . $ext);
if($imgSize[0] > 100 || $imgSize[1]> 100){
$thumbcheck = make_thumb($uploadDirectory . $filename . '.' . $ext,$uploadDirectory . "thumbs/" . $filename ."_thmb" . '.' . $ext,100,100);
if($thumbcheck == "true"){
$thumbnailPath = $uploadDirectory . "thumbs/" . $filename ."_thmb". '.' . $ext;
}
}else{
$this->file->save($uploadDirectory . "thumbs/" . $filename ."_thmb" . '.' . $ext);
$thumbnailPath = $uploadDirectory . "thumbs/" . $filename ."_thmb". '.' . $ext;
}
if($imgSize[0] > 500 || $imgSize[1] > 500){
resize_orig($uploadDirectory . $filename . '.' . $ext,$uploadDirectory . $filename . '.' . $ext,500,500);
$imgPath = $uploadDirectory . $filename . '.' . $ext;
$newsize = getimagesize($imgPath);
$imgWidth = ($newsize[0]+30);
$imgHeight = ($newsize[1]+50);
}else{
$imgPath = $uploadDirectory . $filename . '.' . $ext;
$newsize = getimagesize($imgPath);
$imgWidth = ($newsize[0]+30);
$imgHeight = ($newsize[1]+50);
}
}
return array('success'=>true,
'thumbnailPath'=>$thumbnailPath,
'imgPath'=>$imgPath,
'imgWidth'=>$imgWidth,
'imgHeight'=>$imgHeight
);
} else {
return array('error'=> 'Could not save uploaded file.' .
'The upload was cancelled, or server error encountered');
}
}
}
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
$allowedExtensions = array();
// max file size in bytes
$sizeLimit = 2097152;
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
$result = $uploader->handleUpload('uploads/');
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
If someone can point me in the right direction about what I'm doing wrong, it would be most appreciated.
Edit:
Thanks Mark B for the help and clarification. So the new code (which I pasted in the same location as the old, the handleUpload function) is still throwing an error no matter what I upload, so I wonder if it needs to be in a different place -- I'm just not sure where to put it.
$newIm = getimagesize($uploadDirectory . $filename . '.' . $ext);
if ($newIm === FALSE) {
return array('error' => 'File is not an image. Please try again');
}
Second Edit:
I believe the answer is here, still trying to implement it.
Just use getimagesize():
$newIm = getimagesize$uploadDirectory . $filename . '.' . $ext');
if ($newIm === FALSE) {
die("Hey! what are you trying to pull?");
}
The problem with your code is the 3 imagecreate calls and subsequent if() statement. It should have been written as an OR clause. "if any of the image load attempts fail, then complain". Yours is written as "if all image attempts fail", which is not possible if a gif/jpg/png actually was uploaded.
The answer detailed here works like a charm, I wish I had seen it before posting. I hope I implemented it correctly...as I have it, it works!
class qqUploadedFileXhr {
/**
* Save the file to the specified path
* #return boolean TRUE on success
*/
function save($path) {
// Store the file in tmp dir, to validate it before storing it in destination dir
$input = fopen('php://input', 'r');
$tmpPath = tempnam(sys_get_temp_dir(), 'upload'); // upl is 3-letter prefix for upload
$tmpStream = fopen($tmpPath, 'w'); // For writing it to tmp dir
$realSize = stream_copy_to_stream($input, $tmpStream);
fclose($input);
fclose($tmpStream);
if ($realSize != $this->getSize()){
return false;
}
$newIm = getimagesize($tmpPath);
if ($newIm === FALSE) {
return false;
}else{
// Store the file in destination dir, after validation
$pathToFile = $path . $filename;
$destination = fopen($pathToFile, 'w');
$tmpStream = fopen($tmpPath, 'r'); // For reading it from tmp dir
stream_copy_to_stream($tmpStream, $destination);
fclose($destination);
fclose($tmpStream);
return true;
}
}
function getName() {
return $_GET['qqfile'];
}
function getSize() {
if (isset($_SERVER["CONTENT_LENGTH"])){
return (int)$_SERVER["CONTENT_LENGTH"];
} else {
throw new Exception('Getting content length is not supported.');
}
}
}
I would kindly ask all of you if you could help me. I'm working in zend framework and I need to adjust my code so, when a user
drops the file in the browser(before the actual upload), the file name and extension is checked in a sense if it already exists. Depending on the existence of the ifle, an
icon right by the trash icon will appear (green tick if fresh upload, no other file with the same name. Red cross if there is a file).
But to address a matter that is more important to me, and that is for me to set up the code in a manner so when uploading depending on the file name and file extension, the file is being uploaded in a specific folder. So e.g. an X.png, gets into a "png" folder - subfolder "X", and Y.pdf gets into a "pdf" folder - subfolder "Y"
Here is my code do far...
This is the application.js and the jquery.fileupload-ui.js. (javascript)
http://pastebin.com/eqpK1KmX
This is the index.phtml and the layout of the index.phtml (view)
http://pastebin.com/mh5jnLju
InterfaceController.php (controller):
<?php
class Design_InterfaceController extends Zend_Controller_Action
{
public function init()
{
$this->_helper->layout()->setLayout('media');
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/modules/design/models'),
realpath(APPLICATION_PATH . '/models'),
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
}
public function indexAction()
{
}
public function mediaAction()
{
$this->_helper->layout()->setLayout('media');
}
public function checkFile(){
//isn't doing anything at all, just my start of thinking in a way of
//sloving this
}
function uploadjqAction()
{
$this->_helper->layout()->setLayout('media');
Zend_Loader::loadClass('Upload',
array(
APPLICATION_PATH.'/modules/design/models/vendors'
)
);
$upload_handler = new Upload();
header('Pragma: no-cache');
header('Cache-Control: private, no-cache');
header('Content-Disposition: inline; filename="files.json"');
header('X-Content-Type-Options: nosniff');
switch ($_SERVER['REQUEST_METHOD']) {
case 'HEAD':
case 'GET':
$upload_handler->get();
break;
case 'POST':
$upload_handler->post();
break;
case 'DELETE':
$upload_handler->delete();
break;
case 'OPTIONS':
break;
default:
header('HTTP/1.0 405 Method Not Allowed');
}
exit;
}
}
This is the upload.php (acting as a model):
<?php
/*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://creativecommons.org/licenses/MIT/
*/
error_reporting(E_ALL | E_STRICT);
class Upload
{
/* public function uploadAction() {
ini_set("max_execution_time", 10000);
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = STORAGE_PATH.'/books/' . $_POST['bookid'] . '/' . $_POST['folder'];
$targetFile = str_replace('//','/',$targetPath) . "/".$_POST['name'].".".$_POST['ext'];
if (!file_exists(str_replace('//','/',$targetPath))) mkdir(str_replace('//','/',$targetPath), 0755, true);
$result = move_uploaded_file($tempFile,$targetFile);
echo ($result)?"Success":"Fail";
}
}
*/
private $options;
function __construct($options=null) {
$this->options = array(
'script_url' => $_SERVER['PHP_SELF'],
'upload_dir' => dirname(__FILE__).'/vendors/files/',
'upload_url' => dirname($_SERVER['PHP_SELF']).'/vendors/files/',
'param_name' => 'files',
// The php.ini settings upload_max_filesize and post_max_size
// take precedence over the following max_file_size setting:
'max_file_size' => 10000000,
'min_file_size' => 1,
'accept_file_types' =>'/(\.|\/)(gif|jpeg|jpg|png|pdf)$/i',
'max_number_of_files' => null,
'discard_aborted_uploads' => true,
'image_versions' => array(
'thumbnail' => array(
'upload_dir' => dirname(__FILE__).'/vendors/thumbnails/',
'upload_url' => dirname($_SERVER['PHP_SELF']).'/vendors/thumbnails/',
'max_width' => 80,
'max_height' => 150
)
)
);
if ($options) {
$this->options = array_replace_recursive($this->options, $options);
}
}
private function get_file_object($file_name) {
$file_path = $this->options['upload_dir'].$file_name;
if (is_file($file_path) && $file_name[0] !== '.') {
$file = new stdClass();
$file->name = $file_name;
$file->size = filesize($file_path);
$file->url = $this->options['upload_url'].rawurlencode($file->name);
foreach($this->options['image_versions'] as $version => $options) {
if (is_file($options['upload_dir'].$file_name)) {
$file->{$version.'_url'} = $options['upload_url']
.rawurlencode($file->name);
}
}
$file->delete_url = $this->options['script_url']
.'?file='.rawurlencode($file->name);
$file->delete_type = 'DELETE';
return $file;
}
return null;
}
private function get_file_objects() {
return array_values(array_filter(array_map(
array($this, 'get_file_object'),
scandir($this->options['upload_dir'])
)));
}
private function create_scaled_image($file_name, $options) {
$file_path = $this->options['upload_dir'].$file_name;
$new_file_path = $options['upload_dir'].$file_name;
list($img_width, $img_height) = #getimagesize($file_path);
if (!$img_width || !$img_height) {
return false;
}
$scale = min(
$options['max_width'] / $img_width,
$options['max_height'] / $img_height
);
if ($scale > 1) {
$scale = 1;
}
$new_width = $img_width * $scale;
$new_height = $img_height * $scale;
$new_img = #imagecreatetruecolor($new_width, $new_height);
switch (strtolower(substr(strrchr($file_name, '.'), 1))) {
case 'jpg':
case 'jpeg':
$src_img = #imagecreatefromjpeg($file_path);
$write_image = 'imagejpeg';
break;
case 'gif':
#imagecolortransparent($new_img, #imagecolorallocate($new_img, 0, 0, 0));
$src_img = #imagecreatefromgif($file_path);
$write_image = 'imagegif';
break;
case 'png':
#imagecolortransparent($new_img, #imagecolorallocate($new_img, 0, 0, 0));
#imagealphablending($new_img, false);
#imagesavealpha($new_img, true);
$src_img = #imagecreatefrompng($file_path);
$write_image = 'imagepng';
break;
default:
$src_img = $image_method = null;
}
$success = $src_img && #imagecopyresampled(
$new_img,
$src_img,
0, 0, 0, 0,
$new_width,
$new_height,
$img_width,
$img_height
) && $write_image($new_img, $new_file_path);
// Free up memory (imagedestroy does not delete files):
#imagedestroy($src_img);
#imagedestroy($new_img);
return $success;
}
private function has_error($uploaded_file, $file, $error) {
if ($error) {
return $error;
}
if (!preg_match($this->options['accept_file_types'], $file->name)) {
return 'acceptFileTypes';
}
if ($uploaded_file && is_uploaded_file($uploaded_file)) {
$file_size = filesize($uploaded_file);
} else {
$file_size = $_SERVER['CONTENT_LENGTH'];
}
if ($this->options['max_file_size'] && (
$file_size > $this->options['max_file_size'] ||
$file->size > $this->options['max_file_size'])
) {
return 'maxFileSize';
}
if ($this->options['min_file_size'] &&
$file_size < $this->options['min_file_size']) {
return 'minFileSize';
}
if (is_int($this->options['max_number_of_files']) && (
count($this->get_file_objects()) >= $this->options['max_number_of_files'])
) {
return 'maxNumberOfFiles';
}
return $error;
}
private function handle_file_upload($uploaded_file, $name, $size, $type, $error) {
$file = new stdClass();
// Remove path information and dots around the filename, to prevent uploading
// into different directories or replacing hidden system files.
// Also remove control characters and spaces (\x00..\x20) around the filename:
$file->name = trim(basename(stripslashes($name)), ".\x00..\x20");
$file->size = intval($size);
$file->type = $type;
$error = $this->has_error($uploaded_file, $file, $error);
if (!$error && $file->name) {
$file_path = $this->options['upload_dir'].$file->name;
$append_file = !$this->options['discard_aborted_uploads'] &&
is_file($file_path) && $file->size > filesize($file_path);
clearstatcache();
if ($uploaded_file && is_uploaded_file($uploaded_file)) {
// multipart/formdata uploads (POST method uploads)
if ($append_file) {
file_put_contents(
$file_path,
fopen($uploaded_file, 'r'),
FILE_APPEND
);
} else {
move_uploaded_file($uploaded_file, $file_path);
}
} else {
// Non-multipart uploads (PUT method support)
file_put_contents(
$file_path,
fopen('php://input', 'r'),
$append_file ? FILE_APPEND : 0
);
}
$file_size = filesize($file_path);
if ($file_size === $file->size) {
$file->url = $this->options['upload_url'].rawurlencode($file->name);
foreach($this->options['image_versions'] as $version => $options) {
if ($this->create_scaled_image($file->name, $options)) {
$file->{$version.'_url'} = $options['upload_url']
.rawurlencode($file->name);
}
}
} else if ($this->options['discard_aborted_uploads']) {
unlink($file_path);
$file->error = 'abort';
}
$file->size = $file_size;
$file->delete_url = $this->options['script_url']
.'?file='.rawurlencode($file->name);
$file->delete_type = 'DELETE';
} else {
$file->error = $error;
}
return $file;
}
public function get() {
$file_name = isset($_REQUEST['file']) ?
basename(stripslashes($_REQUEST['file'])) : null;
if ($file_name) {
$info = $this->get_file_object($file_name);
} else {
$info = $this->get_file_objects();
}
header('Content-type: application/json');
echo json_encode($info);
}
public function post() {
$upload = isset($_FILES[$this->options['param_name']]) ?
$_FILES[$this->options['param_name']] : array(
'tmp_name' => null,
'name' => null,
'size' => null,
'type' => null,
'error' => null
);
$info = array();
if (is_array($upload['tmp_name'])) {
foreach ($upload['tmp_name'] as $index => $value) {
$info[] = $this->handle_file_upload(
$upload['tmp_name'][$index],
isset($_SERVER['HTTP_X_FILE_NAME']) ?
$_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index],
isset($_SERVER['HTTP_X_FILE_SIZE']) ?
$_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'][$index],
isset($_SERVER['HTTP_X_FILE_TYPE']) ?
$_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'][$index],
$upload['error'][$index]
);
}
} else {
$info[] = $this->handle_file_upload(
$upload['tmp_name'],
isset($_SERVER['HTTP_X_FILE_NAME']) ?
$_SERVER['HTTP_X_FILE_NAME'] : $upload['name'],
isset($_SERVER['HTTP_X_FILE_SIZE']) ?
$_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'],
isset($_SERVER['HTTP_X_FILE_TYPE']) ?
$_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'],
$upload['error']
);
}
header('Vary: Accept');
if (isset($_SERVER['HTTP_ACCEPT']) &&
(strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
header('Content-type: application/json');
} else {
header('Content-type: text/plain');
}
echo json_encode($info);
}
public function delete() {
$file_name = isset($_REQUEST['file']) ?
basename(stripslashes($_REQUEST['file'])) : null;
$file_path = $this->options['upload_dir'].$file_name;
$success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
if ($success) {
foreach($this->options['image_versions'] as $version => $options) {
$file = $options['upload_dir'].$file_name;
if (is_file($file)) {
unlink($file);
}
}
}
header('Content-type: application/json');
echo json_encode($success);
}
}
?>
If anyone is willing to help, I would be very very grateful, I know it a lot of work, I'm a noob and I need all the help I can get.
Thank you in advance! and please don't get mad at me.
A few general comments.
Typically, the include_path setting is done at Bootstrap, not in the controller.
I would clearly separate in my mind what happens on the server side and what happens on the client side.
First, think of it first as a standard form submission. The form has a file element, the user browses his file system to select his file. He clicks submit. It either succeeds or fails. All the dragging and dropping and changing icons is pure client-side candy to be added after you have the core functionality in place.
So, I would create a form that has a standard file element. To that element, I would attach a custom validator that performs your specific directory/filename checks. In the event of a valid submission, you employ a model/service that moves the file to the right place, writes your db records, etc.
Then I would layer on some AJAX handling. Client-side script intercepts the form's submit event and you use an AjaxContext action helper on the server side to send back JSON responses. These responses are handled by client-side code that renders your ok/fail icons.
Finally, I would layer on the client-side drag/drop functionality to trigger the submit event.
The benefits:
It clearly delineate server-side and client-side issues.
It breaks the overall job into a targeted collection of well-defined tasks.
Progressive enhancement/graceful degradation.
Seems more consistent with the ZF way of handling form submissions in controllers (create form with validators, check isValid(), process successful submission).
I recognize that this is only broad brush-strokes, but I hope it helps to clarify some thinking.