Add .docx, .pdf, .txt etc as attachment with PHPMailer - pdf

I need to make possible for people to send their documents, be it .docx, .pdf or whatever from their computers, using PHPMailer. Of every solution I found, none of them worked for me. The error Could not access file: keeps showing up when using $mailer->ErrorInfo.
This is the code I have:
$mailer->From = $mail1;
$mailer->FromName = $name1;
$mailer->addAddress("gmfernandes#neo-e.com.br");
$mailer->Subject = $name1;
$mailer->ContentType = "Content-type: text/html; charset=utf-8";
$mailer->msgHTML($template);
$mailer->addAttachment($_FILES['anexoTrabalho']['tmp_name'], $_FILES['anexoTrabalho']['name']);
Thank you in advance

You need to learn how to handle uploads correctly. Don't access $_FILES directly; use move_uploaded_file first. To save you the hassle of looking it all up, adapt the example provided with PHPMailer, the important bit of which I reproduce here:
$msg = '';
if (array_key_exists('userfile', $_FILES)) {
// First handle the upload
// Don't trust provided filename - same goes for MIME types
// See http://php.net/manual/en/features.file-upload.php#114004 for more thorough upload validation
$uploadfile = tempnam(sys_get_temp_dir(), sha1($_FILES['userfile']['name']));
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
// Upload handled successfully
// Now create a message
// This should be somewhere in your include_path
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->setFrom('from#example.com', 'First Last');
$mail->addAddress('whoto#example.com', 'John Doe');
$mail->Subject = 'PHPMailer file sender';
$mail->msgHTML("My message body");
// Attach the uploaded file
$mail->addAttachment($uploadfile, 'My uploaded file');
if (!$mail->send()) {
$msg = "Mailer Error: " . $mail->ErrorInfo;
} else {
$msg = "Message sent!";
}
} else {
$msg = 'Failed to move file to ' . $uploadfile;
}
}

Related

Trying to find a file that doesnt exist Yii2

Im trying to create an email function that sends a file attached.
I've created the function and added attach() with the route of file I want to attach as follows:
public function newMonthlyBillingRegister(Clinic $clinic, ClinicMonthlyBilling $clinicMonthlyBilling)
{
$countryAdmins = $clinic->findCountryAdmins($clinic->country->id);
$adminEmails = [];
foreach ($countryAdmins as $admin) {
$adminEmails[$admin->email] = $admin->fullName;
}
/** #var BaseMailer $mailer */
$mailer = Yii::$app->mailer;
$mailer->htmlLayout = 'layouts/standard_html';
//$mailer->htmlLayout = 'layouts/invoice_html';
// $mailer->textLayout = 'layouts/invoice_text';
try{
return $mailer
->compose(
['html' => 'newMonthlyBillingRegister-html', 'text' => 'newMonthlyBillingRegister-text'],
[
'clinic' => $clinic,
'clinicMonthlyBilling' => $clinicMonthlyBilling,
]
)
->setFrom([Yii::$app->params['supportEmail'] => Yii::t('app', 'support-email-name', ['appName' => Yii::$app->name])])
->setTo($adminEmails)
->setSubject(Yii::t('app', '[CLINIC][BACKOFFICE] A clinic has upgraded its information in Guarantee Fund Modal.'))
->attach('app/media/uploads/clinic/monthly-billing/'.$clinicMonthlyBilling->trimestralBillingFile)
->queue() && YII_DEBUG && Yii::$app->mailqueue->process();
}
catch(\Exception $e){
LogService::getLogger()->error("Error while sending mail.","EmailService:newMonthlyBillingRegister()",$e->getMessage());
}
}
It gave me an error, but the problem comes when I delete attach() from my code, reverting all my changes on this email function, and when I try to send again the email the following message appears:
PHP Warning: fopen(app/media/uploads/clinic/monthly-billing/user_1_clinic_1_trimestral_billing_file_2019_05_09_08_22_35): failed to open stream: No such file or directory in /app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php on line 142
The user_1_clinic_1_trimestral_billing_file_2019_05_09_08_22_35 file doesnt exist in app/media/uploads/clinic/monthly-billing/ folder and even in my database
...what's wrong?¿ I know is in my local but I dont know the reason of trying to search a file that doesn't exist and I didn't code anything to search it,
Anyone can help? Im using PHPStorm,
Thanks a lot for your attention!
I had to clean my email queue and it worked!! Thanks a lot Insane Skull for your help ;)

export data from bigquery to cloud storage- php client library - there is one extra empty new line in the cloud storage file

I followed this sample
https://cloud.google.com/bigquery/docs/exporting-data
public function exportDailyRecordsToCloudStorage($date, $tableId)
{
$validTableIds = ['table1', 'table2'];
if (!in_array($tableId, $validTableIds))
{
die("Wrong TableId");
}
$date = date("Ymd", date(strtotime($date)));
$datasetId = $date;
$dataset = $this->bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);
// load the storage object
$storage = $this->storage;
$bucketName = 'mybucket';
$objectName = "daily_records/{$tableId}_" . $date;
$destinationObject = $storage->bucket($bucketName)->object($objectName);
// create the import job
$format = 'NEWLINE_DELIMITED_JSON';
$options = ['jobConfig' => ['destinationFormat' => $format]];
$job = $table->export($destinationObject, $options);
// poll the job until it is complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
print('Waiting for job to complete' . PHP_EOL);
$job->reload();
if (!$job->isComplete()) {
//throw new Exception('Job has not yet completed', 500);
}
});
// check if the job has errors
if (isset($job->info()['status']['errorResult'])) {
$error = $job->info()['status']['errorResult']['message'];
printf('Error running job: %s' . PHP_EOL, $error);
} else {
print('Data exported successfully' . PHP_EOL);
}
I have 37670 rows in my table1, and the cloud storage file has 37671 lines.
And I have 388065 my table2, and the cloud storage file has 388066 lines.
The last line in both cloud storage files is empty line.
Is this a Google BigQuery feature improvement request? or I did something wrong in my codes above?
What you described seems like an unexpected outcome. The output file should generally has the same number of lines as the source table.
Your PHP code looks fine and shouldn't be the cause of the issue.
I'm trying reproduce it but unable to. Could you double-check if the last empty line is somehow added by another tool like a text editor or something? How are you counting the lines of the resulting output.
If you have ruled that out and are sure the newline is indeed added by BigQuery export feature, please consider opening a bug using the BigQuery Issue Tracker as suggested by xuejian and include your job ID so that we can investigate further.

Snappy / WKHTMLtoPDF - How to change the save folder

I'm using Laravel with the snappy wrapper. It is all working except that it saves the PDF's into the public folder. I want it to go to a different folder. There is nothing obvious on the snappy git site, nor in the config. And the wkhtlptopdf docs are very sparse imho. How do I change the $pdf->save() statement so it goes where I want it to go ?
My PDF is generated by laravel like this:
if( $email == 'email'){
$quotation = $this->quotation->get_PdfQuote($ref);
$pdf = PDF::loadView('quotations/pdf_quotation',compact('quotation') );
$pdf->save($ref.'.pdf'); //THIS SAVES INTO THE PUBLIC FOLDER.
$title = 'Your Quotation';
$firstname = $customer['firstname1'];
$pathtoFile = '/var/www/auburntree/public/'.$ref.'.pdf';
Mail::send('emails.quotation', ['title' => $title, 'firstname'=>$firstname ], function ($m) use($customer,$pathtoFile) {
$m->from('myemail#gmail.com', 'Auburntree');
$m->to($customer['email1'],($customer['firstname1'] . $customer['lastname1']))->subject('Your Quotation');
$m->attach($pathtoFile);
});
Flash::success('The Quote Has Been Saved. An Email has ben sent to the customer ');
return redirect ('quotes');
} else
Ok, I hope this helps someone else.
$quotation = $this->quotation->get_PdfQuote($ref); //pulled in from DB
$pdf = PDF::loadView('quotations/pdf_quotation',compact('quotation') );
$filename = base_path('public/pdf/'.$ref.'.pdf');
$pdf->save($filename);

file name automatically change when i upload the file

I'm new to CodeIgniter and having the following issue. When I upload a file, its successfully uploaded on my local folder and the file name saved to the db. The problem is, file name has been changed after uploading.
eg:
file name "screenshot image 123.png" -> "screenshot_image_123.png"
It just convert the space into underscore;this issue occurred only when the file name having space.Other than this issue all the other files uploading successfully. Given below is my code which I used on my controller page:
public function upload_pic()
{
$image_path = realpath(APPPATH . '../uploads');
$config['upload_path'] = $image_path;
$config['allowed_types'] = "gif|jpg|jpeg|png";
$config['file_name'] = $_FILES['file']['name'];
$config['encrypt_name'] = TRUE;
$config['overwrite'] = TRUE;
$this->load->library('upload',$config);
$this->upload->initialize($config);
if(!$this->upload->do_upload('file'))
{
echo $this->upload->display_errors();
}
else
{
$finfo=$this->upload->data();
$data['uploadInfo'] = $finfo;
}
}
Can anyone help me????
Try before saving file name generate some unique
$filename = $_FILES['file']['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$filename = sha1_file($filename). md5(date('Y-m-d H:i:s:u')) . '.'. $ext; //not only this you can generate any format
$config['file_name'] = $filename; //Use this file name is db too

Get pdf-attachments from Gmail as text

I searched around the web & Stack Overflow but didn't find a solution. What I try to do is the following: I get certain attachments via mail that I would like to have as (Plain) text for further processing. My script looks like this:
function MyFunction() {
var threads = GmailApp.search ('label:templabel');
var messages = GmailApp.getMessagesForThreads(threads);
for (i = 0; i < messages.length; ++i)
{
j = messages[i].length;
var messageBody = messages[i][0].getBody();
var messageSubject = messages [i][0].getSubject();
var attach = messages [i][0].getAttachments();
var attachcontent = attach.getContentAsString();
GmailApp.sendEmail("mail", messageSubject, "", {htmlBody: attachcontent});
}
}
Unfortunately this doesn't work. Does anybody here have an idea how I can do this? Is it even possible?
Thank you very much in advance.
Best, Phil
Edit: Updated for DriveApp, as DocsList deprecated.
I suggest breaking this down into two problems. The first is how to get a pdf attachment from an email, the second is how to convert that pdf to text.
As you've found out, getContentAsString() does not magically change a pdf attachment to plain text or html. We need to do something a little more complicated.
First, we'll get the attachment as a Blob, a utility class used by several Services to exchange data.
var blob = attachments[0].getAs(MimeType.PDF);
So with the second problem separated out, and maintaining the assumption that we're interested in only the first attachment of the first message of each thread labeled templabel, here is how myFunction() looks:
/**
* Get messages labeled 'templabel', and send myself the text contents of
* pdf attachments in new emails.
*/
function myFunction() {
var threads = GmailApp.search('label:templabel');
var threadsMessages = GmailApp.getMessagesForThreads(threads);
for (var thread = 0; thread < threadsMessages.length; ++thread) {
var message = threadsMessages[thread][0];
var messageBody = message.getBody();
var messageSubject = message.getSubject();
var attachments = message.getAttachments();
var blob = attachments[0].getAs(MimeType.PDF);
var filetext = pdfToText( blob, {keepTextfile: false} );
GmailApp.sendEmail(Session.getActiveUser().getEmail(), messageSubject, filetext);
}
}
We're relying on a helper function, pdfToText(), to convert our pdf blob into text, which we'll then send to ourselves as a plain text email. This helper function has a variety of options; by setting keepTextfile: false, we've elected to just have it return the text content of the PDF file to us, and leave no residual files in our Drive.
pdfToText()
This utility is available as a gist. Several examples are provided there.
A previous answer indicated that it was possible to use the Drive API's insert method to perform OCR, but it didn't provide code details. With the introduction of Advanced Google Services, the Drive API is easily accessible from Google Apps Script. You do need to switch on and enable the Drive API from the editor, under Resources > Advanced Google Services.
pdfToText() uses the Drive service to generate a Google Doc from the content of the PDF file. Unfortunately, this contains the "pictures" of each page in the document - not much we can do about that. It then uses the regular DocumentService to extract the document body as plain text.
/**
* See gist: https://gist.github.com/mogsdad/e6795e438615d252584f
*
* Convert pdf file (blob) to a text file on Drive, using built-in OCR.
* By default, the text file will be placed in the root folder, with the same
* name as source pdf (but extension 'txt'). Options:
* keepPdf (boolean, default false) Keep a copy of the original PDF file.
* keepGdoc (boolean, default false) Keep a copy of the OCR Google Doc file.
* keepTextfile (boolean, default true) Keep a copy of the text file.
* path (string, default blank) Folder path to store file(s) in.
* ocrLanguage (ISO 639-1 code) Default 'en'.
* textResult (boolean, default false) If true and keepTextfile true, return
* string of text content. If keepTextfile
* is false, text content is returned without
* regard to this option. Otherwise, return
* id of textfile.
*
* #param {blob} pdfFile Blob containing pdf file
* #param {object} options (Optional) Object specifying handling details
*
* #returns {string} id of text file (default) or text content
*/
function pdfToText ( pdfFile, options ) {
// Ensure Advanced Drive Service is enabled
try {
Drive.Files.list();
}
catch (e) {
throw new Error( "To use pdfToText(), first enable 'Drive API' in Resources > Advanced Google Services." );
}
// Set default options
options = options || {};
options.keepTextfile = options.hasOwnProperty("keepTextfile") ? options.keepTextfile : true;
// Prepare resource object for file creation
var parents = [];
if (options.path) {
parents.push( getDriveFolderFromPath (options.path) );
}
var pdfName = pdfFile.getName();
var resource = {
title: pdfName,
mimeType: pdfFile.getContentType(),
parents: parents
};
// Save PDF to Drive, if requested
if (options.keepPdf) {
var file = Drive.Files.insert(resource, pdfFile);
}
// Save PDF as GDOC
resource.title = pdfName.replace(/pdf$/, 'gdoc');
var insertOpts = {
ocr: true,
ocrLanguage: options.ocrLanguage || 'en'
}
var gdocFile = Drive.Files.insert(resource, pdfFile, insertOpts);
// Get text from GDOC
var gdocDoc = DocumentApp.openById(gdocFile.id);
var text = gdocDoc.getBody().getText();
// We're done using the Gdoc. Unless requested to keepGdoc, delete it.
if (!options.keepGdoc) {
Drive.Files.remove(gdocFile.id);
}
// Save text file, if requested
if (options.keepTextfile) {
resource.title = pdfName.replace(/pdf$/, 'txt');
resource.mimeType = MimeType.PLAIN_TEXT;
var textBlob = Utilities.newBlob(text, MimeType.PLAIN_TEXT, resource.title);
var textFile = Drive.Files.insert(resource, textBlob);
}
// Return result of conversion
if (!options.keepTextfile || options.textResult) {
return text;
}
else {
return textFile.id
}
}
The conversion to DriveApp is helped with this utility from Bruce McPherson:
// From: http://ramblings.mcpher.com/Home/excelquirks/gooscript/driveapppathfolder
function getDriveFolderFromPath (path) {
return (path || "/").split("/").reduce ( function(prev,current) {
if (prev && current) {
var fldrs = prev.getFoldersByName(current);
return fldrs.hasNext() ? fldrs.next() : null;
}
else {
return current ? null : prev;
}
},DriveApp.getRootFolder());
}