ReceiptRenderingEngine::generate_receipt() │ public │ WC 1.0
Get the (transient) file name of the receipt for an order, creating a new file if necessary.
If $force_new is false, and a receipt file for the order already exists (as pointed by order meta key RECEIPT_FILE_NAME_META_KEY), then the name of the already existing receipt file is returned.
If $force_new is true, OR if it's false but no receipt file for the order exists (no order meta with key RECEIPT_FILE_NAME_META_KEY exists, OR it exists but the file it points to doesn't), then a new receipt transient file is created with the supplied expiration date (defaulting to "tomorrow"), and the new file name is stored as order meta with the key RECEIPT_FILE_NAME_META_KEY.
public function generate_receipt( $order, $expiration_date = null, bool $force_new = false ): ?string {
if ( ! $order instanceof WC_Abstract_Order ) {
$order = wc_get_order( $order );
if ( false === $order ) {
return null;
}
}
if ( ! $force_new ) {
$existing_receipt_filename = $this->get_existing_receipt( $order );
if ( ! is_null( $existing_receipt_filename ) ) {
return $existing_receipt_filename;
}
}
$expiration_date ??=
$this->legacy_proxy->call_function(
'gmdate',
'Y-m-d',
$this->legacy_proxy->call_function(
'strtotime',
'+1 days'
)
);
/**
* Filter to customize the set of data that is used to render the receipt.
* The formatted line items aren't included, use the woocommerce_printable_order_receipt_formatted_line_item
* filter to customize those.
*
* See the value returned by the 'get_order_data' and 'get_woo_pay_data' methods for a reference of
* the structure of the data.
*
* See the template file, Templates/order-receipt.php, for reference on how the data is used.
*
* @param array $data The original set of data.
* @param WC_Abstract_Order $order The order for which the receipt is being generated.
* @returns array The updated set of data.
*
* @since 9.0.0
*/
$data = apply_filters( 'woocommerce_printable_order_receipt_data', $this->get_order_data( $order ), $order );
$formatted_line_items = array();
$row_index = 0;
foreach ( $data['line_items'] as $line_item_data ) {
$quantity_data = isset( $line_item_data['quantity'] ) ? " × {$line_item_data['quantity']}" : '';
$line_item_display_data = array(
'inner_html' => "<td>{$line_item_data['title']}$quantity_data</td><td>{$line_item_data['amount']}</td>",
'tr_attributes' => array(),
'row_index' => $row_index++,
);
/**
* Filter to customize the HTML that gets rendered for each order line item in the receipt.
*
* $line_item_display_data will be passed (and must be returned) with the following keys:
*
* - inner_html: the HTML text that will go inside a <tr> element, note that
* wp_kses_post will be applied to this text before actual rendering.
* - tr_attributes: attributes (e.g. 'class', 'data', 'style') that will be applied to the <tr> element,
* as an associative array of attribute name => value.
* - row_index: a number that starts at 0 and increases by one for each processed line item.
*
* $line_item_data will contain the following keys:
*
* - type: One of 'product', 'subtotal', 'discount', 'fee', 'shipping_total', 'taxes_total', 'amount_paid'
* - title
* - amount (formatted with wc_price)
* - item (only when type is 'product'), and instance of WC_Order_Item
* - quantity (only when type is 'product')
*
* @param string $line_item_display_data Data to use to generate the HTML table row to be rendered for the line item.
* @param array $line_item_data The relevant data for the line item for which the HTML table row is being generated.
* @param WC_Abstract_Order $order The order for which the receipt is being generated.
* @return string The actual data to use to generate the HTML for the line item.
*
* @since 9.0.0
*/
$line_item_display_data = apply_filters( 'woocommerce_printable_order_receipt_line_item_display_data', $line_item_display_data, $line_item_data, $order );
$attributes = '';
foreach ( $line_item_display_data['tr_attributes'] as $attribute_name => $attribute_value ) {
$attribute_value = esc_attr( $attribute_value );
$attributes .= " $attribute_name=\"$attribute_value\"";
}
$formatted_line_items[] = wp_kses_post( "<tr$attributes>{$line_item_display_data['inner_html']}</tr>" );
}
$data['formatted_line_items'] = $formatted_line_items;
ob_start();
$css = include __DIR__ . '/Templates/order-receipt-css.php';
$css = ob_get_contents();
ob_end_clean();
/**
* Filter to customize the CSS styles used to render the receipt.
*
* See Templates/order-receipt.php for guidance on the existing HTMl elements and their ids.
* See Templates/order-receipt-css.php for the original CSS styles.
*
* @param string $css The original CSS styles to use.
* @param WC_Abstract_Order $order The order for which the receipt is being generated.
* @return string The actual CSS styles that will be used.
*
* @since 9.0.0
*/
$data['css'] = apply_filters( 'woocommerce_printable_order_receipt_css', $css, $order );
$default_template_path = __DIR__ . '/Templates/order-receipt.php';
/**
* Filter the order receipt template path.
*
* @since 9.2.0
* @hook wc_get_template
* @param string $template The template path.
* @param string $template_name The template name.
* @param array $args The available data for the template.
* @param string $template_path The template path.
* @param string $default_path The default template path.
*/
$template_path = apply_filters(
'wc_get_template',
$default_template_path,
'ReceiptRendering/order-receipt.php',
$data,
$default_template_path,
$default_template_path
);
if ( ! file_exists( $template_path ) ) {
$template_path = $default_template_path;
}
ob_start();
include $template_path;
$rendered_template = ob_get_contents();
ob_end_clean();
$file_name = $this->transient_files_engine->create_transient_file( $rendered_template, $expiration_date );
$order->update_meta_data( self::RECEIPT_FILE_NAME_META_KEY, $file_name );
$order->save_meta_data();
return $file_name;
}