Move file operations to separate File object

Use curl for remote file operations
Do file operations in memory instead of file system
Add config.php to .gitignore
This commit is contained in:
Kumi 2020-09-04 15:09:39 +02:00
parent 0737316ed7
commit 1db8d5a2af
3 changed files with 90 additions and 5 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
vendor/
composer.lock
config.php

82
File.class.php Normal file
View file

@ -0,0 +1,82 @@
<?php
class File {
public $url;
function __construct($url) {
$this->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);
}
}

View file

@ -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()}"