WooCommerce PDF Invoices & Packing Slips - Version 2.3.5

Version Description

  • Feature: Accept single order ID for wcpdf_get_document function
  • Feature: Filter to change number store for invoice
  • Tweak: Always prefer WC() function over global for WC3.0+
  • Fix: Incorrectly stored attachment settings couldn't be reset
  • Fix: Prevent error notices during setup wizard
  • Tested up to WooCommerce 3.8
Download this release

Release Info

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

Code changes from version 2.3.4 to 2.3.5

assets/css/settings-styles.css CHANGED
@@ -1,148 +1,148 @@
1
- span.wpo-warning {
2
- display: inline-block;
3
- border: 1px solid red;
4
- border-left: 4px solid red;
5
- padding: 5px 15px;
6
- background-color: white;
7
- }
8
- .wcpdf-extensions-ad {
9
- position: relative;
10
- min-height: 90px;
11
- border: 1px solid #3D5C99;
12
- background-color: #EBF5FF;
13
- border-radius: 5px;
14
- padding: 15px;
15
- padding-left: 100px;
16
- margin-top: 15px;
17
- }
18
-
19
- img.wpo-helper {
20
- position: absolute;
21
- top: -20px;
22
- left: 3px;
23
- }
24
-
25
- .wcpdf-extensions-ad h3 {
26
- margin: 0;
27
- }
28
-
29
- .wcpdf-extensions-ad ul {
30
- margin: 0;
31
- margin-left: 1.5em;
32
- }
33
-
34
- .extensions li {
35
- margin: 0;
36
- }
37
-
38
- .extensions li ul {
39
- list-style-type: square;
40
- margin-top: 0.5em;
41
- margin-bottom: 0.5em;
42
- }
43
-
44
- .extensions > li:before {
45
- content: "";
46
- border-color: transparent transparent transparent #111;
47
- border-style: solid;
48
- border-width: 0.35em 0.35em 0.35em 0.45em;
49
- display: block;
50
- height: 0;
51
- width: 0;
52
- left: -1em;
53
- top: 0.9em;
54
- position: relative;
55
- }
56
-
57
- .extensions li:not(.expanded) {
58
- cursor:pointer;
59
- }
60
-
61
- .extensions .expanded:before {
62
- border-color: #111 transparent transparent transparent;
63
- left: -1.17em;
64
- border-width: 0.45em 0.45em 0.35em 0.35em !important;
65
- }
66
-
67
- .extensions .more {
68
- padding: 10px;
69
- background-color: white;
70
- border: 1px solid #ccc;
71
- border-radius: 5px;
72
- }
73
-
74
- .extensions table td {
75
- vertical-align: top;
76
- }
77
-
78
- .dropbox-logo {
79
- margin-bottom: -10px;
80
- margin-right: 10px;
81
- }
82
- .cloud-logo {
83
- margin-bottom: -10px;
84
- margin-top: -5px;
85
- margin-right: 10px;
86
- }
87
-
88
- #img-header_logo {
89
- max-height: 200px;
90
- width: auto;
91
- }
92
-
93
- .multiple-text-input label {
94
- min-width: 120px;
95
- display: inline-block;
96
- }
97
-
98
- table.wcpdf_documents_settings_list {
99
- width: 100%;
100
- border-collapse: collapse;
101
- border-spacing: 0;
102
- background-color: white;
103
- border-top: 2px solid black;
104
- }
105
- table.wcpdf_documents_settings_list tr.odd {
106
- background-color: #EBF5FF;
107
- }
108
-
109
- table.wcpdf_documents_settings_list td {
110
- padding: 5px;
111
- }
112
-
113
- table.wcpdf_documents_settings_list a {
114
- text-decoration: none;
115
- }
116
-
117
- table.wcpdf_documents_settings_list td.settings-icon {
118
- text-align: right;
119
- }
120
-
121
- table.wcpdf_documents_settings_list td.title {
122
- font-weight: bold;
123
- }
124
-
125
- .wcpdf_document_settings_sections {
126
- margin-top: 10px;
127
- font-size: 120%;
128
- }
129
- .wcpdf_document_settings_sections li,
130
- .wcpdf_document_settings_sections ul {
131
- display: inline;
132
- }
133
- .wcpdf_document_settings_sections li + li:before {
134
- content: " | ";
135
- }
136
- .wcpdf_document_settings_sections a.active {
137
- text-decoration: none;
138
- font-weight: bold;
139
- color: black;
140
- }
141
-
142
- .edit-next-number {
143
- opacity:0.5;
144
- }
145
- .edit-next-number:hover {
146
- opacity:1;
147
- cursor:pointer;
148
- }
1
+ span.wpo-warning {
2
+ display: inline-block;
3
+ border: 1px solid red;
4
+ border-left: 4px solid red;
5
+ padding: 5px 15px;
6
+ background-color: white;
7
+ }
8
+ .wcpdf-extensions-ad {
9
+ position: relative;
10
+ min-height: 90px;
11
+ border: 1px solid #3D5C99;
12
+ background-color: #EBF5FF;
13
+ border-radius: 5px;
14
+ padding: 15px;
15
+ padding-left: 100px;
16
+ margin-top: 15px;
17
+ }
18
+
19
+ img.wpo-helper {
20
+ position: absolute;
21
+ bottom: 0px;
22
+ left: 3px;
23
+ }
24
+
25
+ .wcpdf-extensions-ad h3 {
26
+ margin: 0;
27
+ }
28
+
29
+ .wcpdf-extensions-ad ul {
30
+ margin: 0;
31
+ margin-left: 1.5em;
32
+ }
33
+
34
+ .extensions li {
35
+ margin: 0;
36
+ }
37
+
38
+ .extensions li ul {
39
+ list-style-type: square;
40
+ margin-top: 0.5em;
41
+ margin-bottom: 0.5em;
42
+ }
43
+
44
+ .extensions > li:before {
45
+ content: "";
46
+ border-color: transparent transparent transparent #111;
47
+ border-style: solid;
48
+ border-width: 0.35em 0.35em 0.35em 0.45em;
49
+ display: block;
50
+ height: 0;
51
+ width: 0;
52
+ left: -1em;
53
+ top: 0.9em;
54
+ position: relative;
55
+ }
56
+
57
+ .extensions li:not(.expanded) {
58
+ cursor:pointer;
59
+ }
60
+
61
+ .extensions .expanded:before {
62
+ border-color: #111 transparent transparent transparent;
63
+ left: -1.17em;
64
+ border-width: 0.45em 0.45em 0.35em 0.35em !important;
65
+ }
66
+
67
+ .extensions .more {
68
+ padding: 10px;
69
+ background-color: white;
70
+ border: 1px solid #ccc;
71
+ border-radius: 5px;
72
+ }
73
+
74
+ .extensions table td {
75
+ vertical-align: top;
76
+ }
77
+
78
+ .dropbox-logo {
79
+ margin-bottom: -10px;
80
+ margin-right: 10px;
81
+ }
82
+ .cloud-logo {
83
+ margin-bottom: -10px;
84
+ margin-top: -5px;
85
+ margin-right: 10px;
86
+ }
87
+
88
+ #img-header_logo {
89
+ max-height: 200px;
90
+ width: auto;
91
+ }
92
+
93
+ .multiple-text-input label {
94
+ min-width: 120px;
95
+ display: inline-block;
96
+ }
97
+
98
+ table.wcpdf_documents_settings_list {
99
+ width: 100%;
100
+ border-collapse: collapse;
101
+ border-spacing: 0;
102
+ background-color: white;
103
+ border-top: 2px solid black;
104
+ }
105
+ table.wcpdf_documents_settings_list tr.odd {
106
+ background-color: #EBF5FF;
107
+ }
108
+
109
+ table.wcpdf_documents_settings_list td {
110
+ padding: 5px;
111
+ }
112
+
113
+ table.wcpdf_documents_settings_list a {
114
+ text-decoration: none;
115
+ }
116
+
117
+ table.wcpdf_documents_settings_list td.settings-icon {
118
+ text-align: right;
119
+ }
120
+
121
+ table.wcpdf_documents_settings_list td.title {
122
+ font-weight: bold;
123
+ }
124
+
125
+ .wcpdf_document_settings_sections {
126
+ margin-top: 10px;
127
+ font-size: 120%;
128
+ }
129
+ .wcpdf_document_settings_sections li,
130
+ .wcpdf_document_settings_sections ul {
131
+ display: inline;
132
+ }
133
+ .wcpdf_document_settings_sections li + li:before {
134
+ content: " | ";
135
+ }
136
+ .wcpdf_document_settings_sections a.active {
137
+ text-decoration: none;
138
+ font-weight: bold;
139
+ color: black;
140
+ }
141
+
142
+ .edit-next-number {
143
+ opacity:0.5;
144
+ }
145
+ .edit-next-number:hover {
146
+ opacity:1;
147
+ cursor:pointer;
148
+ }
assets/images/wpo-helper.png CHANGED
Binary file
includes/documents/abstract-wcpdf-order-document-methods.php CHANGED
@@ -736,8 +736,6 @@ abstract class Order_Document_Methods extends Order_Document {
736
  * @return string
737
  */
738
  public function get_thumbnail_id ( $product ) {
739
- global $woocommerce;
740
-
741
  $product_id = WCX_Product::get_id( $product );
742
 
743
  if ( has_post_thumbnail( $product_id ) ) {
736
  * @return string
737
  */
738
  public function get_thumbnail_id ( $product ) {
 
 
739
  $product_id = WCX_Product::get_id( $product );
740
 
741
  if ( has_post_thumbnail( $product_id ) ) {
includes/documents/abstract-wcpdf-order-document.php CHANGED
@@ -166,6 +166,7 @@ abstract class Order_Document {
166
  $non_historical_settings = apply_filters( 'wpo_wcpdf_non_historical_settings', array(
167
  'enabled',
168
  'attach_to_email_ids',
 
169
  'number_format', // this is stored in the number data already!
170
  'my_account_buttons',
171
  'my_account_restrict',
@@ -182,7 +183,7 @@ abstract class Order_Document {
182
  }
183
 
184
  public function get_attach_to_email_ids() {
185
- $email_ids = isset( $this->settings['attach_to_email_ids'] ) ? array_keys( $this->settings['attach_to_email_ids'] ) : array();
186
  return $email_ids;
187
  }
188
 
@@ -743,8 +744,12 @@ abstract class Order_Document {
743
  */
744
  public function get_wc_emails() {
745
  // get emails from WooCommerce
746
- global $woocommerce;
747
- $mailer = $woocommerce->mailer();
 
 
 
 
748
  $wc_emails = $mailer->get_emails();
749
 
750
  $non_order_emails = array(
166
  $non_historical_settings = apply_filters( 'wpo_wcpdf_non_historical_settings', array(
167
  'enabled',
168
  'attach_to_email_ids',
169
+ 'disable_for_statuses',
170
  'number_format', // this is stored in the number data already!
171
  'my_account_buttons',
172
  'my_account_restrict',
183
  }
184
 
185
  public function get_attach_to_email_ids() {
186
+ $email_ids = isset( $this->settings['attach_to_email_ids'] ) ? array_keys( array_filter( $this->settings['attach_to_email_ids'] ) ) : array();
187
  return $email_ids;
188
  }
189
 
744
  */
745
  public function get_wc_emails() {
746
  // get emails from WooCommerce
747
+ if (function_exists('WC')) {
748
+ $mailer = WC()->mailer();
749
+ } else {
750
+ global $woocommerce;
751
+ $mailer = $woocommerce->mailer();
752
+ }
753
  $wc_emails = $mailer->get_emails();
754
 
755
  $non_order_emails = array(
includes/documents/class-wcpdf-invoice.php CHANGED
@@ -93,7 +93,8 @@ class Invoice extends Order_Document_Methods {
93
  }
94
 
95
  $number_store_method = WPO_WCPDF()->settings->get_sequential_number_store_method();
96
- $number_store = new Sequential_Number_Store( 'invoice_number', $number_store_method );
 
97
  // reset invoice number yearly
98
  if ( isset( $this->settings['reset_number_yearly'] ) ) {
99
  $current_year = date("Y");
93
  }
94
 
95
  $number_store_method = WPO_WCPDF()->settings->get_sequential_number_store_method();
96
+ $number_store_name = apply_filters( 'wpo_wcpdf_document_sequential_number_store', 'invoice_number', $this );
97
+ $number_store = new Sequential_Number_Store( $number_store_name, $number_store_method );
98
  // reset invoice number yearly
99
  if ( isset( $this->settings['reset_number_yearly'] ) ) {
100
  $current_year = date("Y");
includes/views/setup-wizard/show-action-buttons.php CHANGED
@@ -6,8 +6,14 @@
6
  </div>
7
  <div class="wpo-setup-input">
8
  <?php
 
9
  $user_id = get_current_user_id();
10
  $hidden = get_user_meta( $user_id, 'manageedit-shop_ordercolumnshidden', true );
 
 
 
 
 
11
  ?>
12
- <input type="checkbox" <?php echo !in_array( 'wc_actions', $hidden ) ? 'checked' : ''; ?> name="wc_show_action_buttons" value="1"><span class="checkbox"><?php _e( 'Show action buttons', 'woocommerce-pdf-invoices-packing-slips' ); ?></span><br>
13
  </div>
6
  </div>
7
  <div class="wpo-setup-input">
8
  <?php
9
+ $actions = true;
10
  $user_id = get_current_user_id();
11
  $hidden = get_user_meta( $user_id, 'manageedit-shop_ordercolumnshidden', true );
12
+ if ( empty( $hidden ) )
13
+ $hidden = array( 'shipping_address', 'billing_address', 'wc_actions' );
14
+ update_user_option( $user_id, 'manageedit-shop_ordercolumnshidden', $hidden, true );
15
+ if ( in_array( 'wc_actions', $hidden ) )
16
+ $actions = false
17
  ?>
18
+ <input type="checkbox" <?php echo $actions !== false ? 'checked' : ''; ?> name="wc_show_action_buttons" value="1"><span class="checkbox"><?php _e( 'Show action buttons', 'woocommerce-pdf-invoices-packing-slips' ); ?></span><br>
19
  </div>
includes/wcpdf-functions.php CHANGED
@@ -1,216 +1,219 @@
1
- <?php
2
- 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
13
- |--------------------------------------------------------------------------
14
- |
15
- | Global functions to get the document object for an order
16
- |
17
- */
18
-
19
- function wcpdf_filter_order_ids( $order_ids, $document_type ) {
20
- $order_ids = apply_filters( 'wpo_wcpdf_process_order_ids', $order_ids, $document_type );
21
- // filter out trashed orders
22
- foreach ( $order_ids as $key => $order_id ) {
23
- $order_status = get_post_status( $order_id );
24
- if ( $order_status == 'trash' ) {
25
- unset( $order_ids[ $key ] );
26
- }
27
- }
28
- return $order_ids;
29
- }
30
-
31
- function wcpdf_get_document( $document_type, $order, $init = false ) {
32
- // $order can be one of the following:
33
- // - WC Order object
34
- // - array of order ids
35
- // - null if order not loaded or loaded later
36
- if ( !empty( $order ) ) {
37
- if ( is_object( $order ) ) {
38
- // we filter order_ids for objects too:
39
- // an order object may need to be converted to several refunds for example
40
- $order_ids = array( WCX_Order::get_id( $order ) );
41
- $filtered_order_ids = wcpdf_filter_order_ids( $order_ids, $document_type );
42
- // check if something has changed
43
- $order_id_diff = array_diff( $filtered_order_ids, $order_ids );
44
- if ( empty( $order_id_diff ) && count( $order_ids ) == count( $filtered_order_ids ) ) {
45
- // nothing changed, load document with Order object
46
- do_action( 'wpo_wcpdf_process_template_order', $document_type, WCX_Order::get_id( $order ) );
47
- $document = WPO_WCPDF()->documents->get_document( $document_type, $order );
48
-
49
- if ( !$document->is_allowed() ) {
50
- return false;
51
- }
52
-
53
- if ( $init && !$document->exists() ) {
54
- $document->init();
55
- $document->save();
56
- }
57
- return $document;
58
- } else {
59
- // order ids array changed, continue processing that array
60
- $order_ids = $filtered_order_ids;
61
- }
62
- } elseif ( is_array( $order ) ) {
63
- $order_ids = wcpdf_filter_order_ids( $order, $document_type );
64
- } else {
65
- return false;
66
- }
67
-
68
- if ( empty( $order_ids ) ) {
69
- // No orders to export for this document type
70
- return false;
71
- }
72
-
73
- // if we only have one order, it's simple
74
- if ( count( $order_ids ) == 1 ) {
75
- $order_id = array_pop ( $order_ids );
76
- do_action( 'wpo_wcpdf_process_template_order', $document_type, $order_id );
77
- $order = WCX::get_order( $order_id );
78
-
79
- $document = WPO_WCPDF()->documents->get_document( $document_type, $order );
80
-
81
- if ( !$document->is_allowed() ) {
82
- return false;
83
- }
84
-
85
- if ( $init && !$document->exists() ) {
86
- $document->init();
87
- $document->save();
88
- }
89
- // otherwise we use bulk class to wrap multiple documents in one
90
- } else {
91
- $document = wcpdf_get_bulk_document( $document_type, $order_ids );
92
- }
93
- } else {
94
- // orderless document (used as wrapper for bulk, for example)
95
- $document = WPO_WCPDF()->documents->get_document( $document_type, $order );
96
- }
97
-
98
- return $document;
99
- }
100
-
101
- function wcpdf_get_bulk_document( $document_type, $order_ids ) {
102
- return new \WPO\WC\PDF_Invoices\Documents\Bulk_Document( $document_type, $order_ids );
103
- }
104
-
105
- function wcpdf_get_invoice( $order, $init = false ) {
106
- return wcpdf_get_document( 'invoice', $order, $init );
107
- }
108
-
109
- function wcpdf_get_packing_slip( $order, $init = false ) {
110
- return wcpdf_get_document( 'packing-slip', $order, $init );
111
- }
112
-
113
- /**
114
- * Load HTML into (pluggable) PDF library, DomPDF 0.6 by default
115
- * Use wpo_wcpdf_pdf_maker filter to change the PDF class (which can wrap another PDF library).
116
- * @return PDF_Maker
117
- */
118
- function wcpdf_get_pdf_maker( $html, $settings = array() ) {
119
- if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\PDF_Maker' ) ) {
120
- include_once( WPO_WCPDF()->plugin_path() . '/includes/class-wcpdf-pdf-maker.php' );
121
- }
122
- $class = apply_filters( 'wpo_wcpdf_pdf_maker', '\\WPO\\WC\\PDF_Invoices\\PDF_Maker' );
123
- return new $class( $html, $settings );
124
- }
125
-
126
- function wcpdf_pdf_headers( $filename, $mode = 'inline', $pdf = null ) {
127
- switch ($mode) {
128
- case 'download':
129
- header('Content-Description: File Transfer');
130
- header('Content-Type: application/pdf');
131
- header('Content-Disposition: attachment; filename="'.$filename.'"');
132
- header('Content-Transfer-Encoding: binary');
133
- header('Connection: Keep-Alive');
134
- header('Expires: 0');
135
- header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
136
- header('Pragma: public');
137
- break;
138
- case 'inline':
139
- default:
140
- header('Content-type: application/pdf');
141
- header('Content-Disposition: inline; filename="'.$filename.'"');
142
- break;
143
- }
144
- }
145
-
146
- /**
147
- * Wrapper for deprecated functions so we can apply some extra logic.
148
- *
149
- * @since 2.0
150
- * @param string $function
151
- * @param string $version
152
- * @param string $replacement
153
- */
154
- function wcpdf_deprecated_function( $function, $version, $replacement = null ) {
155
- if ( apply_filters( 'wcpdf_disable_deprecation_notices', false ) ) {
156
- return;
157
- }
158
- // if the deprecated function is called from one of our filters, $this should be $document
159
- $filter = current_filter();
160
- $global_wcpdf_filters = array( 'wp_ajax_generate_wpo_wcpdf' );
161
- if ( !in_array($filter, $global_wcpdf_filters) && strpos($filter, 'wpo_wcpdf') !== false && strpos($replacement, '$this') !== false ) {
162
- $replacement = str_replace('$this', '$document', $replacement);
163
- $replacement = "{$replacement} - check that the \$document parameter is included in your action or filter ($filter)!";
164
- }
165
- if ( is_ajax() ) {
166
- do_action( 'deprecated_function_run', $function, $replacement, $version );
167
- $log_string = "The {$function} function is deprecated since version {$version}.";
168
- $log_string .= $replacement ? " Replace with {$replacement}." : '';
169
- error_log( $log_string );
170
- wcpdf_log_error( $log_string, 'warning' );
171
- } else {
172
- _deprecated_function( $function, $version, $replacement );
173
- }
174
- }
175
-
176
- /**
177
- * Logger function to capture errors thrown by this plugin, uses the WC Logger when possible (WC3.0+)
178
- */
179
- function wcpdf_log_error( $message, $level = 'error', $e = null ) {
180
- if (function_exists('wc_get_logger')) {
181
- $logger = wc_get_logger();
182
- $context = array( 'source' => 'wpo-wcpdf' );
183
-
184
- if ( apply_filters( 'wcpdf_log_stacktrace', false ) && !empty($e) && is_callable( array( $e, 'getTraceAsString') ) ) {
185
- $message .= "\n".$e->getTraceAsString();
186
- }
187
-
188
- // The `log` method accepts any valid level as its first argument.
189
- // debug - 'Detailed debug information'
190
- // info - 'Interesting events'
191
- // notice - 'Normal but significant events'
192
- // warning - 'Exceptional occurrences that are not errors'
193
- // error - 'Runtime errors that do not require immediate'
194
- // critical - 'Critical conditions'
195
- // alert - 'Action must be taken immediately'
196
- // emergency - 'System is unusable'
197
- $logger->log( $level, $message, $context );
198
- } else {
199
- error_log( "WCPDF error ({$level}): {$message}" );
200
- }
201
- }
202
-
203
- function wcpdf_output_error( $message, $level = 'error', $e = null ) {
204
- if ( !current_user_can( 'edit_shop_orders' ) ) {
205
- _e( 'Error creating PDF, please contact the site owner.', 'woocommerce-pdf-invoices-packing-slips' );
206
- return;
207
- }
208
- ?>
209
- <div style="border: 2px solid red; padding: 5px;">
210
- <h3><?php echo $message; ?></h3>
211
- <?php if ( !empty($e) && is_callable( array( $e, 'getTraceAsString') ) ): ?>
212
- <pre><?php echo $e->getTraceAsString(); ?></pre>
213
- <?php endif ?>
214
- </div>
215
- <?php
 
 
 
216
  }
1
+ <?php
2
+ 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
13
+ |--------------------------------------------------------------------------
14
+ |
15
+ | Global functions to get the document object for an order
16
+ |
17
+ */
18
+
19
+ function wcpdf_filter_order_ids( $order_ids, $document_type ) {
20
+ $order_ids = apply_filters( 'wpo_wcpdf_process_order_ids', $order_ids, $document_type );
21
+ // filter out trashed orders
22
+ foreach ( $order_ids as $key => $order_id ) {
23
+ $order_status = get_post_status( $order_id );
24
+ if ( $order_status == 'trash' ) {
25
+ unset( $order_ids[ $key ] );
26
+ }
27
+ }
28
+ return $order_ids;
29
+ }
30
+
31
+ function wcpdf_get_document( $document_type, $order, $init = false ) {
32
+ // $order can be one of the following:
33
+ // - WC Order object
34
+ // - array of order ids
35
+ // - null if order not loaded or loaded later
36
+ if ( !empty( $order ) ) {
37
+ if ( !is_object( $order) && !is_array( $order ) && is_numeric( $order ) ) {
38
+ $order = array( absint( $order ) ); // convert single order id to array.
39
+ }
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() ) {
53
+ return false;
54
+ }
55
+
56
+ if ( $init && !$document->exists() ) {
57
+ $document->init();
58
+ $document->save();
59
+ }
60
+ return $document;
61
+ } else {
62
+ // order ids array changed, continue processing that array
63
+ $order_ids = $filtered_order_ids;
64
+ }
65
+ } elseif ( is_array( $order ) ) {
66
+ $order_ids = wcpdf_filter_order_ids( $order, $document_type );
67
+ } else {
68
+ return false;
69
+ }
70
+
71
+ if ( empty( $order_ids ) ) {
72
+ // No orders to export for this document type
73
+ return false;
74
+ }
75
+
76
+ // if we only have one order, it's simple
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
+
84
+ if ( !$document->is_allowed() ) {
85
+ return false;
86
+ }
87
+
88
+ if ( $init && !$document->exists() ) {
89
+ $document->init();
90
+ $document->save();
91
+ }
92
+ // otherwise we use bulk class to wrap multiple documents in one
93
+ } else {
94
+ $document = wcpdf_get_bulk_document( $document_type, $order_ids );
95
+ }
96
+ } else {
97
+ // orderless document (used as wrapper for bulk, for example)
98
+ $document = WPO_WCPDF()->documents->get_document( $document_type, $order );
99
+ }
100
+
101
+ return $document;
102
+ }
103
+
104
+ function wcpdf_get_bulk_document( $document_type, $order_ids ) {
105
+ return new \WPO\WC\PDF_Invoices\Documents\Bulk_Document( $document_type, $order_ids );
106
+ }
107
+
108
+ function wcpdf_get_invoice( $order, $init = false ) {
109
+ return wcpdf_get_document( 'invoice', $order, $init );
110
+ }
111
+
112
+ function wcpdf_get_packing_slip( $order, $init = false ) {
113
+ return wcpdf_get_document( 'packing-slip', $order, $init );
114
+ }
115
+
116
+ /**
117
+ * Load HTML into (pluggable) PDF library, DomPDF 0.6 by default
118
+ * Use wpo_wcpdf_pdf_maker filter to change the PDF class (which can wrap another PDF library).
119
+ * @return PDF_Maker
120
+ */
121
+ function wcpdf_get_pdf_maker( $html, $settings = array() ) {
122
+ if ( ! class_exists( '\\WPO\\WC\\PDF_Invoices\\PDF_Maker' ) ) {
123
+ include_once( WPO_WCPDF()->plugin_path() . '/includes/class-wcpdf-pdf-maker.php' );
124
+ }
125
+ $class = apply_filters( 'wpo_wcpdf_pdf_maker', '\\WPO\\WC\\PDF_Invoices\\PDF_Maker' );
126
+ return new $class( $html, $settings );
127
+ }
128
+
129
+ function wcpdf_pdf_headers( $filename, $mode = 'inline', $pdf = null ) {
130
+ switch ($mode) {
131
+ case 'download':
132
+ header('Content-Description: File Transfer');
133
+ header('Content-Type: application/pdf');
134
+ header('Content-Disposition: attachment; filename="'.$filename.'"');
135
+ header('Content-Transfer-Encoding: binary');
136
+ header('Connection: Keep-Alive');
137
+ header('Expires: 0');
138
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
139
+ header('Pragma: public');
140
+ break;
141
+ case 'inline':
142
+ default:
143
+ header('Content-type: application/pdf');
144
+ header('Content-Disposition: inline; filename="'.$filename.'"');
145
+ break;
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Wrapper for deprecated functions so we can apply some extra logic.
151
+ *
152
+ * @since 2.0
153
+ * @param string $function
154
+ * @param string $version
155
+ * @param string $replacement
156
+ */
157
+ function wcpdf_deprecated_function( $function, $version, $replacement = null ) {
158
+ if ( apply_filters( 'wcpdf_disable_deprecation_notices', false ) ) {
159
+ return;
160
+ }
161
+ // if the deprecated function is called from one of our filters, $this should be $document
162
+ $filter = current_filter();
163
+ $global_wcpdf_filters = array( 'wp_ajax_generate_wpo_wcpdf' );
164
+ if ( !in_array($filter, $global_wcpdf_filters) && strpos($filter, 'wpo_wcpdf') !== false && strpos($replacement, '$this') !== false ) {
165
+ $replacement = str_replace('$this', '$document', $replacement);
166
+ $replacement = "{$replacement} - check that the \$document parameter is included in your action or filter ($filter)!";
167
+ }
168
+ if ( is_ajax() ) {
169
+ do_action( 'deprecated_function_run', $function, $replacement, $version );
170
+ $log_string = "The {$function} function is deprecated since version {$version}.";
171
+ $log_string .= $replacement ? " Replace with {$replacement}." : '';
172
+ error_log( $log_string );
173
+ wcpdf_log_error( $log_string, 'warning' );
174
+ } else {
175
+ _deprecated_function( $function, $version, $replacement );
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Logger function to capture errors thrown by this plugin, uses the WC Logger when possible (WC3.0+)
181
+ */
182
+ function wcpdf_log_error( $message, $level = 'error', $e = null ) {
183
+ if (function_exists('wc_get_logger')) {
184
+ $logger = wc_get_logger();
185
+ $context = array( 'source' => 'wpo-wcpdf' );
186
+
187
+ if ( apply_filters( 'wcpdf_log_stacktrace', false ) && !empty($e) && is_callable( array( $e, 'getTraceAsString') ) ) {
188
+ $message .= "\n".$e->getTraceAsString();
189
+ }
190
+
191
+ // The `log` method accepts any valid level as its first argument.
192
+ // debug - 'Detailed debug information'
193
+ // info - 'Interesting events'
194
+ // notice - 'Normal but significant events'
195
+ // warning - 'Exceptional occurrences that are not errors'
196
+ // error - 'Runtime errors that do not require immediate'
197
+ // critical - 'Critical conditions'
198
+ // alert - 'Action must be taken immediately'
199
+ // emergency - 'System is unusable'
200
+ $logger->log( $level, $message, $context );
201
+ } else {
202
+ error_log( "WCPDF error ({$level}): {$message}" );
203
+ }
204
+ }
205
+
206
+ function wcpdf_output_error( $message, $level = 'error', $e = null ) {
207
+ if ( !current_user_can( 'edit_shop_orders' ) ) {
208
+ _e( 'Error creating PDF, please contact the site owner.', 'woocommerce-pdf-invoices-packing-slips' );
209
+ return;
210
+ }
211
+ ?>
212
+ <div style="border: 2px solid red; padding: 5px;">
213
+ <h3><?php echo $message; ?></h3>
214
+ <?php if ( !empty($e) && is_callable( array( $e, 'getTraceAsString') ) ): ?>
215
+ <pre><?php echo $e->getTraceAsString(); ?></pre>
216
+ <?php endif ?>
217
+ </div>
218
+ <?php
219
  }
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: pomegranate
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: 5.2
7
  Requires PHP: 5.3
8
- Stable tag: 2.3.4
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -102,6 +102,14 @@ There's a setting on the Status tab of the settings page that allows you to togg
102
 
103
  == Changelog ==
104
 
 
 
 
 
 
 
 
 
105
  = 2.3.4 =
106
  * Fix: Prevent duplicate invoice numbers for multiple attachment setups
107
  * Fix: Apply email order filter for each email separately
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: 5.3
7
  Requires PHP: 5.3
8
+ Stable tag: 2.3.5
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
102
 
103
  == Changelog ==
104
 
105
+ = 2.3.5 =
106
+ * Feature: Accept single order ID for wcpdf_get_document function
107
+ * Feature: Filter to change number store for invoice
108
+ * Tweak: Always prefer WC() function over global for WC3.0+
109
+ * Fix: Incorrectly stored attachment settings couldn't be reset
110
+ * Fix: Prevent error notices during setup wizard
111
+ * Tested up to WooCommerce 3.8
112
+
113
  = 2.3.4 =
114
  * Fix: Prevent duplicate invoice numbers for multiple attachment setups
115
  * Fix: Apply email order filter for each email separately
woocommerce-pdf-invoices-packingslips.php CHANGED
@@ -3,14 +3,14 @@
3
  * Plugin Name: WooCommerce PDF Invoices & Packing Slips
4
  * Plugin URI: http://www.wpovernight.com
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
- * Version: 2.3.4
7
  * Author: Ewout Fernhout
8
  * Author URI: http://www.wpovernight.com
9
  * License: GPLv2 or later
10
  * License URI: http://www.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: 3.7.0
14
  */
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
@@ -21,7 +21,7 @@ if ( !class_exists( 'WPO_WCPDF' ) ) :
21
 
22
  class WPO_WCPDF {
23
 
24
- public $version = '2.3.4';
25
  public $plugin_basename;
26
  public $legacy_mode;
27
 
3
  * Plugin Name: WooCommerce PDF Invoices & Packing Slips
4
  * Plugin URI: http://www.wpovernight.com
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
+ * Version: 2.3.5
7
  * Author: Ewout Fernhout
8
  * Author URI: http://www.wpovernight.com
9
  * License: GPLv2 or later
10
  * License URI: http://www.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: 3.8.0
14
  */
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
21
 
22
  class WPO_WCPDF {
23
 
24
+ public $version = '2.3.5';
25
  public $plugin_basename;
26
  public $legacy_mode;
27