get_bloginfo('name') [Site Title] * {{siteurl}} -> home_url() [Home URL of the site] * {{wordpress-url}} -> site_url() [WordPress install URL] * {{tagline}} -> get_bloginfo('description') [Site Tagline] * {{privacy-policy}} -> get_privacy_policy_url() [Privacy Policy Page URL] * * 2. WORDPRESS USER (If no WC order, but user info is present): * - Original / Legacy: * {{user_name}} -> user->user_login [Username] * {{user_first_last_name}} -> user_meta('first_name' + 'last_name') [Full Name] * {{wc_billing_first_name}}-> user_meta('billing_first_name') [Billing First Name] * {{wc_billing_last_name}} -> user_meta('billing_last_name') [Billing Last Name] * {{wc_billing_phone}} -> user_meta('billing_phone') [Billing Phone] * {{shop_name}} -> get_bloginfo('name') [Site Title] * {{current_date_time}} -> Carbon::now() [Current Server Date/Time] * {{site_link}} -> site_url() [Site URL] * {{customer_note}} -> base_replacement [Custom context note] * * - New (wp- prefix): * {{wp-first-name}} -> user_meta('first_name') [User First Name] * {{wp-last-name}} -> user_meta('last_name') [User Last Name] * {{wp-username}} -> user->user_login [Username] * {{wp-nickname}} -> user_meta('nickname') [User Nickname] * {{wp-display-name}} -> user->display_name [User Display Name] * {{wp-email}} -> user->user_email [User Email Address] * {{wp-user-website}} -> user->user_url [User Website URL] * {{wp-user-bio}} -> user->description [User Bio / Description] * * - Custom User Meta: * e.g. {{meta_key}} -> get_user_meta($user->ID, 'meta_key', true) [Value from Database] * * 3. WOOCOMMERCE ORDER (If an order object is present): * Used in Order Status changes, New Order alerts, Refunds, and any WooCommerce-triggered actions. * * - Custom Order Meta: * e.g. {{my_meta}} -> $order->get_meta('my_meta') [Value from Order Meta / Custom Fields] * * - Legacy / Original (Common): * {{id}} -> $order->get_id() [Order ID] * {{order_key}} -> $order->get_order_key() [Unique Order Key] * {{order_date}} -> $order->get_date_created() [Formatted Order Date] * {{order_link}} -> WC View Order URL [Link with order key] * {{order_total}} -> $order->get_total() [Grand Total] * {{order_subtotal}} -> $order->get_subtotal() [Order Subtotal] * {{order_discount}} -> $order->get_total_discount() [Total Discount Amount] * {{order_tax}} -> $order->get_total_tax() [Total Tax Amount] * {{order_shipping}} -> $order->get_shipping_total() [Shipping Cost] * {{order_shipping_tax}} -> $order->get_shipping_tax() [Shipping Tax Amount] * {{status}} -> $order->get_status() [Current Order Status] * {{currency}} -> get_woocommerce_currency_symbol() [Currency Symbol] * {{payment_method}} -> $order->get_payment_method() [Payment Method Slug] * {{payment_method_title}} -> $order->get_payment_method_title() [Payment Method Name] * {{transaction_id}} -> $order->get_transaction_id() [Payment Transaction ID] * {{bacs_account}} -> woocommerce_bacs_accounts [Bank Transfer Details] * {{shop_name}} -> get_bloginfo('name') [Site Title] * {{cust_note}} -> $order->get_customer_note() [Customer Note] * {{product}} -> Order Items Summary [Detailed list with Qty and Prices] * {{product_name}} -> $item->get_name() [Comma-separated Product Titles] * {{unique_transfer_code}} -> _unique_transfer_code [Custom Transfer Code] * * - Billing & Shipping (Legacy): * {{billing_first_name}} -> Billing First Name * {{billing_last_name}} -> Billing Last Name * {{billing_company}} -> Billing Company * {{billing_address_1}} -> Billing Address Line 1 * {{billing_address_2}} -> Billing Address Line 2 * {{billing_city}} -> Billing City * {{billing_postcode}} -> Billing Postcode * {{billing_country}} -> Billing Country * {{billing_state}} -> Billing State * {{billing_email}} -> Billing Email * {{billing_phone}} -> Billing Phone * {{shipping_first_name}} -> Shipping First Name * {{shipping_last_name}} -> Shipping Last Name * {{shipping_company}} -> Shipping Company * {{shipping_address_1}} -> Shipping Address Line 1 * {{shipping_address_2}} -> Shipping Address Line 2 * {{shipping_city}} -> Shipping City * {{shipping_postcode}} -> Shipping Postcode * {{shipping_country}} -> Shipping Country * {{shipping_state}} -> Shipping State * {{shipping_method}} -> Shipping Method Slug * {{shipping_method_title}} -> Shipping Method Name * * - Additional WooCommerce (wc- prefix): * Used for smart formatting (New-lines, Lists, Links). Ideal for professional summaries. * {{wc-order}} -> $order->get_order_number() [Order Number] * {{wc-order-id}} -> $order->get_id() [Order ID] * {{wc-order-status}} -> $order->get_status() [Order Status] * {{wc-order-date}} -> $order->get_date_created() [Formatted Order Date] * {{wc-product-names}} -> Product titles [Comma-separated Names] * {{wc-product-names-br}} -> Product titles [New-line separated Names] * {{wc-product-name-count}} -> Summary [e.g. 'Product A and 2 more'] * {{wc-product-link}} -> Product URLs [Comma-separated permalinks] * {{wc-product-link-br}} -> Product URLs [New-line separated permalinks] * {{wc-product-name-link}} -> Title (URL) [Comma-separated Name + URL] * {{wc-product-name-link-br}} -> Title (URL) [New-line separated Name + URL] * {{wc-total-products}} -> Unique product count [Number of unique items in order] * {{wc-total-items}} -> Total item quantity [Sum of all item quantities] * {{wc-order-items}} -> Detailed list [Name x Qty] * {{wc-order-items-br}} -> Detailed list [Name x Qty (New-line)] * {{wc-order-items-price}} -> Full summary [Name x Qty - Price] * {{wc-sku}} -> Product SKUs [Comma-separated SKUs] * {{wc-sku-br}} -> Product SKUs [New-line separated SKUs] * {{wc-order-amount}} -> $order->get_total() [Grand Total] * {{wc-discount}} -> $order->get_total_discount() [Discount Amount] * {{wc-tax}} -> $order->get_total_tax() [Tax Amount] * {{wc-order-amount-ex-tax}}-> Total - Tax [Net Order Amount] * {{wc-payment-method}} -> $order->get_payment_method() [Payment Method ID] * {{wc-shipping-method}} -> $order->get_shipping_method() [Shipping Method Name] * {{wc-shipping-cost}} -> $order->get_shipping_total() [Shipping Amount] * {{wc-refund-amount}} -> $order->get_total_refunded() [Total Refunded] * {{wc-refund-reason}} -> Refund reasons [Comma-separated reasons] * {{wc-order-notes}} -> $order->get_customer_note() [Customer Note] * * - WooCommerce Billing/Shipping (hyphen versions): * Alternative naming convention for easier integration and consistency. * {{wc-billing-first-name}} -> $order->get_billing_first_name() [First Name] * {{wc-billing-last-name}} -> $order->get_billing_last_name() [Last Name] * {{wc-billing-email}} -> $order->get_billing_email() [Email Address] * {{wc-billing-phone}} -> $order->get_billing_phone() [Phone Number] * {{wc-billing-address-line-1}} -> $order->get_billing_address_1() [Address Line 1] * {{wc-billing-address-line-2}} -> $order->get_billing_address_2() [Address Line 2] * {{wc-billing-city}} -> $order->get_billing_city() [City] * {{wc-billing-postcode}} -> $order->get_billing_postcode() [Postcode] * {{wc-billing-state}} -> $order->get_billing_state() [State] * {{wc-billing-country}} -> $order->get_billing_country() [Country Code] * {{wc-shipping-first-name}} -> $order->get_shipping_first_name() [First Name] * {{wc-shipping-last-name}} -> $order->get_shipping_last_name() [Last Name] * {{wc-shipping-address-line-1}} -> $order->get_shipping_address_1() [Shipping Address 1] * {{wc-shipping-city}} -> $order->get_shipping_city() [Shipping City] * * If a placeholder is not recognized, it defaults to “N/A”. */ if (!defined('ABSPATH')) exit; // Exit if accessed directly use WAWP\Vendor\Carbon\Carbon; class WAWP_Message_Parser { public static function parse_message_placeholders($msg, $base_replacements, $order_id, $user_id) { $awp_wa = [ 'id','order_key','billing_first_name','billing_last_name','billing_company','billing_address_1', 'billing_address_2','billing_city','billing_postcode','billing_country','billing_state', 'billing_email','billing_phone','shipping_first_name','shipping_last_name','shipping_company', 'shipping_address_1','shipping_address_2','shipping_city','shipping_postcode','shipping_country', 'shipping_state','shipping_method','shipping_method_title','bacs_account','payment_method', 'payment_method_title','order_subtotal','order_discount','cart_discount','order_tax', 'order_shipping','order_shipping_tax','order_total','status','shop_name','currency', 'cust_note','note','product','product_name','dpd','unique_transfer_code','order_date', 'order_link','transaction_id','current_date_time','user_name','user_first_last_name', 'wc_billing_first_name','wc_billing_last_name','wc_billing_phone','site_link','customer_note' ]; $order = null; $user = null; if ($order_id) { $order = function_exists('wc_get_order') ? wc_get_order($order_id) : null; } if ($user_id) { $user = get_userdata($user_id); } // Replace any "base replacements" first if (is_array($base_replacements)) { foreach ($base_replacements as $k => $v) { $inner_key = trim($k, '{}'); if (!empty($inner_key)) { // Replace double braces first to avoid leaving outer braces $msg = str_replace('{{' . $inner_key . '}}', $v, $msg); // Then replace single braces $msg = str_replace('{' . $inner_key . '}', $v, $msg); } // Finally replace exact original key $msg = str_replace($k, $v, $msg); } } // Determine symbols and locale $currency_symb = (class_exists('WooCommerce') && function_exists('get_woocommerce_currency_symbol')) ? html_entity_decode(get_woocommerce_currency_symbol()) : ''; // Regex for {{placeholder}} preg_match_all('/{{(.*?)}}/', $msg, $search); $locale = get_locale(); $is_arabic = (strpos($locale, 'ar') === 0); foreach ($search[1] as $variable) { $var_lower = strtolower($variable); // -------------------------------------------------------------- // 1) Handle "General" placeholders that always apply // -------------------------------------------------------------- if (in_array($var_lower, ['sitename','siteurl','wordpress-url','tagline','privacy-policy'], true)) { switch ($var_lower) { case 'sitename': $msg = str_replace('{{' . $variable . '}}', get_bloginfo('name'), $msg); break; case 'siteurl': $msg = str_replace('{{' . $variable . '}}', home_url(), $msg); break; case 'wordpress-url': $msg = str_replace('{{' . $variable . '}}', site_url(), $msg); break; case 'tagline': $msg = str_replace('{{' . $variable . '}}', get_bloginfo('description'), $msg); break; case 'privacy-policy': $pp_url = function_exists('get_privacy_policy_url') ? get_privacy_policy_url() : ''; $msg = str_replace('{{' . $variable . '}}', $pp_url ?: '', $msg); break; } continue; } // -------------------------------------------------------------- // 2) If NO WooCommerce Order but we DO have a WP user // -------------------------------------------------------------- if (!$order && $user) { switch ($var_lower) { case 'user_name': $msg = str_replace('{{' . $variable . '}}', $user->user_login, $msg); break; case 'user_first_last_name': $fn = get_user_meta($user->ID, 'first_name', true); $ln = get_user_meta($user->ID, 'last_name', true); $nm = trim($fn . ' ' . $ln); $msg = str_replace('{{' . $variable . '}}', $nm, $msg); break; case 'wc_billing_first_name': case 'wc_billing_last_name': case 'wc_billing_phone': $val = get_user_meta($user->ID, str_replace('wc_', '', $var_lower), true); $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'shop_name': $msg = str_replace('{{' . $variable . '}}', get_bloginfo('name'), $msg); break; case 'current_date_time': $formatted = $is_arabic ? Carbon::now()->translatedFormat('Y-m-d H:i:s') : Carbon::now()->toDateTimeString(); $msg = str_replace('{{' . $variable . '}}', $formatted, $msg); break; case 'site_link': $msg = str_replace('{{' . $variable . '}}', site_url(), $msg); break; case 'customer_note': $val = isset($base_replacements['{customer_note}']) ? $base_replacements['{customer_note}'] : 'N/A'; $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; // New WP placeholders case 'wp-first-name': $val = get_user_meta($user->ID, 'first_name', true); $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-last-name': $val = get_user_meta($user->ID, 'last_name', true); $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-username': $val = $user->user_login; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-nickname': $val = get_user_meta($user->ID, 'nickname', true); $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-display-name': $val = $user->display_name; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-email': $val = $user->user_email; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-user-website': $val = $user->user_url; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-user-bio': $val = $user->description; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; default: // Attempt to load from user meta for unknown placeholders $val = get_user_meta($user->ID, $var_lower, true); if (!$val) { $val = 'N/A'; } $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; } } // -------------------------------------------------------------- // 3) If we DO have a WooCommerce order // -------------------------------------------------------------- elseif ($order instanceof \WC_Order) { // Load user from order if not already loaded if (!$user && $order->get_user_id()) { $user = get_userdata($order->get_user_id()); } switch ($var_lower) { // Existing placeholders (unchanged) case 'id': $msg = str_replace('{{' . $variable . '}}', $order->get_id(), $msg); break; case 'order_date': $df = get_option('date_format'); $tf = get_option('time_format'); $od = $order->get_date_created(); $d_str = $od ? $od->date("$df $tf") : ''; if ($is_arabic && $d_str) { $d_str = Carbon::parse($d_str)->translatedFormat("$df $tf"); } $msg = str_replace('{{' . $variable . '}}', $d_str, $msg); break; case 'order_link': $url = wc_get_endpoint_url('order-received', $order->get_id(), wc_get_checkout_url()); $url = add_query_arg('key', $order->get_order_key(), $url); $msg = str_replace('{{' . $variable . '}}', $url, $msg); break; case 'product': $items = ''; $i = 0; foreach ($order->get_items() as $it) { $i++; $nl = ($i > 1) ? "\n" : ''; $p = $it->get_product(); $pn = $p ? $p->get_name() : ''; $qty = $it->get_quantity(); $tot = $it->get_total(); $items .= $nl . $i . '. ' . $pn . ' * (' . $qty . ') = ' . number_format($tot, wc_get_price_decimals()) . ' ' . $currency_symb; } $msg = str_replace('{{' . $variable . '}}', html_entity_decode($items), $msg); break; case 'order_discount': $val = number_format($order->get_total_discount(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'product_name': $names = []; foreach ($order->get_items() as $it) { $prod = $it->get_product(); if ($prod) { $names[] = $prod->get_name(); } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $names), $msg); break; case 'cart_discount': $val = number_format($order->get_discount_total(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'order_subtotal': $val = number_format($order->get_subtotal(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'order_total': $val = number_format($order->get_total(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'status': $status_name = wc_get_order_status_name($order->get_status()); $msg = str_replace('{{' . $variable . '}}', $status_name, $msg); break; case 'order_tax': $val = number_format($order->get_total_tax(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'order_discount': $val = number_format($order->get_total_discount(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'cart_discount': $val = number_format($order->get_discount_total(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'order_shipping': $val = number_format($order->get_shipping_total(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'order_shipping_tax': $val = number_format($order->get_shipping_tax(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'currency': $msg = str_replace('{{' . $variable . '}}', $currency_symb, $msg); break; case 'shop_name': $msg = str_replace('{{' . $variable . '}}', html_entity_decode(get_bloginfo('name')), $msg); break; case 'cust_note': $msg = str_replace('{{' . $variable . '}}', $order->get_customer_note(), $msg); break; case 'shipping_method': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_method(), $msg); break; case 'order_shipping': $val = number_format($order->get_shipping_total(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'order_shipping_tax': $val = number_format($order->get_shipping_tax(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'transaction_id': $tid = $order->get_transaction_id(); $msg = str_replace('{{' . $variable . '}}', $tid ?: 'N/A', $msg); break; case 'bacs_account': $info = get_option('woocommerce_bacs_accounts'); $accs = ''; if ($info) { foreach ($info as $acc) { $accs .= '🏦 ' . esc_attr(wp_unslash($acc['bank_name'])) . "\n"; $accs .= '👤 ' . esc_attr(wp_unslash($acc['account_name'])) . "\n"; $accs .= '🔢 ' . esc_attr($acc['account_number']) . "\n"; } } $msg = str_replace('{{' . $variable . '}}', $accs, $msg); break; case 'note': $msg = str_replace('{{' . $variable . '}}', 'N/A', $msg); break; case 'unique_transfer_code': $val = $order->get_meta('_unique_transfer_code', true); $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'site_link': $msg = str_replace('{{' . $variable . '}}', site_url(), $msg); break; // New WP placeholders if there's a user tied to the order case 'wp-first-name': $val = $user ? get_user_meta($user->ID, 'first_name', true) : ''; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-last-name': $val = $user ? get_user_meta($user->ID, 'last_name', true) : ''; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-username': $val = $user ? $user->user_login : ''; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-nickname': $val = $user ? get_user_meta($user->ID, 'nickname', true) : ''; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-display-name': $val = $user ? $user->display_name : ''; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-email': $val = $user ? $user->user_email : ''; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-user-website': $val = $user ? $user->user_url : ''; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wp-user-bio': $val = $user ? $user->description : ''; $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; // Additional WooCommerce placeholders case 'wc-order': $msg = str_replace('{{' . $variable . '}}', $order->get_order_number(), $msg); break; case 'wc-order-id': $msg = str_replace('{{' . $variable . '}}', $order->get_id(), $msg); break; case 'wc-order-status': $status_name = wc_get_order_status_name($order->get_status()); $msg = str_replace('{{' . $variable . '}}', $status_name, $msg); break; case 'wc-order-date': $df = get_option('date_format'); $tf = get_option('time_format'); $od = $order->get_date_created(); $d_str = $od ? $od->date("$df $tf") : ''; if ($is_arabic && $d_str) { $d_str = Carbon::parse($d_str)->translatedFormat("$df $tf"); } $msg = str_replace('{{' . $variable . '}}', $d_str, $msg); break; case 'wc-product-names': $names = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $names[] = $prod->get_name(); } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $names), $msg); break; case 'wc-product-names-br': $names = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $names[] = $prod->get_name(); } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $names), $msg); break; case 'wc-product-names-variable': $names = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod && $prod->is_type('variable')) { $names[] = $prod->get_name(); } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $names), $msg); break; case 'wc-product-names-variable-br': $names = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod && $prod->is_type('variable')) { $names[] = $prod->get_name(); } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $names), $msg); break; case 'wc-product-name-count': $items = $order->get_items(); $count = count($items); if ($count > 1) { $first_item = reset($items); $prod = $first_item->get_product(); $first_name = $prod ? $prod->get_name() : ''; $others = $count - 1; $val = $first_name . ' and ' . $others . ' more'; } else { // Only 1 item $prod = count($items) ? current($items)->get_product() : null; $val = $prod ? $prod->get_name() : 'N/A'; } $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'wc-product-link': $links = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $links[] = get_permalink($prod->get_id()); } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $links), $msg); break; case 'wc-product-link-br': $links = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $links[] = get_permalink($prod->get_id()); } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $links), $msg); break; case 'wc-product-name-link': $pairs = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $url = get_permalink($prod->get_id()); $pairs[] = $prod->get_name() . ' (' . $url . ')'; } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $pairs), $msg); break; case 'wc-product-name-link-br': $pairs = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $url = get_permalink($prod->get_id()); $pairs[] = $prod->get_name() . ' (' . $url . ')'; } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $pairs), $msg); break; case 'wc-total-products': $count = count($order->get_items()); $msg = str_replace('{{' . $variable . '}}', $count, $msg); break; case 'wc-total-items': $qty = 0; foreach ($order->get_items() as $item) { $qty += $item->get_quantity(); } $msg = str_replace('{{' . $variable . '}}', $qty, $msg); break; case 'wc-order-items': $lines = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $lines[] = $prod->get_name() . ' x ' . $item->get_quantity(); } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $lines), $msg); break; case 'wc-order-items-br': $lines = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $lines[] = $prod->get_name() . ' x ' . $item->get_quantity(); } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $lines), $msg); break; case 'wc-order-items-variable': $lines = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod && $prod->is_type('variable')) { $lines[] = $prod->get_name() . ' x ' . $item->get_quantity(); } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $lines), $msg); break; case 'wc-order-items-variable-br': $lines = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod && $prod->is_type('variable')) { $lines[] = $prod->get_name() . ' x ' . $item->get_quantity(); } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $lines), $msg); break; case 'wc-order-items-price': $lines = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $lines[] = $prod->get_name() . ' x ' . $item->get_quantity() . ' - ' . $currency_symb . number_format($item->get_total(), wc_get_price_decimals()); } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $lines), $msg); break; case 'wc-order-items-price-br': $lines = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $lines[] = $prod->get_name() . ' x ' . $item->get_quantity() . ' - ' . $currency_symb . number_format($item->get_total(), wc_get_price_decimals()); } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $lines), $msg); break; case 'wc-all-order-items-br': $detail_lines = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $detail_lines[] = sprintf( '%s x %d = %s%s', $prod->get_name(), $item->get_quantity(), $currency_symb, number_format($item->get_total(), wc_get_price_decimals()) ); } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $detail_lines), $msg); break; case 'wc-sku': $skus = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $sku = $prod->get_sku(); if ($sku) { $skus[] = $sku; } } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $skus), $msg); break; case 'wc-sku-br': $skus = []; foreach ($order->get_items() as $item) { $prod = $item->get_product(); if ($prod) { $sku = $prod->get_sku(); if ($sku) { $skus[] = $sku; } } } $msg = str_replace('{{' . $variable . '}}', implode("\n", $skus), $msg); break; case 'wc-order-amount': $val = number_format($order->get_total(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'wc-discount': $val = number_format($order->get_total_discount(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'wc-tax': $val = number_format($order->get_total_tax(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'wc-order-amount-ex-tax': $total_ex_tax = $order->get_total() - $order->get_total_tax(); $val = number_format($total_ex_tax, wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'wc-payment-method': $val = $order->get_payment_method(); $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wc-transaction-id': $tid = $order->get_transaction_id(); $msg = str_replace('{{' . $variable . '}}', $tid ?: 'N/A', $msg); break; case 'wc-shipping-method': $val = $order->get_shipping_method(); $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; case 'wc-shipping-cost': $val = number_format($order->get_shipping_total(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'wc-refund-amount': $val = number_format($order->get_total_refunded(), wc_get_price_decimals()); $msg = str_replace('{{' . $variable . '}}', $val, $msg); break; case 'wc-refund-reason': $refunds = $order->get_refunds(); $reasons = []; foreach ($refunds as $refund) { $reason = $refund->get_reason(); if ($reason) { $reasons[] = $reason; } } $msg = str_replace('{{' . $variable . '}}', implode(', ', $reasons), $msg); break; case 'wc-order-notes': $val = $order->get_customer_note(); $msg = str_replace('{{' . $variable . '}}', $val ?: 'N/A', $msg); break; // WooCommerce Billing/Shipping with hyphens case 'wc-billing-first-name': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_first_name(), $msg); break; case 'wc-billing-last-name': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_last_name(), $msg); break; case 'wc-billing-company': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_company(), $msg); break; case 'wc-billing-address-line-1': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_address_1(), $msg); break; case 'wc-billing-address-line-2': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_address_2(), $msg); break; case 'wc-billing-city': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_city(), $msg); break; case 'wc-billing-postcode': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_postcode(), $msg); break; case 'wc-billing-state': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_state(), $msg); break; case 'wc-billing-country': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_country(), $msg); break; case 'wc-billing-email': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_email(), $msg); break; case 'wc-billing-phone': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_phone(), $msg); break; case 'wc-shipping-first-name': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_first_name(), $msg); break; case 'wc-shipping-last-name': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_last_name(), $msg); break; case 'wc-shipping-company': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_company(), $msg); break; case 'wc-shipping-address-line-1': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_address_1(), $msg); break; case 'wc-shipping-address-line-2': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_address_2(), $msg); break; case 'wc-shipping-city': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_city(), $msg); break; case 'wc-shipping-postcode': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_postcode(), $msg); break; case 'wc-shipping-state': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_state(), $msg); break; case 'wc-shipping-country': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_country(), $msg); break; // Legacy Billing/Shipping explicit cases case 'billing_first_name': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_first_name() ?: 'N/A', $msg); break; case 'billing_last_name': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_last_name() ?: 'N/A', $msg); break; case 'billing_email': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_email() ?: 'N/A', $msg); break; case 'billing_phone': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_phone() ?: 'N/A', $msg); break; case 'billing_address_1': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_address_1() ?: 'N/A', $msg); break; case 'billing_address_2': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_address_2() ?: 'N/A', $msg); break; case 'billing_city': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_city() ?: 'N/A', $msg); break; case 'billing_postcode': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_postcode() ?: 'N/A', $msg); break; case 'billing_state': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_state() ?: 'N/A', $msg); break; case 'billing_country': $msg = str_replace('{{' . $variable . '}}', $order->get_billing_country() ?: 'N/A', $msg); break; case 'shipping_first_name': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_first_name() ?: 'N/A', $msg); break; case 'shipping_last_name': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_last_name() ?: 'N/A', $msg); break; case 'shipping_address_1': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_address_1() ?: 'N/A', $msg); break; case 'shipping_city': $msg = str_replace('{{' . $variable . '}}', $order->get_shipping_city() ?: 'N/A', $msg); break; default: // If it's a known placeholder in $awp_wa not handled above, or custom meta: $meta_val = $order->get_meta($var_lower); if (!$meta_val) { // Try '_field' or 'field' in post meta $meta_val = get_post_meta($order->get_id(), '_' . $var_lower, true); if (!$meta_val) { $meta_val = get_post_meta($order->get_id(), $var_lower, true); } } // Fallback to user meta if order meta is empty if (!$meta_val && $user) { $meta_val = get_user_meta($user->ID, $var_lower, true); } if (!$meta_val) { $meta_val = 'N/A'; } $msg = str_replace('{{' . $variable . '}}', $meta_val, $msg); break; } } // -------------------------------------------------------------- // 4) If no order AND no user, just set placeholder to "N/A" // -------------------------------------------------------------- else { $msg = str_replace('{{' . $variable . '}}', 'N/A', $msg); } } return $msg; } }