Jump to content
ianhaney

only allow jpg and png file extensions phpmailer

Recommended Posts

How do I only allow jpg and png file extensions to be uploaded as a attachment. My current code is below

 

$msg = '';
if (array_key_exists('userfile', $_FILES)) {

// create object of PHPMailer class with boolean parameter which sets/unsets exception.
$mail = new PHPMailer(true);
try {
    
    //$mail->isSMTP(); // using SMTP protocol
    $mail->Host = 'host'; // SMTP host as gmail 
    $mail->SMTPAuth = true;  // enable smtp authentication
    $mail->Username = 'emailaddress';  // sender gmail host              
    $mail->Password = 'emailpassword'; // sender gmail host password                          
    $mail->SMTPSecure = 'ssl';  // for encrypted connection                           
    $mail->Port = 587;   // port for SMTP     

    $mail->setFrom('emailaddress', "Name"); // sender's email and name
    $mail->addAddress('emailaddress', "Name");  // receiver's email and name
    
    $attachmentNames = [];
    
    //Attach multiple files one by one
    for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {
        $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
        $filename = $_FILES['userfile']['name'][$ct];
        if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
            if(isset($uploadfile))
            $mail->addAttachment($uploadfile, $filename);
            $attachmentNames[] = $_FILES['userfile']['name'][$ct];
        } else {
            $msg .= 'Failed to move file to ' . $uploadfile;
        }
    }

 

Share this post


Link to post
Share on other sites

Use explode  with '.' on the file path, then look at the last array element and that is the file type.

Share this post


Link to post
Share on other sites

??? You do it with PHP. Check the file type and if is it unacceptable do not attach it.

Share this post


Link to post
Share on other sites

I did try the following

 

//Attach multiple files one by one
    for ($ct = 0, $ctMax = count($_FILES['userfile']['tmp_name']); $ct < $ctMax; $ct++) {
        $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
        $filename = $_FILES['userfile']['name'][$ct];
        
        $AllowedFileTypes = array("jpg","png"); // build array
        $FileName = $_FILES['userfile']['name']; // get filename of file input
        $FileType = end((explode(".", $FileName))); // get file type/extension
        if(in_array($FileType, $AllowedFileTypes)){ // check to see if file type is allowed
        if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
            if ($mail->addAttachment($uploadfile, $filename)) {
            $attachmentNames[] = $_FILES['userfile']['name'][$ct];
        } else {
            $msg .= 'Failed to attach file ' . $_FILES['userfile']['name'][$ct];
            }
        } else {
            $msg .= 'Failed to move file to ' . $uploadfile;
            }
        } else {
            $msg .= 'Only jpg and png files allowed';
            }
        }

That just gives me the following errors

PHP Warning: explode() expects parameter 2 to be string, array given PHP Warning: end() expects parameter 1 to be array, null given
 

I got the code from https://stackoverflow.com/questions/41244570/allowed-extension-phpmailer

Share this post


Link to post
Share on other sites

I found a example below but unsure how to know that only jpg or png files can be uploaded/attached

 

$fname = $_FILES['file']['name'];
$this->ext = pathinfo($fname, PATHINFO_EXTENSION);
//I assume you've done the if move_upload thing to get the file to its destination
$this->filename = $name.'-'.date('dmY-Hi').'-cv.'.$this->ext;
$mail->AddAttachment('files/cvs/'.$this->filename, "CV File");

 

Share this post


Link to post
Share on other sites

It looks like you are missing one 'if' and have an extra 'else'. Where are you checking the file type? You need to practice good programming practice by properly indenting your code.

if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
   if ($mail->addAttachment($uploadfile, $filename)) {
/* You need to check for the desired file types here berfore you add it to the attach array */
      $attachmentNames[] = $_FILES['userfile']['name'][$ct];
   }
   else {
      $msg .= 'Failed to attach file ' . $_FILES['userfile']['name'][$ct];
   }
}
else {
   $msg .= 'Failed to move file to ' . $uploadfile;
}
/* Where is the if for the next else, which doesn't belong here anyway? */

 

Share this post


Link to post
Share on other sites

I have currently updated the code to the following but does not say the message about only uploading jpg or png files, the email does work though if I do upload the wrong file and I receive the email but don't attach the wrong file type attachment but if I attach the correct file types, it sends the email with the attachments

 

//Attach multiple files one by one
    for ($ct = 0, $ctMax = count($_FILES['userfile']['tmp_name']); $ct < $ctMax; $ct++) {
        $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
        	$filename = $_FILES['userfile']['name'][$ct];        
        		$FileType = pathinfo($filename, PATHINFO_EXTENSION);
        // Allow certain file formats
        $allowTypes = array('jpg', 'png', 'jpeg');
        	if(in_array($FileType, $allowTypes)){
        		if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
            		if ($mail->addAttachment($uploadfile, $filename)) {
            	$attachmentNames[] = $_FILES['userfile']['name'][$ct];
        } else {
            $msg .= 'Failed to attach file ' . $_FILES['userfile']['name'][$ct];
            }
        } else {
            $msg .= 'Failed to move file to ' . $uploadfile;
            }
        } else {
            $msg .= 'Sorry only jpg, png and jpeg files are allowed to upload';
        }
    }

I do try and indent the code as best I can as know it's easier to read if indented correctly

 

Share this post


Link to post
Share on other sites

A good IDE will help you with your indents which are still messed up making it difficult to read. I don't see where you initialize '$msg' to an empty string and I am not sure what happens when you concatenate to a variable that does not yet exist. Poor programming practice even if that works. Do the other errors show up?

Share this post


Link to post
Share on other sites
Posted (edited)

Sorry forgot about that line, the line 

$msg = '';
if (array_key_exists('userfile', $_FILES)) {

is just above 

$mail = new PHPMailer(true);

I don't get any errors show

Edited by ianhaney
added text

Share this post


Link to post
Share on other sites

They don't show any messages no but guess that's because they don't need to as they are not failing to trigger the msg line

Share this post


Link to post
Share on other sites

Been playing about with the code and getting there I think, it now works and shows the message if I try to send the form with a incorrect file type, it gives me the notice that it's the wrong file type and have to go back to the form to upload the correct file type and the code sends the form with the correct file type so that bit is all ok and working but tested with no file attachment and it's saying the message as if I was selecting a non allowed file type, below is the updated code

 

$allowed = array( 'jpg', 'jpeg', 'gif', 'png');
    foreach($_FILES['userfile']['name'] as $name) {
	$type = pathinfo($name, PATHINFO_EXTENSION); 
	if(!in_array($type, $allowed)) 
	die("Error: Only jpg, jpeg, gif and png files are allowed.-".$type); 
    }
    
    //Attach multiple files one by one
    for ($ct = 0, $ctMax = count($_FILES['userfile']['tmp_name']); $ct < $ctMax; $ct++) {
        $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
        $filename = $_FILES['userfile']['name'][$ct];
        $uploadfile=$filename.'.'.pathinfo($filename, PATHINFO_EXTENSION);
        if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
            if ($mail->addAttachment($uploadfile, $filename)) {
            $attachmentNames[] = $_FILES['userfile']['name'][$ct];
        } else {
            $msg .= 'Failed to attach file ' . $_FILES['userfile']['name'][$ct];
            }
        } else {
            $msg .= 'Failed to move file to ' . $uploadfile;
            }
        }

I think it may be just hopefully moving some of the code around

Share this post


Link to post
Share on other sites
if (is_array($_FILES['userfile'])) {
   foreach($_FILES['userfile']['name'] as $name) {
      $type = pathinfo($name, PATHINFO_EXTENSION); 
      if(!in_array($type, $allowed)) 
         die("Error: Only jpg, jpeg, gif and png files are allowed.-".$type); 
      }
   }
}
    
    

 

Share this post


Link to post
Share on other sites

I updated the code to the following

 

$allowed = array( 'jpg', 'jpeg', 'gif', 'png');
        if (is_array($_FILES['userfile'])) {
            foreach($_FILES['userfile']['name'] as $name) {
    $type = pathinfo($name, PATHINFO_EXTENSION);
        if(!in_array($type, $allowed))
            die("Error: Only jpg, jpeg, gif and png files are allowed.-".$type);
        }
    }

and below

 

//Attach multiple files one by one
    for ($ct = 0, $ctMax = count($_FILES['userfile']['tmp_name']); $ct < $ctMax; $ct++) {
        $uploadfile=$name.'.'.pathinfo($name, PATHINFO_EXTENSION);
        $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
        $filename = $_FILES['userfile']['name'][$ct];
        if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
            if ($mail->addAttachment($uploadfile, $filename)) {
            $attachmentNames[] = $_FILES['userfile']['name'][$ct];
        } else {
            $msg .= 'Failed to attach file ' . $_FILES['userfile']['name'][$ct];
            }
        } else {
            $msg .= 'Failed to move file to ' . $uploadfile;
            }
        }

But seem to be getting new errors that I did not get before

The errors are below

PHP Notice:  file_get_contents(): Content-type not specified assuming application/x-www-form-urlencoded in booking-process.php on line 76
PHP Fatal error:  Uncaught Error: Call to undefined function json_decode() in booking-process.php:77
Stack trace:
#0 {main}
  thrown in booking-process.php on line 77

Line 76 is $verify = file_get_contents($url, false, $context);

Line 77 is $captcha_success=json_decode($verify);

Share this post


Link to post
Share on other sites

The 2nd error is because the first failed. You don't show what '$context' contains but I'm guessing you only need 1 parameter, the file path.

Share this post


Link to post
Share on other sites

The whole code is below as thought that might be better to post the whole code and to follow

 

$msg = '';
if (array_key_exists('userfile', $_FILES)) {

// create object of PHPMailer class with boolean parameter which sets/unsets exception.
$mail = new PHPMailer(true);
try {
    
    //$mail->isSMTP(); // using SMTP protocol
    $mail->Host = 'host'; // SMTP host as gmail 
    $mail->SMTPAuth = true;  // enable smtp authentication
    $mail->Username = 'emailaddress';  // sender gmail host              
    $mail->Password = 'emailpassword'; // sender gmail host password                          
    $mail->SMTPSecure = 'ssl';  // for encrypted connection                           
    $mail->Port = 587;   // port for SMTP     

    $mail->setFrom('emailaddress', "Name"); // sender's email and name
    $mail->addAddress('emailaddress', "Name");  // receiver's email and name
    
    $attachmentNames = [];
    
    $allowed = array( 'jpg', 'jpeg', 'gif', 'png');
        if (is_array($_FILES['userfile'])) {
            foreach($_FILES['userfile']['name'] as $name) {
    $type = pathinfo($name, PATHINFO_EXTENSION);
        if(!in_array($type, $allowed))
            die("Error: Only jpg, jpeg, gif and png files are allowed.-".$type);
        }
    }
    
    //Attach multiple files one by one
    for ($ct = 0, $ctMax = count($_FILES['userfile']['tmp_name']); $ct < $ctMax; $ct++) {
        $uploadfile=$name.'.'.pathinfo($name, PATHINFO_EXTENSION);
        $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
        $filename = $_FILES['userfile']['name'][$ct];
        if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
            if ($mail->addAttachment($uploadfile, $filename)) {
            $attachmentNames[] = $_FILES['userfile']['name'][$ct];
        } else {
            $msg .= 'Failed to attach file ' . $_FILES['userfile']['name'][$ct];
            }
        } else {
            $msg .= 'Failed to move file to ' . $uploadfile;
            }
        }

$mail->Subject = 'New Repair Booking Made At' . ' ' .date('d-m-Y H:i:s');
    
    $mail->Body    = "A new repair has been booked in. This repair booking was made at " . $date = date('d-m-Y H:i:s') . "\r\n\r\n" . "The repair information is below" . "\r\n\r\n" . "Repair Date/Time: " . $_POST["date"] . "\r\n" . "Device: " . $_POST["selectdevice"] . "\r\n" . "Brand: " . $_POST["selectbrand"] . "\r\n" . "Name: " . $_POST["name"] . "\r\n" . "Email: " . $_POST["email"] . "\r\n" . "Phone Number: " . $_POST["phone"] . "\r\n" . "Repair Description/Issue: " . $_POST["repairdescription"] . "\r\n\r\n" . "Attached Filename(s): " . implode(', ', $attachmentNames);
        
$response = $_POST["g-recaptcha-response"];

	$url = 'https://www.google.com/recaptcha/api/siteverify';
	$data = array(
		'secret' => 'SECRETKEY',
		'response' => $_POST["g-recaptcha-response"]
	);
    $query = http_build_query($data);
	$options = array(
		'http' => array (
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
            "Content-Length: ".strlen($query)."\r\n".
            "User-Agent:MyAgent/1.0\r\n",
			'method' => 'POST',
			'content' => $query
		)
	);
	$context  = stream_context_create($options);
	$verify = file_get_contents($url, false, $context);
	$captcha_success=json_decode($verify);

	if ($captcha_success->success==false) {
		echo "<p>You are a bot! Go away!</p>";
        echo "<br><a href=\"javascript:history.go(-1)\">Go Back To Form</a>";
        exit();
    } else if ($captcha_success->success==true) {
        
        if(!$mail->send()){
    header('Location:booking-confirmation.php');
    }
    }    } catch (Exception $e) { // handle error.
    echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
        }
};

 

Share this post


Link to post
Share on other sites

My bad. The first error is a warning/notice. You did not specify the Content-type correctly but it assumed the correct value. As for the 2nd error it looks like you are running PHP version 5.1 or earlier. Version 5.2 or better has json built in. Your version does not and you will need to install php-pecl-json.

Share this post


Link to post
Share on other sites

It's odd one as never had the error come up before until today, I'm running php version 7.3.6

Share this post


Link to post
Share on other sites

Just checked again and it was on PHP 7.3 (alt-php73) so changed it to PHP 7.3 (ea-php73) and will see if that makes a difference

Share this post


Link to post
Share on other sites

Tried it again and still getting a blank white page but no error log this time on the server so guessing the code is almost correct and it's sending the email if there is attachments but if no attachments it shows the error message Error: Only jpg, jpeg, gif and png files are allowed.-

and it's not redirecting to the confirmation page when there are files attached and guessing will do the same when no files are attached

Share this post


Link to post
Share on other sites

Getting closer, I have updated the code to below and it now gives me the notice if trying to upload a file that is not allowed so go back to the form and upload the correct file types and it send the email and redirects me to the confirmation page but if try to send the form with no files attached, I get the notice Error: Only jpg, jpeg, gif and png files are allowed.

$msg = '';
if (array_key_exists('userfile', $_FILES)) {

// create object of PHPMailer class with boolean parameter which sets/unsets exception.
$mail = new PHPMailer(true);
    
    //$mail->isSMTP(); // using SMTP protocol
    $mail->Host = 'host'; // SMTP host as gmail 
    $mail->SMTPAuth = true;  // enable smtp authentication
    $mail->Username = 'emailaddress';  // sender gmail host              
    $mail->Password = 'emailpassword'; // sender gmail host password                          
    $mail->SMTPSecure = 'ssl';  // for encrypted connection                           
    $mail->Port = 587;   // port for SMTP     

    $mail->setFrom('emailaddress', "Name"); // sender's email and name
    $mail->addAddress('emailaddress', "Name");  // receiver's email and name
    
    $attachmentNames = [];
    
    $allowed = array( 'jpg', 'jpeg', 'gif', 'png');
        if (is_array($_FILES['userfile'])) {
            foreach($_FILES['userfile']['name'] as $name) {
    $type = pathinfo($name, PATHINFO_EXTENSION);
        if(!in_array($type, $allowed))
            die("Error: Only jpg, jpeg, gif and png files are allowed.-".$type);
        }
    }
}
    
    //Attach multiple files one by one
    for ($ct = 0, $ctMax = count($_FILES['userfile']['tmp_name']); $ct < $ctMax; $ct++) {
        $uploadfile=$name.'.'.pathinfo($name, PATHINFO_EXTENSION);
        $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
        $filename = $_FILES['userfile']['name'][$ct];
        if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
            if ($mail->addAttachment($uploadfile, $filename)) {
            $attachmentNames[] = $_FILES['userfile']['name'][$ct];
        } else {
            $msg .= 'Failed to attach file ' . $_FILES['userfile']['name'][$ct];
            }
        } else {
            $msg .= 'Failed to move file to ' . $uploadfile;
            }
        }

$mail->Subject = 'New Repair Booking Made At' . ' ' .date('d-m-Y H:i:s');
    
    $mail->Body    = "A new repair has been booked in. This repair booking was made at " . $date = date('d-m-Y H:i:s') . "\r\n\r\n" . "The repair information is below" . "\r\n\r\n" . "Repair Date/Time: " . $_POST["date"] . "\r\n" . "Device: " . $_POST["selectdevice"] . "\r\n" . "Brand: " . $_POST["selectbrand"] . "\r\n" . "Name: " . $_POST["name"] . "\r\n" . "Email: " . $_POST["email"] . "\r\n" . "Phone Number: " . $_POST["phone"] . "\r\n" . "Repair Description/Issue: " . $_POST["repairdescription"] . "\r\n\r\n" . "Attached Filename(s): " . implode(', ', $attachmentNames);
        
$response = $_POST["g-recaptcha-response"];

	$url = 'https://www.google.com/recaptcha/api/siteverify';
	$data = array(
		'secret' => 'SECRETKEY',
		'response' => $_POST["g-recaptcha-response"]
	);
    $query = http_build_query($data);
	$options = array(
		'http' => array (
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
            "Content-Length: ".strlen($query)."\r\n".
            "User-Agent:MyAgent/1.0\r\n",
			'method' => 'POST',
			'content' => $query
		)
	);
	$context  = stream_context_create($options);
	$verify = file_get_contents($url, false, $context);
	$captcha_success=json_decode($verify);

	if ($captcha_success->success==false) {
		echo "<p>You are a bot! Go away!</p>";
        echo "<br><a href=\"javascript:history.go(-1)\">Go Back To Form</a>";
        exit();
    } else if ($captcha_success->success==true) {
        
        if(!$mail->send()) {
            echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
        } else {
    header('Location:booking-confirmation.php');
    }
    };

 

Share this post


Link to post
Share on other sites

That means there is something in the array. See what it there with this:

echo "<pre>";
print_r($_FILES['userfile']);
echo "</pre>";

 

Share this post


Link to post
Share on other sites

I put the code in like below but does not say what's in the userfile, just says the same notice about only the jpg etc files allowed

 

$allowed = array( 'jpg', 'jpeg', 'gif', 'png');
        if (is_array($_FILES['userfile'])) {
            foreach($_FILES['userfile']['name'] as $name) {
    $type = pathinfo($name, PATHINFO_EXTENSION);
        if(!in_array($type, $allowed))
            die("Error: Only jpg, jpeg, gif and png files are allowed.-".$type);
        }
    }
}

echo "<pre>";
print_r($_FILES['userfile']);
echo "</pre>";

Have I put the print code in the wrong place?

Share this post


Link to post
Share on other sites
Posted (edited)

Manged to get the array printed out and the results are below

 

Array
(
    [name] => Array
        (
            [0] => 
        )

    [type] => Array
        (
            [0] => 
        )

    [tmp_name] => Array
        (
            [0] => 
        )

    [error] => Array
        (
            [0] => 4
        )

    [size] => Array
        (
            [0] => 0
        )

)

Looking at the error codes online, it looks like 4 means no file was uploaded but I need the upload file be optional so the form can be submitted without files uploaded as well as files uploaded and only allow jpg, png files to be uploaded if a user does upload a file or files

Edited by ianhaney
wrapped code in code tag

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.