Catch Up Quickly: Due to the nature of what I've most recently found. I have recreated this question in a different category because this does not seem to be a Mailgun issue. That question can be found here:
PHP 7.2 CURLFile Gives "Invalid Filename" Warning
I'm aware of the SDK and that Mailgun does not offer support outside of it, and that's why I'm trying to get some support here for a light-weight implementation I'm working on; it was actually already complete and working until I decided to extend it with attachments, and it's still working, just no attachments are being added to the email. I have reviewed a few previous questions, and I can't seem to get attachments to work based on the solutions offered.
Info
- PHP 5.5 or Greater in Use (php 7.2 in my specific instance)
- Attached files have been confirmed that they exist and are readable by PHP/Apache
- php-curl and related php libraries are up-to-date
- Sensitive variables in the code and output below have been modified (including the various email addresses/domains)
- Emails deliver exactly as intended aside from the lack of attachments
- This is a snippet from within an object, thus the references to
$this
. All variables are loading correctly. - Currently testing with a simple text email (not HTML).
- The functionality is configured to send multiple attachments using attachment[] key approach, which is documented as working on other SO threads, BUT I have also tried using just one attachment approach and setting just the
attachment
key -- the result is the same.
Code Block
$curl = curl_init();
$log->AddStep('Mailgun', 'API send request starting...');
$postUrl = 'https://' . $this->host . self::API_URL_BASE . '/' . $this->domain . '/messages';
$curlOpts = array(
CURLOPT_POST => 1,
CURLOPT_URL => $postUrl,
CURLOPT_TIMEOUT => 20,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => 'api:' . $this->apiKey
);
$postFields = array(
'from' => $email->from,
'to' => $email->to,
'subject' => $email->subject
);
if (strlen($email->cc) > 0) {
$postFields['cc'] = $email->cc;
}
if (strlen($email->bcc) > 0) {
$postFields['bcc'] = $email->bcc;
}
if (strlen($email->html) > 0) {
$postFields['html'] = $email->html;
} else {
$postFields['text'] = $email->text;
}
if (count($email->attachments) > 0) {
// Curl attachments for < PHP5.5 not supported
if (function_exists('curl_file_create')) {
$curlOpts[CURLOPT_SAFE_UPLOAD] = 1; // for < PHP 7
//$curlOpts[CURLOPT_HTTPHEADER] = array('Content-Type: multipart/form-data');
for ($i = 1; $i <= count($email->attachments); $i++) {
$postFields['attachment[' . $i . ']'] = curl_file_create($email->attachments[$i - 1], "text/csv", basename($email->attachments[$i - 1]));
}
} else {
\D3DevelForms\Models\Error::CreateAndSaveSystemError(
$plugin,
\D3DevelForms\Common::ERROR_WARNING,
'PHP 5.5 or newer required for Mailgun Attachments',
\D3DevelForms\Models\Error::ERROR_CODE_API_MAILGUN_LOCAL_ERROR,
'You are using an outdated version of PHP. Email attachments via Mailgun will be ignored.');
}
}
$curlOpts[CURLOPT_POSTFIELDS] = $postFields;
$log->UpdateDebugLog('Mailgun API Options', $curlOpts);
curl_setopt_array($curl, $curlOpts);
$curl_response = curl_exec($curl);
$info = curl_getinfo($curl);
Curl Options ($curlOpts
)
Array
(
[47] => 1
[10002] => https://api.mailgun.net/v3/devtester.devtest.com/messages
[13] => 20
[19913] => 1
[107] => 1
[10005] => api:APIKEY
[-1] => 1
[10015] => Array
(
[from] => Dev Tester <devtester@devtest.com>
[to] => devemail@gmail.com
[subject] => Form Summary
[text] => My Text Content
[attachment[1]] => CURLFile Object
(
[name] => /var/www/path_to/my_file.csv
[mime] => text/csv
[postname] => my_file.csv
)
)
)
Curl Info Returned ($info
)
Array
(
[url] => https://api.mailgun.net/v3/devtester.devtest.com/messages
[content_type] => application/json
[http_code] => 200
[header_size] => 388
[request_size] => 312
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.503718
[namelookup_time] => 0.004273
[connect_time] => 0.0932
[pretransfer_time] => 0.279756
[size_upload] => 1021
[size_download] => 105
[speed_download] => 208
[speed_upload] => 2026
[download_content_length] => 105
[upload_content_length] => 1021
[starttransfer_time] => 0.368725
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => Y.Y.Y.Y
[certinfo] => Array
(
)
[primary_port] => 443
[local_ip] => X.X.X.X
[local_port] => 38636
)
Mailgun API Response
{
"id": "<AA.BB.CC@devtester.devtest.com>",
"message": "Queued. Thank you."
}
Mailgun Log
{
"tags": [],
"envelope": {
"sender": "devtester@devtest.com",
"transport": "smtp",
"targets": "devemail@gmail.com"
},
"storage": {
"url": "https://sw.api.mailgun.net/v3/domains/devtester.devtest.com/messages/KK",
"key": "KK"
},
"log-level": "info",
"id": "II",
"campaigns": [],
"method": "http",
"user-variables": {},
"flags": {
"is-routed": false,
"is-authenticated": true,
"is-system-test": false,
"is-test-mode": false
},
"recipient-domain": "gmail.com",
"timestamp": 1550085991.344005,
"message": {
"headers": {
"to": "devemail@gmail.com",
"message-id": "AA.BB.CC@devtester.devtest.com",
"from": "Dev Tester <devtester@devtest.com>",
"subject": "Form Summary"
},
"attachments": [],
"size": 945
},
"recipient": "devemail@gmail.com",
"event": "accepted"
}
I've been struggling with this for a couple days now with the goal of avoiding this question simply because of the anticipated resistance to not using the SDK, which I consider a last resort since this is all but working without needing to load an entire library.
Is there anything you guys can see that would prevent this code from sending the attachment via PHP + cURL?
Related Questions Reviewed:
- Mailgun send mail with attachment
- Using PHP Curl and Mailgun API to send mail with attachment using remote file
- Mailgun Sent mail With attachment
Update: When testing with cURL from command line, it does work as intended including when I run it as an the apache
process.
sudo -u apache curl -s --user 'api:APIKEY' \
https://api.mailgun.net/v3/devtester.devtest.com/messages \
-F from='Dev Tester <devtest@devtester.devtest.com>' \
-F to='devtester@gmail.com' \
-F subject='Hello' \
-F text='Testing some Mailgun awesomness!' \
-F attachment=@/var/www/path_to/my_file.csv
{
"id": "<AA.BB.CC@devtester.devtest.com>",
"message": "Queued. Thank you."
}
Update (Closing in on the Problem):
I am getting a PHP warning in the Apache logs, that appears as follows:
"PHP Warning: curl_setopt_array(): Invalid filename for key attachment[1]"
This is tricky because I have confirmed the following:
- The file exists
- The file is readable by Apache
- The file path does not include any characters outside of letters, numbers, slashes and hyphens
- Because the file is generated within the same thread, I have tried referencing a static file, but the result is the same.