diff --git a/.gitignore b/.gitignore index d1502b0..3cef16d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ vendor/ composer.lock +config.php \ No newline at end of file diff --git a/File.class.php b/File.class.php new file mode 100644 index 0000000..de88b00 --- /dev/null +++ b/File.class.php @@ -0,0 +1,82 @@ +url = $url; + } + + function get_headers($follow=true) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $this->url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $follow); + curl_setopt($ch, CURLOPT_HEADER, true); + curl_setopt($ch, CURLOPT_NOBODY, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + + $output = curl_exec($ch); + + curl_close($ch); + + $headers = []; + $output = rtrim($output); + $data = explode("\n", $output); + $headers['status'] = $data[0]; + array_shift($data); + + foreach($data as $part) { + $middle = explode(":",$part,2); + if ( !isset($middle[1]) ) { $middle[1] = null; } + $headers[trim($middle[0])] = trim($middle[1]); + } + + return $headers; + } + + function get_status($follow=true) { + return $this->get_headers($follow)["status"]; + } + + function get_filename($follow=true) { + $content = $this->get_headers($follow); + $content = array_change_key_case($content, CASE_LOWER); + + if ($content['content-disposition']) { + $tmp_name = explode('=', $content['content-disposition']); + if ($tmp_name[1]) $realfilename = trim($tmp_name[1],'";\''); + }; + + if (!$realfilename) { + $stripped_url = preg_replace('/\\?.*/', '', $this->url); + $stripped_url = preg_replace('/\\/$/', '', $stripped_url); + $realfilename = basename($stripped_url); + } + + return $realfilename; + } + + function fetch_file($write=false, $path=null, $follow=true) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $this->url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $follow); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_NOBODY, false); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + + $output = curl_exec($ch); + + if(curl_errno($ch)) throw new Exception('Error downloading file. ' . curl_error($ch)); + + curl_close($ch); + + if ($write) { + if (!$path) $path = tempnam(sys_get_temp_dir(), "EXPMAIL_"); + if (!file_put_contents($path, $output)) throw new Exception('Error saving file to ' . $path); + } + + return ($write ? $path : $output); + } +} \ No newline at end of file diff --git a/sender.php b/sender.php index e905eea..d2bea7d 100644 --- a/sender.php +++ b/sender.php @@ -3,6 +3,7 @@ require_once 'vendor/autoload.php'; require_once 'config.php'; require_once 'helpers.php'; +require_once 'File.class.php'; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; @@ -56,10 +57,11 @@ try { $mailer->AltBody = ($html ? $text : null); foreach ($json["attachments"] as $attachment) { - $tempfile = tempnam(sys_get_temp_dir(), "EXPMAIL_"); - file_put_contents($tempfile, file_get_contents($attachment["url"])); - $filename = ($attachment["filename"] ? $attachment["filename"] : getFilename($attachment["url"])); - $mailer->addAttachment($tempfile, $filename); + $file = new File($attachment["url"]); + if ($file->get_status() >= 400) throw new Exception("Error downloading " . $attachment["url"] . " - Status: " . $file->get_status()); + $content = $file->fetch_file(); + $filename = ($attachment["filename"] ? $attachment["filename"] : $file->get_filename()); + $mailer->addStringAttachment($content, $filename); } $mailer->send(); @@ -68,7 +70,7 @@ try { "status" => "success" ); -} catch (Exception $e) { +} catch (\Exception $e) { $response = array( "status" => "error", "error" => "{$e->getMessage()}"