Sending emails with attachments in Ubercart

Table of Contents

Ubercart has its own CA (Conditional Actions) module which purpose is to execute  some actions when certain events happen -- you can find CA configuration screen on admin/store/ca/overview. The most typical CA use case is sending emails to customers when order is placed. But, I couldn't find any answers on how files can be attached to these emails. Sending attachment can be an essential feature of your Ubercart store - potentially, you can send your software product attached to email to customer when order was approved, or you can send .pdf with invoice for printing, and lots of other use cases. Here is the related thread on ubercart.org with no answers: http://www.ubercart.org/forum/support/10634/sendingfileattachmentordernotificationemailcustomer

My use case description: customer and site admin need to get a notification email with attached .txt file in special format where all products are listed (for later import in 1C accounting software). This email is sent when order is placed on website.

1. Enable mimemail module

Go to http://drupal.org/project/mimemail and grab latest 6.x branch version.
Enable it in Drupal admin modules page, and check mimemail settings at admin/settings/mimemail (there is no need to change anything to make our new code work, though).

2. Implement _ca_action() hook

You need to use your new custom module. My module has 'sitehelper' name (I use that module name for small pieces of custom code, on all our projects).
By implementing caaction hook, we register new conditional action so it can be selected in CA admin section.

'uc_order',     '#title' => t('Order'),   );    $actions = array();   $actions['uc_order_email_invoice_mime'] = array(     '#title' => t('Email an order invoice (mime)'),     '#category' => t('Order'),     '#callback' => 'site_helper_action_email_invoice',     '#arguments' => array(       'order' => $order_arg,     ),   );    return $actions; } ?>

3. Implement action callback

This is my custom action. This function is executed every time customer creates an order, and the main line here is mimemail() call which generates and sends html email with attachment.
Here is the mimemail function arguments description from README:

  1. $sender      - a user object, text email address or an array with name, mail
  2. $recipient   - a user object, text email address or an array with name, mail
  3. $subject     - subject line
  4. $body        - body text in HTML format
  5. $plaintext   - boolean, whether to send messages in plaintext-only (default FALSE)
  6. $headers     - a keyed array with headers (optional)
  7. $text        - plaintext portion of a multipart e-mail (optional)
  8. $attachments - array of arrays with the file's path, MIME type (optional)
  9. $mailkey     - message identifier

primary_email;      $recipients[] = variable_get('uc_store_email', 'siteadmin@example.com');    $subject = "Test email subject";   $body = "Richtext in body";    // generate file that we will send as attachment.    $order_data = "Attachment file text";   $filepath = file_directory_temp() . '/' . 'order' . $order->order_id . '.txt';   file_put_contents($filepath, $order_data);    // send an email!   mimemail( $settings['from'], $recipients, $subject, $body, FALSE, array(), check_plain($body), array(array('filepath' => '/'.$filepath, 'filemime' => 'text/plain', 'filename' => 'order' . $order->order_id . '.txt')) );   unlink($filepath);  } ?>

4. Configure you action.

I wanted to use my action when customer creates an order, so I've clicked "Add a predicate" on Conditional Actions settings form, and selected "Customer completes checkout" trigger. After I've clicked submit button, I've skipped "conditions" settings form for this predicate, and on "Actions" tab I've selected my new action.

5. Profit!