File: /home/zwafgyp/locationdebateau/wp-content/plugins/woocommerce-delivery-notes/templates/base.php
<?php
/**
* WCDN Document Template.
*
* This is the shared layout file rendered for all five document types:
* invoice, receipt, delivery note, packing slip, and credit note.
*
* ============================================================================
* OVERRIDING THIS TEMPLATE
* ============================================================================
* Copy this file to your active theme and the plugin will use your copy
* instead of the bundled one:
*
* your-theme/woocommerce-delivery-notes/base.php
*
* Keep the @version tag in your copy. The plugin uses it to detect when the
* bundled template has been updated so it can warn you that your override may
* need to be updated too.
*
* ============================================================================
* OVERRIDING CSS
* ============================================================================
* Three CSS files control the document appearance. Copy any of them to your
* theme at the corresponding path to override styles without editing the plugin:
*
* Shared styles (HTML + PDF):
* your-theme/woocommerce-delivery-notes/css/style.css
*
* HTML print-preview only:
* your-theme/woocommerce-delivery-notes/css/html/style.css
*
* PDF generation only:
* your-theme/woocommerce-delivery-notes/css/pdf/style.css
*
* Theme CSS is loaded first; the plugin's dynamic settings CSS is applied on
* top, so inline styles set via the settings page will still take effect.
*
* ============================================================================
* USING HOOKS INSTEAD OF FULL OVERRIDES
* ============================================================================
* For smaller changes, hooks are safer than copying the whole file because
* they are unaffected by plugin updates:
*
* Actions (fire unconditionally unless noted):
* wcdn_before_document( $order, $template ) — before all content
* wcdn_before_logo( $order, $template ) — before shop logo
* wcdn_after_logo( $order, $template ) — after shop logo
* wcdn_before_title( $order, $template ) — before document title
* wcdn_after_title( $order, $template ) — after document title
* wcdn_before_branding( $order, $template ) — before shop name/address block
* wcdn_after_branding( $order, $template ) — after shop name/address block *
* wcdn_before_addresses( $order, $template ) — before billing/shipping/meta
* wcdn_after_addresses( $order, $template ) — after billing/shipping/meta *
* wcdn_before_items( $order, $template ) — before the line-items table *
* wcdn_order_item_before( $item, $order, $template ) — before each line item
* wcdn_order_item_after( $item, $order, $template ) — after each line item
* wcdn_after_items( $order, $template ) — after the line-items table *
* wcdn_before_totals( $order, $template ) — before the totals table
* wcdn_after_totals( $order, $template ) — after the totals table
* wcdn_before_pay_button( $order, $template ) — before the pay-now button
* wcdn_after_pay_button( $order, $template ) — after the pay-now button
* wcdn_before_notes( $order, $template ) — before the customer note
* wcdn_after_notes( $order, $template ) — after the customer note *
* wcdn_before_policies( $order, $template ) — before the policies section
* wcdn_after_policies( $order, $template ) — after the policies section
* wcdn_before_complimentary_close( $order, $template ) — before the complimentary close
* wcdn_after_complimentary_close( $order, $template ) — after the complimentary close
* wcdn_before_footer( $order, $template ) — before the footer
* wcdn_after_footer( $order, $template ) — after the footer
* wcdn_after_document( $order, $template ) — after all content
*
* Filters:
* wcdn_watermark_text( $text, $order, $template ) — override watermark text
*
* * = fires only when the section is visible (conditional context)
*
* @package WCDN/Templates
* @version 7.1.2
*/
defined( 'ABSPATH' ) || exit;
/**
* ============================================================================
* AVAILABLE VARIABLES
* ============================================================================
* All variables below are prepared by Template_Renderer::prepare_template_data()
* and extracted into scope before this file is included. The full raw data is
* also accessible via the $data array (e.g. $data['order'], $data['settings']).
*
* --- SHOP ---
*
* @var array $shop {
* Shop/store information pulled from plugin settings.
*
* @type string $name Store name.
* @type string $address Store address (may contain HTML line breaks).
* @type string $phone Store phone number.
* @type string $email Store email address.
* @type string $logo Logo URL (used in HTML context).
* @type string $logo_path Logo absolute file path (used in PDF context).
* }
*
* --- ORDER ---
* @var array $order {
* Formatted order data for the current document.
*
* @type int $id WooCommerce order ID.
* @type string $invoiceNumber Formatted invoice number (e.g. "INV-00042").
* @type string $documentDate Formatted document date string.
* @type string $orderNumber WooCommerce order number (may differ from ID).
* @type string $date Order creation date (ISO 8601).
* @type string $paymentDate Order payment date (ISO 8601), empty if unpaid.
* @type string $paymentMethod Payment gateway title (e.g. "PayPal").
* @type string $shippingMethod Shipping method name (e.g. "Flat rate").
* @type string $currency Currency code (e.g. "USD").
* @type string $payment_url Checkout payment URL; empty when already paid.
* @type string $customer_note Customer-provided order note.
* @type string $status Order status slug (e.g. "processing").
* @type array $billing {
* @type string $name Full billing name.
* @type array $address Address lines as a flat array of strings.
* @type string $phone Billing phone number.
* @type string $email Billing email address.
* }
* @type array $shipping {
* @type string $name Full shipping name.
* @type array $address Address lines as a flat array of strings.
* }
* @type array $items See $items below.
* @type array $totals See $totals below.
* @type array $refund Refund data; used by credit note template only.
* }
*
* --- DOCUMENT ---
* @var array $document {
* Document-level content pulled from template settings.
*
* @type string $policies Policies text (HTML allowed).
* @type string $complimentaryClose Complimentary close text (HTML allowed).
* @type string $footer Footer text (HTML allowed).
* @type bool $isRTL Whether the site locale is right-to-left.
* }
*
* --- SETTINGS ---
* @var array $settings {
* Per-template settings configured in the admin Template Editor.
* All values below are examples; the full set is defined in Template_Engine.
*
* Visibility toggles (bool):
* @type bool $showLogo Show the store logo.
* @type bool $showDocumentTitle Show the document title heading.
* @type bool $showShopName Show the store name.
* @type bool $showShopAddress Show the store address.
* @type bool $showShopPhone Show the store phone number.
* @type bool $showShopEmail Show the store email address.
* @type bool $showBillingAddress Show the billing address column.
* @type bool $showShippingAddress Show the shipping address column.
* @type bool $showBillingPhone Show billing phone in the address block.
* @type bool $showBillingEmail Show billing email in the address block.
* @type bool $showProductImages Show product thumbnail images in the items table.
* @type bool $showWatermark Show the watermark overlay.
* @type bool $showCustomerNote Show the customer order note.
* @type bool $showPolicies Show the policies section.
* @type bool $showComplimentaryClose Show the complimentary close section.
* @type bool $showFooter Show the footer section.
* @type bool $showSubtotal Show the subtotal row in the totals table.
* @type bool $showTax Show the tax row in the totals table.
* @type bool $showShipping Show the shipping row in the totals table.
* @type bool $showProductCharges Master toggle for subtotal/tax/shipping rows.
* @type bool $displayPriceInProductDetailsTable Show price/total columns in the items table.
*
* Labels (string):
* @type string $documentTitle The document heading text (e.g. "Invoice").
* @type string $billingAddressText Label above the billing address block.
* @type string $shippingAddressText Label above the shipping address block.
* @type string $billingPhoneText Label for the billing phone field.
* @type string $billingEmailText Label for the billing email field.
* @type string $shopPhoneText Label prefix for the store phone number.
* @type string $shopEmailText Label prefix for the store email address.
* @type string $customerNoteTitle Label shown before the customer note.
* @type string $payNowLabel Text on the pay-now button.
* @type string $logoAlignment Logo alignment: 'left', 'center', or 'right'.
* @type string $watermarkText Watermark overlay text.
* @type string $watermarkLayout Watermark layout: 'single' or 'repeat'.
* @type string $orderDataHeaderText Optional heading above the order meta table.
*
* Numeric:
* @type int $productImageSize Product image size in pixels (default: 40).
* @type int $documentZoom Document zoom level 70–130 (default: 100).
* }
*
* --- ITEMS ---
* @var array $items {
* Formatted line items. Each element is an associative array:
*
* @type string $name Product name (may contain HTML).
* @type string $sku Product SKU; empty string when not set.
* @type string $price Formatted unit price HTML (e.g. "<span>$10.00</span>").
* @type int $quantity Line item quantity.
* @type string $total Formatted line total HTML.
* @type int $product_id WooCommerce product ID (0 if product deleted).
* @type int $order_item_id WooCommerce order item ID.
* @type array $meta Extra meta rows: [ [ 'label' => '', 'value' => '' ], … ]
* @type array|null $addon WC Product Addons data: [ 'name' => '', 'value' => '' ] or null.
* @type string $image_url Product image URL (HTML context).
* @type string $image_path Product image absolute path (PDF context).
* }
*
* --- TOTALS ---
* @var array $totals {
* Formatted order totals. Keys are conditionally present based on the order.
*
* @type string $subtotal Formatted subtotal HTML.
* @type string $discount Formatted discount HTML (present when > 0).
* @type string $tax Formatted tax HTML (present when no tax lines).
* @type array $tax_lines Itemised tax lines: [ [ 'label' => '', 'value' => '' ], … ]
* @type string $shipping Formatted shipping total HTML.
* @type array $fee_lines Fee lines: [ [ 'label' => '', 'value' => '' ], … ]
* @type string $total Formatted order total HTML.
* @type bool $has_refund True when the order has a non-zero refund.
* @type string $refunded Formatted refunded amount HTML (present when has_refund).
* @type string $net_total Formatted net total HTML (present when has_refund).
* @type string $tax_label Inclusive tax note for net total (may be empty).
* @type string $awcdp_deposit Deposit amount (AWCDP plugin; present when applicable).
* @type string $awcdp_future_payments Future payments amount (AWCDP plugin; present when applicable).
* @type string $dfw_deposit Deposit amount (Deposits for WooCommerce plugin).
* @type string $dfw_future_payment Future payment amount (Deposits for WooCommerce plugin).
* @type string $dfw_total_cart_amount Total cart amount (Deposits for WooCommerce plugin).
* }
*
* --- OTHER ---
* @var string $template Template key: 'invoice', 'receipt', 'deliverynote', 'packingslip', 'creditnote'.
* @var string $type Render context: 'html' (print preview) or 'pdf' (Dompdf).
* @var bool $is_rtl True when the document locale is right-to-left.
* @var bool $show_billing True when the billing address column should be rendered.
* @var bool $show_shipping True when the shipping address column should be rendered.
* @var string $order_meta_position 'columns' (beside addresses) or 'below' (separate table).
* @var array $order_meta_fields Prepared meta rows ready for rendering.
* @var bool $has_order_meta True when at least one meta row has a non-empty value.
* @var int $col_width Width percentage assigned to each address/meta column.
* @var int $angle Watermark rotation angle in degrees.
* @var bool $show_pay_now_button True when the pay-now button should be shown.
*/
/*
* Helper: build an inline style string from a meta field's font settings.
* $field keys: fontSize, fontWeight, textAlign, color.
* Returns an empty string when no fontSize is set (no inline style needed).
*/
$meta_style_for = function ( $field ) {
if ( ! isset( $field['fontSize'] ) ) {
return '';
}
return 'font-size:' . $field['fontSize'] . 'px;'
. 'font-weight:' . $field['fontWeight'] . ';'
. 'text-align:' . $field['textAlign'] . ';'
. 'color:' . $field['color'] . ';';
};
/*
* Build address column closures.
* Each visible column (billing, shipping, meta) is stored as a callable so
* they can be reversed for RTL layouts without duplicating markup logic.
*/
$columns_data = array();
/*
* Billing address column.
* Controlled by: Settings > Show Billing Address
* CSS classes: .wcdn-billing-address
*/
if ( $show_billing ) {
$columns_data['billing'] = function () use ( $order, $settings, $col_width, $order_meta_position ) {
?>
<td style="width: <?php echo esc_attr( $col_width ); ?>%; vertical-align: top;" class="wcdn-billing-address">
<strong><?php echo esc_html( $settings['billingAddressText'] ); ?></strong>
<p>
<?php echo esc_html( $order['billing']['name'] ); ?><br />
<?php if ( ! empty( $order['billing']['address'] ) ) : ?>
<?php foreach ( $order['billing']['address'] as $line ) : ?>
<?php echo esc_html( $line ); ?><br />
<?php endforeach; ?>
<?php endif; ?>
</p>
<?php
/*
* Phone and email are only shown here when order data is in 'columns' mode.
* In 'below' mode they appear inside the order meta table instead.
*/
?>
<?php if ( 'columns' === $order_meta_position ) : ?>
<?php if ( ! empty( $settings['showBillingPhone'] ) && ! empty( $order['billing']['phone'] ) ) : ?>
<p class="wcdn-columns-billingPhone">
<?php echo esc_html( ( $settings['billingPhoneText'] ?? __( 'Phone', 'woocommerce-delivery-notes' ) ) . ': ' . wcdn_format_phone_number( $order['billing']['phone'], $order['billing']['country'] ?? '' ) ); ?>
</p>
<?php endif; ?>
<?php if ( ! empty( $settings['showBillingEmail'] ) && ! empty( $order['billing']['email'] ) ) : ?>
<p class="wcdn-columns-billingEmail">
<?php echo esc_html( ( $settings['billingEmailText'] ?? __( 'Email', 'woocommerce-delivery-notes' ) ) . ': ' . $order['billing']['email'] ); ?>
</p>
<?php endif; ?>
<?php endif; ?>
</td>
<?php
};
}
/*
* Shipping address column.
* Controlled by: Settings > Show Shipping Address
* CSS classes: .wcdn-shipping-address
*/
if ( $show_shipping ) {
$columns_data['shipping'] = function () use ( $order, $settings, $col_width ) {
?>
<td style="width: <?php echo esc_attr( $col_width ); ?>%; vertical-align: top;" class="wcdn-shipping-address">
<strong><?php echo esc_html( $settings['shippingAddressText'] ); ?></strong>
<p>
<?php echo esc_html( $order['shipping']['name'] ); ?><br />
<?php if ( ! empty( $order['shipping']['address'] ) ) : ?>
<?php foreach ( $order['shipping']['address'] as $line ) : ?>
<?php echo esc_html( $line ); ?><br />
<?php endforeach; ?>
<?php endif; ?>
<?php if ( ! empty( $order['shipping']['email'] ) ) : ?>
<?php echo esc_html( __( 'Email', 'woocommerce-delivery-notes' ) . ': ' . $order['shipping']['email'] ); ?><br />
<?php endif; ?>
</p>
</td>
<?php
};
}
/*
* Order meta column (columns mode only).
* When order data position is set to 'columns', the meta table appears as a
* third column beside billing/shipping. When set to 'below', it is rendered
* as a full-width table below the address grid instead (see further below).
* CSS classes: .wcdn-order-meta
*/
if ( $has_order_meta && 'columns' === $order_meta_position ) {
$columns_data['meta'] = function () use ( $order_meta_fields, $settings, $col_width, $meta_style_for ) {
?>
<td style="width: <?php echo esc_attr( $col_width ); ?>%; vertical-align: top;" class="wcdn-order-meta">
<table>
<?php foreach ( $order_meta_fields as $field ) : ?>
<?php
/*
* Each $field: [ 'key' => string, 'label' => string, 'value' => string,
* 'show' => bool, 'fontSize' => int, 'fontWeight' => string,
* 'textAlign' => string, 'color' => string ]
* Only rows with show=true AND a non-empty value are rendered.
*/
?>
<?php if ( $field['show'] && ! empty( $field['value'] ) ) : ?>
<?php $meta_style = $meta_style_for( $field ); ?>
<tr class="wcdn-meta-<?php echo esc_attr( $field['key'] ); ?>">
<td class="label" <?php echo $meta_style ? ' style="' . esc_attr( $meta_style ) . '"' : ''; ?>>
<?php echo esc_html( $field['label'] ); ?>:</td>
<td class="value" <?php echo $meta_style ? ' style="' . esc_attr( $meta_style ) . '"' : ''; ?>>
<?php echo esc_html( $field['value'] ); ?></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</table>
</td>
<?php
};
}
/* RTL support: reverse column order so billing appears on the right. */
if ( $is_rtl ) {
$columns_data = array_reverse( $columns_data );
}
?>
<?php
/*
* DOCUMENT WRAPPER
* CSS class: .wcdn-document
* Add .is-rtl when the locale is right-to-left.
*/
?>
<div class="wcdn-document <?php echo $is_rtl ? 'is-rtl' : ''; ?>">
<?php
/**
* Hook: wcdn_before_document
*
* Fires at the very start of the document, inside .wcdn-document but before
* any content. Use this to prepend custom HTML to every document.
*
* @param array $order Formatted order data array.
* @param string $template Template key (e.g. 'invoice').
*/
do_action( 'wcdn_before_document', $order, $template );
?>
<?php
/*
* WATERMARK
* Controlled by: Settings > Watermark
* Two layouts available: 'single' (centred overlay) or 'repeat' (tiled grid of 12 spans).
* CSS classes: .wcdn-watermark | .wcdn-watermark-repeat
*/
?>
<?php
if (
! empty( $settings['showWatermark'] ) && ! empty( $settings['watermarkText'] ) ) :
/**
* Filter the watermark text displayed on the document.
*
* Use this filter to replace the watermark text programmatically
* (e.g. based on order status, customer, or document type) without
* changing the setting stored in the database.
*
* @param string $watermark_text The configured watermark text.
* @param array $order Formatted order data array.
* @param string $template Template key.
* @since 7.1.2
*/
$watermark_text = apply_filters( 'wcdn_watermark_text', $settings['watermarkText'], $order, $template );
if ( isset( $settings['watermarkLayout'] ) && 'repeat' === $settings['watermarkLayout'] ) :
?>
<div class="wcdn-watermark-repeat">
<?php for ( $i = 0; $i < 12; $i++ ) : ?>
<span style="transform: rotate(<?php echo esc_attr( $angle ); ?>deg);">
<?php echo esc_html( $watermark_text ); ?>
</span>
<?php endfor; ?>
</div>
<?php else : ?>
<div class="wcdn-watermark" style="transform: translate(-50%, -50%) rotate(<?php echo esc_attr( $angle ); ?>deg);">
<?php echo esc_html( $watermark_text ); ?>
</div>
<?php endif; ?>
<?php endif; ?>
<?php
/**
* Hook: wcdn_before_logo
*
* Fires before the shop logo block (before the logo visibility check).
* Use this to prepend a banner, header image, or custom HTML above the logo.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_logo', $order, $template );
?>
<?php
/*
* LOGO
* Controlled by: Settings > Logo
* In PDF context, $shop['logo_path'] (absolute path) is used instead of $shop['logo'] (URL)
* so Dompdf can read the file directly.
* CSS classes: .wcdn-logo .wcdn-logo-image
* Alignment modifier: .align-left | .align-center | .align-right
*/
?>
<?php if ( ! empty( $settings['showLogo'] ) ) : ?>
<div
class="wcdn-logo align-<?php echo esc_attr( isset( $settings['logoAlignment'] ) ? $settings['logoAlignment'] : 'center' ); ?>">
<?php if ( ! empty( $shop['logo'] ) ) : ?>
<img class="wcdn-logo-image"
src="<?php echo esc_attr( ( 'pdf' === $type && ! empty( $shop['logo_path'] ) ) ? $shop['logo_path'] : $shop['logo'] ); ?>"
alt="<?php echo esc_attr( $shop['name'] ?? '' ); ?>" />
<?php endif; ?>
</div>
<?php endif; ?>
<?php
/**
* Hook: wcdn_after_logo
*
* Fires after the logo block (whether the logo is shown or not).
* Use this to insert content between the logo and the document title.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_logo', $order, $template );
?>
<?php
/**
* Hook: wcdn_before_title
*
* Fires before the document title heading (before the visibility check).
* Use this to insert a tagline, reference number, or custom element between
* the logo and the document title.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_title', $order, $template );
?>
<?php
/*
* DOCUMENT TITLE
* Controlled by: Settings > Document Title
* $settings['documentTitle'] holds the configured heading text.
* CSS classes: .wcdn-title
*/
?>
<?php if ( ! isset( $settings['showDocumentTitle'] ) || ! empty( $settings['showDocumentTitle'] ) ) : ?>
<h1 class="wcdn-title">
<?php echo esc_html( isset( $settings['documentTitle'] ) ? $settings['documentTitle'] : __( 'Document', 'woocommerce-delivery-notes' ) ); ?>
</h1>
<?php endif; ?>
<?php
/**
* Hook: wcdn_after_title
*
* Fires after the document title heading.
* Use this to insert a subtitle, tagline, or custom metadata line.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_title', $order, $template );
?>
<?php
/**
* Hook: wcdn_before_branding
*
* Fires before the shop name/address/phone/email block (before the visibility
* check). Use this to insert content between the document title and the
* store details regardless of whether the branding block is enabled.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_branding', $order, $template );
?>
<?php
/*
* SHOP / BRANDING BLOCK
* Controlled by: Settings > Shop Name / Address / Phone / Email
* The entire block (including its hr) is hidden when all four toggles are off.
* CSS classes: .wcdn-shop .wcdn-shop-name .wcdn-shop-address
* .wcdn-shop-phone .wcdn-shop-email
*/
?>
<?php
if (
! empty( $settings['showShopName'] ) ||
! empty( $settings['showShopAddress'] ) ||
! empty( $settings['showShopPhone'] ) ||
! empty( $settings['showShopEmail'] )
) :
?>
<hr />
<div class="wcdn-shop">
<?php if ( ! empty( $settings['showShopName'] ) && ! empty( $shop['name'] ) ) : ?>
<div class="wcdn-shop-name"><?php echo esc_html( $shop['name'] ); ?></div>
<?php endif; ?>
<?php
/*
* $shop['address'] may contain <br> tags from the settings textarea.
* nl2br + wp_kses_post preserves intentional line breaks safely.
*/
?>
<?php if ( ! empty( $settings['showShopAddress'] ) && ! empty( $shop['address'] ) ) : ?>
<div class="wcdn-shop-address"><?php echo nl2br( wp_kses_post( $shop['address'] ) ); ?></div>
<?php endif; ?>
<?php
/*
* $settings['shopPhoneText'] is the label prefix (e.g. "Phone").
* When set, it is prepended as "Phone: 555-1234".
*/
?>
<?php if ( ! empty( $settings['showShopPhone'] ) && ! empty( $shop['phone'] ) ) : ?>
<div class="wcdn-shop-phone">
<?php echo esc_html( ( ! empty( $settings['shopPhoneText'] ) ? $settings['shopPhoneText'] . ': ' : '' ) . $shop['phone'] ); ?>
</div>
<?php endif; ?>
<?php if ( ! empty( $settings['showShopEmail'] ) && ! empty( $shop['email'] ) ) : ?>
<div class="wcdn-shop-email">
<?php echo esc_html( ( ! empty( $settings['shopEmailText'] ) ? $settings['shopEmailText'] . ': ' : '' ) . $shop['email'] ); ?>
</div>
<?php endif; ?>
</div>
<?php
/**
* Hook: wcdn_after_branding
*
* Fires after the shop name/address/phone/email block.
* Only fires when at least one branding field is enabled.
* Use this to append additional store information (e.g. VAT number,
* registration number) directly below the shop details.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_branding', $order, $template );
?>
<?php endif; ?>
<?php
/**
* Hook: wcdn_before_addresses
*
* Fires before the billing/shipping address grid and order meta block (before
* the visibility check). Use this to add content between the branding and
* address sections regardless of whether any address is enabled.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_addresses', $order, $template );
?>
<?php
/*
* ADDRESS GRID + ORDER META
* $show_address_grid — true when billing and/or shipping is enabled.
* $show_meta_below — true when order data position is 'below'.
* The hr and this entire section are hidden when both are false.
* CSS classes: .wcdn-address-grid .wcdn-order-meta
* .wcdn-order-meta-below .wcdn-order-data-header
*/
?>
<?php
$show_address_grid = ! empty( $columns_data );
$show_meta_below = 'below' === $order_meta_position && $has_order_meta;
?>
<?php if ( $show_address_grid || $show_meta_below ) : ?>
<hr />
<?php
/*
* Address grid: a single-row table with one <td> per column.
* Column width ($col_width %) is divided equally across visible columns.
* Column order is reversed automatically for RTL locales (see above).
*/
?>
<?php if ( $show_address_grid ) : ?>
<table class="wcdn-address-grid">
<tr>
<?php
foreach ( $columns_data as $column ) {
$column();
}
?>
</tr>
</table>
<?php endif; ?>
<?php if ( $show_meta_below ) : ?>
<?php
/*
* Optional section header above the meta table.
* Controlled by: Settings > Order Data Header / Order Data Header Border.
*/
?>
<?php if ( ! empty( $settings['showOrderDataHeader'] ) && ! empty( $settings['orderDataHeaderText'] ) ) : ?>
<p class="wcdn-order-data-header">
<?php echo esc_html( $settings['orderDataHeaderText'] ); ?>
</p>
<?php if ( ! empty( $settings['showOrderDataHeaderBorder'] ) ) : ?>
<hr class="wcdn-order-data-header-border" style="margin: 0" />
<?php endif; ?>
<?php endif; ?>
<?php
/*
* Full-width order meta table (shown when position = 'below').
* Each $field in $order_meta_fields: [ 'key', 'label', 'value', 'show',
* 'fontSize', 'fontWeight', 'textAlign', 'color' ]
* CSS row class: .wcdn-meta-{key} (e.g. .wcdn-meta-orderNumber)
*/
?>
<table class="wcdn-order-meta wcdn-order-meta-below" style="width: 100%;">
<?php foreach ( $order_meta_fields as $field ) : ?>
<?php if ( $field['show'] && ! empty( $field['value'] ) ) : ?>
<?php $meta_style = $meta_style_for( $field ); ?>
<tr class="wcdn-meta-<?php echo esc_attr( $field['key'] ); ?>">
<td class="label" <?php echo $meta_style ? ' style="' . esc_attr( $meta_style ) . '"' : ''; ?>>
<?php echo esc_html( $field['label'] ); ?>:</td>
<td class="value" <?php echo $meta_style ? ' style="' . esc_attr( $meta_style ) . '"' : ''; ?>>
<?php echo esc_html( $field['value'] ); ?></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</table>
<?php endif; ?>
<?php
/**
* Hook: wcdn_after_addresses
*
* Fires after the billing/shipping address grid and order meta block.
* Only fires when at least one address or meta section is visible.
* Use this to add content between the address block and the items table
* (e.g. a delivery instructions field or a custom reference number).
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_addresses', $order, $template );
?>
<?php endif; ?>
<?php
/*
* LINE ITEMS TABLE
* Hidden entirely when $items is empty (e.g. manual-amount refunds).
* $show_price_cols — true when price/total columns should be shown.
* For normal templates: controlled by displayPriceInProductDetailsTable setting.
* For credit notes: controlled by displayRefundItemsInTable.
* Column widths (with prices): Product 50% | Price 15% | Qty 15% | Total 20%
* Column widths (without prices): Product 80% | Qty 20%
* CSS classes: .wcdn-items .wcdn-col-product .wcdn-col-price
* .wcdn-col-qty .wcdn-col-total .wcdn-product-cell
* .wcdn-item-name .wcdn-item-sku .wcdn-item-meta
* .wcdn-item-image .wcdn-item-layout
* .wcdn-item-addon-name .wcdn-item-addon-value
*/
?>
<?php if ( ! empty( $items ) ) : ?>
<?php
$show_price_cols = ! empty( $settings['displayPriceInProductDetailsTable'] ) ||
( 'creditnote' === $template && ! empty( $settings['displayRefundItemsInTable'] ) );
?>
<?php
/**
* Hook: wcdn_before_items
*
* Fires immediately before the line-items table.
* Use this to add a custom section header or summary row above the table.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_items', $order, $template );
?>
<hr style="margin: 0 0 10px 0;" />
<table class="wcdn-items">
<?php if ( $show_price_cols ) : ?>
<colgroup>
<col class="wcdn-col-product" style="width:50%;">
<col class="wcdn-col-price" style="width:15%;">
<col class="wcdn-col-qty" style="width:15%;">
<col class="wcdn-col-total" style="width:20%;">
</colgroup>
<?php endif; ?>
<thead>
<tr>
<?php
/* Header label switches to "Refunded Item" for credit notes. */
?>
<th style="width:<?php echo $show_price_cols ? '50%' : '80%'; ?>;">
<?php echo esc_html( ( 'creditnote' === $template ) ? __( 'Refunded Item', 'woocommerce-delivery-notes' ) : __( 'Product', 'woocommerce-delivery-notes' ) ); ?>
</th>
<?php if ( $show_price_cols ) : ?>
<th style="width:15%;"><?php esc_html_e( 'Price', 'woocommerce-delivery-notes' ); ?></th>
<?php endif; ?>
<th style="width:<?php echo $show_price_cols ? '15%' : '20%'; ?>;">
<?php esc_html_e( 'Quantity', 'woocommerce-delivery-notes' ); ?></th>
<?php if ( $show_price_cols ) : ?>
<th style="width:20%;">
<?php
/* "Total Refunded" for credit notes; "Total" for everything else. */
echo esc_html( ( 'creditnote' === $template ) ? __( 'Total Refunded', 'woocommerce-delivery-notes' ) : __( 'Total', 'woocommerce-delivery-notes' ) );
?>
</th>
<?php endif; ?>
</tr>
</thead>
<tbody>
<?php
/*
* Resolve the native WC_Order and WC_Order_Item objects for this order.
* These are passed to the deprecated pre-v7 wcdn_order_item_before/after hooks
* for backwards compatibility. New code should use $item, $order, $template.
*/
$_wcdn_wc_order = ! empty( $order['id'] ) ? wc_get_order( $order['id'] ) : null;
?>
<?php foreach ( $items as $item ) : ?>
<?php
/*
* Resolve product and order item objects for the deprecated hooks.
* $item is the formatted array; $_wcdn_wc_order_item is the raw WC object.
*/
$_wcdn_wc_product = ! empty( $item['product_id'] ) ? wc_get_product( $item['product_id'] ) : null;
$_wcdn_wc_order_item = ( $_wcdn_wc_order && ! empty( $item['order_item_id'] ) )
? $_wcdn_wc_order->get_item( $item['order_item_id'] )
: null;
?>
<tr>
<td class="wcdn-product-cell">
<?php
/**
* Hook: wcdn_order_item_before
*
* Fires before each line item's product cell content.
* Use this to prepend custom HTML to a specific item row.
*
* Note: the deprecated form passed ( $product, $order, $item ) as
* WC objects. The current signature is:
*
* @param array $item Formatted item array (name, sku, price, etc.).
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action_deprecated(
'wcdn_order_item_before',
array( $_wcdn_wc_product, $_wcdn_wc_order, $_wcdn_wc_order_item ),
'7.0.0',
'wcdn_order_item_before',
esc_html__( 'The wcdn_order_item_before hook argument order changed in v7.0. Update your callback to accept ( $item, $order, $template ) instead of ( $product, $order, $item ).', 'woocommerce-delivery-notes' )
);
do_action( 'wcdn_order_item_before', $item, $order, $template );
?>
<?php
/*
* WC Product Addons (PAO): when an item is a PAO add-on, it carries
* 'addon' data instead of a standard name+meta layout.
*/
?>
<?php if ( ! empty( $item['addon'] ) ) : ?>
<div class="wcdn-item-addon-name"><?php echo esc_html( $item['addon']['name'] ); ?></div>
<div class="wcdn-item-addon-value"><?php echo esc_html( $item['addon']['value'] ); ?></div>
<?php else : ?>
<?php
/*
* Product image: shown when Settings > Show Product Images is enabled.
* In PDF context, $item['image_path'] (absolute path) is used so
* Dompdf can load the image from disk.
* Image size is configurable via Settings > Product Image Size (px).
*/
$img_src = '';
$img_size = (int) ( $settings['productImageSize'] ?? 40 );
if ( ! empty( $settings['showProductImages'] ) ) {
$img_src = ( 'pdf' === $type ) ? ( $item['image_path'] ?? '' ) : ( $item['image_url'] ?? '' );
}
$has_image = ! empty( $img_src );
?>
<?php
/*
* When an image is present, a nested table is used to align the image
* and text side by side. This avoids float/flex which Dompdf does not
* fully support.
*/
?>
<?php if ( $has_image ) : ?>
<table class="wcdn-item-layout" style="border-collapse:collapse;width:100%;">
<tr>
<td
style="width:<?php echo esc_attr( $img_size ); ?>px;padding-right:6px;vertical-align:top;">
<img class="wcdn-item-image" src="<?php echo esc_attr( $img_src ); ?>"
width="<?php echo esc_attr( $img_size ); ?>"
height="<?php echo esc_attr( $img_size ); ?>" alt="" />
</td>
<td style="vertical-align:middle;">
<?php endif; ?>
<?php
/*
* Product name: filtered via wcdn_order_item_name.
* SKU: shown inline when non-empty; toggle in CSS via .wcdn-item-sku.
*/
?>
<span class="wcdn-item-name">
<?php echo wp_kses_post( $item['name'] ); ?>
<?php if ( ! empty( $item['sku'] ) ) : ?>
<span
class="wcdn-item-sku"><?php echo wp_kses_post( '(' . __( 'SKU', 'woocommerce-delivery-notes' ) . ': ' . $item['sku'] . ')' ); ?></span>
<?php endif; ?>
</span>
<?php
/*
* Item meta: variation attributes, custom fields, download count, etc.
* Each row: [ 'label' => string, 'value' => string ]
* CSS classes: .wcdn-item-meta dt dd
*/
?>
<?php if ( ! empty( $item['meta'] ) ) : ?>
<dl class="wcdn-item-meta">
<?php foreach ( $item['meta'] as $row ) : ?>
<dt><?php echo wp_kses_post( $row['label'] ); ?></dt>
<dd><?php echo wp_kses_post( $row['value'] ); ?></dd>
<?php endforeach; ?>
</dl>
<?php endif; ?>
<?php if ( $has_image ) : ?>
</td>
</tr>
</table>
<?php endif; ?>
<?php endif; ?>
<?php
/**
* Hook: wcdn_order_item_after
*
* Fires after each line item's product cell content.
* Use this to append custom HTML below a specific item (e.g. a
* delivery date, gift message, or fulfilment note).
*
* @param array $item Formatted item array.
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action_deprecated(
'wcdn_order_item_after',
array( $_wcdn_wc_product, $_wcdn_wc_order, $_wcdn_wc_order_item ),
'7.0.0',
'wcdn_order_item_after',
esc_html__( 'The wcdn_order_item_after hook argument order changed in v7.0. Update your callback to accept ( $item, $order, $template ) instead of ( $product, $order, $item ).', 'woocommerce-delivery-notes' )
);
do_action( 'wcdn_order_item_after', $item, $order, $template );
?>
</td>
<?php if ( $show_price_cols ) : ?>
<td><?php echo wp_kses_post( $item['price'] ); ?></td>
<?php endif; ?>
<td><?php echo esc_html( $item['quantity'] ); ?></td>
<?php if ( $show_price_cols ) : ?>
<td><?php echo wp_kses_post( $item['total'] ); ?></td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
</tbody>
<?php
/*
* Total Quantity footer row: shown only when the table has more than one
* non-addon item. Add-on rows are excluded from the count because they do
* not represent standalone quantities.
* CSS class: .wcdn-total-quantity
*/
$total_quantity = 0;
$non_addon_count = 0;
foreach ( $items as $item ) {
if ( empty( $item['addon'] ) ) {
$total_quantity += (float) $item['quantity'];
++$non_addon_count;
}
}
$total_quantity = ( floor( $total_quantity ) === $total_quantity ) ? (int) $total_quantity : $total_quantity;
?>
<?php if ( $non_addon_count > 1 ) : ?>
<tfoot>
<tr class="wcdn-total-quantity">
<?php if ( $show_price_cols ) : ?>
<td colspan="2" class="wcdn-totals-label">
<?php esc_html_e( 'Total Qty:', 'woocommerce-delivery-notes' ); ?></td>
<td><?php echo esc_html( $total_quantity ); ?></td>
<td></td>
<?php else : ?>
<td class="wcdn-totals-label"><?php esc_html_e( 'Total Qty:', 'woocommerce-delivery-notes' ); ?></td>
<td><?php echo esc_html( $total_quantity ); ?></td>
<?php endif; ?>
</tr>
</tfoot>
<?php endif; ?>
</table>
<?php
/**
* Hook: wcdn_after_items
*
* Fires immediately after the line-items table closing tag.
* Use this to add a custom summary block, totals override, or notes
* section directly below the items.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_items', $order, $template );
?>
<?php endif; ?>
<?php
/**
* Hook: wcdn_before_totals
*
* Fires before the order totals table (before the visibility check).
* Use this to insert a custom summary row, a sub-total note, or a separator
* between the items table and the totals regardless of whether totals are shown.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_totals', $order, $template );
?>
<?php
/*
* ORDER TOTALS TABLE
* ==================
* Shown only when:
* - $totals['total'] is set, AND
* - template is not 'creditnote', AND
* - displayPriceInProductDetailsTable is enabled.
*
* Rows rendered conditionally based on $totals keys and settings:
* subtotal — shown when showProductCharges + showSubtotal on
* discount — shown when $totals['discount'] exists
* tax/tax_lines— shown when showProductCharges + showTax on
* shipping — shown when showProductCharges + showShipping on
* fee_lines — always shown when present
* total — always shown (bold)
* refunded/net — shown when $totals['has_refund'] is true
* awcdp_* — Deposits & Partial Payments for WC Pro rows
* dfw_* — Deposits for WooCommerce rows
*
* CSS classes: .wcdn-totals .wcdn-totals-label .wcdn-totals-value
* .wcdn-total (on the grand total row)
*
* To customise row labels use the filter:
* wcdn_invoice_order_total_label( $label, $order )
*/
?>
<?php
if ( isset( $totals['total'] ) && 'creditnote' !== $template && ! empty( $settings['displayPriceInProductDetailsTable'] ) ) :
$render_totals_row = function ( $value, $label, $bold = false, $row_class = '' ) use ( $order ) {
$formatted = esc_html( apply_filters( 'wcdn_invoice_order_total_label', $label, $order ) );
$cell_label = $bold ? '<strong>' . $formatted . '</strong>' : $formatted;
?>
<tr<?php echo $row_class ? ' class="' . esc_attr( $row_class ) . '"' : ''; ?>>
<td colspan="3" class="wcdn-totals-label"><?php echo wp_kses( $cell_label, array( 'strong' => array() ) ); ?></td>
<td class="wcdn-totals-value"><?php echo wp_kses_post( $value ); ?></td>
</tr>
<?php
};
?>
<table class="wcdn-totals" width="100%">
<colgroup>
<col class="wcdn-col-product" style="width:50%;">
<col class="wcdn-col-price" style="width:15%;">
<col class="wcdn-col-qty" style="width:15%;">
<col class="wcdn-col-total" style="width:20%;">
</colgroup>
<?php
/*
* Zero-height spacer row keeps the totals columns aligned with the items table
* columns above. Dompdf requires explicit width declarations on each cell.
*/
?>
<tr style="line-height:0;font-size:0;">
<td style="width:50%;height:0;padding:0;border:none;"></td>
<td style="width:15%;height:0;padding:0;border:none;"></td>
<td style="width:15%;height:0;padding:0;border:none;"></td>
<td style="width:20%;height:0;padding:0;border:none;"></td>
</tr>
<?php if ( isset( $totals['subtotal'] ) && ! empty( $settings['showProductCharges'] ) && ! empty( $settings['showSubtotal'] ) ) : ?>
<?php $render_totals_row( $totals['subtotal'], __( 'Subtotal:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
<?php if ( isset( $totals['discount'] ) ) : ?>
<?php $render_totals_row( $totals['discount'], __( 'Discount:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
<?php
/*
* Tax: renders itemised lines when available, falls back to a single row.
* Both are gated behind showProductCharges + showTax toggles.
*/
?>
<?php if ( ( isset( $totals['tax'] ) || ! empty( $totals['tax_lines'] ) ) && ! empty( $settings['showProductCharges'] ) && ! empty( $settings['showTax'] ) ) : ?>
<?php if ( ! empty( $totals['tax_lines'] ) ) : ?>
<?php foreach ( $totals['tax_lines'] as $tax_line ) : ?>
<?php $render_totals_row( $tax_line['value'], $tax_line['label'] . ':' ); ?>
<?php endforeach; ?>
<?php elseif ( isset( $totals['tax'] ) ) : ?>
<?php $render_totals_row( $totals['tax'], __( 'Tax:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
<?php endif; ?>
<?php if ( isset( $totals['shipping'] ) && ! empty( $settings['showProductCharges'] ) && ! empty( $settings['showShipping'] ) ) : ?>
<?php $render_totals_row( $totals['shipping'], __( 'Shipping:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
<?php
/*
* Fee lines: injected by WooCommerce or third-party plugins (e.g. payment
* gateway surcharges). Rendered unconditionally when present.
*/
?>
<?php if ( ! empty( $totals['fee_lines'] ) ) : ?>
<?php foreach ( $totals['fee_lines'] as $fee_line ) : ?>
<?php $render_totals_row( $fee_line['value'], $fee_line['label'] . ':' ); ?>
<?php endforeach; ?>
<?php endif; ?>
<?php
/*
* When has_refund is true, the order has been partially or fully refunded.
* Three rows are shown: Order Total, Refund, and a bold Net Total.
* Otherwise a single bold Total row is shown.
*/
?>
<?php if ( ! empty( $totals['has_refund'] ) ) : ?>
<?php $render_totals_row( $totals['total'], __( 'Order Total:', 'woocommerce-delivery-notes' ), true ); ?>
<?php $render_totals_row( $totals['refunded'], __( 'Refund:', 'woocommerce-delivery-notes' ) ); ?>
<?php $render_totals_row( $totals['net_total'] . ( ! empty( $totals['tax_label'] ) ? ' ' . $totals['tax_label'] : '' ), __( 'Total:', 'woocommerce-delivery-notes' ), true, 'wcdn-total' ); ?>
<?php else : ?>
<?php $render_totals_row( $totals['total'], __( 'Total:', 'woocommerce-delivery-notes' ), true, 'wcdn-total' ); ?>
<?php endif; ?>
<?php
/*
* Deposits & Partial Payments for WooCommerce Pro (AWCDP) rows.
* Added by the AWCDP integration via the wcdn_order_totals filter.
*/
?>
<?php if ( isset( $totals['awcdp_deposit'] ) ) : ?>
<?php $render_totals_row( $totals['awcdp_deposit'], __( 'Deposit:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
<?php if ( isset( $totals['awcdp_future_payments'] ) ) : ?>
<?php $render_totals_row( $totals['awcdp_future_payments'], __( 'Future Payments:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
<?php
/*
* Deposits for WooCommerce (DFW) rows.
* Added via the wcdn_order_totals filter when DFW is active.
*/
?>
<?php if ( isset( $totals['dfw_deposit'] ) ) : ?>
<?php $render_totals_row( $totals['dfw_deposit'], __( 'Deposit:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
<?php if ( isset( $totals['dfw_future_payment'] ) ) : ?>
<?php $render_totals_row( $totals['dfw_future_payment'], __( 'Future Payment:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
<?php if ( isset( $totals['dfw_total_cart_amount'] ) ) : ?>
<?php $render_totals_row( $totals['dfw_total_cart_amount'], __( 'Total Cart Amount:', 'woocommerce-delivery-notes' ) ); ?>
<?php endif; ?>
</table>
<?php endif; ?>
<?php
/**
* Hook: wcdn_after_totals
*
* Fires after the order totals table (or after the items table when
* price columns are disabled).
* Use this to add a custom totals row, a payment summary, or a
* tax breakdown that the core plugin does not render.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_totals', $order, $template );
?>
<?php
/**
* Hook: wcdn_before_pay_button
*
* Fires before the pay-now button block (before the visibility check).
* Use this to add a payment instructions notice or custom CTA above the button.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_pay_button', $order, $template );
?>
<?php
/*
* PAY NOW BUTTON
* Shown when $show_pay_now_button is true, which requires:
* - Settings > Pay Now enabled, AND
* - the order has a payment URL (i.e. it has not yet been paid).
* CSS classes: .wcdn-pay .wcdn-payment-button
*/
?>
<?php if ( $show_pay_now_button ) : ?>
<div class="wcdn-pay">
<table align="center">
<tr>
<td>
<a class="wcdn-payment-button" href="<?php echo esc_url( $order['payment_url'] ); ?>">
<?php echo esc_html( $settings['payNowLabel'] ); ?> —
<?php echo wp_kses_post( $totals['total'] ); ?>
</a>
</td>
</tr>
</table>
</div>
<?php endif; ?>
<?php
/**
* Hook: wcdn_after_pay_button
*
* Fires after the pay-now button block (whether or not the button is shown).
* Use this to add payment instructions or a QR code below the button.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_pay_button', $order, $template );
?>
<?php
/**
* Hook: wcdn_before_notes
*
* Fires before the customer note block (before the visibility check).
* Use this to add a separator or intro text above the customer note section.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_notes', $order, $template );
?>
<?php
/*
* CUSTOMER NOTE
* Controlled by: Settings > Customer Note
* $order['customer_note'] is the note the customer entered at checkout.
* CSS classes: .wcdn-customer-note
*/
?>
<?php if ( ! empty( $settings['showCustomerNote'] ) && ! empty( $order['customer_note'] ) ) : ?>
<hr style="margin: 5px 0;" />
<div class="wcdn-customer-note">
<?php echo esc_html( $settings['customerNoteTitle'] ); ?>:
<?php echo esc_html( $order['customer_note'] ); ?>
</div>
<?php
/**
* Hook: wcdn_after_notes
*
* Fires after the customer note block.
* Only fires when the note is visible (setting on + note non-empty).
* Use this to add a custom notice or internal memo below the note.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_notes', $order, $template );
?>
<?php endif; ?>
<?php
/**
* Hook: wcdn_before_policies
*
* Fires before the policies block (before the visibility check).
* Use this to insert content between the customer note and the policies section.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_policies', $order, $template );
?>
<?php
/*
* POLICIES
* Controlled by: Settings > Policies
* $document['policies'] comes from the template's Policies textarea.
* HTML is allowed (wp_kses_post).
* CSS classes: .wcdn-policies
*/
?>
<?php if ( ! empty( $settings['showPolicies'] ) && ! empty( $document['policies'] ) ) : ?>
<hr style="margin: 5px 0;" />
<div class="wcdn-policies">
<?php echo wp_kses_post( $document['policies'] ); ?>
</div>
<?php endif; ?>
<?php
/**
* Hook: wcdn_after_policies
*
* Fires after the policies block (after the visibility check).
* Use this to append content below the policies section.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_policies', $order, $template );
?>
<?php
/**
* Hook: wcdn_before_complimentary_close
*
* Fires before the complimentary close block (before the visibility check).
* Use this to insert a signature line or custom message above the closing.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_complimentary_close', $order, $template );
?>
<?php
/*
* COMPLIMENTARY CLOSE
* Controlled by: Settings > Complimentary Close
* $document['complimentaryClose'] comes from the template textarea.
* HTML is allowed (wp_kses_post).
* CSS classes: .wcdn-complimentary-close
*/
?>
<?php if ( ! empty( $settings['showComplimentaryClose'] ) && ! empty( $document['complimentaryClose'] ) ) : ?>
<hr style="margin: 5px 0;" />
<div class="wcdn-complimentary-close">
<?php echo wp_kses_post( $document['complimentaryClose'] ); ?>
</div>
<?php endif; ?>
<?php
/**
* Hook: wcdn_after_complimentary_close
*
* Fires after the complimentary close block (after the visibility check).
* Use this to add a digital signature image or custom sign-off below the close.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_complimentary_close', $order, $template );
?>
<?php
/**
* Hook: wcdn_before_footer
*
* Fires before the footer block (before the visibility check).
* Use this to add a separator or custom content just above the footer.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_before_footer', $order, $template );
?>
<?php
/*
* FOOTER.
* Controlled by: Settings > Footer.
* $document['footer'] comes from the template's Footer textarea.
* HTML is allowed (wp_kses_post).
* CSS classes: .wcdn-footer.
*/
?>
<?php if ( ! empty( $settings['showFooter'] ) && ! empty( $document['footer'] ) ) : ?>
<hr style="margin: 5px 0;" />
<div class="wcdn-footer">
<?php echo wp_kses_post( $document['footer'] ); ?>
</div>
<?php endif; ?>
<?php
/**
* Hook: wcdn_after_footer
*
* Fires after the footer block (after the visibility check).
* Use this to append content at the very bottom of the document, below the
* footer, but before wcdn_after_document.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_footer', $order, $template );
?>
<?php
/**
* Hook: wcdn_after_document
*
* Fires at the very end of the document, before the closing .wcdn-document
* div. Use this to append any custom HTML that should appear on every
* document regardless of which sections are enabled.
*
* @param array $order Formatted order data array.
* @param string $template Template key.
*/
do_action( 'wcdn_after_document', $order, $template );
?>
</div>