WooCommerce PDF Invoices & Packing Slips - Version 3.2.2

Version Description

(2022-10-25) = * New: filter to allow customers to access your PDF with a unique key * Fix: check if the shop logo exists * Fix: check if HTML is escaped properly before echoing * Fix: maybe reinstall fonts (if are missing) before PDF output * Fix: bug on automatic cleanup cron job * Fix: removes WC legacy versions compatibility classes. Bumps WC minimum version to 3.0 * Fix: allow manually resending new order email * Fix: run action hooks within invoice columns under order list * Marked tested up to WooCommerce 7.0

Download this release

Release Info

Developer wpovernight
Plugin Icon 128x128 WooCommerce PDF Invoices & Packing Slips
Version 3.2.2
Comparing to
See all releases

Code changes from version 3.2.1 to 3.2.2

Files changed (39) hide show
  1. assets/css/order-styles-buttons-wc20.css +0 -3
  2. assets/css/order-styles-buttons-wc20.min.css +0 -1
  3. includes/class-wcpdf-admin.php +15 -47
  4. includes/class-wcpdf-assets.php +1 -11
  5. includes/class-wcpdf-endpoint.php +3 -5
  6. includes/class-wcpdf-frontend.php +2 -6
  7. includes/class-wcpdf-install.php +0 -4
  8. includes/class-wcpdf-main.php +92 -8
  9. includes/class-wcpdf-settings-callbacks.php +10 -10
  10. includes/class-wcpdf-settings-debug.php +1 -13
  11. includes/class-wcpdf-settings-documents.php +2 -2
  12. includes/class-wcpdf-settings.php +11 -1
  13. includes/compatibility/abstract-wc-data-compatibility.php +0 -204
  14. includes/compatibility/class-wc-core-compatibility.php +0 -231
  15. includes/compatibility/class-wc-date-compatibility.php +0 -114
  16. includes/compatibility/class-wc-order-compatibility.php +0 -412
  17. includes/compatibility/class-wc-product-compatibility.php +0 -288
  18. includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php +14 -17
  19. includes/compatibility/wc-datetime-functions-compatibility.php +0 -48
  20. includes/documents/abstract-wcpdf-order-document-methods.php +84 -189
  21. includes/documents/abstract-wcpdf-order-document.php +73 -55
  22. includes/documents/class-wcpdf-bulk-document.php +1 -5
  23. includes/documents/class-wcpdf-document-number.php +2 -6
  24. includes/documents/class-wcpdf-invoice.php +2 -6
  25. includes/documents/class-wcpdf-packing-slip.php +1 -5
  26. includes/legacy/class-wcpdf-legacy-deprecated-hooks.php +4 -8
  27. includes/legacy/class-wcpdf-legacy-document.php +0 -4
  28. includes/legacy/class-wcpdf-legacy-export.php +2 -6
  29. includes/legacy/class-wcpdf-legacy-functions.php +0 -4
  30. includes/legacy/class-wcpdf-legacy-settings.php +3 -3
  31. includes/views/dompdf-status.php +4 -4
  32. includes/views/setup-wizard/display-options.php +3 -3
  33. includes/views/wcpdf-settings-page.php +2 -2
  34. includes/wcpdf-functions.php +5 -9
  35. readme.txt +14 -3
  36. templates/Simple/html-document-wrapper.php +1 -1
  37. templates/Simple/invoice.php +15 -15
  38. templates/Simple/packing-slip.php +9 -9
  39. woocommerce-pdf-invoices-packingslips.php +33 -13
assets/css/order-styles-buttons-wc20.css DELETED
@@ -1,3 +0,0 @@
1
- .type-shop_order .column-order_actions a.button.wpo_wcpdf {
2
- padding: 0 2px;
3
- }
 
 
 
assets/css/order-styles-buttons-wc20.min.css DELETED
@@ -1 +0,0 @@
1
- .type-shop_order .column-order_actions a.button.wpo_wcpdf{padding:0 2px}
 
includes/class-wcpdf-admin.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -18,11 +14,7 @@ class Admin {
18
  add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_invoice_columns' ), 999 );
19
  add_action( 'manage_shop_order_posts_custom_column', array( $this, 'invoice_columns_data' ), 2 );
20
  add_filter( 'manage_edit-shop_order_sortable_columns', array( $this, 'invoice_columns_sortable' ) );
21
- if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.0', '>=' ) ) {
22
- add_filter( 'request', array( $this, 'request_query_sort_by_column' ) );
23
- } else {
24
- add_filter( 'pre_get_posts', array( $this, 'pre_get_posts_sort_by_column' ) );
25
- }
26
 
27
  add_action( 'add_meta_boxes_shop_order', array( $this, 'add_meta_boxes' ) );
28
  if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.3', '>=' ) ) {
@@ -253,27 +245,23 @@ class Admin {
253
  $this->disable_storing_document_settings();
254
 
255
  $order = '';
256
- if ( empty( $the_order ) || WCX_Order::get_id( $the_order ) != $post->ID ) {
257
- $order = WCX::get_order( $post->ID );
258
  } else {
259
  $order = $the_order;
260
  }
261
 
262
  $invoice = wcpdf_get_invoice( $order );
263
 
264
- if ( empty( $invoice ) ) {
265
- return;
266
- }
267
-
268
  switch ( $column ) {
269
  case 'invoice_number_column':
270
- echo $invoice->get_number();
 
271
  do_action( 'wcpdf_invoice_number_column_end', $order );
272
  break;
273
  case 'invoice_date_column':
274
- if ( ! empty( $date = $invoice->get_date() ) ) {
275
- echo $date->date_i18n( wcpdf_date_format( $invoice, 'invoice_date_column' ) );
276
- }
277
  do_action( 'wcpdf_invoice_date_column_end', $order );
278
  break;
279
  default:
@@ -290,28 +278,6 @@ class Admin {
290
  return $columns;
291
  }
292
 
293
- /**
294
- * Pre WC3.X sorting
295
- */
296
- public function pre_get_posts_sort_by_column( $query ) {
297
- if ( ! is_admin() ) {
298
- return;
299
- }
300
-
301
- switch ( $query->get( 'orderby' ) ) {
302
- case 'invoice_number_column':
303
- $query->set( 'meta_key', '_wcpdf_invoice_number' );
304
- $query->set( 'orderby', apply_filters( 'wpo_wcpdf_invoice_number_column_orderby', 'meta_value' ) );
305
- break;
306
- case 'invoice_date_column':
307
- $query->set( 'meta_key', '_wcpdf_invoice_date' );
308
- $query->set( 'orderby', apply_filters( 'wpo_wcpdf_invoice_date_column_orderby', 'meta_value' ) );
309
- break;
310
- default:
311
- return;
312
- }
313
- }
314
-
315
  /**
316
  * WC3.X+ sorting
317
  */
@@ -426,7 +392,7 @@ class Admin {
426
 
427
  $meta_box_actions = array();
428
  $documents = WPO_WCPDF()->documents->get_documents();
429
- $order = WCX::get_order( $post->ID );
430
  foreach ( $documents as $document ) {
431
  $document_title = $document->get_title();
432
  if ( $document = wcpdf_get_document( $document->get_type(), $order ) ) {
@@ -462,7 +428,7 @@ class Admin {
462
  }
463
 
464
  public function data_input_box_content( $post ) {
465
- $order = WCX::get_order( $post->ID );
466
  $this->disable_storing_document_settings();
467
  $invoice = wcpdf_get_document( 'invoice', $order );
468
 
@@ -525,7 +491,7 @@ class Admin {
525
  if( empty( $document ) || empty( $data ) ) return;
526
  $data = $this->get_current_values_for_document( $document, $data );
527
  ?>
528
- <div class="wcpdf-data-fields" data-document="<?= esc_attr( $document->get_type() ); ?>" data-order_id="<?php echo esc_attr( WCX_Order::get_id( $document->order ) ); ?>">
529
  <section class="wcpdf-data-fields-section number-date">
530
  <!-- Title -->
531
  <h4>
@@ -663,7 +629,7 @@ class Admin {
663
  <script type="text/javascript">
664
  jQuery(document).ready(function() {
665
  <?php foreach ($this->get_bulk_actions() as $action => $title) { ?>
666
- jQuery('<option>').val('<?php echo $action; ?>').html('<?php echo esc_attr( $title ); ?>').appendTo("select[name='action'], select[name='action2']");
667
  <?php } ?>
668
  });
669
  </script>
@@ -696,7 +662,7 @@ class Admin {
696
  return;
697
  }
698
 
699
- $order = WCX::get_order( $post_id );
700
  if ( $invoice = wcpdf_get_invoice( $order ) ) {
701
  $is_new = false === $invoice->exists();
702
  $_POST = stripslashes_deep( $_POST );
@@ -759,7 +725,9 @@ class Admin {
759
  if ( ! empty( $mails ) ) {
760
  foreach ( $mails as $mail ) {
761
  if ( $mail->id == $email_to_send ) {
 
762
  $mail->trigger( $order->get_id(), $order );
 
763
  /* translators: %s: email title */
764
  $order->add_order_note( sprintf( esc_html__( '%s email notification manually sent.', 'woocommerce-pdf-invoices-packing-slips' ), $mail->title ), false, true );
765
  }
@@ -832,7 +800,7 @@ class Admin {
832
  }
833
 
834
  $order_id = absint( $_POST['order_id'] );
835
- $order = WCX::get_order( $order_id );
836
  $document_type = sanitize_text_field( $_POST['document_type'] );
837
  $action_type = sanitize_text_field( $_POST['action_type'] );
838
  $notice = sanitize_text_field( $_POST['wpcdf_document_data_notice'] );
1
  <?php
2
  namespace WPO\WC\PDF_Invoices;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
14
  add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_invoice_columns' ), 999 );
15
  add_action( 'manage_shop_order_posts_custom_column', array( $this, 'invoice_columns_data' ), 2 );
16
  add_filter( 'manage_edit-shop_order_sortable_columns', array( $this, 'invoice_columns_sortable' ) );
17
+ add_filter( 'request', array( $this, 'request_query_sort_by_column' ) );
 
 
 
 
18
 
19
  add_action( 'add_meta_boxes_shop_order', array( $this, 'add_meta_boxes' ) );
20
  if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.3', '>=' ) ) {
245
  $this->disable_storing_document_settings();
246
 
247
  $order = '';
248
+ if ( empty( $the_order ) || $the_order->get_id() != $post->ID ) {
249
+ $order = wc_get_order( $post->ID );
250
  } else {
251
  $order = $the_order;
252
  }
253
 
254
  $invoice = wcpdf_get_invoice( $order );
255
 
 
 
 
 
256
  switch ( $column ) {
257
  case 'invoice_number_column':
258
+ $invoice_number = ! empty( $invoice ) && ! empty( $invoice->get_number() ) ? esc_attr( $invoice->get_number() ) : '';
259
+ echo $invoice_number;
260
  do_action( 'wcpdf_invoice_number_column_end', $order );
261
  break;
262
  case 'invoice_date_column':
263
+ $invoice_date = ! empty( $invoice ) && ! empty( $invoice->get_date() ) ? esc_attr( $invoice->get_date()->date_i18n( wcpdf_date_format( $invoice, 'invoice_date_column' ) ) ) : '';
264
+ echo $invoice_date;
 
265
  do_action( 'wcpdf_invoice_date_column_end', $order );
266
  break;
267
  default:
278
  return $columns;
279
  }
280
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  /**
282
  * WC3.X+ sorting
283
  */
392
 
393
  $meta_box_actions = array();
394
  $documents = WPO_WCPDF()->documents->get_documents();
395
+ $order = wc_get_order( $post->ID );
396
  foreach ( $documents as $document ) {
397
  $document_title = $document->get_title();
398
  if ( $document = wcpdf_get_document( $document->get_type(), $order ) ) {
428
  }
429
 
430
  public function data_input_box_content( $post ) {
431
+ $order = wc_get_order( $post->ID );
432
  $this->disable_storing_document_settings();
433
  $invoice = wcpdf_get_document( 'invoice', $order );
434
 
491
  if( empty( $document ) || empty( $data ) ) return;
492
  $data = $this->get_current_values_for_document( $document, $data );
493
  ?>
494
+ <div class="wcpdf-data-fields" data-document="<?= esc_attr( $document->get_type() ); ?>" data-order_id="<?php echo esc_attr( $document->order->get_id() ); ?>">
495
  <section class="wcpdf-data-fields-section number-date">
496
  <!-- Title -->
497
  <h4>
629
  <script type="text/javascript">
630
  jQuery(document).ready(function() {
631
  <?php foreach ($this->get_bulk_actions() as $action => $title) { ?>
632
+ jQuery('<option>').val('<?php echo esc_attr( $action ); ?>').html('<?php echo esc_attr( $title ); ?>').appendTo("select[name='action'], select[name='action2']");
633
  <?php } ?>
634
  });
635
  </script>
662
  return;
663
  }
664
 
665
+ $order = wc_get_order( $post_id );
666
  if ( $invoice = wcpdf_get_invoice( $order ) ) {
667
  $is_new = false === $invoice->exists();
668
  $_POST = stripslashes_deep( $_POST );
725
  if ( ! empty( $mails ) ) {
726
  foreach ( $mails as $mail ) {
727
  if ( $mail->id == $email_to_send ) {
728
+ add_filter( 'woocommerce_new_order_email_allows_resend', '__return_true' );
729
  $mail->trigger( $order->get_id(), $order );
730
+ remove_filter( 'woocommerce_new_order_email_allows_resend', '__return_true' );
731
  /* translators: %s: email title */
732
  $order->add_order_note( sprintf( esc_html__( '%s email notification manually sent.', 'woocommerce-pdf-invoices-packing-slips' ), $mail->title ), false, true );
733
  }
800
  }
801
 
802
  $order_id = absint( $_POST['order_id'] );
803
+ $order = wc_get_order( $order_id );
804
  $document_type = sanitize_text_field( $_POST['document_type'] );
805
  $action_type = sanitize_text_field( $_POST['action_type'] );
806
  $notice = sanitize_text_field( $_POST['wpcdf_document_data_notice'] );
includes/class-wcpdf-assets.php CHANGED
@@ -40,17 +40,7 @@ class Assets {
40
  WPO_WCPDF_VERSION
41
  );
42
 
43
- $wc_version = defined( 'WC_VERSION' ) ? WC_VERSION : WOOCOMMERCE_VERSION;
44
-
45
- if ( version_compare( $wc_version, '2.1', '<' ) ) {
46
- // legacy WC2.0 styles
47
- wp_enqueue_style(
48
- 'wpo-wcpdf-order-styles-buttons',
49
- WPO_WCPDF()->plugin_url() . '/assets/css/order-styles-buttons-wc20'.$suffix.'.css',
50
- array(),
51
- WPO_WCPDF_VERSION
52
- );
53
- } elseif ( version_compare( $wc_version, '2.1', '>=' ) && version_compare( $wp_version, '5.3', '<' ) ) {
54
  // WC2.1 - WC3.2 (MP6) is used: bigger buttons
55
  // also applied to WC3.3+ but without affect due to .column-order_actions class being deprecated in 3.3+
56
  wp_enqueue_style(
40
  WPO_WCPDF_VERSION
41
  );
42
 
43
+ if ( version_compare( $wp_version, '5.3', '<' ) ) {
 
 
 
 
 
 
 
 
 
 
44
  // WC2.1 - WC3.2 (MP6) is used: bigger buttons
45
  // also applied to WC3.3+ but without affect due to .column-order_actions class being deprecated in 3.3+
46
  wp_enqueue_style(
includes/class-wcpdf-endpoint.php CHANGED
@@ -1,8 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
5
-
6
  if ( ! defined( 'ABSPATH' ) ) {
7
  exit; // Exit if accessed directly
8
  }
@@ -75,7 +73,7 @@ class Endpoint {
75
  $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() );
76
  if ( is_user_logged_in() ) {
77
  $access_key = wp_create_nonce( $this->action );
78
- } elseif ( ! is_user_logged_in() && isset( $debug_settings['guest_access'] ) ) {
79
  $access_key = $order->get_order_key();
80
  } else {
81
  return '';
@@ -85,7 +83,7 @@ class Endpoint {
85
  $parameters = array(
86
  $this->get_identifier(),
87
  $document_type,
88
- WCX_Order::get_id( $order ),
89
  $access_key,
90
  );
91
  $document_link = trailingslashit( get_home_url() ) . implode( '/', $parameters );
@@ -93,7 +91,7 @@ class Endpoint {
93
  $document_link = add_query_arg( array(
94
  'action' => $this->action,
95
  'document_type' => $document_type,
96
- 'order_ids' => WCX_Order::get_id( $order ),
97
  'access_key' => $access_key,
98
  ), admin_url( 'admin-ajax.php' ) );
99
  }
1
  <?php
2
  namespace WPO\WC\PDF_Invoices;
3
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
73
  $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() );
74
  if ( is_user_logged_in() ) {
75
  $access_key = wp_create_nonce( $this->action );
76
+ } elseif ( ! is_user_logged_in() && WPO_WCPDF()->settings->is_guest_access_enabled() ) {
77
  $access_key = $order->get_order_key();
78
  } else {
79
  return '';
83
  $parameters = array(
84
  $this->get_identifier(),
85
  $document_type,
86
+ $order->get_id(),
87
  $access_key,
88
  );
89
  $document_link = trailingslashit( get_home_url() ) . implode( '/', $parameters );
91
  $document_link = add_query_arg( array(
92
  'action' => $this->action,
93
  'document_type' => $document_type,
94
+ 'order_ids' => $order->get_id(),
95
  'access_key' => $access_key,
96
  ), admin_url( 'admin-ajax.php' ) );
97
  }
includes/class-wcpdf-frontend.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -44,7 +40,7 @@ class Frontend {
44
  break;
45
  case 'custom':
46
  $allowed_statuses = $button_setting = $invoice->get_setting( 'my_account_restrict', array() );
47
- if ( !empty( $allowed_statuses ) && in_array( WCX_Order::get_status( $order ), array_keys( $allowed_statuses ) ) ) {
48
  $invoice_allowed = true;
49
  } else {
50
  $invoice_allowed = false;
@@ -53,7 +49,7 @@ class Frontend {
53
  }
54
 
55
  // Check if invoice has been created already or if status allows download (filter your own array of allowed statuses)
56
- if ( $invoice_allowed || in_array( WCX_Order::get_status( $order ), apply_filters( 'wpo_wcpdf_myaccount_allowed_order_statuses', array() ) ) ) {
57
  $actions['invoice'] = array(
58
  'url' => esc_url( $pdf_url ),
59
  'name' => apply_filters( 'wpo_wcpdf_myaccount_button_text', $invoice->get_title(), $invoice )
1
  <?php
2
  namespace WPO\WC\PDF_Invoices;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
40
  break;
41
  case 'custom':
42
  $allowed_statuses = $button_setting = $invoice->get_setting( 'my_account_restrict', array() );
43
+ if ( !empty( $allowed_statuses ) && in_array( $order->get_status(), array_keys( $allowed_statuses ) ) ) {
44
  $invoice_allowed = true;
45
  } else {
46
  $invoice_allowed = false;
49
  }
50
 
51
  // Check if invoice has been created already or if status allows download (filter your own array of allowed statuses)
52
+ if ( $invoice_allowed || in_array( $order->get_status(), apply_filters( 'wpo_wcpdf_myaccount_allowed_order_statuses', array() ) ) ) {
53
  $actions['invoice'] = array(
54
  'url' => esc_url( $pdf_url ),
55
  'name' => apply_filters( 'wpo_wcpdf_myaccount_button_text', $invoice->get_title(), $invoice )
includes/class-wcpdf-install.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
1
  <?php
2
  namespace WPO\WC\PDF_Invoices;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
includes/class-wcpdf-main.php CHANGED
@@ -2,9 +2,6 @@
2
  namespace WPO\WC\PDF_Invoices;
3
 
4
  use WPO\WC\PDF_Invoices\Font_Synchronizer;
5
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
6
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
7
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
8
 
9
  if ( ! defined( 'ABSPATH' ) ) {
10
  exit; // Exit if accessed directly
@@ -80,7 +77,7 @@ class Main {
80
  return $attachments;
81
  }
82
 
83
- $order_id = WCX_Order::get_id( $order );
84
 
85
  if ( ! ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) && $order_id == false ) {
86
  return $attachments;
@@ -90,7 +87,7 @@ class Main {
90
  if ( get_post_type( $order_id ) == 'wc_booking' && isset( $order->order ) ) {
91
  // $order is actually a WC_Booking object!
92
  $order = $order->order;
93
- $order_id = WCX_Order::get_id( $order );
94
  }
95
 
96
  // do not process low stock notifications, user emails etc!
@@ -123,7 +120,7 @@ class Main {
123
  $attach_to_document_types = $this->get_documents_for_email( $email_id, $order );
124
  foreach ( $attach_to_document_types as $document_type ) {
125
  $email_order = apply_filters( 'wpo_wcpdf_email_attachment_order', $order, $email, $document_type );
126
- $email_order_id = WCX_Order::get_id( $email_order );
127
 
128
  do_action( 'wpo_wcpdf_before_attachment_creation', $email_order, $email_id, $document_type );
129
 
@@ -256,7 +253,7 @@ class Main {
256
  * Load and generate the template output with ajax
257
  */
258
  public function generate_pdf_ajax() {
259
- $guest_access = isset( WPO_WCPDF()->settings->debug_settings['guest_access'] );
260
  if ( ! $guest_access && current_filter() == 'wp_ajax_nopriv_generate_wpo_wcpdf' ) {
261
  wp_die( esc_attr__( 'You do not have sufficient permissions to access this page.', 'woocommerce-pdf-invoices-packing-slips' ) );
262
  }
@@ -525,6 +522,91 @@ class Main {
525
  return $wp_upload_base;
526
  }
527
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  /**
529
  * Generate random string
530
  */
@@ -909,7 +991,9 @@ class Main {
909
  if ( ! function_exists( 'list_files' ) ) {
910
  include_once( ABSPATH.'wp-admin/includes/file.php' );
911
  }
912
- $files = array_merge( $files, list_files( $path, $folders_level ) );
 
 
913
  }
914
 
915
  if ( ! empty( $files ) ) {
2
  namespace WPO\WC\PDF_Invoices;
3
 
4
  use WPO\WC\PDF_Invoices\Font_Synchronizer;
 
 
 
5
 
6
  if ( ! defined( 'ABSPATH' ) ) {
7
  exit; // Exit if accessed directly
77
  return $attachments;
78
  }
79
 
80
+ $order_id = $order->get_id();
81
 
82
  if ( ! ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) && $order_id == false ) {
83
  return $attachments;
87
  if ( get_post_type( $order_id ) == 'wc_booking' && isset( $order->order ) ) {
88
  // $order is actually a WC_Booking object!
89
  $order = $order->order;
90
+ $order_id = $order->get_id();
91
  }
92
 
93
  // do not process low stock notifications, user emails etc!
120
  $attach_to_document_types = $this->get_documents_for_email( $email_id, $order );
121
  foreach ( $attach_to_document_types as $document_type ) {
122
  $email_order = apply_filters( 'wpo_wcpdf_email_attachment_order', $order, $email, $document_type );
123
+ $email_order_id = $email_order->get_id();
124
 
125
  do_action( 'wpo_wcpdf_before_attachment_creation', $email_order, $email_id, $document_type );
126
 
253
  * Load and generate the template output with ajax
254
  */
255
  public function generate_pdf_ajax() {
256
+ $guest_access = WPO_WCPDF()->settings->is_guest_access_enabled();
257
  if ( ! $guest_access && current_filter() == 'wp_ajax_nopriv_generate_wpo_wcpdf' ) {
258
  wp_die( esc_attr__( 'You do not have sufficient permissions to access this page.', 'woocommerce-pdf-invoices-packing-slips' ) );
259
  }
522
  return $wp_upload_base;
523
  }
524
 
525
+ /**
526
+ * Checks if the tmp subfolder has files
527
+ *
528
+ * @param string $subfolder can be 'attachments', 'fonts' or 'dompdf'
529
+ *
530
+ * @return bool
531
+ */
532
+ public function tmp_subfolder_has_files( $subfolder ) {
533
+ $has_files = false;
534
+
535
+ if ( empty( $subfolder ) || ! in_array( $subfolder, $this->subfolders ) ) {
536
+ wcpdf_log_error( sprintf( 'The directory %s is not a default tmp subfolder from this plugin.', $subfolder ), 'critical' );
537
+ return $has_files;
538
+ }
539
+
540
+ // we have a cached value
541
+ if ( get_transient( "wpo_wcpdf_subfolder_{$subfolder}_has_files" ) !== false ) {
542
+ return wc_string_to_bool( get_transient( "wpo_wcpdf_subfolder_{$subfolder}_has_files" ) );
543
+ }
544
+
545
+ if ( ! function_exists( 'glob' ) ) {
546
+ wcpdf_log_error( 'PHP glob function not found.', 'critical' );
547
+ return $has_files;
548
+ }
549
+
550
+ $tmp_path = untrailingslashit( $this->get_tmp_path( $subfolder ) );
551
+
552
+ switch ( $subfolder ) {
553
+ case 'attachments':
554
+ if ( ! empty( glob( $tmp_path.'/*.pdf' ) ) ) {
555
+ $has_files = true;
556
+ }
557
+ break;
558
+ case 'fonts':
559
+ if ( ! empty( glob( $tmp_path.'/*.ttf' ) ) ) {
560
+ $has_files = true;
561
+ }
562
+ break;
563
+ case 'dompdf':
564
+ if ( ! empty( glob( $tmp_path.'/*.*' ) ) ) {
565
+ $has_files = true;
566
+ }
567
+ break;
568
+ }
569
+
570
+ // save value to cache
571
+ set_transient( "wpo_wcpdf_subfolder_{$subfolder}_has_files", ( true === $has_files ) ? 'yes' : 'no' , DAY_IN_SECONDS );
572
+
573
+ return $has_files;
574
+ }
575
+
576
+ /**
577
+ * Maybe reinstall fonts
578
+ *
579
+ * @param bool $force force fonts reinstall
580
+ *
581
+ * @return void
582
+ */
583
+ public function maybe_reinstall_fonts( $force = false ) {
584
+ if ( false === $this->tmp_subfolder_has_files( 'fonts' ) || true === $force ) {
585
+ $fonts_path = untrailingslashit( $this->get_tmp_path( 'fonts' ) );
586
+
587
+ // clear folder first
588
+ if ( function_exists( 'glob' ) && $files = glob( $fonts_path.'/*.*' ) ) {
589
+ $exclude_files = array( 'index.php', '.htaccess' );
590
+ foreach ( $files as $file ) {
591
+ if ( is_file( $file ) && ! in_array( basename( $file ), $exclude_files ) ) {
592
+ unlink( $file );
593
+ }
594
+ }
595
+ } else {
596
+ wcpdf_log_error( "Couldn't clear fonts tmp subfolder before copy fonts.", 'critical' );
597
+ }
598
+
599
+ // copy fonts
600
+ $this->copy_fonts( $fonts_path );
601
+
602
+ // save to cache
603
+ if ( get_transient( 'wpo_wcpdf_subfolder_fonts_has_files' ) !== false ) {
604
+ delete_transient( 'wpo_wcpdf_subfolder_fonts_has_files' );
605
+ }
606
+ set_transient( 'wpo_wcpdf_subfolder_fonts_has_files', 'yes' , DAY_IN_SECONDS );
607
+ }
608
+ }
609
+
610
  /**
611
  * Generate random string
612
  */
991
  if ( ! function_exists( 'list_files' ) ) {
992
  include_once( ABSPATH.'wp-admin/includes/file.php' );
993
  }
994
+ if ( $listed_files = list_files( $path, $folders_level ) ) {
995
+ $files = array_merge( $files, $listed_files );
996
+ }
997
  }
998
 
999
  if ( ! empty( $files ) ) {
includes/class-wcpdf-settings-callbacks.php CHANGED
@@ -224,7 +224,7 @@ class Settings_Callbacks {
224
  $title = ! empty( $title ) ? esc_attr( $title ) : '';
225
  $class = 'wc-enhanced-select wpo-wcpdf-enhanced-select';
226
  $css = 'width:400px';
227
- printf( '<select id="%1$s" name="%2$s" data-placeholder="%3$s" title="%4$s" class="%5$s" style="%6$s" %7$s>', esc_attr( $id ), esc_attr( $setting_name ), esc_attr( $placeholder ), esc_attr( $title ), esc_attr( $class ), esc_attr( $css ), $multiple );
228
  } else {
229
  printf( '<select id="%1$s" name="%2$s">', esc_attr( $id ), esc_attr( $setting_name ) );
230
  }
@@ -236,9 +236,9 @@ class Settings_Callbacks {
236
  foreach ( $options as $key => $label ) {
237
  if ( ! empty( $multiple ) && is_array( $current ) ) {
238
  $selected = in_array( $key, $current ) ? ' selected="selected"' : '';
239
- printf( '<option value="%s"%s>%s</option>', esc_attr( $key ), $selected, esc_html( $label ) );
240
  } else {
241
- printf( '<option value="%s"%s>%s</option>', esc_attr( $key ), selected( $current, $key, false ), esc_html( $label ) );
242
  }
243
  }
244
 
@@ -255,19 +255,19 @@ class Settings_Callbacks {
255
  ?>
256
  <script type="text/javascript">
257
  jQuery(document).ready(function($) {
258
- function check_<?php echo $id; ?>_custom() {
259
- var custom = $('#<?php echo $id; ?>').val();
260
  if (custom == '<?php echo $custom_option; ?>') {
261
- $( '.<?php echo $id; ?>_custom').show();
262
  } else {
263
- $( '.<?php echo $id; ?>_custom').hide();
264
  }
265
  }
266
 
267
- check_<?php echo $id; ?>_custom();
268
 
269
- $( '#<?php echo $id; ?>' ).on( 'change', function() {
270
- check_<?php echo $id; ?>_custom();
271
  });
272
 
273
  });
224
  $title = ! empty( $title ) ? esc_attr( $title ) : '';
225
  $class = 'wc-enhanced-select wpo-wcpdf-enhanced-select';
226
  $css = 'width:400px';
227
+ printf( '<select id="%1$s" name="%2$s" data-placeholder="%3$s" title="%4$s" class="%5$s" style="%6$s" %7$s>', esc_attr( $id ), esc_attr( $setting_name ), esc_attr( $placeholder ), esc_attr( $title ), esc_attr( $class ), esc_attr( $css ), esc_attr( $multiple ) );
228
  } else {
229
  printf( '<select id="%1$s" name="%2$s">', esc_attr( $id ), esc_attr( $setting_name ) );
230
  }
236
  foreach ( $options as $key => $label ) {
237
  if ( ! empty( $multiple ) && is_array( $current ) ) {
238
  $selected = in_array( $key, $current ) ? ' selected="selected"' : '';
239
+ printf( '<option value="%s"%s>%s</option>', esc_attr( $key ), esc_attr( $selected ), esc_html( $label ) );
240
  } else {
241
+ printf( '<option value="%s"%s>%s</option>', esc_attr( $key ), esc_attr( selected( $current, $key, false ) ), esc_html( $label ) );
242
  }
243
  }
244
 
255
  ?>
256
  <script type="text/javascript">
257
  jQuery(document).ready(function($) {
258
+ function check_<?php echo esc_attr( $id ); ?>_custom() {
259
+ var custom = $('#<?php echo esc_attr( $id ); ?>').val();
260
  if (custom == '<?php echo $custom_option; ?>') {
261
+ $( '.<?php echo esc_attr( $id ); ?>_custom').show();
262
  } else {
263
+ $( '.<?php echo esc_attr( $id ); ?>_custom').hide();
264
  }
265
  }
266
 
267
+ check_<?php echo esc_attr( $id ); ?>_custom();
268
 
269
+ $( '#<?php echo esc_attr( $id ); ?>' ).on( 'change', function() {
270
+ check_<?php echo esc_attr( $id ); ?>_custom();
271
  });
272
 
273
  });
includes/class-wcpdf-settings-debug.php CHANGED
@@ -73,19 +73,7 @@ class Settings_Debug {
73
  return;
74
  }
75
 
76
- $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
77
-
78
- // clear folder first
79
- if ( function_exists( "glob" ) && $files = glob( $font_path.'/*.*' ) ) {
80
- $exclude_files = array( 'index.php', '.htaccess' );
81
- foreach( $files as $file ) {
82
- if( is_file( $file ) && !in_array( basename( $file ), $exclude_files ) ) {
83
- unlink( $file );
84
- }
85
- }
86
- }
87
-
88
- WPO_WCPDF()->main->copy_fonts( $font_path );
89
  printf('<div class="notice notice-success"><p>%s</p></div>', esc_html__( 'Fonts reinstalled!', 'woocommerce-pdf-invoices-packing-slips' ) );
90
  }
91
  ?>
73
  return;
74
  }
75
 
76
+ WPO_WCPDF()->main->maybe_reinstall_fonts( true );
 
 
 
 
 
 
 
 
 
 
 
 
77
  printf('<div class="notice notice-success"><p>%s</p></div>', esc_html__( 'Fonts reinstalled!', 'woocommerce-pdf-invoices-packing-slips' ) );
78
  }
79
  ?>
includes/class-wcpdf-settings-documents.php CHANGED
@@ -31,7 +31,7 @@ class Settings_Documents {
31
  <?php
32
  foreach ( $documents as $document ) {
33
  if ( $document->get_type() == $section ) {
34
- echo '<h2>'.$document->get_title().'<span class="arrow-down">&#9660;</span></h2>';
35
  }
36
  }
37
  ?>
@@ -44,7 +44,7 @@ class Settings_Documents {
44
  $title = '['.__( 'untitled', 'woocommerce-pdf-invoices-packing-slips' ).']';
45
  }
46
  $active = $document->get_type() == $section ? 'active' : '';
47
- printf( '<li class="%2$s"><a href="%1$s" class="%2$s">%3$s</a></li>', esc_url( add_query_arg( 'section', $document->get_type() ) ), $active, esc_html( $title ) );
48
  }
49
  }
50
  ?>
31
  <?php
32
  foreach ( $documents as $document ) {
33
  if ( $document->get_type() == $section ) {
34
+ echo '<h2>'.esc_html( $document->get_title() ).'<span class="arrow-down">&#9660;</span></h2>';
35
  }
36
  }
37
  ?>
44
  $title = '['.__( 'untitled', 'woocommerce-pdf-invoices-packing-slips' ).']';
45
  }
46
  $active = $document->get_type() == $section ? 'active' : '';
47
+ printf( '<li class="%2$s"><a href="%1$s" class="%2$s">%3$s</a></li>', esc_url( add_query_arg( 'section', $document->get_type() ) ), esc_attr( $active ), esc_html( $title ) );
48
  }
49
  }
50
  ?>
includes/class-wcpdf-settings.php CHANGED
@@ -677,7 +677,7 @@ class Settings {
677
  $number_store_method = $this->get_sequential_number_store_method();
678
  $number_store = new Sequential_Number_Store( $_POST['store'], $number_store_method );
679
  $number_store->set_next( $number );
680
- echo "next number ({$_POST['store']}) set to {$number}";
681
  die();
682
  }
683
 
@@ -746,6 +746,16 @@ class Settings {
746
  return $new_settings;
747
  }
748
 
 
 
 
 
 
 
 
 
 
 
749
  }
750
 
751
  endif; // class_exists
677
  $number_store_method = $this->get_sequential_number_store_method();
678
  $number_store = new Sequential_Number_Store( $_POST['store'], $number_store_method );
679
  $number_store->set_next( $number );
680
+ echo wp_kses_post( "next number ({$_POST['store']}) set to {$number}" );
681
  die();
682
  }
683
 
746
  return $new_settings;
747
  }
748
 
749
+ /**
750
+ * Checks if guest access is enabled
751
+ *
752
+ * @return bool
753
+ */
754
+ public function is_guest_access_enabled() {
755
+ $guest_access = isset( $this->debug_settings['guest_access'] ) ? true : false;
756
+
757
+ return apply_filters( 'wpo_wcpdf_guest_access_enabled', $guest_access, $this );
758
+ }
759
  }
760
 
761
  endif; // class_exists
includes/compatibility/abstract-wc-data-compatibility.php DELETED
@@ -1,204 +0,0 @@
1
- <?php
2
- namespace WPO\WC\PDF_Invoices\Compatibility;
3
-
4
- /**
5
- * Derived from SkyVerge WooCommerce Plugin Framework https://github.com/skyverge/wc-plugin-framework/
6
- */
7
-
8
- defined( 'ABSPATH' ) or exit;
9
-
10
- if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\Compatibility\\Data' ) ) :
11
-
12
- /**
13
- * WooCommerce data compatibility class.
14
- *
15
- * @since 4.6.0-dev
16
- */
17
- abstract class Data {
18
-
19
- /**
20
- * Creates aliases for add_meta_data, update_meta_data and delete_meta_data without the _data suffix
21
- *
22
- * @param string $name static function name
23
- * @param array $arguments function arguments
24
- */
25
- public static function __callStatic( $name, $arguments ) {
26
- if ( substr( $name, -strlen('_meta') ) == '_meta' && method_exists( __CLASS__, $name.'_data' ) ) {
27
- call_user_func_array( array( __CLASS__, $name.'_data' ), $arguments );
28
- }
29
- }
30
-
31
-
32
- /**
33
- * Gets an object property.
34
- *
35
- * @since 4.6.0-dev
36
- * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
37
- * @param string $prop the property name
38
- * @param string $context if 'view' then the value will be filtered
39
- * @param array $compat_props Compatibility properties.
40
- * @return mixed
41
- */
42
- public static function get_prop( $object, $prop, $context = 'edit', $compat_props = array() ) {
43
-
44
- $value = '';
45
-
46
- if ( WC_Core::is_wc_version_gte_3_0() ) {
47
-
48
- if ( is_callable( array( $object, "get_{$prop}" ) ) ) {
49
- $value = $object->{"get_{$prop}"}( $context );
50
- }
51
-
52
- } else {
53
-
54
- // backport the property name
55
- if ( isset( $compat_props[ $prop ] ) ) {
56
- $prop = $compat_props[ $prop ];
57
- }
58
-
59
- // if this is the 'view' context and there is an accessor method, use it
60
- if ( is_callable( array( $object, "get_{$prop}" ) ) && 'view' === $context ) {
61
- $value = $object->{"get_{$prop}"}();
62
- } else {
63
- $value = $object->$prop;
64
- }
65
- }
66
-
67
- return $value;
68
- }
69
-
70
-
71
- /**
72
- * Sets an object's properties.
73
- *
74
- * Note that this does not save any data to the database.
75
- *
76
- * @since 4.6.0-dev
77
- * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
78
- * @param array $props the new properties as $key => $value
79
- * @param array $compat_props Compatibility properties.
80
- * @return \WC_Data
81
- */
82
- public static function set_props( $object, $props, $compat_props = array() ) {
83
-
84
- if ( WC_Core::is_wc_version_gte_3_0() ) {
85
-
86
- $object->set_props( $props );
87
-
88
- } else {
89
-
90
- foreach ( $props as $prop => $value ) {
91
-
92
- if ( isset( $compat_props[ $prop ] ) ) {
93
- $prop = $compat_props[ $prop ];
94
- }
95
-
96
- $object->$prop = $value;
97
- }
98
- }
99
-
100
- return $object;
101
- }
102
-
103
-
104
- /**
105
- * Gets an object's stored meta value.
106
- *
107
- * @since 4.6.0-dev
108
- * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
109
- * @param string $key the meta key
110
- * @param bool $single whether to get the meta as a single item. Defaults to `true`
111
- * @param string $context if 'view' then the value will be filtered
112
- * @return mixed
113
- */
114
- public static function get_meta( $object, $key = '', $single = true, $context = 'edit' ) {
115
-
116
- if ( WC_Core::is_wc_version_gte_3_0() ) {
117
- $value = $object->get_meta( $key, $single, $context );
118
- } else {
119
- $object_id = is_callable( array( $object, 'get_id' ) ) ? $object->get_id() : $object->id;
120
- $value = get_post_meta( $object_id, $key, $single );
121
- }
122
-
123
- return $value;
124
- }
125
-
126
-
127
- /**
128
- * Stores an object meta value.
129
- *
130
- * @since 4.6.0-dev
131
- * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
132
- * @param string $key the meta key
133
- * @param string $value the meta value
134
- * @param string $meta_id Optional. The specific meta ID to update
135
- * @param bool $unique Optional. Whether the meta should be unique.
136
- */
137
- public static function add_meta_data( $object, $key, $value, $unique = false ) {
138
-
139
- if ( WC_Core::is_wc_version_gte_3_0() ) {
140
-
141
- $object->add_meta_data( $key, $value, $unique );
142
-
143
- $object->save_meta_data();
144
-
145
- } else {
146
-
147
- $object_id = is_callable( array( $object, 'get_id' ) ) ? $object->get_id() : $object->id;
148
- add_post_meta( $object_id, $key, $value, $unique );
149
- }
150
- }
151
-
152
-
153
- /**
154
- * Updates an object's stored meta value.
155
- *
156
- * @since 4.6.0-dev
157
- * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
158
- * @param string $key the meta key
159
- * @param string|array $value the meta value
160
- * @param int|string $meta_id Optional. The specific meta ID to update
161
- */
162
- public static function update_meta_data( $object, $key, $value, $meta_id = '' ) {
163
-
164
- if ( WC_Core::is_wc_version_gte_3_0() ) {
165
-
166
- $object->update_meta_data( $key, $value, $meta_id );
167
-
168
- $object->save_meta_data();
169
-
170
- } else {
171
-
172
- $object_id = is_callable( array( $object, 'get_id' ) ) ? $object->get_id() : $object->id;
173
- update_post_meta( $object_id, $key, $value );
174
- }
175
- }
176
-
177
-
178
- /**
179
- * Deletes an object's stored meta value.
180
- *
181
- * @since 4.6.0-dev
182
- * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
183
- * @param string $key the meta key
184
- */
185
- public static function delete_meta_data( $object, $key ) {
186
-
187
- if ( WC_Core::is_wc_version_gte_3_0() ) {
188
-
189
- $object->delete_meta_data( $key );
190
-
191
- $object->save_meta_data();
192
-
193
- } else {
194
-
195
- $object_id = is_callable( array( $object, 'get_id' ) ) ? $object->get_id() : $object->id;
196
- delete_post_meta( $object_id, $key );
197
- }
198
- }
199
-
200
-
201
- }
202
-
203
-
204
- endif; // Class exists check
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/compatibility/class-wc-core-compatibility.php DELETED
@@ -1,231 +0,0 @@
1
- <?php
2
- namespace WPO\WC\PDF_Invoices\Compatibility;
3
-
4
- /**
5
- * Derived from SkyVerge WooCommerce Plugin Framework https://github.com/skyverge/wc-plugin-framework/
6
- */
7
-
8
- defined( 'ABSPATH' ) or exit;
9
-
10
- if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\Compatibility\\WC_Core' ) ) :
11
-
12
- /**
13
- * WooCommerce Compatibility Utility Class
14
- *
15
- * The unfortunate purpose of this class is to provide a single point of
16
- * compatibility functions for dealing with supporting multiple versions
17
- * of WooCommerce and various extensions.
18
- *
19
- * The expected procedure is to remove methods from this class, using the
20
- * latest ones directly in code, as support for older versions of WooCommerce
21
- * are dropped.
22
- *
23
- * Current Compatibility
24
- * + Core 2.5.5 - 3.0.x
25
- *
26
- *
27
- * @since 2.0.0
28
- */
29
- class WC_Core {
30
-
31
- /**
32
- * Backports wc_get_order() to pre-2.2.0
33
- *
34
- * @since 4.3.0
35
- * @return \WC_Order $order order object
36
- */
37
- public static function get_order( $order_id ) {
38
-
39
- if ( function_exists( 'wc_get_order' ) ) {
40
-
41
- return wc_get_order( $order_id );
42
-
43
- } else {
44
-
45
- return new \WC_Order( $order_id );
46
- }
47
- }
48
-
49
-
50
- /**
51
- * Backports wc_checkout_is_https() to 2.4.x
52
- *
53
- * @since 4.3.0
54
- * @return bool
55
- */
56
- public static function wc_checkout_is_https() {
57
-
58
- if ( self::is_wc_version_gte_2_5() ) {
59
-
60
- return wc_checkout_is_https();
61
-
62
- } else {
63
-
64
- return wc_site_is_https() || 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) || class_exists( 'WordPressHTTPS' ) || strstr( wc_get_page_permalink( 'checkout' ), 'https:' );
65
- }
66
- }
67
-
68
-
69
- /**
70
- * Backports wc_help_tip() to WC 2.4.x
71
- *
72
- * @link https://github.com/woothemes/woocommerce/pull/9417
73
- *
74
- * @since 4.2.0
75
- * @param string $tip help tip content, HTML allowed if $has_html is true
76
- * @param bool $has_html false by default, true to indicate tip content has HTML
77
- * @return string help tip HTML, a <span> in WC 2.5, <img> in WC 2.4
78
- */
79
- public static function wc_help_tip( $tip, $has_html = false ) {
80
-
81
- if ( self::is_wc_version_gte_2_5() ) {
82
-
83
- return wc_help_tip( $tip, $has_html );
84
-
85
- } else {
86
-
87
- $tip = $has_html ? wc_sanitize_tooltip( $tip ) : esc_attr( $tip );
88
-
89
- return sprintf( '<img class="help_tip" data-tip="%1$s" src="%2$s" height="16" width="16" />', $tip, esc_url( WC()->plugin_url() ) . '/assets/images/help.png' );
90
- }
91
- }
92
-
93
-
94
- /**
95
- * Helper method to get the version of the currently installed WooCommerce
96
- *
97
- * @since 3.0.0
98
- * @return string woocommerce version number or null
99
- */
100
- protected static function get_wc_version() {
101
-
102
- return defined( 'WC_VERSION' ) && WC_VERSION ? WC_VERSION : null;
103
- }
104
-
105
-
106
- /**
107
- * Determines if the installed version of WooCommerce is 2.2.0 or greater.
108
- *
109
- * @since 4.2.0
110
- * @return bool
111
- */
112
- public static function is_wc_version_gte_2_2() {
113
- return self::get_wc_version() && version_compare( self::get_wc_version(), '2.2', '>=' );
114
- }
115
-
116
-
117
- /**
118
- * Determines if the installed version of WooCommerce is less than 2.2.0
119
- *
120
- * @since 4.2.0
121
- * @return bool
122
- */
123
- public static function is_wc_version_lt_2_2() {
124
- return self::get_wc_version() && version_compare( self::get_wc_version(), '2.2', '<' );
125
- }
126
-
127
-
128
- /**
129
- * Determines if the installed version of WooCommerce is 2.5.0 or greater.
130
- *
131
- * @since 4.2.0
132
- * @return bool
133
- */
134
- public static function is_wc_version_gte_2_5() {
135
- return self::get_wc_version() && version_compare( self::get_wc_version(), '2.5', '>=' );
136
- }
137
-
138
-
139
- /**
140
- * Determines if the installed version of WooCommerce is less than 2.5.0
141
- *
142
- * @since 4.2.0
143
- * @return bool
144
- */
145
- public static function is_wc_version_lt_2_5() {
146
- return self::get_wc_version() && version_compare( self::get_wc_version(), '2.5', '<' );
147
- }
148
-
149
-
150
- /**
151
- * Determines if the installed version of WooCommerce is 2.6.0 or greater.
152
- *
153
- * @since 4.4.0
154
- * @return bool
155
- */
156
- public static function is_wc_version_gte_2_6() {
157
- return self::get_wc_version() && version_compare( self::get_wc_version(), '2.6', '>=' );
158
- }
159
-
160
-
161
- /**
162
- * Determines if the installed version of WooCommerce is less than 2.6.0
163
- *
164
- * @since 4.4.0
165
- * @return bool
166
- */
167
- public static function is_wc_version_lt_2_6() {
168
- return self::get_wc_version() && version_compare( self::get_wc_version(), '2.6', '<' );
169
- }
170
-
171
-
172
- /**
173
- * Determines if the installed version of WooCommerce is 3.0.0 or greater.
174
- *
175
- * @since 4.6.0-dev
176
- * @return bool
177
- */
178
- public static function is_wc_version_gte_3_0() {
179
- return self::get_wc_version() && version_compare( self::get_wc_version(), '3.0', '>=' );
180
- }
181
-
182
-
183
- /**
184
- * Determines if the installed version of WooCommerce is less than 3.0.0
185
- *
186
- * @since 4.6.0-dev
187
- * @return bool
188
- */
189
- public static function is_wc_version_lt_3_0() {
190
- return self::get_wc_version() && version_compare( self::get_wc_version(), '3.0', '<' );
191
- }
192
-
193
- /**
194
- * Returns true if the installed version of WooCommerce is greater than $version
195
- *
196
- * @since 2.0.0
197
- * @param string $version the version to compare
198
- * @return boolean true if the installed version of WooCommerce is > $version
199
- */
200
- public static function is_wc_version_gt( $version ) {
201
- return self::get_wc_version() && version_compare( self::get_wc_version(), $version, '>' );
202
- }
203
-
204
-
205
- /** WordPress core ******************************************************/
206
-
207
-
208
- /**
209
- * Normalizes a WooCommerce page screen ID.
210
- *
211
- * Needed because WordPress uses a menu title (which is translatable), not slug, to generate screen ID.
212
- * See details in: https://core.trac.wordpress.org/ticket/21454
213
- * TODO: Add WP version check when https://core.trac.wordpress.org/ticket/18857 is addressed {BR 2016-12-12}
214
- *
215
- * @since 4.6.0-dev
216
- * @param string $slug The slug for the screen ID to normalize (minus `woocommerce_page_`).
217
- * @return string Normalized screen ID.
218
- */
219
- public static function normalize_wc_screen_id( $slug = 'wc-settings' ) {
220
-
221
- // The textdomain usage is intentional here, we need to match the menu title.
222
- $prefix = sanitize_title( __( 'WooCommerce', 'woocommerce' ) );
223
-
224
- return $prefix . '_page_' . $slug;
225
- }
226
-
227
-
228
- }
229
-
230
-
231
- endif; // Class exists check
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/compatibility/class-wc-date-compatibility.php DELETED
@@ -1,114 +0,0 @@
1
- <?php
2
- namespace WPO\WC\PDF_Invoices\Compatibility;
3
-
4
- /**
5
- * Copy of WC3.0 WC_DateTime class
6
- */
7
-
8
- defined( 'ABSPATH' ) or exit;
9
-
10
- if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\Compatibility\\WC_DateTime' ) ) :
11
-
12
-
13
- /**
14
- * WC Wrapper for PHP DateTime which adds support for gmt/utc offset when a
15
- * timezone is absent
16
- *
17
- * @since 3.0.0
18
- * @package WooCommerce\Classes
19
- */
20
- class WC_DateTime extends \DateTime {
21
-
22
- /**
23
- * UTC Offset, if needed. Only used when a timezone is not set. When
24
- * timezones are used this will equal 0.
25
- *
26
- * @var integer
27
- */
28
- protected $utc_offset = 0;
29
-
30
- /**
31
- * Output an ISO 8601 date string in local (WordPress) timezone.
32
- *
33
- * @since 3.0.0
34
- * @return string
35
- */
36
- public function __toString() {
37
- return $this->format( DATE_ATOM );
38
- }
39
-
40
- /**
41
- * Set UTC offset - this is a fixed offset instead of a timezone.
42
- *
43
- * @param int $offset Offset.
44
- */
45
- public function set_utc_offset( $offset ) {
46
- $this->utc_offset = intval( $offset );
47
- }
48
-
49
- /**
50
- * Get UTC offset if set, or default to the DateTime object's offset.
51
- */
52
- #[\ReturnTypeWillChange]
53
- public function getOffset() {
54
- return $this->utc_offset ? $this->utc_offset : parent::getOffset();
55
- }
56
-
57
- /**
58
- * Set timezone.
59
- *
60
- * @param DateTimeZone $timezone DateTimeZone instance.
61
- * @return DateTime
62
- */
63
- #[\ReturnTypeWillChange]
64
- public function setTimezone( $timezone ) {
65
- $this->utc_offset = 0;
66
- return parent::setTimezone( $timezone );
67
- }
68
-
69
- /**
70
- * Missing in PHP 5.2 so just here so it can be supported consistently.
71
- *
72
- * @since 3.0.0
73
- * @return int
74
- */
75
- #[\ReturnTypeWillChange]
76
- public function getTimestamp() {
77
- return method_exists( 'DateTime', 'getTimestamp' ) ? parent::getTimestamp() : $this->format( 'U' );
78
- }
79
-
80
- /**
81
- * Get the timestamp with the WordPress timezone offset added or subtracted.
82
- *
83
- * @since 3.0.0
84
- * @return int
85
- */
86
- public function getOffsetTimestamp() {
87
- return $this->getTimestamp() + $this->getOffset();
88
- }
89
-
90
- /**
91
- * Format a date based on the offset timestamp.
92
- *
93
- * @since 3.0.0
94
- * @param string $format Date format.
95
- * @return string
96
- */
97
- public function date( $format ) {
98
- return gmdate( $format, $this->getOffsetTimestamp() );
99
- }
100
-
101
- /**
102
- * Return a localised date based on offset timestamp. Wrapper for date_i18n function.
103
- *
104
- * @since 3.0.0
105
- * @param string $format Date format.
106
- * @return string
107
- */
108
- public function date_i18n( $format = 'Y-m-d' ) {
109
- return date_i18n( $format, $this->getOffsetTimestamp() );
110
- }
111
- }
112
-
113
- endif; // Class exists check
114
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/compatibility/class-wc-order-compatibility.php DELETED
@@ -1,412 +0,0 @@
1
- <?php
2
- namespace WPO\WC\PDF_Invoices\Compatibility;
3
-
4
- /**
5
- * Derived from SkyVerge WooCommerce Plugin Framework https://github.com/skyverge/wc-plugin-framework/
6
- */
7
-
8
- defined( 'ABSPATH' ) or exit;
9
-
10
- if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\Compatibility\\Order' ) ) :
11
-
12
- /**
13
- * WooCommerce order compatibility class.
14
- *
15
- * @since 4.6.0-dev
16
- */
17
- class Order extends Data {
18
-
19
-
20
- /** @var array mapped compatibility properties, as `$new_prop => $old_prop` */
21
- protected static $compat_props = array(
22
- 'date_completed' => 'completed_date',
23
- 'date_paid' => 'paid_date',
24
- 'date_modified' => 'modified_date',
25
- 'date_created' => 'order_date',
26
- 'customer_id' => 'customer_user',
27
- 'discount' => 'cart_discount',
28
- 'discount_tax' => 'cart_discount_tax',
29
- 'shipping_total' => 'total_shipping',
30
- 'type' => 'order_type',
31
- 'currency' => 'order_currency',
32
- 'version' => 'order_version',
33
- );
34
-
35
-
36
- /**
37
- * Backports WC_Order::get_id() method to pre-2.6.0
38
- *
39
- * @since 4.2.0
40
- * @param \WC_Order $order order object
41
- * @return string|int order ID
42
- */
43
- public static function get_id( $order ) {
44
-
45
- if ( method_exists( $order, 'get_id' ) ) {
46
-
47
- return $order->get_id();
48
-
49
- } else {
50
-
51
- return isset($order->id) ? $order->id : false;
52
- }
53
- }
54
-
55
-
56
- /**
57
- * Gets an order property.
58
- *
59
- * @since 4.6.0-dev
60
- * @param \WC_Order $object the order object
61
- * @param string $prop the property name
62
- * @param string $context if 'view' then the value will be filtered
63
- * @return mixed
64
- */
65
- public static function get_prop( $object, $prop, $context = 'edit', $compat_props = array() ) {
66
-
67
- // backport a few specific properties to pre-3.0
68
- if ( WC_Core::is_wc_version_lt_3_0() ) {
69
-
70
- // converge the shipping total prop for the raw context
71
- if ( 'shipping_total' === $prop && 'view' !== $context ) {
72
-
73
- $prop = 'order_shipping';
74
-
75
- // get the post_parent and bail early
76
- } elseif ( 'parent_id' === $prop ) {
77
-
78
- return $object->post->post_parent;
79
- }
80
- }
81
-
82
- $value = parent::get_prop( $object, $prop, $context, self::$compat_props );
83
-
84
- // 3.0+ date getters return a DateTime object, where previously MySQL date strings were returned
85
- if ( WC_Core::is_wc_version_lt_3_0() && in_array( $prop, array( 'date_completed', 'date_paid', 'date_modified', 'date_created' ), true ) ) {
86
- // parent fallback for empty date values in refunds
87
- if ( empty( $value ) && $object->order_type == 'refund' ) {
88
- $parent_order_id = wp_get_post_parent_id( $object->id );
89
- $parent_order = wc_get_order( $parent_order_id );
90
- $value = parent::get_prop( $parent_order, $prop, $context, self::$compat_props );
91
- }
92
-
93
- // abort mission if still empty
94
- if ( empty( $value ) ) {
95
- return $value;
96
- }
97
-
98
- if ( is_numeric( $value ) ) { // incidental for WC2.7 orders
99
- $value = new WC_DateTime( "@{$value}", new \DateTimeZone( 'UTC' ) );
100
- $value->setTimezone( new \DateTimeZone( wc_timezone_string() ) );
101
- } else {
102
- // Strings are defined in local WP timezone. Convert to UTC.
103
- if ( 1 === preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|((-|\+)\d{2}:\d{2}))$/', $value, $date_bits ) ) {
104
- $offset = ! empty( $date_bits[7] ) ? iso8601_timezone_to_offset( $date_bits[7] ) : wc_timezone_offset();
105
- $timestamp = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] ) - $offset;
106
- } else {
107
- $timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $value ) ) ) );
108
- }
109
- $value = new WC_DateTime( "@{$timestamp}", new \DateTimeZone( 'UTC' ) );
110
- }
111
-
112
- // Set local timezone or offset.
113
- if ( get_option( 'timezone_string' ) ) {
114
- $value->setTimezone( new \DateTimeZone( wc_timezone_string() ) );
115
- } else {
116
- $value->set_utc_offset( wc_timezone_offset() );
117
- }
118
- }
119
-
120
- return $value;
121
- }
122
-
123
-
124
- /**
125
- * Sets an order's properties.
126
- *
127
- * Note that this does not save any data to the database.
128
- *
129
- * @since 4.6.0-dev
130
- * @param \WC_Order $object the order object
131
- * @param array $props the new properties as $key => $value
132
- * @return \WC_Order
133
- */
134
- public static function set_props( $object, $props, $compat_props = array() ) {
135
-
136
- return parent::set_props( $object, $props, self::$compat_props );
137
- }
138
-
139
- /**
140
- * Backports WC_Order::set_address_prop() to pre-3.0
141
- * Saves by default.
142
- *
143
- * @since 4.6.0-dev
144
- * @param \WC_Order $order the order object
145
- * @param string $prop Name of prop to set.
146
- * @param string $address Name of address to set. billing or shipping.
147
- * @param mixed $value Value of the prop.
148
- * @param bool $save whether to save the order/property
149
- * @return \WC_Order
150
- */
151
- public static function set_address_prop( \WC_Order $order, $prop, $address = 'billing', $value = null, $save = true ) {
152
- if ( WC_Core::is_wc_version_gte_3_0() ) {
153
- if ( is_callable( array( $order, "set_{$address}_{$prop}" ) ) ) {
154
- $order->{"set_{$address}_{$prop}"}( $value );
155
- if ($save === true) {
156
- $order->save();
157
- }
158
- }
159
- } else {
160
- // wc 2.6 or older
161
- if ($save === true) {
162
- // store directly in postmeta
163
- update_post_meta( $order->id, "_{$address}_{$prop}", $value );
164
- } else {
165
- // only change property in the order
166
- $order->$prop = $value;
167
- }
168
- }
169
-
170
- return $order;
171
- }
172
-
173
- /**
174
- * Implements WC_Order::get_item_meta for 3.0+
175
- * @param \WC_Order $order the order object
176
- * @param int $item_id the item id
177
- * @param int $key the meta key
178
- * @param boolean $single single or multiple
179
- * @return mixed item meta
180
- */
181
- public static function get_item_meta( $object, $item_id, $key = '', $single = false ) {
182
- if (function_exists('wc_get_order_item_meta')) {
183
- $item_meta = wc_get_order_item_meta( $item_id, $key, $single );
184
- } else {
185
- $item_meta = $object->get_item_meta( $item_id, $key, $single );
186
- }
187
- return $item_meta;
188
- }
189
-
190
- /**
191
- * Backports WC_Order::get_status() to pre-3.0.0
192
- *
193
- * @since 4.6.0-dev
194
- * @param \WC_Order $order the order object
195
- * @return string order status
196
- */
197
- public static function get_status( \WC_Order $order ) {
198
-
199
- if ( method_exists( $order, 'get_status' ) ) {
200
- return $order->get_status();
201
- } else {
202
- return $order->status;
203
- }
204
- }
205
-
206
- /**
207
- * Order item CRUD compatibility method to add a coupon to an order.
208
- *
209
- * @since 4.6.0-dev
210
- * @param \WC_Order $order the order object
211
- * @param array $code the coupon code
212
- * @param int $discount the discount amount.
213
- * @param int $discount_tax the discount tax amount.
214
- * @return int the order item ID
215
- */
216
- public static function add_coupon( \WC_Order $order, $code = array(), $discount = 0, $discount_tax = 0 ) {
217
-
218
- if ( WC_Core::is_wc_version_gte_3_0() ) {
219
-
220
- $item = new \WC_Order_Item_Coupon();
221
-
222
- $item->set_props( array(
223
- 'code' => $code,
224
- 'discount' => $discount,
225
- 'discount_tax' => $discount_tax,
226
- 'order_id' => $order->get_id(),
227
- ) );
228
-
229
- $item->save();
230
-
231
- $order->add_item( $item );
232
-
233
- return $item->get_id();
234
-
235
- } else {
236
-
237
- return $order->add_coupon( $code, $discount, $discount_tax );
238
- }
239
- }
240
-
241
-
242
- /**
243
- * Order item CRUD compatibility method to add a fee to an order.
244
- *
245
- * @since 4.6.0-dev
246
- * @param \WC_Order $order the order object
247
- * @param object $fee the fee to add
248
- * @return int|\WC_Order_Item the order item ID
249
- */
250
- public static function add_fee( \WC_Order $order, $fee ) {
251
-
252
- if ( WC_Core::is_wc_version_gte_3_0() ) {
253
-
254
- $item = new \WC_Order_Item_Fee();
255
-
256
- $item->set_props( array(
257
- 'name' => $fee->name,
258
- 'tax_class' => $fee->taxable ? $fee->tax_class : 0,
259
- 'total' => $fee->amount,
260
- 'total_tax' => $fee->tax,
261
- 'taxes' => array(
262
- 'total' => $fee->tax_data,
263
- ),
264
- 'order_id' => $order->get_id(),
265
- ) );
266
-
267
- $item->save();
268
-
269
- $order->add_item( $item );
270
-
271
- return $item->get_id();
272
-
273
- } else {
274
-
275
- return $order->add_fee( $fee );
276
- }
277
- }
278
-
279
-
280
- /**
281
- * Order item CRUD compatibility method to update an order coupon.
282
- *
283
- * @since 4.6.0-dev
284
- * @param \WC_Order $order the order object
285
- * @param int|\WC_Order_Item $item the order item ID
286
- * @param array $args {
287
- * The coupon item args.
288
- *
289
- * @type string $code the coupon code
290
- * @type float $discount the coupon discount amount
291
- * @type float $discount_tax the coupon discount tax amount
292
- * }
293
- * @return int|bool the order item ID or false on failure
294
- */
295
- public static function update_coupon( \WC_Order $order, $item, $args ) {
296
-
297
- if ( WC_Core::is_wc_version_gte_3_0() ) {
298
-
299
- if ( is_numeric( $item ) ) {
300
- $item = $order->get_item( $item );
301
- }
302
-
303
- if ( ! is_object( $item ) || ! $item->is_type( 'coupon' ) ) {
304
- return false;
305
- }
306
-
307
- if ( ! $order->get_id() ) {
308
- $order->save();
309
- }
310
-
311
- $item->set_order_id( $order->get_id() );
312
- $item->set_props( $args );
313
- $item->save();
314
-
315
- return $item->get_id();
316
-
317
- } else {
318
-
319
- // convert 3.0+ args for backwards compatibility
320
- if ( isset( $args['discount'] ) ) {
321
- $args['discount_amount'] = $args['discount'];
322
- }
323
- if ( isset( $args['discount_tax'] ) ) {
324
- $args['discount_amount_tax'] = $args['discount_tax'];
325
- }
326
-
327
- return $order->update_coupon( $item, $args );
328
- }
329
- }
330
-
331
-
332
- /**
333
- * Order item CRUD compatibility method to update an order fee.
334
- *
335
- * @since 4.6.0-dev
336
- * @param \WC_Order $order the order object
337
- * @param int $item the order item ID
338
- * @param array $args {
339
- * The fee item args.
340
- *
341
- * @type string $name the fee name
342
- * @type string $tax_class the fee's tax class
343
- * @type float $line_total the fee total amount
344
- * @type float $line_tax the fee tax amount
345
- * }
346
- * @return int|bool the order item ID or false on failure
347
- */
348
- public static function update_fee( \WC_Order $order, $item, $args ) {
349
-
350
- if ( WC_Core::is_wc_version_gte_3_0() ) {
351
-
352
- if ( is_numeric( $item ) ) {
353
- $item = $order->get_item( $item );
354
- }
355
-
356
- if ( ! is_object( $item ) || ! $item->is_type( 'fee' ) ) {
357
- return false;
358
- }
359
-
360
- if ( ! $order->get_id() ) {
361
- $order->save();
362
- }
363
-
364
- $item->set_order_id( $order->get_id() );
365
- $item->set_props( $args );
366
- $item->save();
367
-
368
- return $item->get_id();
369
-
370
- } else {
371
-
372
- return $order->update_fee( $item, $args );
373
- }
374
- }
375
-
376
-
377
- /**
378
- * Backports wc_reduce_stock_levels() to pre-3.0.0
379
- *
380
- * @since 4.6.0-dev
381
- * @param \WC_Order $order the order object
382
- */
383
- public static function reduce_stock_levels( \WC_Order $order ) {
384
-
385
- if ( WC_Core::is_wc_version_gte_3_0() ) {
386
- wc_reduce_stock_levels( $order->get_id() );
387
- } else {
388
- $order->reduce_order_stock();
389
- }
390
- }
391
-
392
-
393
- /**
394
- * Backports wc_update_total_sales_counts() to pre-3.0.0
395
- *
396
- * @since 4.6.0-dev
397
- * @param \WC_Order $order the order object
398
- */
399
- public static function update_total_sales_counts( \WC_Order $order ) {
400
-
401
- if ( WC_Core::is_wc_version_gte_3_0() ) {
402
- wc_update_total_sales_counts( $order->get_id() );
403
- } else {
404
- $order->record_product_sales();
405
- }
406
- }
407
-
408
-
409
- }
410
-
411
-
412
- endif; // Class exists check
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/compatibility/class-wc-product-compatibility.php DELETED
@@ -1,288 +0,0 @@
1
- <?php
2
- namespace WPO\WC\PDF_Invoices\Compatibility;
3
-
4
- /**
5
- * Derived from SkyVerge WooCommerce Plugin Framework https://github.com/skyverge/wc-plugin-framework/
6
- */
7
-
8
- defined( 'ABSPATH' ) or exit;
9
-
10
- if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\Compatibility\\Product' ) ) :
11
-
12
- /**
13
- * WooCommerce product compatibility class.
14
- *
15
- * @since 4.6.0-dev
16
- */
17
- class Product extends Data {
18
-
19
-
20
- /** @var array mapped compatibility properties, as `$new_prop => $old_prop` */
21
- protected static $compat_props = array(
22
- 'catalog_visibility' => 'visibility',
23
- 'date_on_sale_from' => 'sale_price_dates_from',
24
- 'date_on_sale_to' => 'sale_price_dates_to',
25
- 'gallery_image_ids' => 'product_image_gallery',
26
- 'cross_sell_ids' => 'crosssell_ids',
27
- );
28
-
29
-
30
- /**
31
- * Backports WC_Product::get_id() method to 2.4.x
32
- *
33
- * @link https://github.com/woothemes/woocommerce/pull/9765
34
- *
35
- * @since 4.2.0
36
- * @param \WC_Product $product product object
37
- * @return string|int product ID
38
- */
39
- public static function get_id( \WC_Product $product ) {
40
-
41
- if ( method_exists( $product, 'get_id' ) ) {
42
-
43
- return $product->get_id();
44
-
45
- } else {
46
-
47
- return $product->is_type( 'variation' ) ? $product->variation_id : $product->id;
48
- }
49
- }
50
-
51
-
52
- /**
53
- * Gets a product property.
54
- *
55
- * @since 4.6.0-dev
56
- * @param \WC_Product $object the product object
57
- * @param string $prop the property name
58
- * @param string $context if 'view' then the value will be filtered
59
- * @return mixed
60
- */
61
- public static function get_prop( $object, $prop, $context = 'edit', $compat_props = array() ) {
62
-
63
- // backport 'WC_Product::get_parent_id()' to pre-3.0
64
- if ( WC_Core::is_wc_version_lt_3_0() && 'parent_id' === $prop ) {
65
- $prop = 'id';
66
- $context = $object->is_type( 'variation' ) ? 'raw' : $context;
67
- }
68
-
69
- return parent::get_prop( $object, $prop, $context, self::$compat_props );
70
- }
71
-
72
-
73
- /**
74
- * Sets an products's properties.
75
- *
76
- * Note that this does not save any data to the database.
77
- *
78
- * @since 4.6.0-dev
79
- * @param \WC_Product $object the product object
80
- * @param array $props the new properties as $key => $value
81
- * @return \WC_Product
82
- */
83
- public static function set_props( $object, $props, $compat_props = array() ) {
84
-
85
- return parent::set_props( $object, $props, self::$compat_props );
86
- }
87
-
88
-
89
- /**
90
- * Makes WC_Product::get_parent() available for WC 3.0+
91
- *
92
- * @since 4.6.0-dev
93
- * @param \WC_Product $product the product object
94
- * @return \WC_Product
95
- */
96
- public static function get_parent( \WC_Product $product ) {
97
-
98
- if ( WC_Core::is_wc_version_gte_3_0() ) {
99
- $parent = wc_get_product( $product->get_parent_id() );
100
- } else {
101
- $parent = $product->get_parent();
102
- }
103
-
104
- return $parent;
105
- }
106
-
107
-
108
-
109
- /**
110
- * Makes WC_Product::get_dimensions() available for WC 3.0+
111
- *
112
- * @since 4.6.0-dev
113
- * @param \WC_Product $product the product object
114
- * @param string $rating Optional. The product rating
115
- * @return string
116
- */
117
- public static function get_dimensions( \WC_Product $product ) {
118
-
119
- if ( WC_Core::is_wc_version_gte_3_0() ) {
120
- $dimensions = array(
121
- 'length' => $product->get_length(),
122
- 'width' => $product->get_width(),
123
- 'height' => $product->get_height(),
124
- );
125
- return apply_filters( 'woocommerce_product_dimensions', wc_format_dimensions( $dimensions ), $product );
126
- } else {
127
- return $product->get_dimensions();
128
- }
129
- }
130
-
131
-
132
- /**
133
- * Backports wc_update_product_stock() to pre-3.0.0
134
- *
135
- * @since 4.6.0-dev
136
- * @param \WC_Product $product the product object
137
- * @param int $amount Optional. The new stock quantity
138
- * @param string $mode Optional. Can be set, add, or subtract
139
- * @return int
140
- */
141
- public static function wc_update_product_stock( \WC_Product $product, $amount = null, $mode = 'set' ) {
142
-
143
- if ( WC_Core::is_wc_version_gte_3_0() ) {
144
- return wc_update_product_stock( $product, $amount, $mode );
145
- } else {
146
- return $product->set_stock( $amount, $mode );
147
- }
148
- }
149
-
150
-
151
- /**
152
- * Backports wc_get_price_html_from_text() to pre-3.0.0
153
- *
154
- * @since 4.6.0-dev
155
- * @param \WC_Product $product the product object
156
- * @return string
157
- */
158
- public static function wc_get_price_html_from_text( \WC_Product $product ) {
159
-
160
- if ( WC_Core::is_wc_version_gte_3_0() ) {
161
- return wc_get_price_html_from_text();
162
- } else {
163
- return $product->get_price_html_from_text();
164
- }
165
- }
166
-
167
-
168
- /**
169
- * Backports wc_get_price_including_tax() to pre-3.0.0
170
- *
171
- * @since 4.6.0-dev
172
- * @param \WC_Product $product the product object
173
- * @param int $qty Optional. The quantity
174
- * @param string $price Optional. The product price
175
- * @return string
176
- */
177
- public static function wc_get_price_including_tax( \WC_Product $product, $qty = 1, $price = '' ) {
178
-
179
- if ( WC_Core::is_wc_version_gte_3_0() ) {
180
-
181
- return wc_get_price_including_tax( $product, array(
182
- 'qty' => $qty,
183
- 'price' => $price,
184
- ) );
185
-
186
- } else {
187
-
188
- return $product->get_price_including_tax( $qty, $price );
189
- }
190
- }
191
-
192
-
193
- /**
194
- * Backports wc_get_price_excluding_tax() to pre-3.0.0
195
- *
196
- * @since 4.6.0-dev
197
- * @param \WC_Product $product the product object
198
- * @param int $qty Optional. The quantity
199
- * @param string $price Optional. The product price
200
- * @return string
201
- */
202
- public static function wc_get_price_excluding_tax( \WC_Product $product, $qty = 1, $price = '' ) {
203
-
204
- if ( WC_Core::is_wc_version_gte_3_0() ) {
205
-
206
- return wc_get_price_excluding_tax( $product, array(
207
- 'qty' => $qty,
208
- 'price' => $price,
209
- ) );
210
-
211
- } else {
212
-
213
- return $product->get_price_excluding_tax( $qty, $price );
214
- }
215
- }
216
-
217
-
218
- /**
219
- * Backports wc_get_price_to_display() to pre-3.0.0
220
- *
221
- * @since 4.6.0-dev
222
- * @param \WC_Product $product the product object
223
- * @param string $price Optional. The product price
224
- * @param int $qty Optional. The quantity
225
- * @return string
226
- */
227
- public static function wc_get_price_to_display( \WC_Product $product, $price = '', $qty = 1 ) {
228
-
229
- if ( WC_Core::is_wc_version_gte_3_0() ) {
230
-
231
- return wc_get_price_to_display( $product, array(
232
- 'qty' => $qty,
233
- 'price' => $price,
234
- ) );
235
-
236
- } else {
237
-
238
- return $product->get_display_price( $price, $qty );
239
- }
240
- }
241
-
242
-
243
- /**
244
- * Backports wc_get_product_category_list() to pre-3.0.0
245
- *
246
- * @since 4.6.0-dev
247
- * @param \WC_Product $product the product object
248
- * @param string $sep Optional. The list separator
249
- * @param string $before Optional. To display before the list
250
- * @param string $after Optional. To display after the list
251
- * @return string
252
- */
253
- public static function wc_get_product_category_list( \WC_Product $product, $sep = ', ', $before = '', $after = '' ) {
254
-
255
- if ( WC_Core::is_wc_version_gte_3_0() ) {
256
-
257
- $id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();
258
-
259
- return wc_get_product_category_list( $id, $sep, $before, $after );
260
-
261
- } else {
262
-
263
- return $product->get_categories( $sep, $before, $after );
264
- }
265
- }
266
-
267
-
268
- /**
269
- * Backports wc_get_rating_html() to pre-3.0.0
270
- *
271
- * @since 4.6.0-dev
272
- * @param \WC_Product $product the product object
273
- * @param string $rating Optional. The product rating
274
- * @return string
275
- */
276
- public static function wc_get_rating_html( \WC_Product $product, $rating = null ) {
277
-
278
- if ( WC_Core::is_wc_version_gte_3_0() ) {
279
- return wc_get_rating_html( $rating );
280
- } else {
281
- return $product->get_rating_html( $rating );
282
- }
283
- }
284
-
285
- }
286
-
287
-
288
- endif; // Class exists check
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php CHANGED
@@ -1,11 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Compatibility;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
- use WPO\WC\PDF_Invoices\Compatibility\WC_DateTime;
8
-
9
  defined( 'ABSPATH' ) or exit;
10
 
11
  if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\Compatibility\\Third_Party_Plugins' ) ) :
@@ -71,11 +66,13 @@ class Third_Party_Plugins {
71
  $order = wc_get_order( $order );
72
  }
73
  // delete invoice number, invoice date & invoice exists meta
74
- WCX_Order::delete_meta_data( $order, '_wcpdf_invoice_number' );
75
- WCX_Order::delete_meta_data( $order, '_wcpdf_invoice_number_data' );
76
- WCX_Order::delete_meta_data( $order, '_wcpdf_formatted_invoice_number' );
77
- WCX_Order::delete_meta_data( $order, '_wcpdf_invoice_date' );
78
- WCX_Order::delete_meta_data( $order, '_wcpdf_invoice_exists' );
 
 
79
  }
80
 
81
  /**
@@ -130,16 +127,16 @@ class Third_Party_Plugins {
130
  return $classes;
131
  }
132
 
133
- if ( $bundled_by = WCX_Order::get_item_meta( $order, $item_id, '_bundled_by', true ) ) {
134
  $classes = $classes . ' bundled-item';
135
 
136
  // check bundled item visibility
137
- if ( $hidden = WCX_Order::get_item_meta( $order, $item_id, '_bundled_item_hidden', true ) ) {
138
  $classes = $classes . ' hidden';
139
  }
140
 
141
  return $classes;
142
- } elseif ( $bundled_items = WCX_Order::get_item_meta( $order, $item_id, '_bundled_items', true ) ) {
143
  return $classes . ' product-bundle';
144
  }
145
 
@@ -164,12 +161,12 @@ class Third_Party_Plugins {
164
  }
165
 
166
  // Add row classes
167
- $refunded_item_id = WCX_Order::get_item_meta( $order, $item_id, '_refunded_item_id', true );
168
  $class_item_id = ! empty( $refunded_item_id ) ? $refunded_item_id : $item_id;
169
 
170
- if ( $bundled_by = WCX_Order::get_item_meta( $order, $class_item_id, '_woosb_parent_id', true ) ) {
171
  $classes = $classes . ' bundled-item';
172
- } elseif ( $bundled_items = WCX_Order::get_item_meta( $order, $class_item_id, '_woosb_ids', true ) ) {
173
  $classes = $classes . ' product-bundle';
174
  }
175
 
@@ -193,7 +190,7 @@ class Third_Party_Plugins {
193
  return $classes;
194
  }
195
 
196
- if ( $chained_product_of = WCX_Order::get_item_meta( $order, $item_id, '_chained_product_of', true ) ) {
197
  return $classes . ' chained-product';
198
  }
199
 
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Compatibility;
3
 
 
 
 
 
 
4
  defined( 'ABSPATH' ) or exit;
5
 
6
  if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\Compatibility\\Third_Party_Plugins' ) ) :
66
  $order = wc_get_order( $order );
67
  }
68
  // delete invoice number, invoice date & invoice exists meta
69
+ $order->delete_meta_data( $order, '_wcpdf_invoice_number' );
70
+ $order->delete_meta_data( $order, '_wcpdf_invoice_number_data' );
71
+ $order->delete_meta_data( $order, '_wcpdf_formatted_invoice_number' );
72
+ $order->delete_meta_data( $order, '_wcpdf_invoice_date' );
73
+ $order->delete_meta_data( $order, '_wcpdf_invoice_exists' );
74
+
75
+ $order->save_meta_data();
76
  }
77
 
78
  /**
127
  return $classes;
128
  }
129
 
130
+ if ( $bundled_by = wc_get_order_item_meta( $item_id, '_bundled_by', true ) ) {
131
  $classes = $classes . ' bundled-item';
132
 
133
  // check bundled item visibility
134
+ if ( $hidden = wc_get_order_item_meta( $item_id, '_bundled_item_hidden', true ) ) {
135
  $classes = $classes . ' hidden';
136
  }
137
 
138
  return $classes;
139
+ } elseif ( $bundled_items = wc_get_order_item_meta( $item_id, '_bundled_items', true ) ) {
140
  return $classes . ' product-bundle';
141
  }
142
 
161
  }
162
 
163
  // Add row classes
164
+ $refunded_item_id = wc_get_order_item_meta( $item_id, '_refunded_item_id', true );
165
  $class_item_id = ! empty( $refunded_item_id ) ? $refunded_item_id : $item_id;
166
 
167
+ if ( $bundled_by = wc_get_order_item_meta( $class_item_id, '_woosb_parent_id', true ) ) {
168
  $classes = $classes . ' bundled-item';
169
+ } elseif ( $bundled_items = wc_get_order_item_meta( $class_item_id, '_woosb_ids', true ) ) {
170
  $classes = $classes . ' product-bundle';
171
  }
172
 
190
  return $classes;
191
  }
192
 
193
+ if ( $chained_product_of = wc_get_order_item_meta( $item_id, '_chained_product_of', true ) ) {
194
  return $classes . ' chained-product';
195
  }
196
 
includes/compatibility/wc-datetime-functions-compatibility.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
3
-
4
- defined( 'ABSPATH' ) or exit;
5
-
6
- // load date/time functions for older WC versions
7
- if ( WCX::is_wc_version_lt_3_0() ) {
8
- if ( !function_exists( 'wc_timezone_offset' ) ) {
9
- /**
10
- * Get timezone offset in seconds.
11
- *
12
- * @since 3.0.0
13
- * @return float
14
- */
15
- function wc_timezone_offset() {
16
- if ( $timezone = get_option( 'timezone_string' ) ) {
17
- $timezone_object = new DateTimeZone( $timezone );
18
- return $timezone_object->getOffset( new DateTime( 'now' ) );
19
- } else {
20
- return floatval( get_option( 'gmt_offset', 0 ) ) * HOUR_IN_SECONDS;
21
- }
22
- }
23
- }
24
-
25
- if ( !function_exists( 'wc_string_to_timestamp' ) ) {
26
- /**
27
- * Convert mysql datetime to PHP timestamp, forcing UTC. Wrapper for strtotime.
28
- *
29
- * Based on wcs_strtotime_dark_knight() from WC Subscriptions by Prospress.
30
- *
31
- * @since 3.0.0
32
- * @return int
33
- */
34
- function wc_string_to_timestamp( $time_string, $from_timestamp = null ) {
35
- $original_timezone = date_default_timezone_get();
36
- // @codingStandardsIgnoreStart
37
- date_default_timezone_set( 'UTC' );
38
- if ( null === $from_timestamp ) {
39
- $next_timestamp = strtotime( $time_string );
40
- } else {
41
- $next_timestamp = strtotime( $time_string, $from_timestamp );
42
- }
43
- date_default_timezone_set( $original_timezone );
44
- // @codingStandardsIgnoreEnd
45
- return $next_timestamp;
46
- }
47
- }
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/documents/abstract-wcpdf-order-document-methods.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -25,23 +21,11 @@ if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Order_Document_Methods'
25
 
26
  abstract class Order_Document_Methods extends Order_Document {
27
  public function is_refund( $order ) {
28
- if ( is_callable( array( $order, 'get_type' ) ) ) { // WC 3.0+
29
- $is_refund = $order->get_type() == 'shop_order_refund';
30
- } else {
31
- $is_refund = get_post_type( WCX_Order::get_id( $order ) ) == 'shop_order_refund';
32
- }
33
-
34
- return $is_refund;
35
  }
36
 
37
  public function get_refund_parent_id( $order ) {
38
- if ( is_callable( array( $order, 'get_parent_id' ) ) ) { // WC3.0+
39
- $parent_order_id = $order->get_parent_id();
40
- } else {
41
- $parent_order_id = wp_get_post_parent_id( WCX_Order::get_id( $order ) );
42
- }
43
-
44
- return $parent_order_id;
45
  }
46
 
47
 
@@ -52,7 +36,7 @@ abstract class Order_Document_Methods extends Order_Document {
52
  }
53
 
54
  $parent_order_id = $this->get_refund_parent_id( $order );
55
- $order = WCX::get_order( $parent_order_id );
56
  return $order;
57
  }
58
 
@@ -81,9 +65,9 @@ abstract class Order_Document_Methods extends Order_Document {
81
  'country'
82
  ), $this );
83
 
84
- foreach ($address_comparison_fields as $address_field) {
85
- $billing_field = WCX_Order::get_prop( $order, "billing_{$address_field}", 'view');
86
- $shipping_field = WCX_Order::get_prop( $order, "shipping_{$address_field}", 'view');
87
  if ( $shipping_field != $billing_field ) {
88
  // this address field is different -> ships to different address!
89
  return true;
@@ -119,7 +103,7 @@ abstract class Order_Document_Methods extends Order_Document {
119
  return $address;
120
  }
121
  public function billing_address() {
122
- echo $this->get_billing_address();
123
  }
124
 
125
  /**
@@ -137,32 +121,34 @@ abstract class Order_Document_Methods extends Order_Document {
137
  * Return/Show billing email
138
  */
139
  public function get_billing_email() {
140
- $billing_email = WCX_Order::get_prop( $this->order, 'billing_email', 'view' );
141
-
142
- if ( !$billing_email && $this->is_refund( $this->order ) ) {
 
 
143
  // try parent
144
- $parent_order = $this->get_refund_parent( $this->order );
145
- $billing_email = WCX_Order::get_prop( $parent_order, 'billing_email', 'view' );
146
  }
147
 
148
  return apply_filters( 'wpo_wcpdf_billing_email', $billing_email, $this );
149
  }
150
  public function billing_email() {
151
- echo $this->get_billing_email();
152
  }
153
 
154
  /**
155
  * Return/Show phone by type
156
  */
157
  public function get_phone( $phone_type = 'billing' ) {
158
- $phone_type = "{$phone_type}_phone";
159
- $phone = WCX_Order::get_prop( $this->order, $phone_type, 'view' );
160
 
161
  // on refund orders
162
  if ( ! $phone && $this->is_refund( $this->order ) ) {
163
  // try parent
164
  $parent_order = $this->get_refund_parent( $this->order );
165
- $phone = WCX_Order::get_prop( $parent_order, $phone_type, 'view' );
166
  }
167
 
168
  return $phone;
@@ -185,11 +171,11 @@ abstract class Order_Document_Methods extends Order_Document {
185
  }
186
 
187
  public function billing_phone() {
188
- echo $this->get_billing_phone();
189
  }
190
 
191
  public function shipping_phone( $fallback_to_billing = false ) {
192
- echo $this->get_shipping_phone( $fallback_to_billing );
193
  }
194
 
195
  /**
@@ -222,7 +208,7 @@ abstract class Order_Document_Methods extends Order_Document {
222
  return $address;
223
  }
224
  public function shipping_address() {
225
- echo $this->get_shipping_address();
226
  }
227
 
228
  /**
@@ -241,11 +227,11 @@ abstract class Order_Document_Methods extends Order_Document {
241
  */
242
  public function get_custom_field( $field_name ) {
243
  if ( !$this->is_order_prop( $field_name ) ) {
244
- $custom_field = WCX_Order::get_meta( $this->order, $field_name, true );
245
  }
246
  // if not found, try prefixed with underscore (not when ACF is active!)
247
  if ( empty( $custom_field ) && substr( $field_name, 0, 1 ) !== '_' && !$this->is_order_prop( "_{$field_name}" ) && !class_exists('ACF') ) {
248
- $custom_field = WCX_Order::get_meta( $this->order, "_{$field_name}", true );
249
  }
250
 
251
  // WC3.0 fallback to properties
@@ -258,7 +244,7 @@ abstract class Order_Document_Methods extends Order_Document {
258
  if ( empty( $custom_field ) && $this->is_refund( $this->order ) ) {
259
  $parent_order = $this->get_refund_parent( $this->order );
260
  if ( !$this->is_order_prop( $field_name ) ) {
261
- $custom_field = WCX_Order::get_meta( $parent_order, $field_name, true );
262
  }
263
 
264
  // WC3.0 fallback to properties
@@ -277,14 +263,11 @@ abstract class Order_Document_Methods extends Order_Document {
277
  }
278
 
279
  if (!empty($custom_field) || $display_empty) {
280
- echo $field_label . nl2br ($custom_field);
281
  }
282
  }
283
 
284
  public function is_order_prop( $key ) {
285
- if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '<' ) ) {
286
- return false; // WC 2.X didn't have CRUD
287
- }
288
  // Taken from WC class
289
  $order_props = array(
290
  // Abstract order props
@@ -360,7 +343,7 @@ abstract class Order_Document_Methods extends Order_Document {
360
  if (empty($attribute)) {
361
  // not a text attribute, try attribute taxonomy
362
  $attribute_key = @wc_attribute_taxonomy_name( $attribute_name );
363
- $product_id = WCX_Product::get_prop($product, 'id');
364
  $product_terms = @wc_get_product_terms( $product_id, $attribute_key, array( 'fields' => 'names' ) );
365
  // check if not empty, then display
366
  if ( !empty($product_terms) ) {
@@ -369,15 +352,15 @@ abstract class Order_Document_Methods extends Order_Document {
369
  }
370
 
371
  // WC3.0+ fallback parent product for variations
372
- if ( empty($attribute) && version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) && $product->is_type( 'variation' ) ) {
373
- $product = wc_get_product( $product->get_parent_id() );
374
  $attribute = $this->get_product_attribute( $attribute_name, $product );
375
  }
376
 
377
  return isset($attribute) ? $attribute : false;
378
  }
379
  public function product_attribute( $attribute_name, $product ) {
380
- echo $this->get_product_attribute( $attribute_name, $product );
381
  }
382
 
383
  /**
@@ -464,7 +447,7 @@ abstract class Order_Document_Methods extends Order_Document {
464
  return apply_filters( 'wpo_wcpdf_date', date_i18n( wcpdf_date_format( $this, 'current_date' ) ) );
465
  }
466
  public function current_date() {
467
- echo $this->get_current_date();
468
  }
469
 
470
  /**
@@ -475,9 +458,9 @@ abstract class Order_Document_Methods extends Order_Document {
475
 
476
  if ( $this->is_refund( $this->order ) ) {
477
  $parent_order = $this->get_refund_parent( $this->order );
478
- $payment_method_title = WCX_Order::get_prop( $parent_order, 'payment_method_title', 'view' );
479
  } else {
480
- $payment_method_title = WCX_Order::get_prop( $this->order, 'payment_method_title', 'view' );
481
  }
482
 
483
  $payment_method = __( $payment_method_title, 'woocommerce' );
@@ -485,7 +468,7 @@ abstract class Order_Document_Methods extends Order_Document {
485
  return apply_filters( 'wpo_wcpdf_payment_method', $payment_method, $this );
486
  }
487
  public function payment_method() {
488
- echo $this->get_payment_method();
489
  }
490
 
491
  /**
@@ -497,7 +480,7 @@ abstract class Order_Document_Methods extends Order_Document {
497
  return apply_filters( 'wpo_wcpdf_shipping_method', $shipping_method, $this );
498
  }
499
  public function shipping_method() {
500
- echo $this->get_shipping_method();
501
  }
502
 
503
  /**
@@ -518,7 +501,7 @@ abstract class Order_Document_Methods extends Order_Document {
518
  return apply_filters( 'wpo_wcpdf_order_number', $order_number, $this );
519
  }
520
  public function order_number() {
521
- echo $this->get_order_number();
522
  }
523
 
524
  /**
@@ -527,9 +510,9 @@ abstract class Order_Document_Methods extends Order_Document {
527
  public function get_order_date() {
528
  if ( $this->is_refund( $this->order ) ) {
529
  $parent_order = $this->get_refund_parent( $this->order );
530
- $order_date = WCX_Order::get_prop( $parent_order, 'date_created' );
531
  } else {
532
- $order_date = WCX_Order::get_prop( $this->order, 'date_created' );
533
  }
534
 
535
  $date = $order_date->date_i18n( wcpdf_date_format( $this, 'order_date' ) );
@@ -537,7 +520,7 @@ abstract class Order_Document_Methods extends Order_Document {
537
  return apply_filters( 'wpo_wcpdf_order_date', $date, $mysql_date, $this );
538
  }
539
  public function order_date() {
540
- echo $this->get_order_date();
541
  }
542
 
543
  /**
@@ -616,7 +599,7 @@ abstract class Order_Document_Methods extends Order_Document {
616
  $data['weight'] = is_callable( array( $product, 'get_weight' ) ) ? $product->get_weight() : '';
617
 
618
  // Set item dimensions
619
- $data['dimensions'] = $product instanceof \WC_Product ? WCX_Product::get_dimensions( $product ) : '';
620
 
621
  // Pass complete product object
622
  $data['product'] = $product;
@@ -626,18 +609,7 @@ abstract class Order_Document_Methods extends Order_Document {
626
  }
627
 
628
  // Set item meta
629
- if (function_exists('wc_display_item_meta')) { // WC3.0+
630
- $data['meta'] = wc_display_item_meta( $item, apply_filters( 'wpo_wcpdf_display_item_meta_args', array(
631
- 'echo' => false,
632
- ), $this ) );
633
- } else {
634
- if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '<' ) ) {
635
- $meta = new \WC_Order_Item_Meta( $item['item_meta'], $product );
636
- } else { // pass complete item for WC2.4+
637
- $meta = new \WC_Order_Item_Meta( $item, $product );
638
- }
639
- $data['meta'] = $meta->display( false, true );
640
- }
641
 
642
  $data_list[$item_id] = apply_filters( 'wpo_wcpdf_order_item_data', $data, $this->order, $this->get_type() );
643
  }
@@ -654,23 +626,15 @@ abstract class Order_Document_Methods extends Order_Document {
654
  * @return string $tax_rates imploded list of tax rates
655
  */
656
  public function get_tax_rate( $item, $order, $force_calculation = false ) {
657
- if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) ) {
658
- $tax_data_container = ( $item['type'] == 'line_item' ) ? 'line_tax_data' : 'taxes';
659
- $tax_data_key = ( $item['type'] == 'line_item' ) ? 'subtotal' : 'total';
660
- $line_total_key = ( $item['type'] == 'line_item' ) ? 'line_total' : 'total';
661
- $line_tax_key = ( $item['type'] == 'shipping' ) ? 'total_tax' : 'line_tax';
662
-
663
- $tax_class = isset($item['tax_class']) ? $item['tax_class'] : '';
664
- $line_tax = $item[$line_tax_key];
665
- $line_total = $item[$line_total_key];
666
- $line_tax_data = $item[$tax_data_container];
667
- } else {
668
- $tax_data_key = ( $item['type'] == 'line_item' ) ? 'subtotal' : 'total';
669
- $tax_class = $item['tax_class'];
670
- $line_total = $item['line_total'];
671
- $line_tax = $item['line_tax'];
672
- $line_tax_data = maybe_unserialize( isset( $item['line_tax_data'] ) ? $item['line_tax_data'] : '' );
673
- }
674
 
675
  // first try the easy wc2.2+ way, using line_tax_data
676
  if ( !empty( $line_tax_data ) && isset($line_tax_data[$tax_data_key]) ) {
@@ -703,8 +667,7 @@ abstract class Order_Document_Methods extends Order_Document {
703
  return '-'; // no need to determine tax rate...
704
  }
705
 
706
- if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 && !apply_filters( 'wpo_wcpdf_calculate_tax_rate', false ) ) {
707
- // WC 2.1 or newer is used
708
  $tax = new \WC_Tax();
709
  $taxes = $tax->get_rates( $tax_class );
710
 
@@ -720,9 +683,6 @@ abstract class Order_Document_Methods extends Order_Document {
720
  }
721
 
722
  $tax_rates = implode(' ,', $tax_rates );
723
- } else {
724
- // Backwards compatibility/fallback: calculate tax from line items
725
- $tax_rates[] = $this->calculate_tax_rate( $line_total, $line_tax );
726
  }
727
 
728
  return $tax_rates;
@@ -818,7 +778,7 @@ abstract class Order_Document_Methods extends Order_Document {
818
  * @return string
819
  */
820
  public function get_thumbnail_id ( $product ) {
821
- $product_id = WCX_Product::get_id( $product );
822
 
823
  if ( has_post_thumbnail( $product_id ) ) {
824
  $thumbnail_id = get_post_thumbnail_id ( $product_id );
@@ -924,20 +884,14 @@ abstract class Order_Document_Methods extends Order_Document {
924
  $totals[$key]['label'] = $label;
925
  }
926
 
927
- // WC2.4 fix order_total for refunded orders
928
  // not if this is the actual refund!
929
  if ( ! $this->is_refund( $this->order ) && apply_filters( 'wpo_wcpdf_remove_refund_totals', true, $this ) ) {
930
  $total_refunded = is_callable( array( $this->order, 'get_total_refunded' ) ) ? $this->order->get_total_refunded() : 0;
931
- if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '>=' ) && isset($totals['order_total']) && $total_refunded ) {
932
- if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) ) {
933
- $tax_display = get_option( 'woocommerce_tax_display_cart' );
934
- } else {
935
- $tax_display = WCX_Order::get_prop( $this->order, 'tax_display_cart' );
936
- }
937
-
938
- $totals['order_total']['value'] = wc_price( $this->order->get_total(), array( 'currency' => WCX_Order::get_prop( $this->order, 'currency' ) ) );
939
- $order_total = $this->order->get_total();
940
- $tax_string = '';
941
 
942
  // Tax for inclusive prices
943
  if ( wc_tax_enabled() && 'incl' == $tax_display ) {
@@ -948,15 +902,10 @@ abstract class Order_Document_Methods extends Order_Document {
948
  $tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label );
949
  }
950
  } else {
951
- $tax_string_array[] = sprintf( '%s %s', wc_price( $this->order->get_total_tax(), array( 'currency' => WCX_Order::get_prop( $this->order, 'currency' ) ) ), WC()->countries->tax_or_vat() );
952
  }
953
  if ( ! empty( $tax_string_array ) ) {
954
- if ( version_compare( WOOCOMMERCE_VERSION, '2.6', '>=' ) ) {
955
- $tax_string = ' ' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) );
956
- } else {
957
- // use old capitalized string
958
- $tax_string = ' ' . sprintf( __( '(Includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) );
959
- }
960
  }
961
  }
962
 
@@ -993,15 +942,15 @@ abstract class Order_Document_Methods extends Order_Document {
993
  }
994
  public function order_subtotal( $tax = 'excl', $discount = 'incl' ) {
995
  $subtotal = $this->get_order_subtotal( $tax, $discount );
996
- echo $subtotal['value'];
997
  }
998
 
999
  /**
1000
  * Return/show the order shipping costs
1001
  */
1002
  public function get_order_shipping( $tax = 'excl' ) { // set $tax to 'incl' to include tax
1003
- $shipping_cost = WCX_Order::get_prop( $this->order, 'shipping_total', 'view' );
1004
- $shipping_tax = WCX_Order::get_prop( $this->order, 'shipping_tax', 'view' );
1005
 
1006
  if ($tax == 'excl' ) {
1007
  $formatted_shipping_cost = $this->format_price( $shipping_cost );
@@ -1018,7 +967,7 @@ abstract class Order_Document_Methods extends Order_Document {
1018
  }
1019
  public function order_shipping( $tax = 'excl' ) {
1020
  $shipping = $this->get_order_shipping( $tax );
1021
- echo $shipping['value'];
1022
  }
1023
 
1024
  /**
@@ -1037,19 +986,7 @@ abstract class Order_Document_Methods extends Order_Document {
1037
  break;
1038
  case 'total':
1039
  // Total Discount
1040
- if ( version_compare( WOOCOMMERCE_VERSION, '2.3' ) >= 0 ) {
1041
- $discount_value = $this->order->get_total_discount( false ); // $ex_tax = false
1042
- } else {
1043
- // WC2.2 and older: recalculate to include tax
1044
- $discount_value = 0;
1045
- $items = $this->order->get_items();;
1046
- if( sizeof( $items ) > 0 ) {
1047
- foreach( $items as $item ) {
1048
- $discount_value += ($item['line_subtotal'] + $item['line_subtotal_tax']) - ($item['line_total'] + $item['line_tax']);
1049
- }
1050
- }
1051
- }
1052
-
1053
  break;
1054
  default:
1055
  // Total Discount - Cart & Order Discounts combined
@@ -1057,19 +994,7 @@ abstract class Order_Document_Methods extends Order_Document {
1057
  break;
1058
  }
1059
  } else { // calculate discount excluding tax
1060
- if ( version_compare( WOOCOMMERCE_VERSION, '2.3' ) >= 0 ) {
1061
- $discount_value = $this->order->get_total_discount( true ); // $ex_tax = true
1062
- } else {
1063
- // WC2.2 and older: recalculate to exclude tax
1064
- $discount_value = 0;
1065
-
1066
- $items = $this->order->get_items();;
1067
- if( sizeof( $items ) > 0 ) {
1068
- foreach( $items as $item ) {
1069
- $discount_value += ($item['line_subtotal'] - $item['line_total']);
1070
- }
1071
- }
1072
- }
1073
  }
1074
 
1075
  $discount = array (
@@ -1084,7 +1009,7 @@ abstract class Order_Document_Methods extends Order_Document {
1084
  }
1085
  public function order_discount( $type = 'total', $tax = 'incl' ) {
1086
  $discount = $this->get_order_discount( $type, $tax );
1087
- echo $discount['value'];
1088
  }
1089
 
1090
  /**
@@ -1114,30 +1039,17 @@ abstract class Order_Document_Methods extends Order_Document {
1114
  * Return the order taxes
1115
  */
1116
  public function get_order_taxes() {
1117
- $tax_label = __( 'VAT', 'woocommerce-pdf-invoices-packing-slips' ); // register alternate label translation
1118
- $tax_label = __( 'Tax rate', 'woocommerce-pdf-invoices-packing-slips' );
1119
  $tax_rate_ids = $this->get_tax_rate_ids();
1120
  if ( $order_taxes = $this->order->get_taxes() ) {
1121
  foreach ( $order_taxes as $key => $tax ) {
1122
- if ( WCX::is_wc_version_gte_3_0() ) {
1123
- $taxes[ $key ] = array(
1124
- 'label' => $tax->get_label(),
1125
- 'value' => $this->format_price( $tax->get_tax_total() + $tax->get_shipping_tax_total() ),
1126
- 'rate_id' => $tax->get_rate_id(),
1127
- 'tax_amount' => $tax->get_tax_total(),
1128
- 'shipping_tax_amount' => $tax->get_shipping_tax_total(),
1129
- 'rate' => isset( $tax_rate_ids[ $tax->get_rate_id() ] ) ? ( (float) $tax_rate_ids[$tax->get_rate_id()]['tax_rate'] ) . ' %': '',
1130
- );
1131
- } else {
1132
- $taxes[ $key ] = array(
1133
- 'label' => isset( $tax[ 'label' ] ) ? $tax[ 'label' ] : $tax[ 'name' ],
1134
- 'value' => $this->format_price( ( $tax[ 'tax_amount' ] + $tax[ 'shipping_tax_amount' ] ) ),
1135
- 'rate_id' => $tax['rate_id'],
1136
- 'tax_amount' => $tax['tax_amount'],
1137
- 'shipping_tax_amount' => $tax['shipping_tax_amount'],
1138
- 'rate' => isset( $tax_rate_ids[ $tax['rate_id'] ] ) ? ( (float) $tax_rate_ids[$tax['rate_id']]['tax_rate'] ) . ' %': '',
1139
- );
1140
- }
1141
 
1142
  }
1143
 
@@ -1149,13 +1061,7 @@ abstract class Order_Document_Methods extends Order_Document {
1149
  * Return/show the order grand total
1150
  */
1151
  public function get_order_grand_total( $tax = 'incl' ) {
1152
- if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) {
1153
- // WC 2.1 or newer is used
1154
- $total_unformatted = $this->order->get_total();
1155
- } else {
1156
- // Backwards compatibility
1157
- $total_unformatted = $this->order->get_order_total();
1158
- }
1159
 
1160
  if ($tax == 'excl' ) {
1161
  $total = $this->format_price( $total_unformatted - $this->order->get_total_tax() );
@@ -1174,7 +1080,7 @@ abstract class Order_Document_Methods extends Order_Document {
1174
  }
1175
  public function order_grand_total( $tax = 'incl' ) {
1176
  $grand_total = $this->get_order_grand_total( $tax );
1177
- echo $grand_total['value'];
1178
  }
1179
 
1180
 
@@ -1183,16 +1089,9 @@ abstract class Order_Document_Methods extends Order_Document {
1183
  */
1184
  public function get_shipping_notes() {
1185
  if ( $this->is_refund( $this->order ) ) {
1186
- // return reason for refund if order is a refund
1187
- if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) ) {
1188
- $shipping_notes = $this->order->get_reason();
1189
- } elseif ( is_callable( array( $this->order, 'get_refund_reason' ) ) ) {
1190
- $shipping_notes = $this->order->get_refund_reason();
1191
- } else {
1192
- $shipping_notes = wpautop( wptexturize( WCX_Order::get_prop( $this->order, 'customer_note', 'view' ) ) );
1193
- }
1194
  } else {
1195
- $shipping_notes = wpautop( wptexturize( WCX_Order::get_prop( $this->order, 'customer_note', 'view' ) ) );
1196
  }
1197
 
1198
  // check document specific setting
@@ -1203,19 +1102,15 @@ abstract class Order_Document_Methods extends Order_Document {
1203
  return apply_filters( 'wpo_wcpdf_shipping_notes', $shipping_notes, $this );
1204
  }
1205
  public function shipping_notes() {
1206
- echo $this->get_shipping_notes();
1207
  }
1208
 
1209
  /**
1210
  * wrapper for wc_price, ensuring currency is always passed
1211
  */
1212
  public function format_price( $price, $args = array() ) {
1213
- if ( function_exists( 'wc_price' ) ) { // WC 2.1+
1214
- $args['currency'] = WCX_Order::get_prop( $this->order, 'currency' );
1215
- $formatted_price = wc_price( $price, $args );
1216
- } else {
1217
- $formatted_price = woocommerce_price( $price );
1218
- }
1219
 
1220
  return $formatted_price;
1221
  }
@@ -1261,7 +1156,7 @@ abstract class Order_Document_Methods extends Order_Document {
1261
  }
1262
 
1263
  public function invoice_number() {
1264
- echo $this->get_invoice_number();
1265
  }
1266
 
1267
  public function get_invoice_date() {
@@ -1273,7 +1168,7 @@ abstract class Order_Document_Methods extends Order_Document {
1273
  }
1274
 
1275
  public function invoice_date() {
1276
- echo $this->get_invoice_date();
1277
  }
1278
 
1279
  public function get_document_notes() {
@@ -1287,9 +1182,9 @@ abstract class Order_Document_Methods extends Order_Document {
1287
  public function document_notes() {
1288
  $document_notes = $this->get_document_notes();
1289
  if( $document_notes == strip_tags( $document_notes ) ) {
1290
- echo nl2br($document_notes);
1291
  } else {
1292
- echo $document_notes;
1293
  }
1294
  }
1295
 
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
21
 
22
  abstract class Order_Document_Methods extends Order_Document {
23
  public function is_refund( $order ) {
24
+ return $order->get_type() == 'shop_order_refund';
 
 
 
 
 
 
25
  }
26
 
27
  public function get_refund_parent_id( $order ) {
28
+ return $order->get_parent_id();
 
 
 
 
 
 
29
  }
30
 
31
 
36
  }
37
 
38
  $parent_order_id = $this->get_refund_parent_id( $order );
39
+ $order = wc_get_order( $parent_order_id );
40
  return $order;
41
  }
42
 
65
  'country'
66
  ), $this );
67
 
68
+ foreach ( $address_comparison_fields as $address_field ) {
69
+ $billing_field = call_user_func( array( $order, "get_billing_{$address_field}" ) );
70
+ $shipping_field = call_user_func( array( $order, "get_shipping_{$address_field}" ) );
71
  if ( $shipping_field != $billing_field ) {
72
  // this address field is different -> ships to different address!
73
  return true;
103
  return $address;
104
  }
105
  public function billing_address() {
106
+ echo wp_kses_post( $this->get_billing_address() );
107
  }
108
 
109
  /**
121
  * Return/Show billing email
122
  */
123
  public function get_billing_email() {
124
+ // normal order
125
+ if ( ! $this->is_refund( $this->order ) && is_callable( array( $this->order, 'get_billing_email' ) ) ) {
126
+ $billing_email = $this->order->get_billing_email();
127
+ // refund order
128
+ } else {
129
  // try parent
130
+ $parent_order = $this->get_refund_parent( $this->order );
131
+ $billing_email = $parent_order->get_billing_email();
132
  }
133
 
134
  return apply_filters( 'wpo_wcpdf_billing_email', $billing_email, $this );
135
  }
136
  public function billing_email() {
137
+ echo wp_kses_post( $this->get_billing_email() );
138
  }
139
 
140
  /**
141
  * Return/Show phone by type
142
  */
143
  public function get_phone( $phone_type = 'billing' ) {
144
+ $phone_type = "get_{$phone_type}_phone";
145
+ $phone = call_user_func( array( $this->order, $phone_type ) );
146
 
147
  // on refund orders
148
  if ( ! $phone && $this->is_refund( $this->order ) ) {
149
  // try parent
150
  $parent_order = $this->get_refund_parent( $this->order );
151
+ $phone = call_user_func( array( $parent_order, $phone_type ) );
152
  }
153
 
154
  return $phone;
171
  }
172
 
173
  public function billing_phone() {
174
+ echo wp_kses_post( $this->get_billing_phone() );
175
  }
176
 
177
  public function shipping_phone( $fallback_to_billing = false ) {
178
+ echo wp_kses_post( $this->get_shipping_phone( $fallback_to_billing ) );
179
  }
180
 
181
  /**
208
  return $address;
209
  }
210
  public function shipping_address() {
211
+ echo wp_kses_post( $this->get_shipping_address() );
212
  }
213
 
214
  /**
227
  */
228
  public function get_custom_field( $field_name ) {
229
  if ( !$this->is_order_prop( $field_name ) ) {
230
+ $custom_field = $this->order->get_meta( $field_name );
231
  }
232
  // if not found, try prefixed with underscore (not when ACF is active!)
233
  if ( empty( $custom_field ) && substr( $field_name, 0, 1 ) !== '_' && !$this->is_order_prop( "_{$field_name}" ) && !class_exists('ACF') ) {
234
+ $custom_field = $this->order->get_meta( "_{$field_name}" );
235
  }
236
 
237
  // WC3.0 fallback to properties
244
  if ( empty( $custom_field ) && $this->is_refund( $this->order ) ) {
245
  $parent_order = $this->get_refund_parent( $this->order );
246
  if ( !$this->is_order_prop( $field_name ) ) {
247
+ $custom_field = $parent_order->get_meta( $field_name );
248
  }
249
 
250
  // WC3.0 fallback to properties
263
  }
264
 
265
  if (!empty($custom_field) || $display_empty) {
266
+ echo wp_kses_post( $field_label . nl2br ($custom_field) );
267
  }
268
  }
269
 
270
  public function is_order_prop( $key ) {
 
 
 
271
  // Taken from WC class
272
  $order_props = array(
273
  // Abstract order props
343
  if (empty($attribute)) {
344
  // not a text attribute, try attribute taxonomy
345
  $attribute_key = @wc_attribute_taxonomy_name( $attribute_name );
346
+ $product_id = $product->get_id();
347
  $product_terms = @wc_get_product_terms( $product_id, $attribute_key, array( 'fields' => 'names' ) );
348
  // check if not empty, then display
349
  if ( !empty($product_terms) ) {
352
  }
353
 
354
  // WC3.0+ fallback parent product for variations
355
+ if ( empty( $attribute ) && $product->is_type( 'variation' ) ) {
356
+ $product = wc_get_product( $product->get_parent_id() );
357
  $attribute = $this->get_product_attribute( $attribute_name, $product );
358
  }
359
 
360
  return isset($attribute) ? $attribute : false;
361
  }
362
  public function product_attribute( $attribute_name, $product ) {
363
+ echo wp_kses_post( $this->get_product_attribute( $attribute_name, $product ) );
364
  }
365
 
366
  /**
447
  return apply_filters( 'wpo_wcpdf_date', date_i18n( wcpdf_date_format( $this, 'current_date' ) ) );
448
  }
449
  public function current_date() {
450
+ echo wp_kses_post( $this->get_current_date() );
451
  }
452
 
453
  /**
458
 
459
  if ( $this->is_refund( $this->order ) ) {
460
  $parent_order = $this->get_refund_parent( $this->order );
461
+ $payment_method_title = $parent_order->get_payment_method_title();
462
  } else {
463
+ $payment_method_title = $this->order->get_payment_method_title();
464
  }
465
 
466
  $payment_method = __( $payment_method_title, 'woocommerce' );
468
  return apply_filters( 'wpo_wcpdf_payment_method', $payment_method, $this );
469
  }
470
  public function payment_method() {
471
+ echo wp_kses_post( $this->get_payment_method() );
472
  }
473
 
474
  /**
480
  return apply_filters( 'wpo_wcpdf_shipping_method', $shipping_method, $this );
481
  }
482
  public function shipping_method() {
483
+ echo wp_kses_post( $this->get_shipping_method() );
484
  }
485
 
486
  /**
501
  return apply_filters( 'wpo_wcpdf_order_number', $order_number, $this );
502
  }
503
  public function order_number() {
504
+ echo esc_attr( $this->get_order_number() );
505
  }
506
 
507
  /**
510
  public function get_order_date() {
511
  if ( $this->is_refund( $this->order ) ) {
512
  $parent_order = $this->get_refund_parent( $this->order );
513
+ $order_date = $parent_order->get_date_created();
514
  } else {
515
+ $order_date = $this->order->get_date_created();
516
  }
517
 
518
  $date = $order_date->date_i18n( wcpdf_date_format( $this, 'order_date' ) );
520
  return apply_filters( 'wpo_wcpdf_order_date', $date, $mysql_date, $this );
521
  }
522
  public function order_date() {
523
+ echo wp_kses_post( $this->get_order_date() );
524
  }
525
 
526
  /**
599
  $data['weight'] = is_callable( array( $product, 'get_weight' ) ) ? $product->get_weight() : '';
600
 
601
  // Set item dimensions
602
+ $data['dimensions'] = $product instanceof \WC_Product ? $product->get_dimensions() : '';
603
 
604
  // Pass complete product object
605
  $data['product'] = $product;
609
  }
610
 
611
  // Set item meta
612
+ $data['meta'] = wc_display_item_meta( $item, apply_filters( 'wpo_wcpdf_display_item_meta_args', array( 'echo' => false ), $this ) );
 
 
 
 
 
 
 
 
 
 
 
613
 
614
  $data_list[$item_id] = apply_filters( 'wpo_wcpdf_order_item_data', $data, $this->order, $this->get_type() );
615
  }
626
  * @return string $tax_rates imploded list of tax rates
627
  */
628
  public function get_tax_rate( $item, $order, $force_calculation = false ) {
629
+ $tax_data_container = ( $item['type'] == 'line_item' ) ? 'line_tax_data' : 'taxes';
630
+ $tax_data_key = ( $item['type'] == 'line_item' ) ? 'subtotal' : 'total';
631
+ $line_total_key = ( $item['type'] == 'line_item' ) ? 'line_total' : 'total';
632
+ $line_tax_key = ( $item['type'] == 'shipping' ) ? 'total_tax' : 'line_tax';
633
+
634
+ $tax_class = isset($item['tax_class']) ? $item['tax_class'] : '';
635
+ $line_tax = $item[$line_tax_key];
636
+ $line_total = $item[$line_total_key];
637
+ $line_tax_data = $item[$tax_data_container];
 
 
 
 
 
 
 
 
638
 
639
  // first try the easy wc2.2+ way, using line_tax_data
640
  if ( !empty( $line_tax_data ) && isset($line_tax_data[$tax_data_key]) ) {
667
  return '-'; // no need to determine tax rate...
668
  }
669
 
670
+ if ( ! apply_filters( 'wpo_wcpdf_calculate_tax_rate', false ) ) {
 
671
  $tax = new \WC_Tax();
672
  $taxes = $tax->get_rates( $tax_class );
673
 
683
  }
684
 
685
  $tax_rates = implode(' ,', $tax_rates );
 
 
 
686
  }
687
 
688
  return $tax_rates;
778
  * @return string
779
  */
780
  public function get_thumbnail_id ( $product ) {
781
+ $product_id = $product->get_id();
782
 
783
  if ( has_post_thumbnail( $product_id ) ) {
784
  $thumbnail_id = get_post_thumbnail_id ( $product_id );
884
  $totals[$key]['label'] = $label;
885
  }
886
 
887
+ // Fix order_total for refunded orders
888
  // not if this is the actual refund!
889
  if ( ! $this->is_refund( $this->order ) && apply_filters( 'wpo_wcpdf_remove_refund_totals', true, $this ) ) {
890
  $total_refunded = is_callable( array( $this->order, 'get_total_refunded' ) ) ? $this->order->get_total_refunded() : 0;
891
+ if ( isset($totals['order_total']) && $total_refunded ) {
892
+ $tax_display = get_option( 'woocommerce_tax_display_cart' );
893
+ $totals['order_total']['value'] = wc_price( $this->order->get_total(), array( 'currency' => $this->order->get_currency() ) );
894
+ $tax_string = '';
 
 
 
 
 
 
895
 
896
  // Tax for inclusive prices
897
  if ( wc_tax_enabled() && 'incl' == $tax_display ) {
902
  $tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label );
903
  }
904
  } else {
905
+ $tax_string_array[] = sprintf( '%s %s', wc_price( $this->order->get_total_tax(), array( 'currency' => $this->order->get_currency() ) ), WC()->countries->tax_or_vat() );
906
  }
907
  if ( ! empty( $tax_string_array ) ) {
908
+ $tax_string = ' ' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) );
 
 
 
 
 
909
  }
910
  }
911
 
942
  }
943
  public function order_subtotal( $tax = 'excl', $discount = 'incl' ) {
944
  $subtotal = $this->get_order_subtotal( $tax, $discount );
945
+ echo wp_kses_post( $subtotal['value'] );
946
  }
947
 
948
  /**
949
  * Return/show the order shipping costs
950
  */
951
  public function get_order_shipping( $tax = 'excl' ) { // set $tax to 'incl' to include tax
952
+ $shipping_cost = $this->order->get_shipping_total();
953
+ $shipping_tax = $this->order->get_shipping_tax();
954
 
955
  if ($tax == 'excl' ) {
956
  $formatted_shipping_cost = $this->format_price( $shipping_cost );
967
  }
968
  public function order_shipping( $tax = 'excl' ) {
969
  $shipping = $this->get_order_shipping( $tax );
970
+ echo wp_kses_post( $shipping['value'] );
971
  }
972
 
973
  /**
986
  break;
987
  case 'total':
988
  // Total Discount
989
+ $discount_value = $this->order->get_total_discount( false ); // $ex_tax = false
 
 
 
 
 
 
 
 
 
 
 
 
990
  break;
991
  default:
992
  // Total Discount - Cart & Order Discounts combined
994
  break;
995
  }
996
  } else { // calculate discount excluding tax
997
+ $discount_value = $this->order->get_total_discount( true ); // $ex_tax = true
 
 
 
 
 
 
 
 
 
 
 
 
998
  }
999
 
1000
  $discount = array (
1009
  }
1010
  public function order_discount( $type = 'total', $tax = 'incl' ) {
1011
  $discount = $this->get_order_discount( $type, $tax );
1012
+ echo wp_kses_post( $discount['value'] );
1013
  }
1014
 
1015
  /**
1039
  * Return the order taxes
1040
  */
1041
  public function get_order_taxes() {
 
 
1042
  $tax_rate_ids = $this->get_tax_rate_ids();
1043
  if ( $order_taxes = $this->order->get_taxes() ) {
1044
  foreach ( $order_taxes as $key => $tax ) {
1045
+ $taxes[$key] = array(
1046
+ 'label' => $tax->get_label(),
1047
+ 'value' => $this->format_price( $tax->get_tax_total() + $tax->get_shipping_tax_total() ),
1048
+ 'rate_id' => $tax->get_rate_id(),
1049
+ 'tax_amount' => $tax->get_tax_total(),
1050
+ 'shipping_tax_amount' => $tax->get_shipping_tax_total(),
1051
+ 'rate' => isset( $tax_rate_ids[ $tax->get_rate_id() ] ) ? ( (float) $tax_rate_ids[$tax->get_rate_id()]['tax_rate'] ) . ' %': '',
1052
+ );
 
 
 
 
 
 
 
 
 
 
 
1053
 
1054
  }
1055
 
1061
  * Return/show the order grand total
1062
  */
1063
  public function get_order_grand_total( $tax = 'incl' ) {
1064
+ $total_unformatted = $this->order->get_total();
 
 
 
 
 
 
1065
 
1066
  if ($tax == 'excl' ) {
1067
  $total = $this->format_price( $total_unformatted - $this->order->get_total_tax() );
1080
  }
1081
  public function order_grand_total( $tax = 'incl' ) {
1082
  $grand_total = $this->get_order_grand_total( $tax );
1083
+ echo wp_kses_post( $grand_total['value'] );
1084
  }
1085
 
1086
 
1089
  */
1090
  public function get_shipping_notes() {
1091
  if ( $this->is_refund( $this->order ) ) {
1092
+ $shipping_notes = $this->order->get_reason();
 
 
 
 
 
 
 
1093
  } else {
1094
+ $shipping_notes = wpautop( wptexturize( $this->order->get_customer_note() ) );
1095
  }
1096
 
1097
  // check document specific setting
1102
  return apply_filters( 'wpo_wcpdf_shipping_notes', $shipping_notes, $this );
1103
  }
1104
  public function shipping_notes() {
1105
+ echo wp_kses_post( $this->get_shipping_notes() );
1106
  }
1107
 
1108
  /**
1109
  * wrapper for wc_price, ensuring currency is always passed
1110
  */
1111
  public function format_price( $price, $args = array() ) {
1112
+ $args['currency'] = $this->order->get_currency();
1113
+ $formatted_price = wc_price( $price, $args );
 
 
 
 
1114
 
1115
  return $formatted_price;
1116
  }
1156
  }
1157
 
1158
  public function invoice_number() {
1159
+ echo esc_attr( $this->get_invoice_number() );
1160
  }
1161
 
1162
  public function get_invoice_date() {
1168
  }
1169
 
1170
  public function invoice_date() {
1171
+ echo wp_kses_post( $this->get_invoice_date() );
1172
  }
1173
 
1174
  public function get_document_notes() {
1182
  public function document_notes() {
1183
  $document_notes = $this->get_document_notes();
1184
  if( $document_notes == strip_tags( $document_notes ) ) {
1185
+ echo wp_kses_post( nl2br( $document_notes ) );
1186
  } else {
1187
+ echo wp_kses_post( $document_notes );
1188
  }
1189
  }
1190
 
includes/documents/abstract-wcpdf-order-document.php CHANGED
@@ -1,11 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
- use WPO\WC\PDF_Invoices\Compatibility\WC_DateTime;
8
-
9
  if ( ! defined( 'ABSPATH' ) ) {
10
  exit; // Exit if accessed directly
11
  }
@@ -105,10 +100,10 @@ abstract class Order_Document {
105
  public function __construct( $order = 0 ) {
106
  if ( is_numeric( $order ) && $order > 0 ) {
107
  $this->order_id = $order;
108
- $this->order = WCX::get_order( $this->order_id );
109
  } elseif ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) {
110
- $this->order_id = WCX_Order::get_id( $order );
111
- $this->order = $order;
112
  }
113
 
114
  // set properties
@@ -146,7 +141,7 @@ abstract class Order_Document {
146
  $order_settings = array();
147
 
148
  if ( ! empty( $this->order ) ) {
149
- $order_settings = WCX_Order::get_meta( $this->order, "_wcpdf_{$this->slug}_settings" );
150
  if ( ! empty( $order_settings ) && ! is_array( $order_settings ) ) {
151
  $order_settings = maybe_unserialize( $order_settings );
152
  }
@@ -199,7 +194,8 @@ abstract class Order_Document {
199
  // this is either the first time the document is generated, or historical settings are disabled
200
  // in both cases, we store the document settings
201
  // exclude non historical settings from being saved in order meta
202
- WCX_Order::update_meta_data( $this->order, "_wcpdf_{$this->slug}_settings", array_diff_key( $settings, array_flip( $this->get_non_historical_settings() ) ) );
 
203
  }
204
  }
205
 
@@ -254,11 +250,11 @@ abstract class Order_Document {
254
  }
255
 
256
  public function read_data( $order ) {
257
- $number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number_data", true );
258
  // fallback to legacy data for number
259
  if ( empty( $number ) ) {
260
- $number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number", true );
261
- $formatted_number = WCX_Order::get_meta( $order, "_wcpdf_formatted_{$this->slug}_number", true );
262
  if (!empty($formatted_number)) {
263
  $number = compact( 'number', 'formatted_number' );
264
  }
@@ -267,9 +263,9 @@ abstract class Order_Document {
267
  // pass data to setter functions
268
  $this->set_data( array(
269
  // always load date before number, because date is used in number formatting
270
- 'date' => WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_date", true ),
271
  'number' => $number,
272
- 'notes' => WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_notes", true ),
273
  ), $order );
274
 
275
  return;
@@ -292,32 +288,34 @@ abstract class Order_Document {
292
 
293
  foreach ( $this->data as $key => $value ) {
294
  if ( empty( $value ) ) {
295
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}" );
296
  if ( $key == 'date' ) {
297
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted" );
298
  } elseif ( $key == 'number' ) {
299
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data" );
300
  // deleting the number = deleting the document, so also delete document settings
301
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_settings" );
302
  } elseif ( $key == 'notes' ) {
303
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}" );
304
  }
305
  } else {
306
  if ( $key == 'date' ) {
307
  // store dates as timestamp and formatted as mysql time
308
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->getTimestamp() );
309
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted", $value->date( 'Y-m-d H:i:s' ) );
310
  } elseif ( $key == 'number' ) {
311
  // store both formatted number and number data
312
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->formatted_number );
313
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data", $value->to_array() );
314
  } elseif ( $key == 'notes' ) {
315
  // store notes
316
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value );
317
  }
318
  }
319
  }
320
 
 
 
321
  do_action( 'wpo_wcpdf_save_document', $this, $order );
322
  }
323
 
@@ -335,10 +333,12 @@ abstract class Order_Document {
335
  'number_data',
336
  'notes',
337
  ), $this );
338
- foreach ($data_to_remove as $data_key) {
339
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$data_key}" );
340
  }
341
 
 
 
342
  do_action( 'wpo_wcpdf_delete_document', $this, $order );
343
  }
344
 
@@ -450,6 +450,10 @@ abstract class Order_Document {
450
  return apply_filters( "wpo_wcpdf_{$this->slug}_title", $this->title, $this );
451
  }
452
 
 
 
 
 
453
  public function get_number_title() {
454
  /* translators: %s: document name */
455
  $number_title = sprintf( __( '%s Number:', 'woocommerce-pdf-invoices-packing-slips' ), $this->title );
@@ -496,7 +500,7 @@ abstract class Order_Document {
496
  $datetime = $value;
497
  } elseif ( is_numeric( $value ) ) {
498
  // Timestamps are handled as UTC timestamps in all cases.
499
- $datetime = new WC_DateTime( "@{$value}", new \DateTimeZone( 'UTC' ) );
500
  } else {
501
  // Strings are defined in local WP timezone. Convert to UTC.
502
  if ( 1 === preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|((-|\+)\d{2}:\d{2}))$/', $value, $date_bits ) ) {
@@ -505,7 +509,7 @@ abstract class Order_Document {
505
  } else {
506
  $timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $value ) ) ) );
507
  }
508
- $datetime = new WC_DateTime( "@{$timestamp}", new \DateTimeZone( 'UTC' ) );
509
  }
510
 
511
  // Set local timezone or offset.
@@ -624,27 +628,40 @@ abstract class Order_Document {
624
  * Show logo html
625
  */
626
  public function header_logo() {
627
- if ($this->get_header_logo_id()) {
628
  $attachment_id = $this->get_header_logo_id();
629
- $company = $this->get_shop_name();
630
- if( $attachment_id ) {
631
- $attachment = wp_get_attachment_image_src( $attachment_id, 'full', false );
 
632
  $attachment_path = get_attached_file( $attachment_id );
 
633
  if ( empty( $attachment ) || empty( $attachment_path ) ) {
634
  return;
635
  }
636
 
637
- $attachment_src = $attachment[0];
638
- $attachment_width = $attachment[1];
639
  $attachment_height = $attachment[2];
640
 
641
  if ( apply_filters( 'wpo_wcpdf_use_path', true ) && file_exists( $attachment_path ) ) {
642
  $src = $attachment_path;
643
  } else {
644
- $src = $attachment_src;
 
 
 
 
 
 
 
 
 
 
 
645
  }
646
 
647
- $img_element = sprintf('<img src="%1$s" alt="%2$s" />', esc_attr( $src ), esc_attr( $company ) );
648
 
649
  echo apply_filters( 'wpo_wcpdf_header_logo_img_element', $img_element, $attachment, $this );
650
  }
@@ -690,7 +707,7 @@ abstract class Order_Document {
690
  return $this->get_settings_text( 'shop_name', $default, false );
691
  }
692
  public function shop_name() {
693
- echo $this->get_shop_name();
694
  }
695
 
696
  /**
@@ -700,7 +717,7 @@ abstract class Order_Document {
700
  return $this->get_settings_text( 'shop_address' );
701
  }
702
  public function shop_address() {
703
- echo $this->get_shop_address();
704
  }
705
 
706
  /**
@@ -709,12 +726,12 @@ abstract class Order_Document {
709
  public function get_footer() {
710
  ob_start();
711
  do_action( 'wpo_wcpdf_before_footer', $this->get_type(), $this->order );
712
- echo $this->get_settings_text( 'footer' );
713
  do_action( 'wpo_wcpdf_after_footer', $this->get_type(), $this->order );
714
  return ob_get_clean();
715
  }
716
  public function footer() {
717
- echo $this->get_footer();
718
  }
719
 
720
  /**
@@ -725,7 +742,7 @@ abstract class Order_Document {
725
 
726
  }
727
  public function extra_1() {
728
- echo $this->get_extra_1();
729
  }
730
 
731
  /**
@@ -735,7 +752,7 @@ abstract class Order_Document {
735
  return $this->get_settings_text( 'extra_2' );
736
  }
737
  public function extra_2() {
738
- echo $this->get_extra_2();
739
  }
740
 
741
  /**
@@ -745,7 +762,7 @@ abstract class Order_Document {
745
  return $this->get_settings_text( 'extra_3' );
746
  }
747
  public function extra_3() {
748
- echo $this->get_extra_3();
749
  }
750
 
751
  /*
@@ -755,6 +772,9 @@ abstract class Order_Document {
755
  */
756
 
757
  public function get_pdf() {
 
 
 
758
  $pdf = null;
759
  if ( $pdf_file = apply_filters( 'wpo_wcpdf_load_pdf_file_path', null, $this ) ) {
760
  $pdf = file_get_contents( $pdf_file );
@@ -789,6 +809,9 @@ abstract class Order_Document {
789
  }
790
 
791
  public function preview_pdf() {
 
 
 
792
  // get last settings
793
  $this->settings = ! empty( $this->latest_settings ) ? $this->latest_settings : $this->get_settings( true );
794
 
@@ -984,18 +1007,13 @@ abstract class Order_Document {
984
  // get list of WooCommerce statuses
985
  public function get_wc_order_status_list() {
986
  $order_statuses = array();
987
- if ( version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
988
- $statuses = (array) get_terms( 'shop_order_status', array( 'hide_empty' => 0, 'orderby' => 'id' ) );
989
- foreach ( $statuses as $status ) {
990
- $order_statuses[esc_attr( $status->slug )] = esc_html__( $status->name, 'woocommerce' );
991
- }
992
- } else {
993
- $statuses = function_exists('wc_get_order_statuses') ? wc_get_order_statuses() : array();
994
- foreach ( $statuses as $status_slug => $status ) {
995
- $status_slug = 'wc-' === substr( $status_slug, 0, 3 ) ? substr( $status_slug, 3 ) : $status_slug;
996
- $order_statuses[$status_slug] = $status;
997
- }
998
  }
 
999
  return $order_statuses;
1000
  }
1001
 
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
100
  public function __construct( $order = 0 ) {
101
  if ( is_numeric( $order ) && $order > 0 ) {
102
  $this->order_id = $order;
103
+ $this->order = wc_get_order( $this->order_id );
104
  } elseif ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) {
105
+ $this->order_id = $order->get_id();
106
+ $this->order = $order;
107
  }
108
 
109
  // set properties
141
  $order_settings = array();
142
 
143
  if ( ! empty( $this->order ) ) {
144
+ $order_settings = $this->order->get_meta( "_wcpdf_{$this->slug}_settings" );
145
  if ( ! empty( $order_settings ) && ! is_array( $order_settings ) ) {
146
  $order_settings = maybe_unserialize( $order_settings );
147
  }
194
  // this is either the first time the document is generated, or historical settings are disabled
195
  // in both cases, we store the document settings
196
  // exclude non historical settings from being saved in order meta
197
+ $this->order->update_meta_data( "_wcpdf_{$this->slug}_settings", array_diff_key( $settings, array_flip( $this->get_non_historical_settings() ) ) );
198
+ $this->order->save_meta_data();
199
  }
200
  }
201
 
250
  }
251
 
252
  public function read_data( $order ) {
253
+ $number = $order->get_meta( "_wcpdf_{$this->slug}_number_data" );
254
  // fallback to legacy data for number
255
  if ( empty( $number ) ) {
256
+ $number = $order->get_meta( "_wcpdf_{$this->slug}_number" );
257
+ $formatted_number = $order->get_meta( "_wcpdf_formatted_{$this->slug}_number" );
258
  if (!empty($formatted_number)) {
259
  $number = compact( 'number', 'formatted_number' );
260
  }
263
  // pass data to setter functions
264
  $this->set_data( array(
265
  // always load date before number, because date is used in number formatting
266
+ 'date' => $order->get_meta( "_wcpdf_{$this->slug}_date" ),
267
  'number' => $number,
268
+ 'notes' => $order->get_meta( "_wcpdf_{$this->slug}_notes" ),
269
  ), $order );
270
 
271
  return;
288
 
289
  foreach ( $this->data as $key => $value ) {
290
  if ( empty( $value ) ) {
291
+ $order->delete_meta_data( "_wcpdf_{$this->slug}_{$key}" );
292
  if ( $key == 'date' ) {
293
+ $order->delete_meta_data( "_wcpdf_{$this->slug}_{$key}_formatted" );
294
  } elseif ( $key == 'number' ) {
295
+ $order->delete_meta_data( "_wcpdf_{$this->slug}_{$key}_data" );
296
  // deleting the number = deleting the document, so also delete document settings
297
+ $order->delete_meta_data( "_wcpdf_{$this->slug}_settings" );
298
  } elseif ( $key == 'notes' ) {
299
+ $order->delete_meta_data( "_wcpdf_{$this->slug}_{$key}" );
300
  }
301
  } else {
302
  if ( $key == 'date' ) {
303
  // store dates as timestamp and formatted as mysql time
304
+ $order->update_meta_data( "_wcpdf_{$this->slug}_{$key}", $value->getTimestamp() );
305
+ $order->update_meta_data( "_wcpdf_{$this->slug}_{$key}_formatted", $value->date( 'Y-m-d H:i:s' ) );
306
  } elseif ( $key == 'number' ) {
307
  // store both formatted number and number data
308
+ $order->update_meta_data( "_wcpdf_{$this->slug}_{$key}", $value->formatted_number );
309
+ $order->update_meta_data( "_wcpdf_{$this->slug}_{$key}_data", $value->to_array() );
310
  } elseif ( $key == 'notes' ) {
311
  // store notes
312
+ $order->update_meta_data( "_wcpdf_{$this->slug}_{$key}", $value );
313
  }
314
  }
315
  }
316
 
317
+ $order->save_meta_data();
318
+
319
  do_action( 'wpo_wcpdf_save_document', $this, $order );
320
  }
321
 
333
  'number_data',
334
  'notes',
335
  ), $this );
336
+ foreach ( $data_to_remove as $data_key ) {
337
+ $order->delete_meta_data( "_wcpdf_{$this->slug}_{$data_key}" );
338
  }
339
 
340
+ $order->save_meta_data();
341
+
342
  do_action( 'wpo_wcpdf_delete_document', $this, $order );
343
  }
344
 
450
  return apply_filters( "wpo_wcpdf_{$this->slug}_title", $this->title, $this );
451
  }
452
 
453
+ public function title() {
454
+ echo esc_html( $this->get_title() );
455
+ }
456
+
457
  public function get_number_title() {
458
  /* translators: %s: document name */
459
  $number_title = sprintf( __( '%s Number:', 'woocommerce-pdf-invoices-packing-slips' ), $this->title );
500
  $datetime = $value;
501
  } elseif ( is_numeric( $value ) ) {
502
  // Timestamps are handled as UTC timestamps in all cases.
503
+ $datetime = new \WC_DateTime( "@{$value}", new \DateTimeZone( 'UTC' ) );
504
  } else {
505
  // Strings are defined in local WP timezone. Convert to UTC.
506
  if ( 1 === preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|((-|\+)\d{2}:\d{2}))$/', $value, $date_bits ) ) {
509
  } else {
510
  $timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $value ) ) ) );
511
  }
512
+ $datetime = new \WC_DateTime( "@{$timestamp}", new \DateTimeZone( 'UTC' ) );
513
  }
514
 
515
  // Set local timezone or offset.
628
  * Show logo html
629
  */
630
  public function header_logo() {
631
+ if ( $this->get_header_logo_id() ) {
632
  $attachment_id = $this->get_header_logo_id();
633
+ $company = $this->get_shop_name();
634
+
635
+ if ( $attachment_id ) {
636
+ $attachment = wp_get_attachment_image_src( $attachment_id, 'full', false );
637
  $attachment_path = get_attached_file( $attachment_id );
638
+
639
  if ( empty( $attachment ) || empty( $attachment_path ) ) {
640
  return;
641
  }
642
 
643
+ $attachment_src = $attachment[0];
644
+ $attachment_width = $attachment[1];
645
  $attachment_height = $attachment[2];
646
 
647
  if ( apply_filters( 'wpo_wcpdf_use_path', true ) && file_exists( $attachment_path ) ) {
648
  $src = $attachment_path;
649
  } else {
650
+ $head = wp_remote_head( $attachment_src, [ 'sslverify' => false ] );
651
+ if ( is_wp_error( $head ) ) {
652
+ $errors = $head->get_error_messages();
653
+ foreach ( $errors as $error ) {
654
+ wcpdf_log_error( $error, 'critical' );
655
+ }
656
+ return;
657
+ } elseif ( isset( $head['response']['code'] ) && $head['response']['code'] === 200 ) {
658
+ $src = $attachment_src;
659
+ } else {
660
+ return;
661
+ }
662
  }
663
 
664
+ $img_element = sprintf( '<img src="%1$s" alt="%2$s" />', esc_attr( $src ), esc_attr( $company ) );
665
 
666
  echo apply_filters( 'wpo_wcpdf_header_logo_img_element', $img_element, $attachment, $this );
667
  }
707
  return $this->get_settings_text( 'shop_name', $default, false );
708
  }
709
  public function shop_name() {
710
+ echo wp_kses_post( $this->get_shop_name() );
711
  }
712
 
713
  /**
717
  return $this->get_settings_text( 'shop_address' );
718
  }
719
  public function shop_address() {
720
+ echo wp_kses_post( $this->get_shop_address() );
721
  }
722
 
723
  /**
726
  public function get_footer() {
727
  ob_start();
728
  do_action( 'wpo_wcpdf_before_footer', $this->get_type(), $this->order );
729
+ echo wp_kses_post( $this->get_settings_text( 'footer' ) );
730
  do_action( 'wpo_wcpdf_after_footer', $this->get_type(), $this->order );
731
  return ob_get_clean();
732
  }
733
  public function footer() {
734
+ echo wp_kses_post( $this->get_footer() );
735
  }
736
 
737
  /**
742
 
743
  }
744
  public function extra_1() {
745
+ echo wp_kses_post( $this->get_extra_1() );
746
  }
747
 
748
  /**
752
  return $this->get_settings_text( 'extra_2' );
753
  }
754
  public function extra_2() {
755
+ echo wp_kses_post( $this->get_extra_2() );
756
  }
757
 
758
  /**
762
  return $this->get_settings_text( 'extra_3' );
763
  }
764
  public function extra_3() {
765
+ echo wp_kses_post( $this->get_extra_3() );
766
  }
767
 
768
  /*
772
  */
773
 
774
  public function get_pdf() {
775
+ // maybe we need to reinstall fonts first?
776
+ WPO_WCPDF()->main->maybe_reinstall_fonts();
777
+
778
  $pdf = null;
779
  if ( $pdf_file = apply_filters( 'wpo_wcpdf_load_pdf_file_path', null, $this ) ) {
780
  $pdf = file_get_contents( $pdf_file );
809
  }
810
 
811
  public function preview_pdf() {
812
+ // maybe we need to reinstall fonts first?
813
+ WPO_WCPDF()->main->maybe_reinstall_fonts();
814
+
815
  // get last settings
816
  $this->settings = ! empty( $this->latest_settings ) ? $this->latest_settings : $this->get_settings( true );
817
 
1007
  // get list of WooCommerce statuses
1008
  public function get_wc_order_status_list() {
1009
  $order_statuses = array();
1010
+ $statuses = function_exists('wc_get_order_statuses') ? wc_get_order_statuses() : array();
1011
+
1012
+ foreach ( $statuses as $status_slug => $status ) {
1013
+ $status_slug = 'wc-' === substr( $status_slug, 0, 3 ) ? substr( $status_slug, 3 ) : $status_slug;
1014
+ $order_statuses[$status_slug] = $status;
 
 
 
 
 
 
1015
  }
1016
+
1017
  return $order_statuses;
1018
  }
1019
 
includes/documents/class-wcpdf-bulk-document.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -86,7 +82,7 @@ class Bulk_Document {
86
  foreach ( $this->order_ids as $key => $order_id ) {
87
  do_action( 'wpo_wcpdf_process_template_order', $this->get_type(), $order_id );
88
 
89
- $order = WCX::get_order( $order_id );
90
 
91
  if ( $document = wcpdf_get_document( $this->get_type(), $order, true ) ) {
92
  $html_content[ $key ] = $document->get_html( array( 'wrap_html_content' => false ) );
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
82
  foreach ( $this->order_ids as $key => $order_id ) {
83
  do_action( 'wpo_wcpdf_process_template_order', $this->get_type(), $order_id );
84
 
85
+ $order = wc_get_order( $order_id );
86
 
87
  if ( $document = wcpdf_get_document( $this->get_type(), $order, true ) ) {
88
  $html_content[ $key ] = $document->get_html( array( 'wrap_html_content' => false ) );
includes/documents/class-wcpdf-document-number.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -88,7 +84,7 @@ class Document_Number {
88
  $this->document_type = $document->get_type();
89
  }
90
  if (!empty($order)) {
91
- $this->order_id = WCX_Order::get_id( $order );
92
  }
93
  }
94
 
@@ -116,7 +112,7 @@ class Document_Number {
116
  $number = $this->number;
117
 
118
  // get dates
119
- $order_date = WCX_Order::get_prop( $order, 'date_created' );
120
  // order date can be empty when order is being saved, fallback to current time
121
  if ( empty( $order_date ) && function_exists('wc_string_to_datetime') ) {
122
  $order_date = wc_string_to_datetime( date_i18n('Y-m-d H:i:s') );
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
84
  $this->document_type = $document->get_type();
85
  }
86
  if (!empty($order)) {
87
+ $this->order_id = $order->get_id();
88
  }
89
  }
90
 
112
  $number = $this->number;
113
 
114
  // get dates
115
+ $order_date = $order->get_date_created();
116
  // order date can be empty when order is being saved, fallback to current time
117
  if ( empty( $order_date ) && function_exists('wc_string_to_datetime') ) {
118
  $order_date = wc_string_to_datetime( date_i18n('Y-m-d H:i:s') );
includes/documents/class-wcpdf-invoice.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -62,7 +58,7 @@ class Invoice extends Order_Document_Methods {
62
  $this->save_settings();
63
 
64
  if ( isset( $this->settings['display_date'] ) && $this->settings['display_date'] == 'order_date' && !empty( $this->order ) ) {
65
- $this->set_date( WCX_Order::get_prop( $this->order, 'date_created' ) );
66
  } elseif( empty( $this->get_date() ) ) {
67
  $this->set_date( current_time( 'timestamp', true ) );
68
  }
@@ -118,7 +114,7 @@ class Invoice extends Order_Document_Methods {
118
  $suffix = (string) $this->get_number();
119
  } else {
120
  if ( empty( $this->order ) && isset( $args['order_ids'][0] ) ) {
121
- $order = WCX::get_order ( $args['order_ids'][0] );
122
  $suffix = is_callable( array( $order, 'get_order_number' ) ) ? $order->get_order_number() : '';
123
  } else {
124
  $suffix = is_callable( array( $this->order, 'get_order_number' ) ) ? $this->order->get_order_number() : '';
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
58
  $this->save_settings();
59
 
60
  if ( isset( $this->settings['display_date'] ) && $this->settings['display_date'] == 'order_date' && !empty( $this->order ) ) {
61
+ $this->set_date( $this->order->get_date_created() );
62
  } elseif( empty( $this->get_date() ) ) {
63
  $this->set_date( current_time( 'timestamp', true ) );
64
  }
114
  $suffix = (string) $this->get_number();
115
  } else {
116
  if ( empty( $this->order ) && isset( $args['order_ids'][0] ) ) {
117
+ $order = wc_get_order( $args['order_ids'][0] );
118
  $suffix = is_callable( array( $order, 'get_order_number' ) ) ? $order->get_order_number() : '';
119
  } else {
120
  $suffix = is_callable( array( $this->order, 'get_order_number' ) ) ? $this->order->get_order_number() : '';
includes/documents/class-wcpdf-packing-slip.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -51,7 +47,7 @@ class Packing_Slip extends Order_Document_Methods {
51
  $suffix = (string) $this->get_number();
52
  } else {
53
  if ( empty( $this->order ) && isset( $args['order_ids'] ) ) {
54
- $order = WCX::get_order ( $args['order_ids'][0] );
55
  $suffix = is_callable( array( $order, 'get_order_number' ) ) ? $order->get_order_number() : '';
56
  } else {
57
  $suffix = is_callable( array( $this->order, 'get_order_number' ) ) ? $this->order->get_order_number() : '';
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
47
  $suffix = (string) $this->get_number();
48
  } else {
49
  if ( empty( $this->order ) && isset( $args['order_ids'] ) ) {
50
+ $order = wc_get_order( $args['order_ids'][0] );
51
  $suffix = is_callable( array( $order, 'get_order_number' ) ) ? $order->get_order_number() : '';
52
  } else {
53
  $suffix = is_callable( array( $this->order, 'get_order_number' ) ) ? $this->order->get_order_number() : '';
includes/legacy/class-wcpdf-legacy-deprecated-hooks.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Legacy;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -25,10 +21,10 @@ class Deprecated_Hooks {
25
  public function wpo_wcpdf_invoice_number( $formatted_number, $number, $document_type, $order_id ) {
26
  if ( $document_type == 'invoice' ) {
27
  // prepare filter arguments
28
- $invoice_number = $number->get_plain();
29
- $order = WCX::get_order( $order_id );
30
- $order_number = $order->get_order_number();
31
- $order_date = WCX_Order::get_prop( $order, 'date_created' );
32
  $mysql_order_date = $order_date->date( "Y-m-d H:i:s" );
33
  // apply filter
34
  $formatted_number = apply_filters( 'wpo_wcpdf_invoice_number', $invoice_number, $order_number, $order_id, $mysql_order_date );
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Legacy;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
21
  public function wpo_wcpdf_invoice_number( $formatted_number, $number, $document_type, $order_id ) {
22
  if ( $document_type == 'invoice' ) {
23
  // prepare filter arguments
24
+ $invoice_number = $number->get_plain();
25
+ $order = wc_get_order( $order_id );
26
+ $order_number = $order->get_order_number();
27
+ $order_date = $order->get_date_created();
28
  $mysql_order_date = $order_date->date( "Y-m-d H:i:s" );
29
  // apply filter
30
  $formatted_number = apply_filters( 'wpo_wcpdf_invoice_number', $invoice_number, $order_number, $order_id, $mysql_order_date );
includes/legacy/class-wcpdf-legacy-document.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Documents;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
includes/legacy/class-wcpdf-legacy-export.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Legacy;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
@@ -70,7 +66,7 @@ class Legacy_Export {
70
  wcpdf_deprecated_function( '$wpo_wcpdf->export->get_display_number()', '2.0' );
71
  if ( empty( $this->document ) ) {
72
  // we don't know what document type we're handling, so we return the order number
73
- $order = WCX::get_order ( $order_id );
74
  $order_number = is_callable( array( $order, 'get_order_number' ) ) ? $order->get_order_number() : '';
75
  return $order_number;
76
  }
@@ -79,7 +75,7 @@ class Legacy_Export {
79
  $order_number = (string) $this->document->get_number();
80
  } else {
81
  if ( empty( $this->order ) ) {
82
- $order = WCX::get_order ( $order_ids[0] );
83
  $order_number = is_callable( array( $order, 'get_order_number' ) ) ? $order->get_order_number() : '';
84
  } else {
85
  $order_number = is_callable( array( $this->order, 'get_order_number' ) ) ? $this->order->get_order_number() : '';
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Legacy;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
66
  wcpdf_deprecated_function( '$wpo_wcpdf->export->get_display_number()', '2.0' );
67
  if ( empty( $this->document ) ) {
68
  // we don't know what document type we're handling, so we return the order number
69
+ $order = wc_get_order( $order_id );
70
  $order_number = is_callable( array( $order, 'get_order_number' ) ) ? $order->get_order_number() : '';
71
  return $order_number;
72
  }
75
  $order_number = (string) $this->document->get_number();
76
  } else {
77
  if ( empty( $this->order ) ) {
78
+ $order = wc_get_order( $order_ids[0] );
79
  $order_number = is_callable( array( $order, 'get_order_number' ) ) ? $order->get_order_number() : '';
80
  } else {
81
  $order_number = is_callable( array( $this->order, 'get_order_number' ) ) ? $this->order->get_order_number() : '';
includes/legacy/class-wcpdf-legacy-functions.php CHANGED
@@ -1,10 +1,6 @@
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Legacy;
3
 
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
  if ( ! defined( 'ABSPATH' ) ) {
9
  exit; // Exit if accessed directly
10
  }
1
  <?php
2
  namespace WPO\WC\PDF_Invoices\Legacy;
3
 
 
 
 
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit; // Exit if accessed directly
6
  }
includes/legacy/class-wcpdf-legacy-settings.php CHANGED
@@ -131,10 +131,10 @@ class Legacy_Settings {
131
 
132
  $title = $field['title'];
133
  $size = $field['size'];
134
- $description = isset( $field['description'] ) ? '<span style="font-style:italic;">'.$field['description'].'</span>' : '';
135
 
136
  echo '<tr>';
137
- printf( '<td style="padding:0 1em 0 0; ">%1$s:</td><td style="padding:0;"><input type="text" id="%2$s" name="%3$s[%2$s]" value="%4$s" size="%5$s"/></td><td style="padding:0 0 0 1em;">%6$s</td>', $title, $id, $menu, $current, $size, $description );
138
  echo '</tr>';
139
  }
140
  echo '</table>';
@@ -142,7 +142,7 @@ class Legacy_Settings {
142
 
143
  // Displays option description.
144
  if ( isset( $args['description'] ) ) {
145
- printf( '<p class="description">%s</p>', $args['description'] );
146
  }
147
 
148
  // echo $html;
131
 
132
  $title = $field['title'];
133
  $size = $field['size'];
134
+ $description = isset( $field['description'] ) ? '<span style="font-style:italic;">'.esc_html( $field['description'] ).'</span>' : '';
135
 
136
  echo '<tr>';
137
+ printf( '<td style="padding:0 1em 0 0; ">%1$s:</td><td style="padding:0;"><input type="text" id="%2$s" name="%3$s[%2$s]" value="%4$s" size="%5$s"/></td><td style="padding:0 0 0 1em;">%6$s</td>', esc_html( $title ), esc_attr( $id ), esc_attr( $menu ), esc_attr( $current ), esc_attr( $size ), esc_html( $description ) );
138
  echo '</tr>';
139
  }
140
  echo '</table>';
142
 
143
  // Displays option description.
144
  if ( isset( $args['description'] ) ) {
145
+ printf( '<p class="description">%s</p>', esc_html( $args['description'] ) );
146
  }
147
 
148
  // echo $html;
includes/views/dompdf-status.php CHANGED
@@ -128,9 +128,9 @@ if( ! $server_configs['PHP version']['result'] ) {
128
  }
129
  ?>
130
  <tr>
131
- <td class="title"><?php echo wp_kses_post( $label ); ?></td>
132
  <td><?php echo wp_kses_post( $server_config['required'] === true ? esc_html__( 'Yes', 'woocommerce-pdf-invoices-packing-slips' ) : $server_config['required'] ); ?></td>
133
- <td style="background-color:<?php echo $background; ?>; color:<?php echo $color; ?>">
134
  <?php
135
  echo wp_kses_post( $server_config['value'] );
136
  if ( $server_config['result'] && ! $server_config['value'] ) echo esc_html__( 'Yes', 'woocommerce-pdf-invoices-packing-slips' );
@@ -205,8 +205,8 @@ if( ! $server_configs['PHP version']['result'] ) {
205
  ?>
206
  <tr>
207
  <td><?php echo wp_kses_post( $permission['description'] ); ?></td>
208
- <td><?php echo str_replace( array('/','\\' ), array('/<wbr>','\\<wbr>' ), wp_kses_post( $permission['value'] ) ); ?></td>
209
- <td style="background-color:<?php echo $background; ?>; color:<?php echo $color; ?>"><?php echo wp_kses_post( $permission['status_message'] ); ?></td>
210
  </tr>
211
 
212
  <?php } ?>
128
  }
129
  ?>
130
  <tr>
131
+ <td class="title"><?php echo esc_html( $label ); ?></td>
132
  <td><?php echo wp_kses_post( $server_config['required'] === true ? esc_html__( 'Yes', 'woocommerce-pdf-invoices-packing-slips' ) : $server_config['required'] ); ?></td>
133
+ <td style="background-color:<?php echo esc_attr( $background ); ?>; color:<?php echo esc_attr( $color ); ?>">
134
  <?php
135
  echo wp_kses_post( $server_config['value'] );
136
  if ( $server_config['result'] && ! $server_config['value'] ) echo esc_html__( 'Yes', 'woocommerce-pdf-invoices-packing-slips' );
205
  ?>
206
  <tr>
207
  <td><?php echo wp_kses_post( $permission['description'] ); ?></td>
208
+ <td><?php echo str_replace( array('/','\\' ), array('/<wbr>','\\<wbr>' ), wp_kses_post( $permission['value'] ) ); ?></td>
209
+ <td style="background-color:<?php echo esc_attr( $background ); ?>; color:<?php echo esc_attr( $color ); ?>"><?php echo wp_kses_post( $permission['status_message'] ); ?></td>
210
  </tr>
211
 
212
  <?php } ?>
includes/views/setup-wizard/display-options.php CHANGED
@@ -23,7 +23,7 @@
23
  );
24
  foreach ( $options as $slug => $name ) {
25
  $selected = ( ! empty( $current_settings['display_shipping_address'] ) && $current_settings['display_shipping_address'] == $slug ) ? 'selected' : '';
26
- echo '<option value="'.$slug.'" '.$selected.'>'.$name.'</option>';
27
  }
28
  ?>
29
  </select>
@@ -62,7 +62,7 @@
62
  );
63
  foreach ( $options as $slug => $name ) {
64
  $selected = ( ! empty( $current_settings['display_date'] ) && $current_settings['display_date'] == $slug ) ? 'selected' : '';
65
- echo '<option value="'.$slug.'" '.$selected.'>'.$name.'</option>';
66
  }
67
  ?>
68
  </select>
@@ -83,7 +83,7 @@
83
  );
84
  foreach ( $options as $slug => $name ) {
85
  $selected = ( ! empty( $current_settings['display_number'] ) && $current_settings['display_number'] == $slug ) ? 'selected' : '';
86
- echo '<option value="'.$slug.'" '.$selected.'>'.$name.'</option>';
87
  }
88
  ?>
89
  </select>
23
  );
24
  foreach ( $options as $slug => $name ) {
25
  $selected = ( ! empty( $current_settings['display_shipping_address'] ) && $current_settings['display_shipping_address'] == $slug ) ? 'selected' : '';
26
+ echo '<option value="'.esc_attr( $slug ).'" '.esc_attr( $selected ).'>'.esc_html( $name ).'</option>';
27
  }
28
  ?>
29
  </select>
62
  );
63
  foreach ( $options as $slug => $name ) {
64
  $selected = ( ! empty( $current_settings['display_date'] ) && $current_settings['display_date'] == $slug ) ? 'selected' : '';
65
+ echo '<option value="'.esc_attr( $slug ).'" '.esc_attr( $selected ).'>'.esc_html( $name ).'</option>';
66
  }
67
  ?>
68
  </select>
83
  );
84
  foreach ( $options as $slug => $name ) {
85
  $selected = ( ! empty( $current_settings['display_number'] ) && $current_settings['display_number'] == $slug ) ? 'selected' : '';
86
+ echo '<option value="'.esc_attr( $slug ).'" '.esc_attr( $selected ).'>'.esc_html( $name ).'</option>';
87
  }
88
  ?>
89
  </select>
includes/views/wcpdf-settings-page.php CHANGED
@@ -44,7 +44,7 @@ $review_invitation = sprintf(
44
  $preview_states = isset( $settings_tabs[$active_tab]['preview_states'] ) ? $settings_tabs[$active_tab]['preview_states'] : 1;
45
  $preview_states_lock = $preview_states == 3 ? false : true;
46
  ?>
47
- <div id="wpo-wcpdf-preview-wrapper" data-preview-states="<?php echo $preview_states; ?>" data-preview-state="closed" data-from-preview-state="" data-preview-states-lock="<?php echo $preview_states_lock; ?>">
48
 
49
  <div class="sidebar">
50
  <form method="post" action="options.php" id="wpo-wcpdf-settings" class="<?php echo esc_attr( "{$active_tab} {$active_section}" ); ?>">
@@ -101,7 +101,7 @@ $review_invitation = sprintf(
101
  <?php
102
  if ( $document_type ) {
103
  $document = WPO_WCPDF()->documents->get_document( sanitize_text_field( $document_type ), null );
104
- echo '<p class="current"><span class="current-label">'.$document->get_title().'</span><span class="arrow-down">&#9660;</span></p>';
105
  } else {
106
  echo '<p class="current"><span class="current-label">'.__( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' ).'</span><span class="arrow-down">&#9660;</span></p>';
107
  }
44
  $preview_states = isset( $settings_tabs[$active_tab]['preview_states'] ) ? $settings_tabs[$active_tab]['preview_states'] : 1;
45
  $preview_states_lock = $preview_states == 3 ? false : true;
46
  ?>
47
+ <div id="wpo-wcpdf-preview-wrapper" data-preview-states="<?php echo esc_attr( $preview_states ); ?>" data-preview-state="closed" data-from-preview-state="" data-preview-states-lock="<?php echo esc_attr( $preview_states_lock ); ?>">
48
 
49
  <div class="sidebar">
50
  <form method="post" action="options.php" id="wpo-wcpdf-settings" class="<?php echo esc_attr( "{$active_tab} {$active_section}" ); ?>">
101
  <?php
102
  if ( $document_type ) {
103
  $document = WPO_WCPDF()->documents->get_document( sanitize_text_field( $document_type ), null );
104
+ echo '<p class="current"><span class="current-label">'.esc_html( $document->get_title() ).'</span><span class="arrow-down">&#9660;</span></p>';
105
  } else {
106
  echo '<p class="current"><span class="current-label">'.__( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' ).'</span><span class="arrow-down">&#9660;</span></p>';
107
  }
includes/wcpdf-functions.php CHANGED
@@ -3,10 +3,6 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit;
4
  }
5
 
6
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
7
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
8
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
9
-
10
  /*
11
  |--------------------------------------------------------------------------
12
  | Document getter functions
@@ -40,13 +36,13 @@ function wcpdf_get_document( $document_type, $order, $init = false ) {
40
  if ( is_object( $order ) ) {
41
  // we filter order_ids for objects too:
42
  // an order object may need to be converted to several refunds for example.
43
- $order_ids = array( WCX_Order::get_id( $order ) );
44
  $filtered_order_ids = wcpdf_filter_order_ids( $order_ids, $document_type );
45
  // check if something has changed.
46
  $order_id_diff = array_diff( $filtered_order_ids, $order_ids );
47
  if ( empty( $order_id_diff ) && count( $order_ids ) == count( $filtered_order_ids ) ) {
48
  // nothing changed, load document with Order object.
49
- do_action( 'wpo_wcpdf_process_template_order', $document_type, WCX_Order::get_id( $order ) );
50
  $document = WPO_WCPDF()->documents->get_document( $document_type, $order );
51
 
52
  if ( ! $document->is_allowed() ) {
@@ -77,7 +73,7 @@ function wcpdf_get_document( $document_type, $order, $init = false ) {
77
  if ( count( $order_ids ) == 1 ) {
78
  $order_id = array_pop( $order_ids );
79
  do_action( 'wpo_wcpdf_process_template_order', $document_type, $order_id );
80
- $order = WCX::get_order( $order_id );
81
 
82
  $document = WPO_WCPDF()->documents->get_document( $document_type, $order );
83
 
@@ -230,10 +226,10 @@ function wcpdf_output_error( $message, $level = 'error', $e = null ) {
230
  <div style="border: 2px solid red; padding: 5px;">
231
  <h3><?php echo wp_kses_post( $message ); ?></h3>
232
  <?php if ( is_callable( array( $e, 'getFile' ) ) && is_callable( array( $e, 'getLine' ) ) ): ?>
233
- <pre><?php echo $e->getFile(); ?> (<?php echo $e->getLine(); ?>)</pre>
234
  <?php endif ?>
235
  <?php if ( is_callable( array( $e, 'getTraceAsString' ) ) ) : ?>
236
- <pre><?php echo $e->getTraceAsString(); ?></pre>
237
  <?php endif ?>
238
  </div>
239
  <?php
3
  exit;
4
  }
5
 
 
 
 
 
6
  /*
7
  |--------------------------------------------------------------------------
8
  | Document getter functions
36
  if ( is_object( $order ) ) {
37
  // we filter order_ids for objects too:
38
  // an order object may need to be converted to several refunds for example.
39
+ $order_ids = array( $order->get_id() );
40
  $filtered_order_ids = wcpdf_filter_order_ids( $order_ids, $document_type );
41
  // check if something has changed.
42
  $order_id_diff = array_diff( $filtered_order_ids, $order_ids );
43
  if ( empty( $order_id_diff ) && count( $order_ids ) == count( $filtered_order_ids ) ) {
44
  // nothing changed, load document with Order object.
45
+ do_action( 'wpo_wcpdf_process_template_order', $document_type, $order->get_id() );
46
  $document = WPO_WCPDF()->documents->get_document( $document_type, $order );
47
 
48
  if ( ! $document->is_allowed() ) {
73
  if ( count( $order_ids ) == 1 ) {
74
  $order_id = array_pop( $order_ids );
75
  do_action( 'wpo_wcpdf_process_template_order', $document_type, $order_id );
76
+ $order = wc_get_order( $order_id );
77
 
78
  $document = WPO_WCPDF()->documents->get_document( $document_type, $order );
79
 
226
  <div style="border: 2px solid red; padding: 5px;">
227
  <h3><?php echo wp_kses_post( $message ); ?></h3>
228
  <?php if ( is_callable( array( $e, 'getFile' ) ) && is_callable( array( $e, 'getLine' ) ) ): ?>
229
+ <pre><?php echo esc_html( $e->getFile() ); ?> (<?php echo esc_html( $e->getLine() ); ?>)</pre>
230
  <?php endif ?>
231
  <?php if ( is_callable( array( $e, 'getTraceAsString' ) ) ) : ?>
232
+ <pre><?php echo esc_html( $e->getTraceAsString() ); ?></pre>
233
  <?php endif ?>
234
  </div>
235
  <?php
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: pomegranate, alexmigf, yordansoares, kluver, dpeyou
3
  Donate link: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
4
  Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice, packing slip, export, email, bulk, automatic
5
  Requires at least: 3.5
6
- Tested up to: 6.0
7
  Requires PHP: 7.1
8
- Stable tag: 3.2.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -42,7 +42,7 @@ In addition to a number of default settings (including a custom header/logo) and
42
 
43
  = Minimum Requirements =
44
 
45
- * WooCommerce 2.2 or later
46
  * WordPress 3.5 or later
47
 
48
  = Automatic installation =
@@ -102,6 +102,17 @@ There's a setting on the Status tab of the settings page that allows you to togg
102
 
103
  == Changelog ==
104
 
 
 
 
 
 
 
 
 
 
 
 
105
  = 3.2.1 (2022-10-06) =
106
  * Renames the plugin to comply with trademark rules
107
 
3
  Donate link: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
4
  Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice, packing slip, export, email, bulk, automatic
5
  Requires at least: 3.5
6
+ Tested up to: 6.1
7
  Requires PHP: 7.1
8
+ Stable tag: 3.2.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
42
 
43
  = Minimum Requirements =
44
 
45
+ * WooCommerce 3.0 or later
46
  * WordPress 3.5 or later
47
 
48
  = Automatic installation =
102
 
103
  == Changelog ==
104
 
105
+ = 3.2.2 (2022-10-25) =
106
+ * New: filter to allow customers to access your PDF with a unique key
107
+ * Fix: check if the shop logo exists
108
+ * Fix: check if HTML is escaped properly before echoing
109
+ * Fix: maybe reinstall fonts (if are missing) before PDF output
110
+ * Fix: bug on automatic cleanup cron job
111
+ * Fix: removes WC legacy versions compatibility classes. Bumps WC minimum version to 3.0
112
+ * Fix: allow manually resending new order email
113
+ * Fix: run action hooks within invoice columns under order list
114
+ * Marked tested up to WooCommerce 7.0
115
+
116
  = 3.2.1 (2022-10-06) =
117
  * Renames the plugin to comply with trademark rules
118
 
templates/Simple/html-document-wrapper.php CHANGED
@@ -3,7 +3,7 @@
3
  <html>
4
  <head>
5
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6
- <title><?php echo $this->get_title(); ?></title>
7
  <style type="text/css"><?php $this->template_styles(); ?></style>
8
  <style type="text/css"><?php do_action( 'wpo_wcpdf_custom_styles', $this->get_type(), $this ); ?></style>
9
  </head>
3
  <html>
4
  <head>
5
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6
+ <title><?php echo esc_html( $this->get_title() ); ?></title>
7
  <style type="text/css"><?php $this->template_styles(); ?></style>
8
  <style type="text/css"><?php do_action( 'wpo_wcpdf_custom_styles', $this->get_type(), $this ); ?></style>
9
  </head>
templates/Simple/invoice.php CHANGED
@@ -11,7 +11,7 @@
11
  $this->header_logo();
12
  do_action( 'wpo_wcpdf_after_shop_logo', $this->get_type(), $this->order );
13
  } else {
14
- echo $this->get_title();
15
  }
16
  ?>
17
  </td>
@@ -29,7 +29,7 @@
29
  <?php do_action( 'wpo_wcpdf_before_document_label', $this->get_type(), $this->order ); ?>
30
 
31
  <h1 class="document-type-label">
32
- <?php if ( $this->has_header_logo() ) echo $this->get_title(); ?>
33
  </h1>
34
 
35
  <?php do_action( 'wpo_wcpdf_after_document_label', $this->get_type(), $this->order ); ?>
@@ -64,13 +64,13 @@
64
  <?php do_action( 'wpo_wcpdf_before_order_data', $this->get_type(), $this->order ); ?>
65
  <?php if ( isset( $this->settings['display_number'] ) ) : ?>
66
  <tr class="invoice-number">
67
- <th><?php echo $this->get_number_title(); ?></th>
68
  <td><?php $this->invoice_number(); ?></td>
69
  </tr>
70
  <?php endif; ?>
71
  <?php if ( isset( $this->settings['display_date'] ) ) : ?>
72
  <tr class="invoice-date">
73
- <th><?php echo $this->get_date_title(); ?></th>
74
  <td><?php $this->invoice_date(); ?></td>
75
  </tr>
76
  <?php endif; ?>
@@ -85,7 +85,7 @@
85
  <?php if ( $payment_method = $this->get_payment_method() ) : ?>
86
  <tr class="payment-method">
87
  <th><?php _e( 'Payment Method:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
88
- <td><?php echo $payment_method; ?></td>
89
  </tr>
90
  <?php endif; ?>
91
  <?php do_action( 'wpo_wcpdf_after_order_data', $this->get_type(), $this->order ); ?>
@@ -106,21 +106,21 @@
106
  </thead>
107
  <tbody>
108
  <?php foreach ( $this->get_order_items() as $item_id => $item ) : ?>
109
- <tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', 'item-'.$item_id, $this->get_type(), $this->order, $item_id ); ?>">
110
  <td class="product">
111
  <?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
112
- <span class="item-name"><?php echo $item['name']; ?></span>
113
  <?php do_action( 'wpo_wcpdf_before_item_meta', $this->get_type(), $item, $this->order ); ?>
114
- <span class="item-meta"><?php echo $item['meta']; ?></span>
115
  <dl class="meta">
116
  <?php $description_label = __( 'SKU', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
117
- <?php if ( ! empty( $item['sku'] ) ) : ?><dt class="sku"><?php _e( 'SKU:', 'woocommerce-pdf-invoices-packing-slips' ); ?></dt><dd class="sku"><?php echo $item['sku']; ?></dd><?php endif; ?>
118
- <?php if ( ! empty( $item['weight'] ) ) : ?><dt class="weight"><?php _e( 'Weight:', 'woocommerce-pdf-invoices-packing-slips' ); ?></dt><dd class="weight"><?php echo $item['weight']; ?><?php echo get_option( 'woocommerce_weight_unit' ); ?></dd><?php endif; ?>
119
  </dl>
120
  <?php do_action( 'wpo_wcpdf_after_item_meta', $this->get_type(), $item, $this->order ); ?>
121
  </td>
122
- <td class="quantity"><?php echo $item['quantity']; ?></td>
123
- <td class="price"><?php echo $item['order_price']; ?></td>
124
  </tr>
125
  <?php endforeach; ?>
126
  </tbody>
@@ -148,9 +148,9 @@
148
  <table class="totals">
149
  <tfoot>
150
  <?php foreach ( $this->get_woocommerce_totals() as $key => $total ) : ?>
151
- <tr class="<?php echo $key; ?>">
152
- <th class="description"><?php echo $total['label']; ?></th>
153
- <td class="price"><span class="totals-price"><?php echo $total['value']; ?></span></td>
154
  </tr>
155
  <?php endforeach; ?>
156
  </tfoot>
11
  $this->header_logo();
12
  do_action( 'wpo_wcpdf_after_shop_logo', $this->get_type(), $this->order );
13
  } else {
14
+ $this->title();
15
  }
16
  ?>
17
  </td>
29
  <?php do_action( 'wpo_wcpdf_before_document_label', $this->get_type(), $this->order ); ?>
30
 
31
  <h1 class="document-type-label">
32
+ <?php if ( $this->has_header_logo() ) $this->title(); ?>
33
  </h1>
34
 
35
  <?php do_action( 'wpo_wcpdf_after_document_label', $this->get_type(), $this->order ); ?>
64
  <?php do_action( 'wpo_wcpdf_before_order_data', $this->get_type(), $this->order ); ?>
65
  <?php if ( isset( $this->settings['display_number'] ) ) : ?>
66
  <tr class="invoice-number">
67
+ <th><?php echo esc_html( $this->get_number_title() ); ?></th>
68
  <td><?php $this->invoice_number(); ?></td>
69
  </tr>
70
  <?php endif; ?>
71
  <?php if ( isset( $this->settings['display_date'] ) ) : ?>
72
  <tr class="invoice-date">
73
+ <th><?php echo esc_html( $this->get_date_title() ); ?></th>
74
  <td><?php $this->invoice_date(); ?></td>
75
  </tr>
76
  <?php endif; ?>
85
  <?php if ( $payment_method = $this->get_payment_method() ) : ?>
86
  <tr class="payment-method">
87
  <th><?php _e( 'Payment Method:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
88
+ <td><?php echo esc_html( $payment_method ); ?></td>
89
  </tr>
90
  <?php endif; ?>
91
  <?php do_action( 'wpo_wcpdf_after_order_data', $this->get_type(), $this->order ); ?>
106
  </thead>
107
  <tbody>
108
  <?php foreach ( $this->get_order_items() as $item_id => $item ) : ?>
109
+ <tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', 'item-'.$item_id, esc_attr( $this->get_type() ), $this->order, $item_id ); ?>">
110
  <td class="product">
111
  <?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
112
+ <span class="item-name"><?php echo esc_html( $item['name'] ); ?></span>
113
  <?php do_action( 'wpo_wcpdf_before_item_meta', $this->get_type(), $item, $this->order ); ?>
114
+ <span class="item-meta"><?php echo wp_kses_post( $item['meta'] ); ?></span>
115
  <dl class="meta">
116
  <?php $description_label = __( 'SKU', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
117
+ <?php if ( ! empty( $item['sku'] ) ) : ?><dt class="sku"><?php _e( 'SKU:', 'woocommerce-pdf-invoices-packing-slips' ); ?></dt><dd class="sku"><?php echo esc_attr( $item['sku'] ); ?></dd><?php endif; ?>
118
+ <?php if ( ! empty( $item['weight'] ) ) : ?><dt class="weight"><?php _e( 'Weight:', 'woocommerce-pdf-invoices-packing-slips' ); ?></dt><dd class="weight"><?php echo esc_attr( $item['weight'] ); ?><?php echo esc_attr( get_option( 'woocommerce_weight_unit' ) ); ?></dd><?php endif; ?>
119
  </dl>
120
  <?php do_action( 'wpo_wcpdf_after_item_meta', $this->get_type(), $item, $this->order ); ?>
121
  </td>
122
+ <td class="quantity"><?php echo esc_attr( $item['quantity'] ); ?></td>
123
+ <td class="price"><?php echo wp_kses_post( $item['order_price'] ); ?></td>
124
  </tr>
125
  <?php endforeach; ?>
126
  </tbody>
148
  <table class="totals">
149
  <tfoot>
150
  <?php foreach ( $this->get_woocommerce_totals() as $key => $total ) : ?>
151
+ <tr class="<?php echo esc_attr( $key ); ?>">
152
+ <th class="description"><?php echo esc_html( $total['label'] ); ?></th>
153
+ <td class="price"><span class="totals-price"><?php echo wp_kses_post( $total['value'] ); ?></span></td>
154
  </tr>
155
  <?php endforeach; ?>
156
  </tfoot>
templates/Simple/packing-slip.php CHANGED
@@ -11,7 +11,7 @@
11
  $this->header_logo();
12
  do_action( 'wpo_wcpdf_after_shop_logo', $this->get_type(), $this->order );
13
  } else {
14
- echo $this->get_title();
15
  }
16
  ?>
17
  </td>
@@ -29,7 +29,7 @@
29
  <?php do_action( 'wpo_wcpdf_before_document_label', $this->get_type(), $this->order ); ?>
30
 
31
  <h1 class="document-type-label">
32
- <?php if ( $this->has_header_logo() ) echo $this->get_title(); ?>
33
  </h1>
34
 
35
  <?php do_action( 'wpo_wcpdf_after_document_label', $this->get_type(), $this->order ); ?>
@@ -73,7 +73,7 @@
73
  <?php if ( $shipping_method = $this->get_shipping_method() ) : ?>
74
  <tr class="shipping-method">
75
  <th><?php _e( 'Shipping Method:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
76
- <td><?php echo $shipping_method; ?></td>
77
  </tr>
78
  <?php endif; ?>
79
  <?php do_action( 'wpo_wcpdf_after_order_data', $this->get_type(), $this->order ); ?>
@@ -93,20 +93,20 @@
93
  </thead>
94
  <tbody>
95
  <?php foreach ( $this->get_order_items() as $item_id => $item ) : ?>
96
- <tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', 'item-'.$item_id, $this->get_type(), $this->order, $item_id ); ?>">
97
  <td class="product">
98
  <?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
99
- <span class="item-name"><?php echo $item['name']; ?></span>
100
  <?php do_action( 'wpo_wcpdf_before_item_meta', $this->get_type(), $item, $this->order ); ?>
101
- <span class="item-meta"><?php echo $item['meta']; ?></span>
102
  <dl class="meta">
103
  <?php $description_label = __( 'SKU', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
104
- <?php if ( ! empty( $item['sku'] ) ) : ?><dt class="sku"><?php _e( 'SKU:', 'woocommerce-pdf-invoices-packing-slips' ); ?></dt><dd class="sku"><?php echo $item['sku']; ?></dd><?php endif; ?>
105
- <?php if ( ! empty( $item['weight'] ) ) : ?><dt class="weight"><?php _e( 'Weight:', 'woocommerce-pdf-invoices-packing-slips' ); ?></dt><dd class="weight"><?php echo $item['weight']; ?><?php echo get_option( 'woocommerce_weight_unit' ); ?></dd><?php endif; ?>
106
  </dl>
107
  <?php do_action( 'wpo_wcpdf_after_item_meta', $this->get_type(), $item, $this->order ); ?>
108
  </td>
109
- <td class="quantity"><?php echo $item['quantity']; ?></td>
110
  </tr>
111
  <?php endforeach; ?>
112
  </tbody>
11
  $this->header_logo();
12
  do_action( 'wpo_wcpdf_after_shop_logo', $this->get_type(), $this->order );
13
  } else {
14
+ $this->title();
15
  }
16
  ?>
17
  </td>
29
  <?php do_action( 'wpo_wcpdf_before_document_label', $this->get_type(), $this->order ); ?>
30
 
31
  <h1 class="document-type-label">
32
+ <?php if ( $this->has_header_logo() ) $this->title(); ?>
33
  </h1>
34
 
35
  <?php do_action( 'wpo_wcpdf_after_document_label', $this->get_type(), $this->order ); ?>
73
  <?php if ( $shipping_method = $this->get_shipping_method() ) : ?>
74
  <tr class="shipping-method">
75
  <th><?php _e( 'Shipping Method:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
76
+ <td><?php echo esc_html( $shipping_method ); ?></td>
77
  </tr>
78
  <?php endif; ?>
79
  <?php do_action( 'wpo_wcpdf_after_order_data', $this->get_type(), $this->order ); ?>
93
  </thead>
94
  <tbody>
95
  <?php foreach ( $this->get_order_items() as $item_id => $item ) : ?>
96
+ <tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', 'item-'.$item_id, esc_attr( $this->get_type() ), $this->order, $item_id ); ?>">
97
  <td class="product">
98
  <?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
99
+ <span class="item-name"><?php echo esc_html( $item['name'] ); ?></span>
100
  <?php do_action( 'wpo_wcpdf_before_item_meta', $this->get_type(), $item, $this->order ); ?>
101
+ <span class="item-meta"><?php echo wp_kses_post( $item['meta'] ); ?></span>
102
  <dl class="meta">
103
  <?php $description_label = __( 'SKU', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
104
+ <?php if ( ! empty( $item['sku'] ) ) : ?><dt class="sku"><?php _e( 'SKU:', 'woocommerce-pdf-invoices-packing-slips' ); ?></dt><dd class="sku"><?php echo esc_attr( $item['sku'] ); ?></dd><?php endif; ?>
105
+ <?php if ( ! empty( $item['weight'] ) ) : ?><dt class="weight"><?php _e( 'Weight:', 'woocommerce-pdf-invoices-packing-slips' ); ?></dt><dd class="weight"><?php echo esc_attr( $item['weight'] ); ?><?php echo esc_attr( get_option( 'woocommerce_weight_unit' ) ); ?></dd><?php endif; ?>
106
  </dl>
107
  <?php do_action( 'wpo_wcpdf_after_item_meta', $this->get_type(), $item, $this->order ); ?>
108
  </td>
109
+ <td class="quantity"><?php echo esc_attr( $item['quantity'] ); ?></td>
110
  </tr>
111
  <?php endforeach; ?>
112
  </tbody>
woocommerce-pdf-invoices-packingslips.php CHANGED
@@ -3,25 +3,25 @@
3
  * Plugin Name: PDF Invoices & Packing Slips for WooCommerce
4
  * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
- * Version: 3.2.1
7
  * Author: WP Overnight
8
  * Author URI: https://www.wpovernight.com
9
  * License: GPLv2 or later
10
  * License URI: https://opensource.org/licenses/gpl-license.php
11
  * Text Domain: woocommerce-pdf-invoices-packing-slips
12
- * WC requires at least: 2.2.0
13
- * WC tested up to: 6.9
14
  */
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
17
  exit; // Exit if accessed directly
18
  }
19
 
20
- if ( !class_exists( 'WPO_WCPDF' ) ) :
21
 
22
  class WPO_WCPDF {
23
 
24
- public $version = '3.2.1';
25
  public $plugin_basename;
26
  public $legacy_mode;
27
  public $legacy_textdomain;
@@ -172,14 +172,6 @@ class WPO_WCPDF {
172
  * Load the main plugin classes and functions
173
  */
174
  public function includes() {
175
- // WooCommerce compatibility classes
176
- include_once( $this->plugin_path() . '/includes/compatibility/abstract-wc-data-compatibility.php' );
177
- include_once( $this->plugin_path() . '/includes/compatibility/class-wc-date-compatibility.php' );
178
- include_once( $this->plugin_path() . '/includes/compatibility/class-wc-core-compatibility.php' );
179
- include_once( $this->plugin_path() . '/includes/compatibility/class-wc-order-compatibility.php' );
180
- include_once( $this->plugin_path() . '/includes/compatibility/class-wc-product-compatibility.php' );
181
- include_once( $this->plugin_path() . '/includes/compatibility/wc-datetime-functions-compatibility.php' );
182
-
183
  // Third party compatibility
184
  include_once( $this->plugin_path() . '/includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php' );
185
 
@@ -210,6 +202,11 @@ class WPO_WCPDF {
210
  return;
211
  }
212
 
 
 
 
 
 
213
  if ( version_compare( PHP_VERSION, '5.6', '<' ) ) {
214
  add_action( 'admin_notices', array ( $this, 'required_php_version' ) );
215
  return;
@@ -246,6 +243,29 @@ class WPO_WCPDF {
246
  return $this->legacy_textdomain;
247
  }
248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  /**
250
  * Check if woocommerce is activated
251
  */
3
  * Plugin Name: PDF Invoices & Packing Slips for WooCommerce
4
  * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
+ * Version: 3.2.2
7
  * Author: WP Overnight
8
  * Author URI: https://www.wpovernight.com
9
  * License: GPLv2 or later
10
  * License URI: https://opensource.org/licenses/gpl-license.php
11
  * Text Domain: woocommerce-pdf-invoices-packing-slips
12
+ * WC requires at least: 3.0
13
+ * WC tested up to: 7.0
14
  */
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
17
  exit; // Exit if accessed directly
18
  }
19
 
20
+ if ( ! class_exists( 'WPO_WCPDF' ) ) :
21
 
22
  class WPO_WCPDF {
23
 
24
+ public $version = '3.2.2';
25
  public $plugin_basename;
26
  public $legacy_mode;
27
  public $legacy_textdomain;
172
  * Load the main plugin classes and functions
173
  */
174
  public function includes() {
 
 
 
 
 
 
 
 
175
  // Third party compatibility
176
  include_once( $this->plugin_path() . '/includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php' );
177
 
202
  return;
203
  }
204
 
205
+ if ( $this->is_woocommerce_version_supported() === false ) {
206
+ add_action( 'admin_notices', array ( $this, 'need_woocommerce_3_0' ) );
207
+ return;
208
+ }
209
+
210
  if ( version_compare( PHP_VERSION, '5.6', '<' ) ) {
211
  add_action( 'admin_notices', array ( $this, 'required_php_version' ) );
212
  return;
243
  return $this->legacy_textdomain;
244
  }
245
 
246
+ /**
247
+ * Check if woocommerce version is supported
248
+ */
249
+ public function is_woocommerce_version_supported() {
250
+ if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.0', '>=' ) ) {
251
+ return true;
252
+ } else {
253
+ return false;
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Woocommerce version < 3.0 notice
259
+ */
260
+ public function need_woocommerce_3_0() {
261
+ /* translators: <a> tags */
262
+ $error = sprintf( esc_html__( 'PDF Invoices & Packing Slips for WooCommerce requires %1$sWooCommerce%2$s version 3.0 or higher!' , 'woocommerce-pdf-invoices-packing-slips' ), '<a href="http://wordpress.org/extend/plugins/woocommerce/">', '</a>' );
263
+
264
+ $message = '<div class="error"><p>' . $error . '</p></div>';
265
+
266
+ echo $message;
267
+ }
268
+
269
  /**
270
  * Check if woocommerce is activated
271
  */