I have a email script that sends file trough attachment from server. The email is sent using phpmailer and the attached file is attached in code like this:
$_img = (object) ($img);
if (!empty($_img->src)) {
$ext = substr($_img->src, -3);
$imginfo_array = getimagesize($_img->src);
$mime_type = $imginfo_array['mime'];
switch($mime_type) {
case "image/jpeg":
$type = "image/jpeg";
break;
case "image/png":
$type = "image/png";
break;
case "image/gif":
$type = "image/gif";
break;
}
$string = file_get_contents($_img->src);
$mail->AddStringAttachment($string, $i . '.' . $ext, 'base64', $type);
}
The problem occurs when a image is not properly saved before adding it to server. If one user decides that the file 'test.jpg' shoul be 'test.png' the attached file will not be visible via email.
The $_img->src is a file saved on server.
I am trying to check for mime type but still with no success.
I want to be able to tell the script that the correct file type is the one auto detected not determined by the extension.
Could someone give me a clue about how this could be done?
$_img = (object) ($img);
if (!empty($_img->src)) {
//$ext = substr($_img->src, -3);
// better solution for get file extension (with variable length: "jpeg" or "jpeg")
$ext = pathinfo($_img->src, PATHINFO_EXTENSION);
$imginfo_array = getimagesize($_img->src);
$mime_type = $imginfo_array['mime'];
switch($mime_type) {
case "image/jpeg":
$type = "image/jpeg";
$ext = 'jpg';
break;
case "image/png":
$type = "image/png";
$ext = 'png';
break;
case "image/gif":
$type = "image/gif";
$ext = 'gif';
break;
// fix for others mime type
default:
$type = "application/octet-stream";
}
// for binary file use AddAttachment()
//$string = file_get_contents($_img->src);
//$mail->AddStringAttachment($string, $i . '.' . $ext, 'base64', $type);
// I hope that the variable $i is set from previous code
$mail->AddAttachment($_img->src, $i . '.' . $ext, 'base64', $type)
}
You can detect the type of the image with the IMAGETYPE_XXX constants at index 2 of the returned imginfo_array. The returned mime field you are using is much less reliable.
See documentation:
http://php.net/manual/en/function.getimagesize.php
Type contants:
http://php.net/manual/en/image.constants.php
Related
I'm using this piece of code to handle an input for uploading multiple images, and resizing them as well. It works but there is one small thing that doesn't want to do its job. The extension that I'm trying to get is not showing up in the file's name.
Here is the piece of code where the problem should be:
if(isset($_POST["submit"])) {
if(is_array($_FILES)) {
foreach ($_FILES['fileToUpload']['tmp_name'] as $uploadedFile) {
//$uploadedFile = $_FILES['fileToUpload']['tmp_name'];
if($uploadedFile <> ''){
$sourceProperties = getimagesize($uploadedFile);
$newFileName = time();
$dirPath = "../images/";
$ext = pathinfo($_FILES['fileToUpload']['name'], PATHINFO_EXTENSION);
$imageType = $sourceProperties[2];
switch ($imageType) {
case IMAGETYPE_PNG:
$imageSrc = imagecreatefrompng($uploadedFile);
$tmp = imageResize($imageSrc,$sourceProperties[0],$sourceProperties[1]);
imagepng($tmp,$dirPath. $newFileName. "_thump.". $ext);
break;
case IMAGETYPE_JPEG:
$imageSrc = imagecreatefromjpeg($uploadedFile);
$tmp = imageResize($imageSrc,$sourceProperties[0],$sourceProperties[1]);
imagejpeg($tmp,$dirPath. $newFileName. "_thump.". $ext);
break;
case IMAGETYPE_GIF:
$imageSrc = imagecreatefromgif($uploadedFile);
$tmp = imageResize($imageSrc,$sourceProperties[0],$sourceProperties[1]);
imagegif($tmp,$dirPath. $newFileName. "_thump.". $ext);
break;
default:
echo "<div class='alert alert-danger'>File is not an image.</div>";
exit;
break;
}
}
}
}
}
For an example, something it is now saving is called 1547265041_thump. in my database.
What is going wrong?
Check $ext getting extension or not.
If it not getting check $_FILES['fileToUpload']['name'] reading or not.
You can debug by echo them.
Check you database character length.
Hope it helps.
The $_FILES['fileToUpload']['name'] seems to be an array, which is logical since you can upload multiple images at once. To loop through, I added a counter to the foreach to output the extension. Now it works well!
I'm running a localhost mysql server with PhpMyAdmin version 4.2. I created a table with a MEDIUMBLOB column to store file. I can upload *.doc files correctly, but when I click the file link, it downloads it as a "tablename-columnname.bin" bin file.
Then I tried to manually rename this "tablename-columnname.bin" to "original_file.doc" and the doc can be opened correctly.
Question: Why phpmyadmin does not download the file as is? What can I do to fix it? I know a bit of php
Thanks!
Use the 'header' before echo the file
header('Content-type: application/msword');
for dynamic way to find the 'Content type' use to store the 'file name' with 'extension' in database.
To make it a bit dynamic (based on MIME) I did the following change:
In tbl_get_field.php file, last few lines:
$mime = PMA_detectMIME($result);
switch($mime){
case 'image/jpeg':
$extension = 'jpg';
case 'image/gif':
$extension = 'gif';
case 'image/png':
$extension = 'png';
case 'application/pdf':
$extension = 'pdf';
default:
$extension = 'bin';
}
PMA_downloadHeader(
$table . '-' . $_GET['transform_key'] . '.' . $extension,
$mime,
strlen($result)
);
echo $result;
Code above should output the file with correct extension instead of always ".bin".
In mime.lib.php file, we need to detect more MIME cases:
function PMA_detectMIME(&$test)
{
$len = strlen($test);
if ($len >= 2 && $test[0] == chr(0xff) && $test[1] == chr(0xd8)) {
return 'image/jpeg';
}
if ($len >= 3 && substr($test, 0, 3) == 'GIF') {
return 'image/gif';
}
if ($len >= 4 && substr($test, 0, 4) == "\x89PNG") {
return 'image/png';
}
return 'application/octet-stream';
}
I want to add pdf and word doc in this, but I dont know how to determine their MIME type base on the stream characters
I'm have using Php, MongoDb and GridFs to store and retrieve files. It works fine for images, but I want to store files with docx, pdf, csv and etc. extensions. Here is my code:
$ext = $this->getFileExt($_FILES["news_attachment"]["name"]);
switch ($ext) {
case 'pdf':
$mimeType = 'application/pdf';
break;
case 'doc':
$mimeType = 'application/msword';
break;
case 'docx':
$mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
break;
case 'xls':
$mimeType = 'application/vnd.ms-excel';
break;
case 'xlsx':
$mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
break;
case 'ppt':
$mimeType = 'application/x-mspowerpoint';
break;
case 'pptx':
$mimeType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
break;
case 'csv':
$mimeType = 'text/csv';
break;
case 'txt':
$mimeType = 'text/plain';
break;
default:
$mimeType='application/pdf';
}
$gridFs = $this->getGridFs();
$fileData = array(
"filename" => microtime(true) . "." . $ext,
"contentType" => $mimeType);
$_id = $gridFs->storeUpload("news_attachment", $fileData);
But I get the same error message Message: error setting up file: . I've checked the file size is 78kb, $fileData is ok also. So, my question is - What else can caused this error?
Would you not be supplying the same argument when trying to upload:
$gridFs->storeUpload($_FILES["news_attachment"]["name"],
or possibly
$gridFs->storeUpload($_FILES["news_attachment"]["tmp_name"],
I just need to add check for error if(!empty($_FILES["news_attachment"]) && $_FILES["news_attachment"]["error"] == 0){ save file}
I'm really new to joomla, I don't have idea what should I do to make it done. I just have this kind of code in administrator table, it refers to uploading files.
//Support for file field: cover
if(isset($_FILES['jform']['name']['cover'])):
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.file');
$file = $_FILES['jform'];
//Check if the server found any error.
$fileError = $file['error']['cover'];
$message = '';
if($fileError > 0 && $fileError != 4) {
switch ($fileError) :
case 1:
$message = JText::_( 'File size exceeds allowed by the server');
break;
case 2:
$message = JText::_( 'File size exceeds allowed by the html form');
break;
case 3:
$message = JText::_( 'Partial upload error');
break;
endswitch;
if($message != '') :
JError::raiseWarning(500,$message);
return false;
endif;
}
else if($fileError == 4){
if(isset($array['cover_hidden'])):;
$array['cover'] = $array['cover_hidden'];
endif;
}
else{
//Check for filesize
$fileSize = $file['size']['cover'];
if($fileSize > 10485760):
JError::raiseWarning(500, 'File bigger than 10MB' );
return false;
endif;
//Replace any special characters in the filename
$filename = explode('.',$file['name']['cover']);
$filename[0] = preg_replace("/[^A-Za-z0-9]/i", "-", $filename[0]);
//Add Timestamp MD5 to avoid overwriting
$filename = md5(time()) . '-' . implode('.',$filename);
$uploadPath = JPATH_ADMINISTRATOR.DIRECTORY_SEPARATOR.'components'.DIRECTORY_SEPARATOR.'com_comic'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$filename;
$fileTemp = $file['tmp_name']['cover'];
if(!JFile::exists($uploadPath)):
if (!JFile::upload($fileTemp, $uploadPath)):
JError::raiseWarning(500,'Error moving file');
return false;
endif;
endif;
$array['cover'] = $filename;
}
endif;
I could upload the file (in this case, an image) from the codes above, but what I'll do next is creating a thumbnail for the uploaded image. I searched for the php codes through the internet but it doesn't seem to work since I can't synchronize it into joomla codes. Umm.. I've made a folder named thumbnail in images folder. So what should I do next?
I'll be so happy and grateful if any of you could help me with this. Thanks.
Well i can share technique I'm using, i hope it will help:
In table's method check after the all validation is done (at the end of the method, just before returning true) i add the following code:
$input = JFactory::getApplication()->input;
$files = $input->files->get('jform');
if (!is_null($files) && isset($files['image']))
$this->image = $this->storeImage($files['image']);
The i create a new method called storeImage() :
protected $_thumb = array('max_w' => 200, 'max_h' => 200);
private function storeImage($file) {
jimport('joomla.filesystem.file');
$filename = JFile::makeSafe($file['name']);
$imageSrc = $file['tmp_name'];
$extension = strtolower(JFile::getExt($filename));
// You can add custom images path here
$imagesPath = JPATH_ROOT . '/media/';
if (in_array($extension, array('jpg', 'jpeg', 'png', 'gif'))) {
// Generate random filename
$noExt = rand(1000, 9999) . time() . rand(1000, 9999);
$newFilename = $noExt . '.' . $extension;
$imageDest = $imagesPath . $newFilename;
if (JFile::upload($imageSrc, $imageDest)) {
// Get image size
list($w, $h, $type) = GetImageSize($imageDest);
switch ($extension) {
case 'jpg':
case 'jpeg':
$srcRes = imagecreatefromjpeg($imageDest);
break;
case 'png':
$srcRes = imagecreatefrompng($imageDest);
break;
case 'gif':
$srcRes = imagecreatefromgif($imageDest);
break;
}
// Calculating thumb size
if($w > $h) {
$width_ratio = $this->_thumb['max_w'] / $w;
$new_width = $this->_thumb['max_w'];
$new_height = $h * $width_ratio;
} else {
$height_ratio = $this->_thumb['max_w'] / $h;
$new_width = $w * $height_ratio;
$new_height = $this->_thumb['max_w'];
}
$destRes = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($destRes, $srcRes, 0, 0, 0, 0, $new_width, $new_height, $w, $h);
// Creating resized thumbnail
switch ($extension) {
case 'jpg':
case 'jpeg':
imagejpeg($destRes, $imagesPath . 'thumb_' . $newFilename, 100);
break;
case 'png':
imagepng($destRes, $imagesPath . 'thumb_' . $newFilename, 1);
break;
case 'gif':
imagegif($destRes, $imagesPath . 'thumb_' . $newFilename, 100);
break;
}
imagedestroy($destRes);
// Delete old image if it was set before
if (($this->image != "") && JFile::exists($imagesPath . $this->image)) {
JFile::delete($imagesPath . $this->image);
JFile::delete($imagesPath . 'thumb_' . $this->image);
}
return $newFilename;
}
}
}
}
return null;
}
This method returns uploaded file filename, which table stores in 'image' column. It creates two files, one original image and resized thumb with file prefix '_thumb'.
I hope it helps :)
I used Jimage : https://api.joomla.org/cms-3/classes/JImage.html
$JImage = new JImage($img_path);
$size_thumb = '150x150';
$JImage->createThumbs($size_thumb,1,$path.'/thumb');
Short, simple and efficient.
I have an image file name without extension (lets assume it is image_file_name - NOTE IT IS MISSING THE EXTENSION) and I also know the file type (lets assume the file type is image/jpeg). Now is there a php function that returns the file extension given its type? As explained in the following pseudo code:
$extension = get_extension('image/jpeg'); // Will return 'jpg'
$file_name = 'image_file_name' . '.' . $extension; // Will result in $file_name = image_file_name.jpg
Please note that the image above was only an example, the file name could be of any file type, such as a web page file name or anything else. and the extension could be anything as well, it could be html, css ...etc.
Is it possible to do the above? And how?
$ext = substr(image_type_to_extension(exif_imagetype('dev.png')), 1); //example png
This will give you the extension correctly and is more reliable than $_FILE['image']['type'].
You can use finfo to perform mime-magic to determine the file type.
$finfo = finfo_open(FILEINFO_MIME, "/path/to/mimiemagic.file");
$res = $finfo->file($filename);
list($type, $encoding) = explode(";", $res);
$typeToExt = array(
"image/jpeg"=>"jpg",
"image/png"=>"png",
"text/html"=>"html",
"text/plain"=>"txt",
"audio/mpeg"=>"mp3",
"video/mpeg"=>"mpg"
);
$ext = $typeToExt[$type];
You can use FILEINFO_MIME directly to determine MIME type and then use a switch case to add extension. There is this mime_content_type(), but it seems deprecated.
$finfo = new FileInfo(null, 'image_file_name');
// Determine the MIME type of the uploaded file
switch ($finfo->file($_FILES['image']['tmp_name'], FILEINFO_MIME) {
case 'image/jpg':
$extension = 'jpg'
$file_name = 'image_file_name' . '.' . $extension;
break;
case 'image/png':
$extension = 'png'
$file_name = 'image_file_name' . '.' . $extension;
break;
case 'image/gif':
$extension = 'gif'
$file_name = 'image_file_name' . '.' . $extension;
break;
}
For more extensions, keep adding cases to switch.