4

I'm selling eBooks, and I'm capturing a name to license each eBook to with a custom field, because the eBooks are mostly bought by teachers on behalf of their students. Each eBook gets watermarked with licensing info using WooCommerce PDF Watermark

I also have a piece of code that separates multiple items of the same product into separate line items:

function split_product_individual_cart_items( $cart_item_data, $product_id ){
  $ids = array(16786);
  if (!empty($product_id) && is_numeric($product_id) && in_array((int)$product_id, $ids)) {
    $unique_cart_item_key = uniqid();
    $cart_item_data['unique_key'] = $unique_cart_item_key;
  }
  return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'split_product_individual_cart_items', 10, 2 );

This is all working fine, and my order complete page looks like this:

enter image description here

Each copy of my testing eBook (ID 16786) shows up separately, with its associated licensed_to field.

I then have the following code which adds the custom fields in to the PDF according to the developer's docs here

function wc_pdf_watermark_extend_template_tags( $parsed_text, $unparsed_text, $order, $product ) {

  $licensed_to_string = ' ';
  $order_items_array = $order->get_items();

  foreach ( $order_items_array as $item_id => $item ) {
      $product_id = $item->get_product_id();
      $licensed_to = $item->get_meta( 'licensed_to', true );
      $licensed_to_string .= $product_id . ' - ' . $item_id . ' - ' . $licensed_to . ' | ';
  }

  $parsed_text = str_replace( '{licensed_to}', $licensed_to_string, $parsed_text );

  return $parsed_text;

}
add_filter( 'woocommerce_pdf_watermark_parse_template_tags', 'wc_pdf_watermark_extend_template_tags', 10, 4 );

The problem is that each PDF shows all 3 names, whereas each downloadable eBook should be licensed to just one person:

enter image description here

Is there any way I can somehow match each custom meta field to it's corresponding PDF? Perhaps counting position in array or something?

Alternatively, is there another trick to change the product name for completed orders, and include the custom field in the name? That could then be included in the watermark and would solve my problem.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
warm__tape
  • 250
  • 4
  • 19

1 Answers1

2

Try the following instead (where I use the 4th variable function argument $product to target the current product from order items):

add_filter( 'woocommerce_pdf_watermark_parse_template_tags', 'wc_pdf_watermark_extend_template_tags', 10, 4 );
function wc_pdf_watermark_extend_template_tags( $parsed_text, $unparsed_text, $order, $product ) {
    // Loop through order items
    foreach ( $order->get_items() as $item_id => $item ) {
        // Target only current product
        if( in_array( $product->get_id(), [$item->get_product_id(), $item->get_variation_id()] ) ) {
            $product_id  = $item->get_product_id();
            $licensed_to = $item->get_meta('licensed_to');
            $replacement = $product_id . ' - ' . $item_id . ' - ' . $licensed_to;
            $parsed_text = str_replace( '{licensed_to}', $replacement, $parsed_text );
        }
    }
    return $parsed_text;
}

Code goes in functions.php file of the active child theme (or active theme). It could work.


Maybe (not sure), you could try to replace the following line:

 $parsed_text = str_replace( '{licensed_to}', $replacement, $parsed_text );

with:

 $parsed_text = str_replace( '{licensed_to}', $replacement, $unparsed_text );
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Hey @LoicTheAztec, I've tried out your suggested code, but it still results in the same behaviour. All 3 names are still printed in each copy of the eBook unfortunately. – warm__tape Mar 30 '21 at 17:37