commerce_invoice_receipt.module in Commerce Invoice Receipt 7.2
Same filename and directory in other branches
Provides a printable invoice receipt along with HTML mailing rules.
File
commerce_invoice_receipt.moduleView source
<?php
/**
* @file
* Provides a printable invoice receipt along with HTML mailing rules.
*/
/**
* Implements hook_menu().
*/
function commerce_invoice_receipt_menu() {
$items['admin/commerce/orders/%commerce_order/view/details'] = array(
'title' => 'Order details',
'page callback' => 'commerce_order_ui_order_view',
'page arguments' => array(
3,
),
'access callback' => 'commerce_order_admin_order_view_access',
'access arguments' => array(
3,
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
);
$items['admin/commerce/orders/%commerce_order/view/print'] = array(
'title' => 'Printable invoice',
'page callback' => 'commerce_invoice_receipt_view_print',
'page arguments' => array(
3,
),
'access callback' => 'commerce_order_access',
'access arguments' => array(
'view',
3,
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'parent' => 'admin/commerce/orders/%commerce_order',
);
$items['admin/commerce/orders/%commerce_order/view/mail'] = array(
'title' => 'Email the invoice',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'commerce_invoice_receipt_mail_form',
3,
),
'access callback' => 'commerce_order_access',
'access arguments' => array(
'view',
3,
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'parent' => 'admin/commerce/orders/%commerce_order',
);
$items['admin/commerce/orders/%commerce_order/edit/edit'] = array(
'title' => 'Edit order',
'page callback' => 'commerce_order_ui_order_form_wrapper',
'page arguments' => array(
3,
),
'access callback' => 'commerce_order_access',
'access arguments' => array(
'update',
3,
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -5,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
'file path' => drupal_get_path('module', 'commerce_order_ui'),
'file' => 'includes/commerce_order_ui.orders.inc',
);
$items['admin/commerce/orders/%commerce_order/edit/print'] = array(
'title' => 'Printable Invoice',
'page callback' => 'commerce_invoice_receipt_view_print',
'page arguments' => array(
3,
),
'access callback' => 'commerce_order_access',
'access arguments' => array(
'view',
3,
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'parent' => 'admin/commerce/orders/%commerce_order',
);
$items['admin/commerce/orders/%commerce_order/edit/mail'] = array(
'title' => 'Email the invoice',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'commerce_invoice_receipt_mail_form',
3,
),
'access callback' => 'commerce_order_access',
'access arguments' => array(
'view',
3,
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'parent' => 'admin/commerce/orders/%commerce_order',
);
$items['user/%user/orders/%commerce_order/view'] = array(
'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['user/%user/orders/%commerce_order/print'] = array(
'title' => 'Printable Invoice',
'page callback' => 'commerce_invoice_receipt_view_print',
'page arguments' => array(
3,
),
'access callback' => 'commerce_order_customer_order_view_access',
'access arguments' => array(
3,
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items['user/%user/orders/%commerce_order/mail'] = array(
'title' => 'Email the invoice',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'commerce_invoice_receipt_mail_form',
3,
),
'access callback' => 'commerce_order_access',
'access arguments' => array(
'view',
3,
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
return $items;
}
/**
* Implements hook_preprocess_commerce_invoice_receipt().
*/
function commerce_invoice_receipt_preprocess_commerce_invoice_receipt(&$variables) {
// Get the CSS path.
$css_path = _commerce_invoice_receipt_css_path();
// Get the contents of target CSS file. This way we can print the styles
// directly in the template file, and make it work with Emogrifier.
$css_styles = file_get_contents($css_path);
// Make this available in our template.
$variables['styles'] = $css_styles;
}
/**
* Menu callback, render invoice.
*/
function commerce_invoice_receipt_view_print($order, $view_mode = 'invoice', $breadcrumb = TRUE) {
$build = entity_view('commerce_order', array(
$order->order_id => $order,
), $view_mode, NULL, TRUE);
$invoice_info = _commerce_invoice_receipt_get_invoice_info($order, $build);
// Theme order invoice.
$html = theme('commerce_invoice_receipt', array(
'info' => $invoice_info,
'order' => $order,
));
// Print formatted output.
print _commerce_invoice_receipt_prepare_output($html);
}
/**
* Implements hook_entity_info_alter().
*/
function commerce_invoice_receipt_entity_info_alter(&$entity_info) {
$entity_info['commerce_order']['view modes']['invoice'] = array(
'label' => t('Invoice/Receipt'),
'custom settings' => TRUE,
);
}
/**
* Implements hook_theme().
*/
function commerce_invoice_receipt_theme() {
// Get current default theme
$default_theme_path = drupal_get_path('theme', variable_get('theme_default', NULL));
$default_template_path = drupal_get_path('module', 'commerce_invoice_receipt') . '/theme';
// Check if the template has been copied in the front end theme.
//
// A manual check is necessary because otherwise Drupal will not find the
// template override in the front end theme, when the site uses an admin theme
// (e.g. when an administrator tries to see printable invoice from the back
// end).
//
// This way the template will always be fetched from the front end theme if
// there is one.
//
// Also, this way the template file can be located anywhere in the front end
// theme (root, templates/, invoice/, or any other subfolder).
$files = file_scan_directory($default_theme_path, '/commerce-invoice-receipt.tpl.php$/');
if (count($files)) {
$first = reset($files);
$default_template_path = dirname($first->uri);
}
return array(
'commerce_invoice_receipt' => array(
'variables' => array(
'info' => NULL,
'order' => NULL,
),
'path' => $default_template_path,
'template' => 'commerce-invoice-receipt',
),
);
}
/**
* Implements hook_mail().
*/
function commerce_invoice_receipt_mail($key, &$message, $params) {
// Set the default language.
$langcode = isset($message['language']) ? $message['language']->language : NULL;
$options = array(
'langcode' => $langcode,
'context' => '',
);
switch ($key) {
// Setup an e-mailed invoice.
case 'invoice':
$build = entity_view('commerce_order', array(
$params['order']->order_id => $params['order'],
), 'invoice', NULL, TRUE);
$invoice_info = _commerce_invoice_receipt_get_invoice_info($params['order'], $build);
// Prepare the message headers.
if (isset($params['headers'])) {
$message['headers'] = $params['headers'];
}
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed;';
if (isset($params['cc'])) {
$message['headers']['Cc'] = $params['cc'];
}
if (isset($params['bcc'])) {
$message['headers']['Bcc'] = $params['bcc'];
}
// Get the email subject.
$message['subject'] = $params['subject'];
// Theme order invoice.
$html = theme('commerce_invoice_receipt', array(
'info' => $invoice_info,
'order' => $params['order'],
));
// Get formatted output.
$message['body'][] = _commerce_invoice_receipt_prepare_output($html);
break;
}
}
/**
* Set recipients of an invoice, and mail it.
*
* @ingroup forms
* @see
* commerce_invoice_receipt_mail_form_validate()
* commerce_invoice_receipt_mail_form_submit()
*/
function commerce_invoice_receipt_mail_form($form_state, $order) {
// Store the order ID.
$form['order_id'] = array(
'#type' => 'hidden',
'#value' => $order['build_info']['args'][0]->order_id,
);
// Recipient email address.
//
// Prepare the description text. Users who can manage orders should be able to
// send the invoice to multiple emails at once.
if (user_access('administer commerce_order entities')) {
$description = t('Please enter an email address where you want to receive another copy of the invoice. You may enter multiple email addresses, separated with a comma.');
}
else {
$description = t('Please enter an email address where you want to receive another copy of the invoice.');
}
// Form field.
$form['email'] = array(
'#type' => 'textfield',
'#title' => t('Recipient e-mail address'),
'#description' => $description,
'#default_value' => $order['build_info']['args'][0]->mail,
'#required' => TRUE,
);
// Form actions.
$form['actions'] = array(
'#type' => 'actions',
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Email invoice'),
);
return $form;
}
/**
* Form validation handler for the commerce_invoice_receipt_mail_form().
*
* @see commerce_invoice_receipt_mail_form()
*/
function commerce_invoice_receipt_mail_form_validate($form, &$form_state) {
$input = check_plain($form_state['values']['email']);
// Validation rules for administrators.
if (user_access('administer commerce_order entities')) {
$recipients = explode(',', $input);
// Since we will need to loop through all recipients (if there are more),
// and need to show only one form validation error message, we will use a
// flag that will indicate whether or not this should be displayed.
$invalid_recipients = FALSE;
foreach ($recipients as $recipient) {
// Trim the recipient email address. We need to do this in case the user
// separated the addresses with a space and a comma (", ").
$recipient = trim($recipient);
// Check if the email is valid.
if (!valid_email_address($recipient)) {
$invalid_recipients = TRUE;
}
}
// Show the validation message.
if ($invalid_recipients) {
form_set_error('email', t('Please enter a valid email address(es). Multiple emails should be separated with a comma.'));
}
}
elseif (!valid_email_address($input)) {
form_set_error('email', t('Please enter a valid email address.'));
}
}
/**
* Form submit handler for the commerce_invoice_receipt_mail_form().
*
* @see commerce_invoice_receipt_mail_form()
*/
function commerce_invoice_receipt_mail_form_submit($form, &$form_state) {
// Load the order.
$order = commerce_order_load($form_state['values']['order_id']);
// Default event we will invoke is the one for the front end.
$event = 'commerce_invoice_receipt_rules_event_invoice_from_front';
// However, if the current path is an administrative one, invoke a different
// event. By default there is no difference, but this provides greater
// flexibility to site builders.
if (path_is_admin(current_path())) {
$event = 'commerce_invoice_receipt_rules_event_invoice_from_admin';
}
// Invoke our event.
rules_invoke_event($event, $order, check_plain($form_state['values']['email']));
}
/**
* Helper function - generate an array for rendering all the invoice info.
*/
function _commerce_invoice_receipt_get_invoice_info($order, $build) {
$info = array(
'order_uid' => $order->uid,
'order_created' => $order->created,
'order_changed' => $order->changed,
'order_number' => $order->order_number,
'order_mail' => $order->mail,
'order_status' => $order->status,
'site_logo' => theme_get_setting('logo', variable_get('theme_default', NULL)),
);
// Adding a drupal_alter for other modules to edit the $info array prior to
// being displayed.
drupal_alter('commerce_invoice_receipt_info', $info, $order, $build);
if (isset($build['commerce_order'][$order->order_id]['commerce_customer_shipping'])) {
$info['customer_shipping'] = $build['commerce_order'][$order->order_id]['commerce_customer_shipping'][0]['#markup'];
}
if (isset($build['commerce_order'][$order->order_id]['commerce_customer_billing'][0]['#markup'])) {
$info['customer_billing'] = $build['commerce_order'][$order->order_id]['commerce_customer_billing'][0]['#markup'];
}
if (isset($build['commerce_order'][$order->order_id]['commerce_line_items'])) {
$info['line_items'] = $build['commerce_order'][$order->order_id]['commerce_line_items'][0]['#markup'];
}
if (isset($build['commerce_order'][$order->order_id]['commerce_order_total'])) {
$info['order_total'] = $build['commerce_order'][$order->order_id]['commerce_order_total'][0]['#markup'];
}
return $info;
}
/**
* Helper function - locate default CSS path.
*/
function _commerce_invoice_receipt_css_path() {
// Get current default theme
$default_theme_path = drupal_get_path('theme', variable_get('theme_default', NULL));
$default_template_css = drupal_get_path('module', 'commerce_invoice_receipt') . '/theme/commerce_invoice_receipt.css';
// Check if the default theme wants to override the invoice stylesheet.
$files = file_scan_directory($default_theme_path, '/commerce_invoice_receipt.css$/');
if (count($files)) {
$default_template_css = key($files);
}
return $default_template_css;
}
/**
* Helper function - prepare the content, depending on whether or not Emogrifier
* module is installed.
*/
function _commerce_invoice_receipt_prepare_output($html) {
// Since this module doesn't require Emogrifier, by default we will return the
// same HTML output.
$output = $html;
// If Emogrifier module is installed, process the HTML with styles.
if (module_exists('emogrifier')) {
$output = _emogrifier_process($html, NULL, NULL, NULL, NULL, NULL);
}
elseif (module_exists('mimemail_compress')) {
module_load_include('inc', 'mimemail_compress');
// Separate CSS from HTML for processing.
$parts = mimemail_compress_clean_message($html);
// Compress HTML and CSS into combined message.
if (!empty($parts)) {
$output = new mimemail_compress($parts['html'], $parts['css']);
$output = $output
->compress();
}
}
return $output;
}