Welcome to the support center for

Fancy Product Designer & Multistep Product Configurator


[EXPORT] Enable bulk print-ready export in Woocommerce

When starting to handle many new orders, it is time-consuming to go inside each order, load it in the Order View and then export a Print-Ready PDF.

Instead, it would be nice to be able to select multiple orders from the orders list admin page and then choose something like "PR Export" from a combo as usual bulk operations are done on orders and have a ZIP file downloading containing print-ready export of the selected kind.

For now, I have written a custom code which does what I need ( see code below ) but it is based on my reverse engineering and might get broken on future updates. This is why I propose to make this feature integrated into the Export Add-on

Please note : the following code will only work on orders received AFTER the Export add-on was installed since only since that point some print-ready essential meta-data is stored inside the order by FPD. Also, it currently only works on PDF and SVG export types.

So this goes in functions.php. Of course, no warranties, backup before, etc.


add_filter( 'bulk_actions-edit-shop_order', 'downloads_bulk_actions_edit_product', 20, 1 );

function downloads_bulk_actions_edit_product( $actions ) {

    $actions['download_pr_fpd_export_pdfs'] = __( 'Download print-ready FPD PDFs', 'YOUR_THEME' );

    return $actions;


add_filter( 'handle_bulk_actions-edit-shop_order', 'downloads_handle_bulk_action_edit_shop_order', 10, 3 );

function downloads_handle_bulk_action_edit_shop_order( $redirect_to, $action, $post_ids ) {

    if ( $action !== 'download_pr_fpd_export_pdfs' )

        return $redirect_to; // Exit on other actions

   // this is the zip file to contain multiple PDFs, it is not possible to download multiple files separately

   $zip = new ZipArchive;

   // file name contains time-stamp. This can probably be done better with some GUID maybe

   $zip_name = FPD_ORDER_DIR . 'print_ready_files/orders-' . date('Y-m-d-H-i-s') .'.zip';

   if ($zip->open($zip_name, ZipArchive::CREATE) === TRUE)


      // go over selected orders

      foreach ( $post_ids as $post_id ) {

          $order = wc_get_order( $post_id );

          $order_data = $order->get_data();

          $order_meta = get_post_meta($post_id);


          // go over each item in the order ( NOTE: my orders have only one item currently so this might need to be debugged when there are more )

          foreach ($order->get_items() as $item_key => $item )


              // i've found that this meta data contains the data for print-ready export

              $fpd_print_order = wc_get_order_item_meta( $item_key, '_fpd_print_order', true );

              $filename = $post_id . '_'. $item_key;

              if( !empty($fpd_print_order) ) 


                // seems that newer FPD versions have json with more slashes than before. So I try both cases to be sure

                $fpd_print_order_decoded = json_decode($fpd_print_order, true );

                if( empty($fpd_print_order_decoded) ) 


                  $fpd_print_order_decoded = json_decode(stripslashes($fpd_print_order), true );


                $output_format = 'pdf';


                // copied from inside FPD                

                $print_data = array(

                  'output_format' => strpos($output_format, 'pdf') === false ? $output_format : 'pdf',

                  'include_font_files' => $output_format === 'zip_pdf_fonts' ? true : false,

                  'name' => $filename,

                  'used_fonts' => $fpd_print_order_decoded['used_fonts'],

                  'svg_data' => $fpd_print_order_decoded['svg_data'],

                  'summary_json' => false,

                  'dpi' => 300,

                  'include_images' => null,


                  $file = Fancy_Product_Designer_Export::create_print_ready_file( $print_data );

                  $file = FPD_ORDER_DIR . 'print_ready_files/' . $file;




                  error_log("empty data");


            if ($file)


               // add current item's exported pdf into the zip








       // Download the zip

        header('Content-Disposition: attachment; filename="'.basename($zip_name).'"');

        header('Content-Type: application/force-download');

        header('Content-Type: application/octet-stream');

        header('Content-Type: application/download');

        header('Content-Description: File Transfer');

        header('Content-Length: ' . filesize($zip_name));

        echo file_get_contents($zip_name);


Hope this ( or any better implementation ) will be integrated into [EXPORT add-on] so I dont loose compatibility on updates :)



3 people like this idea


A small update for the sake of those who want to use the above code in Windows.

1. Please replace this :


With this :


2. Also, for better usage please replace this :

if ($zip->open($zip_name, ZipArchive::CREATE) === TRUE)

With this :

if ($zip->open($zip_name, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE)

Good luck

Login or Signup to post a comment