(array) $run, 'ctx' => (array) $ctx, 'wf' => (array) $wf, 'step' => (array) $step, 'coupon' => is_array( $coupon ) ? $coupon : null, 'products' => (array) $products, 'mode' => ( 'text' === $mode ) ? 'text' : 'html', '_user' => null, '_user_done' => false, '_order' => null, '_order_done' => false, ); $out = preg_replace_callback( '/\{\{\s*(.*?)\s*\}\}/u', function ( $m ) use ( &$bag ) { return self::resolve_one( $m[1], $bag ); }, $text ); return ( null === $out ) ? $text : (string) $out; } private static function resolve_one( $inner, &$bag ) { $inner = trim( str_replace( "\xc2\xa0", ' ', (string) $inner ) ); if ( ! preg_match( '/^([a-z0-9_.]+)/', $inner, $nm ) ) { return ''; } $name = $nm[1]; if ( false === strpos( $name, '.' ) ) { return ''; } $params = self::parse_params( substr( $inner, strlen( $name ) ) ); list( $type, $field ) = explode( '.', $name, 2 ); $val = (string) self::value_for( $name, $type, $field, $params, $bag ); if ( '' === $val ) { $fb = isset( $params['fallback'] ) ? $params['fallback'] : ( isset( $params['default'] ) ? $params['default'] : '' ); if ( '' === $fb ) { return ''; } return ( 'html' === $bag['mode'] ) ? esc_html( $fb ) : $fb; } if ( in_array( $name, self::HTML_TOKENS, true ) ) { return ( 'text' === $bag['mode'] ) ? wp_strip_all_tags( $val ) : $val; } return ( 'html' === $bag['mode'] ) ? esc_html( $val ) : $val; } private static function parse_params( $s ) { $s = trim( (string) $s ); if ( '' === $s ) { return array(); } if ( '|' === $s[0] ) { $s = trim( substr( $s, 1 ) ); } $out = array(); $frags = preg_split( "/(,)(?=(?:[^']|'[^']*')*$)/", $s ); foreach ( (array) $frags as $frag ) { $frag = trim( (string) $frag ); if ( '' === $frag || false === strpos( $frag, ':' ) ) { continue; } list( $k, $v ) = explode( ':', $frag, 2 ); $k = sanitize_key( trim( $k ) ); $v = trim( $v ); if ( strlen( $v ) >= 2 && "'" === $v[0] && "'" === substr( $v, -1 ) ) { $v = substr( $v, 1, -1 ); } if ( '' !== $k ) { $out[ $k ] = $v; } } return $out; } private static function value_for( $name, $type, $field, $params, &$bag ) { switch ( $name ) { case 'customer.first_name': return self::customer_name( $bag, 'first' ); case 'customer.last_name': return self::customer_name( $bag, 'last' ); case 'customer.email': return self::recipient_email( $bag ); case 'customer.generate_coupon': return ( is_array( $bag['coupon'] ) && ! empty( $bag['coupon']['code'] ) ) ? strtoupper( (string) $bag['coupon']['code'] ) : ''; case 'shop.title': case 'shop.name': return (string) get_bloginfo( 'name' ); case 'shop.url': return home_url( '/' ); case 'cart.link': return self::cart_link( $bag ); case 'survey.link': return self::survey_link( $params, $bag ); case 'cart.items': return self::cart_items_html( $bag ); case 'order.related_products': $prods = $bag['products']; if ( empty( $prods ) && class_exists( 'AIEO_Behavioural_Reco' ) ) { $sid = (int) ( $bag['run']['subject_id'] ?? 0 ); if ( $sid > 0 ) { foreach ( AIEO_Behavioural_Reco::recommend( $sid, 4 ) as $r ) { $prods[] = (int) $r['item_id']; } } } return self::products_html( $prods, $bag ); case 'order.number': $o = self::order_obj( $bag ); return $o ? (string) $o->get_order_number() : ''; case 'order.total': $o = self::order_obj( $bag ); return ( $o && function_exists( 'wc_price' ) ) ? wp_strip_all_tags( (string) wc_price( $o->get_total() ) ) : ''; } return ''; } private static function customer( &$bag ) { if ( ! $bag['_user_done'] ) { $bag['_user_done'] = true; $uid = (int) ( $bag['run']['wp_user_id'] ?? 0 ); $bag['_user'] = $uid > 0 ? get_user_by( 'id', $uid ) : null; } return $bag['_user']; } private static function order_obj( &$bag ) { if ( ! $bag['_order_done'] ) { $bag['_order_done'] = true; $oid = (int) ( $bag['ctx']['order_id'] ?? 0 ); $bag['_order'] = ( $oid > 0 && function_exists( 'wc_get_order' ) ) ? wc_get_order( $oid ) : null; } return $bag['_order']; } private static function customer_name( &$bag, $which ) { $field = ( 'last' === $which ) ? 'last_name' : 'first_name'; $u = self::customer( $bag ); if ( $u ) { $v = trim( (string) $u->get( $field ) ); if ( '' !== $v ) { return $v; } } $o = self::order_obj( $bag ); if ( $o ) { $v = ( 'last' === $which ) ? (string) $o->get_billing_last_name() : (string) $o->get_billing_first_name(); if ( '' !== trim( $v ) ) { return trim( $v ); } } return ''; } private static function recipient_email( &$bag ) { $u = self::customer( $bag ); if ( $u && ! empty( $u->user_email ) ) { return (string) $u->user_email; } foreach ( array( 'bill_email', 'guest_email', 'wl_email' ) as $k ) { if ( ! empty( $bag['ctx'][ $k ] ) ) { return (string) $bag['ctx'][ $k ]; } } return ''; } private static function survey_link( $params, &$bag ) { if ( ! class_exists( 'AIEO_Survey_Placement' ) ) { return ''; } $survey = isset( $params['survey'] ) ? (string) $params['survey'] : ''; if ( '' === $survey ) { return ''; } $url = AIEO_Survey_Placement::url( $survey, (int) ( $bag['ctx']['order_id'] ?? 0 ), self::recipient_email( $bag ), (int) ( $bag['run']['id'] ?? 0 ) ); if ( '' === $url ) { return ''; } $text = isset( $params['text'] ) ? trim( (string) $params['text'] ) : ''; if ( '' === $text || 'text' === $bag['mode'] ) { return $url; } return '' . esc_html( $text ) . ''; } private static function cart_link( &$bag ) { $cid = (int) ( $bag['ctx']['cart_id'] ?? 0 ); if ( $cid > 0 && class_exists( 'AIEO_Carts_Store' ) ) { $c = AIEO_Carts_Store::get( $cid ); if ( $c && ! empty( $c->token ) ) { return home_url( '/?aieo_cart=' . rawurlencode( (string) $c->token ) ); } } return function_exists( 'wc_get_cart_url' ) ? wc_get_cart_url() : home_url( '/cart/' ); } private static function cart_items_html( &$bag ) { $cid = (int) ( $bag['ctx']['cart_id'] ?? 0 ); if ( $cid > 0 && class_exists( 'AIEO_Carts_Store' ) ) { global $wpdb; $t = AIEO_Carts_Store::items_table(); $rows = $wpdb->get_results( $wpdb->prepare( "SELECT name, quantity, product_id FROM `{$t}` WHERE cart_id = %d ORDER BY id ASC", $cid ) ); if ( ! empty( $rows ) ) { $li = ''; foreach ( $rows as $r ) { $nm = (string) $r->name; if ( '' === $nm && (int) $r->product_id > 0 && function_exists( 'wc_get_product' ) ) { $p = wc_get_product( (int) $r->product_id ); if ( $p ) { $nm = (string) $p->get_name(); } } if ( '' === $nm ) { continue; } $li .= '
  • ' . esc_html( $nm ) . ' × ' . max( 1, (int) $r->quantity ) . '
  • '; } if ( '' !== $li ) { return ''; } } } return self::products_html( $bag['products'], $bag ); } private static function products_html( $products, &$bag ) { if ( ! function_exists( 'wc_get_product' ) ) { return ''; } $li = ''; foreach ( (array) $products as $pid ) { $p = wc_get_product( (int) $pid ); if ( ! $p || 'publish' !== $p->get_status() ) { continue; } $img = $p->get_image_id(); $li .= '
  • ' . ( $img ? '' : '' ) . '' . esc_html( (string) $p->get_name() ) . '
  • '; } return '' !== $li ? '' : ''; } } endif;