Search code examples
phpphpmaileremail-attachmentsmailtoscandir

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 = "[email protected]";
$mail->From     = "[email protected]";
$mail->FromName = "My Company";
$mail->AddReplyTo( "[email protected]", "DO NOT REPLY" );
//$mail->AddAddress("[email protected]");
$mail->AddAddress("[email protected]");
$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 = "[email protected]";
    $mail->From     = "[email protected]";
    $mail->FromName = "My Company";
    $mail->AddReplyTo( "[email protected]", "DO NOT REPLY" );
    //$mail->AddAddress("[email protected]");
    $mail->AddAddress("[email protected]");
    $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();
}

?>

Solution

  • PHP's dir() function returns items in an indeterminate order. If you want to retrieve files ordered by date, see this answer.