Sending attachment(s) in email - php

I've never touched PHP, but was tasked with fixing an Intern's code..
I am trying to attach a file being uploaded to an email that I am sending. The email sends, but without the file. I am using PHPMailerAutoUpload.php (found on GitHub).
Here's the code I am using.
The attachment is being saved via move_uploaded_file
move_uploaded_file( $resume['tmp_name'] , $up_dir .basename( $random_var . '_wse_' . $resume['name'] ) )
Note: I have commented out the move_uploaded_file function to make sure I wasn't getting rid of the attachment.
require_once('phpmailer/PHPMailerAutoload.php');
$mail = new PHPMailer(true);
$mail->IsSMTP();
$mail->SMTPDebug = 2;
$mail->SMTPAuth = false;
$mail->Host = 'oursmtp';
$mail->Port = 25;
$mail->setFrom( $_POST['E-mail'] , $_POST['first_name'] . " " . $_POST['last_name'] );
$mail->addAddress( 'test#test.com' );
$mail->Subject = "Test" . #date('M/D/Y');
$mail->msgHTML($msgDoc);
if (isset($_FILES['uploaded_file']) &&
$_FILES['uploaded_file']['error'] == UPLOAD_ERR_OK) {
$mail->AddAttachment($_FILES['uploaded_file']['tmp_name'],
$_FILES['uploaded_file']['name']);
}
if (!$mail->send()) {
$mailError = $mail->ErrorInfo;
$outcomeArr = array(
'outcome'=>'failure',
'message'=>'Error' . $mailError
);
echo json_encode( $outcomeArr );
exit();
} else {
// success
$outcomeArr = array(
'outcome'=>'success',
'message'=>'Thank you'
);
echo json_encode( $outcomeArr );
}
From what I have read, $_FILES is a temporary storage for uploaded files in PHP. With this code, the email sends, but with no attachment (only a link to the uploaded file location).
I tried following this, but it isn't working for me.

Your intern was apparently a rockstar that had no need to check for or indicate error conditions, and then mail will send even if there's no attachment or if there was an error during the upload. Change these bits to the code to tell you why the file wasn't attached:
if (isset($_FILES['uploaded_file']) && $_FILES['uploaded_file']['error'] == UPLOAD_ERR_OK) {
if( ! $mail->AddAttachment($_FILES['uploaded_file']['tmp_name'], $_FILES['uploaded_file']['name']) ) {
echo 'Error adding attachment: ' . $mail->ErrorInfo;
}
} else if( !isset($_FILES['uploaded_file']) ) {
echo 'No uploaded file found';
} else {
echo 'Uploaded file error: ' . $_FILES['uploaded_file']['error'];
}

Related

Forbidden(403) error when try to redirect to url

I've got form on my page, when press send and attachment is too big I would like to back to form and display info that file is too big.
I used:
$file_name = $_FILES['uploaded-file']["name"][$i]; $redirectUrl = sprintf('Location: %s#file-size-error', $_SERVER['HTTP_REFERER']);
if ($_FILES['uploaded-file']['size'][$i] > $max_size) {
$_SESSION['file-size'] = "plik. $file_name .jest zbyt duży";
header($redirectUrl);
die();
}
When I press send button and file is too big, sometimes it works as it should and sometimes I have 403 error. When I put direct url to header result is the same. I set chmod of project folder to 775 still the same problem, can it be a fault of serwer settings ?
full php code:
<?php
session_start();
//Import PHPMailer classes into the global namespace
//These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
//Load Composer's autoloader
require 'autoload.php';
//Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true);
//$mail->addCustomHeader('Content-Type', 'text/plain;charset=utf-8');
$mail->CharSet = 'UTF-8';
$mail->Encoding = 'base64';
setlocale( LC_ALL, "pl_PL.UTF-8" );
$honeypot = $_POST['honey'];
$user_name = $_POST['name'];
$user_email = $_POST['email'];
$user_message = $_POST['message'];
$user_phone = $_POST['phone'];
$honeypot = trim($_POST["honey"]);
$max_size = 2 * 1024 * 1204; //2mb
$attachment = $_FILES['uploaded-file'];
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if(!empty($honeypot)) {
echo "NO SPAM!";
exit;
} else {
$mail = new PHPMailer; //From email address and name
$mail->isMail();
//sender
$mail->From = $user_email;
$mail->FromName = $user_name;
//recipient
$mail->addAddress("jarek.m01#gmail.com");
//mail subject
$mail->Subject = "Zapytanie ze strony www";
$mail->isHTML(true);
//body mail
$mail->Body = "Telefon:$user_phone<br><br>Treść wiadomośći:<br>$user_message";
$mail->AltBody = "Telefon:$user_phone\n$content";
//attachment
if(isset($attachment)) {
$amount_ofFiles = count($_FILES['uploaded-file']['size']);
$redirectUrl = sprintf('Location: %s#file-size-error', $_SERVER['HTTP_REFERER']);
if ($amount_ofFiles > 3) {
$_SESSION['file-amount'] = "przekroczono limit załączników";
header($redirectUrl);
die();
}
for ($i = 0; $i < count($_FILES['uploaded-file']['name']); $i++) {
if ($_FILES['uploaded-file']['error'][$i] !== UPLOAD_ERR_OK) continue;
$file_TmpName = $_FILES['uploaded-file']["tmp_name"][$i];
$file_name = $_FILES['uploaded-file']["name"][$i];
if ($_FILES['uploaded-file']['size'][$i] > $max_size) {
$_SESSION['file-size'] = "plik. $file_name .jest zbyt duży";
header($redirectUrl);
die();
}
else{
move_uploaded_file($file_TmpName, "uploads/" . $file_name);
$mail-> AddAttachment("uploads/". $file_name);
}
}//for
}//isset
if(!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
exit();
}
else {
header("Location: sent.html");
exit();
}//if send else
}//honey else end
}//post end
code in my html file(set in htaccess to treat html files as php)
<div id ="file-size-error" class="file-error">
<?php
session_start();
if(isset($_SESSION['status'])) {
echo($_SESSION['status']);
unset($_SESSION['status']);
}
?>
</div>```
Problem was in .htaccess file
By default in htaccess attached to CMS(batflat) there was a line, that caused the problem:
<Files ~ "^.*\.(sdb|md|html|txt)$">
<IfModule !mod_authz_core.c>
Order allow,deny
Deny from all
Satisfy All
</IfModule>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</Files>

Email Attachment from directory is not always the latest using PHPMailer

UPDATE #2 - FINAL ANSWER
I figured and you'll see in the comments below that my comparison symbol needed to be changed. So I took the code in Update #1 and simply changed this:
return filemtime($a) < filemtime($b);
to:
return filemtime($a) > filemtime($b);
And that did it!!! Thanks everyone for the dialog.
UPDATE
I've updated my code. Now I'm getting the attachment sent but again, it's not grabbing the latest one. Here's my latest code:
<?php
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'php/PHPMailer2020/src/Exception.php';
require 'php/PHPMailer2020/src/PHPMailer.php';
$dir = "php/sketch-drawings/";
$pics = scandir($dir);
$files = glob($dir . "*.*");
usort($files, function($a, $b){
return filemtime($a) < filemtime($b);
});
foreach ($files as $pics) {
echo '<img src="'. $pics . '">';
}
// SEND EMAIL W/ ATTACHMENT OF LATEST IMAGE
$mail = new PHPMailer();
$mail->Sender = "hello#myemail.com";
$mail->From = "mail#myemail.com";
$mail->FromName = "My Company";
$mail->AddReplyTo( "mail#mycompany.com", "DO NOT REPLY" );
//$mail->AddAddress("info#mycompany.com");
$mail->AddAddress("myemail#gmail.com");
$mail->isHTML(true);
$mail->Subject = "Latest Sketch Image";
$mail->Body = "Latest Image Attached! \n\n Thanks - XYZ Digital.";
$mail->AddAttachment($pics);
if(!$mail->Send()) {
echo 'Email Failed To Send.';
}
else {
echo 'Email Was Successfully Sent.';
echo "</p>";
echo '<script language="javascript">';
echo 'alert("Thanks! Message Sent")';
echo '</script>';
}
$mail->ClearAddresses();
?>
This issue:
The AddAttachment($filepath) returns an attachment, but it's not the most recent one-- I need it to always return the most recent image in the directory.
Here's what I'm doing:
I've created a web application that is basically a sketch pad. When a user taps on "Save" the code snaps a pic of the element saves it to a directory and then sends an email to the pre-defined address with the snap of the canvas as an attachment... and the issue is above.
What I've done:
I've looked all over the place for a solve -- seems as though the only find is around uploading the attachments via a web form--which isn't my issue. My workflow is different and why I'm here asking now. :)
What's not working:
Everything works except for the attachment part. I'm using PHPMailer but for some reason, the attachment is never the latest one. In fact, it seems to always be the same attachment no matter what.
I tried to get the first element in the array doing this (which I echo in the bottom of the code and it returns the right image:
$mail->addAttachment($sketches[0]);
this doesn't work -- it sends the email, but nothing attached.
How in the world, can I adjust my code below to get the latest attachment? I appreciate any help as PHP is not my area of expertise.
See the code below...
<?php // NEW
// DEFINE ERRORS
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer2020/src/Exception.php';
require 'PHPMailer2020/src/PHPMailer.php';
// GET LATEST UPLOAD -- AND HAVE IT STORED IN DOM (WHEN NEEDED)
$path = ('sketch-drawings');
// Sort in descending order
$sketches = scandir($path, 1);
$latest_ctime = 1;
$latest_filename = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
// could do also other checks than just checking whether the entry is a file
if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_filename = $entry;
}
// SEND EMAIL W/ ATTACHMENT OF LATEST IMAGE
$mail = new PHPMailer();
$mail->Sender = "hello#myemail.com";
$mail->From = "mail#myemail.com";
$mail->FromName = "My Company";
$mail->AddReplyTo( "mail#myemail.com", "DO NOT REPLY" );
//$mail->AddAddress("info#myemail.com");
$mail->AddAddress("myemail#gmail.com");
$mail->isHTML(true);
$mail->Subject = "Latest Sketch Image";
$mail->Body = "Latest Image Attached! \n\n Thanks - XYZ Digital.";
$mail->AddAttachment($filepath);
//$mail->addAttachment($sketches);
if(!$mail->Send()) {
echo 'Email Failed To Send.';
} else {
echo $filepath;
echo "<br><br>";
print $latest_filename;
echo "</p>";
echo "<p>";
print $sketches[0];
echo "</p>";
echo "<p>";
echo 'Email Was Successfully Sent.';
echo "</p>";
echo '<script language="javascript">';
echo 'alert("Thanks! Message Sent")';
echo '</script>';
}
$mail1->ClearAddresses();
}
?>
PHP's dir() function returns items in an indeterminate order. If you want to retrieve files ordered by date, see this answer.

Custom PHP Mailer attachment not attached with email

I have customize mailer function where except file attachment, rest of things are working well. To make it simplify, I have added only code related to attachment. As output, I can see file uploaded to server but it's going to attach in email. I am getting all details in email except file attachment. it's customize mailer class which I have created but not sure why attachment not sending to email.
Mailer.class.php
<?php
class Mailer
{
private $addAttachment = [];
public function addAttachment($addAttachment)
{
if (empty($addAttachment))
{
$this->setError('No Attachments','empty');
}else{
$this->addAttachment[] = $addAttachment;
echo $addAttachment;
}
return $this;
}
}
For Sending test.php
require_once 'Mailer.class.php';
$toemails = array("my_email_address#gmail.com");
$toemail = implode(',', $toemails);
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$attachment = $_FILES["uploaded_file"]["tmp_name"];
$folder = '/uploads/';
$file_name1 = $_FILES["uploaded_file"]["name"];
move_uploaded_file($_FILES["uploaded_file"]["tmp_name"], "$folder".$_FILES["uploaded_file"]["name"]);
print_r($_FILES);
$mailer = new Mailer(true);
$mailer->setToEmail($toemail)
->setFromName(isset($_POST['fname'])?$_POST['fname']:'')
->setFromEmail(isset($_POST['email'])?$_POST['email']:'')
->setSubject('Application Regarding'.$_POST['Title'])
->addAttachment('/uploads/'.$_FILES["uploaded_file"]["name"])
->setBody($body)
->run();
exit();
if(!$mailer->sendMail()) {
echo "Something has gone wrong, please contact the site administrator or try again.";
}
else {
echo "Email Successfully Submitted";
}
print "</pre>";
}
?>
print_r($_FILES) gives me following Output for attachment:
Array
(
[uploaded_file] => Array
(
[name] => Image_Manager.pdf
[type] => application/pdf
[tmp_name] => /tmp/phplBV7gV
[error] => 0
[size] => 150300
)
)

Mail sent but attachment not received in wp_mail()

I am new in wordpress. I am trying to send a mail with an attachment. But every time the mail is being sent but the attachment is not. I searched almost all the post related to this topic here but all the solutions failed for me. I checked the path a lot of times and found that it is correct from 'uploads' folder. Please help me. This is my code,
<?php
if(isset($_POST['email'])){
$to = $_POST['email'];
$pdf = $_POST['pdf'];
$subject = "Presidency Alumni Annual Report";
$message = "Please download the attachment.";
$headers = 'From: Presidency Alumni Association Calcutta <noreply#presidencyalumni.com>' . "\n";
if($pdf == 'a'){
$attachments = array(WP_CONTENT_DIR . 'uploads/2015/01/Coffee-Mug-Banner.jpg');
}
else if($pdf == 'b'){
$attachments = array(WP_CONTENT_DIR . 'uploads/2014/08/Alumni-Autumn-Annual-2014.pdf');
}
else{
$attachments = array(WP_CONTENT_DIR . 'uploads/2014/08/Autumn-Annual-2012.pdf');
}
wp_mail($to, $subject, $message, $headers, $attachments);
print '<script type="text/javascript">';
print 'alert("Your Mail has been sent successfully")';
print '</script>';
}
?>
The most probable reason this to happen is if the condition if($pdf == 'a') {...} else if ($pdf == 'b') {...}) is not true. Check to see if this variable pdf is set properly in your post HTML form.
Also make sure that the constant WP_CONTENT_DIR contains something, i.e. is not empty string, because otherwise your path to the attachments will be invalid, i.e. it is better to access your uploads directory like this:
<?php $upload_dir = wp_upload_dir(); ?>
The $upload_dir now contains something like the following (if successful):
Array (
[path] => C:\path\to\wordpress\wp-content\uploads\2010\05
[url] => http://example.com/wp-content/uploads/2010/05
[subdir] => /2010/05
[basedir] => C:\path\to\wordpress\wp-content\uploads
[baseurl] => http://example.com/wp-content/uploads
[error] =>
)
Then, modify your code:
$attachments = array($upload_dir['url'] . '/2014/08/Autumn-Annual-2012.pdf');
See the documentation.

Validate Image with exif_imagetype but still able to upload non image files

I am not sure if my exif_imagetype is coded wrong. It send the email just fine with photos attached. But when I try to attach non image files it will still allow me to do so and send the email with the attachment. Please help.
ob_start();
require("class.phpmailer.php");
$photo = $_FILES['photo'];
isset($_POST['submit']);
$active_keys = array();
foreach($_FILES[$photo]['name'] as $key => $filename){
if(!empty($filename)){
$active_keys[] = $key;
} }
foreach($active_keys as $key){
switch(exif_imagetype($_FILES[$photo]['tmp_name'][$key])) {
case IMAGETYPE_JPEG:
case IMAGETYPE_PNG:
break;
default:
echo "{";
echo "$errors: 'This is no photo..'\n";
echo "}";
exit(0);
} }
$message = "some message";
$mail = new PHPMailer();
$mail->From = ('sample#youdomain.net');
$mail->AddAddress=('sample#youdomain.net');
$mail->Subject = "Submitted Photos";
$mail->Body = $message;
$mail->WordWrap = 50;
foreach($_FILES['photo']['tmp_name'] as $photo)
if(!empty($photo)) {
$mail->AddAttachment($photo);
}
$mail->Send();
header("Location: thankyou.php");
exit();
}}
use getimagesize() function before processing anything, it provides better result
example:
if(getimagesize($fullpath_to_file)){
//then do something here
}

Categories