I'm using a gift card plugin for my woocommerce shop and I would like to add a generated pdf file to allow customers to download the gift card as a pdf.

The idea is to use TCpdf or Fpdf to generate the pdf and output it as a string.

// Close and output PDF document
// This method has several options, check the source code documentation for more information.

echo $pdf->Output('S');

The problem is to get this file as an attachment with wp_mail. Right now, I have this code from the plugin, and i don't know how to call the pdf :

 * Hooks before the email is sent
 * @since 2.1
do_action( 'kodiak_email_send_before', $this );

$subject = $this->parse_tags( $subject );
$message = $this->parse_tags( $message );
$message = $this->build_email( $message );

$attachments = ??;

$sent = wp_mail( $to, $subject, $message, $this->get_headers(), $attachments );
$log_errors = apply_filters( 'kodiak_log_email_errors', true, $to, $subject, $message );

if( ! $sent && true === $log_errors ) {
  if ( is_array( $to ) ) {
    $to = implode( ',', $to );

  $log_message = sprintf(
    __( "Email from Gift Cards failed to send.\nSend time: %s\nTo: %s\nSubject: %s\n\n", 'kodiak-giftcards' ),
    date_i18n( 'F j Y H:i:s', current_time( 'timestamp' ) ),

Is someone can help me with this ?

Thank you for the answer !

3 Answers 3


It is possible to add an attachment using the standard 'wp_mail' function, however you would need to hook into the phpmailer_init action to do so.

Because this will require calling another function where you don't have any context, you may need to register the action function anonymously with the use ( $attachments ) statement, store the attachment content as a global variable or property, or place the attachment generation code into the new function.

I can see that OP's code seems to be in the context of a class method, so I'll try to create an example which should be compatible / consistent.

    // Previous Code...
    // Use this action to generate and/or attach files.
    add_filter( 'phpmailer_init', array( $this, 'add_attachments' ) );
    // And/or store the attachments as a property.
    $this->set_attachments( $attachments );
    $sent = wp_mail( $to, $subject, $message, $this->get_headers() );

    // Log errors etc...
    if ( ! $sent ) {
        $this->log_error( $error_message );

 * Add attachments to the email.
 * This method must be public in order to work as an action.
 * @param PHPMailer\PHPMailer\PHPMailer $phpmailer
public function add_attachments( $phpmailer ) {
    // Remove filter to prevent attaching the files to subsequent emails.
    remove_action( 'phpmailer_init', array( $this, 'add_attachments' ) );
    // Get or generate the attachments somehow.
    foreach ( $this->get_attachments() as $filename, $file_contents ) {
        try {
            $phpmailer->addStringAttachment( $file_contents, $filename );
        } catch( \Exception $ex ) {
            // An exception may thrown which would prevent the remaining files from being attached, so we'll catch these and log the errors.
            // This email may be sent without attachments. Do not try/catch if you don't want the email to be sent without all the attachments.
            $this->log_error( $ex->getMessage() );

 * Abstraction for the logging code to make it reusable.
 * @param string $log_message
protected function log_error( $log_message ) {
    if ( ! $this->log_errors ) {
    // Log errors here.

This is kind of tricky to do, but it is possible. Write a class which will extend PHPMailer. Override the addAttachment method, so in a certain condition (ex. you make a Boolean class variable) it will call addStringAttachment from the original class and in every other cases the addAttachment class. All you have to do is to set

$attachment = array("your content goes here");

When this is done, make sure that the global $phpmailer variable is an instance of your class and then create the specific condition. wp_mail will call the addAttachment from your class, and together with your special condition the attachment will be sent without saving the file.


Usually I proceed like this

$attachment = array(filepath);

Where filepath is the path to your file.

  • 1
    The author is asking to add attachments by string, not from a file path.
    – Laurent
    Apr 20, 2022 at 1:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.