WooCommerce PDF Invoices & Packing Slips - Version 2.2.2

Version Description

  • Feature: Added option to always use most current settings for the invoice
  • Fix: Double check for empty document numbers on initialization
  • New filter: wpo_wcpdf_output_format to set output per document type
Download this release

Release Info

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

Code changes from version 2.2.1 to 2.2.2

includes/class-wcpdf-install.php CHANGED
@@ -176,7 +176,7 @@ class Install {
176
  }
177
 
178
  // set transient for wizard notification
179
- set_transient( 'wpo_wcpdf_new_install', 'yes', WEEK_IN_SECONDS );
180
  }
181
 
182
  /**
176
  }
177
 
178
  // set transient for wizard notification
179
+ set_transient( 'wpo_wcpdf_new_install', 'yes', DAY_IN_SECONDS * 2 );
180
  }
181
 
182
  /**
includes/class-wcpdf-main.php CHANGED
@@ -21,9 +21,6 @@ class Main {
21
  if ( isset(WPO_WCPDF()->settings->debug_settings['enable_debug']) ) {
22
  $this->enable_debug();
23
  }
24
- if ( isset(WPO_WCPDF()->settings->debug_settings['html_output']) ) {
25
- add_filter( 'wpo_wcpdf_use_path', '__return_false' );
26
- }
27
 
28
  // include template specific custom functions
29
  $template_path = WPO_WCPDF()->settings->get_template_path();
@@ -222,6 +219,7 @@ class Main {
222
  $output_format = WPO_WCPDF()->settings->get_output_format( $document_type );
223
  switch ( $output_format ) {
224
  case 'html':
 
225
  $document->output_html();
226
  break;
227
  case 'pdf':
21
  if ( isset(WPO_WCPDF()->settings->debug_settings['enable_debug']) ) {
22
  $this->enable_debug();
23
  }
 
 
 
24
 
25
  // include template specific custom functions
26
  $template_path = WPO_WCPDF()->settings->get_template_path();
219
  $output_format = WPO_WCPDF()->settings->get_output_format( $document_type );
220
  switch ( $output_format ) {
221
  case 'html':
222
+ add_filter( 'wpo_wcpdf_use_path', '__return_false' );
223
  $document->output_html();
224
  break;
225
  case 'pdf':
includes/class-wcpdf-settings.php CHANGED
@@ -178,13 +178,13 @@ class Settings {
178
  return false;
179
  }
180
 
181
- public function get_output_format() {
182
  if ( isset( $this->debug_settings['html_output'] ) ) {
183
  $output_format = 'html';
184
  } else {
185
  $output_format = 'pdf';
186
  }
187
- return $output_format;
188
  }
189
 
190
  public function get_output_mode() {
178
  return false;
179
  }
180
 
181
+ public function get_output_format( $document_type = null ) {
182
  if ( isset( $this->debug_settings['html_output'] ) ) {
183
  $output_format = 'html';
184
  } else {
185
  $output_format = 'pdf';
186
  }
187
+ return apply_filters( 'wpo_wcpdf_output_format', $output_format, $document_type );
188
  }
189
 
190
  public function get_output_mode() {
includes/documents/abstract-wcpdf-order-document.php CHANGED
@@ -1,735 +1,749 @@
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
- }
12
-
13
- if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Order_Document' ) ) :
14
-
15
- /**
16
- * Abstract Document
17
- *
18
- * Handles generic pdf document & order data and database interaction
19
- * which is extended by both Invoices & Packing Slips
20
- *
21
- * @class \WPO\WC\PDF_Invoices\Documents\Order_Document
22
- * @version 2.0
23
- * @category Class
24
- * @author Ewout Fernhout
25
- */
26
-
27
- abstract class Order_Document {
28
- /**
29
- * Document type.
30
- * @var String
31
- */
32
- public $type;
33
-
34
- /**
35
- * Document slug.
36
- * @var String
37
- */
38
- public $slug;
39
-
40
- /**
41
- * Document title.
42
- * @var string
43
- */
44
- public $title;
45
-
46
- /**
47
- * Document icon.
48
- * @var string
49
- */
50
- public $icon;
51
-
52
- /**
53
- * WC Order object
54
- * @var object
55
- */
56
- public $order;
57
-
58
- /**
59
- * WC Order ID
60
- * @var object
61
- */
62
- public $order_id;
63
-
64
- /**
65
- * Document settings.
66
- * @var array
67
- */
68
- public $settings;
69
-
70
- /**
71
- * TRUE if document is enabled.
72
- * @var bool
73
- */
74
- public $enabled;
75
-
76
- /**
77
- * Linked documents, used for data retrieval
78
- * @var array
79
- */
80
- protected $linked_documents = array();
81
-
82
- /**
83
- * Core data for this object. Name value pairs (name + default value).
84
- * @var array
85
- */
86
- protected $data = array();
87
-
88
- /**
89
- * Init/load the order object.
90
- *
91
- * @param int|object|WC_Order $order Order to init.
92
- */
93
- public function __construct( $order = 0 ) {
94
- if ( is_numeric( $order ) && $order > 0 ) {
95
- $this->order_id = $order;
96
- $this->order = WCX::get_order( $this->order_id );
97
- } elseif ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) {
98
- $this->order_id = WCX_Order::get_id( $order );
99
- $this->order = $order;
100
- }
101
-
102
- // set properties
103
- $this->slug = str_replace('-', '_', $this->type);
104
-
105
- // load data
106
- if ( $this->order ) {
107
- $this->read_data( $this->order );
108
- if ( WPO_WCPDF()->legacy_mode_enabled() ) {
109
- global $wpo_wcpdf;
110
- $wpo_wcpdf->export->order = $this->order;
111
- $wpo_wcpdf->export->document = $this;
112
- $wpo_wcpdf->export->order_id = $this->order_id;
113
- $wpo_wcpdf->export->template_type = $this->type;
114
- }
115
- }
116
-
117
- // load settings
118
- $this->settings = $this->get_settings();
119
- $this->enabled = $this->get_setting( 'enabled', false );
120
- }
121
-
122
- public function init_settings() {
123
- return;
124
- }
125
-
126
- public function get_settings() {
127
- if ( empty( $this->order ) || !$this->exists() ) {
128
- $common_settings = WPO_WCPDF()->settings->get_common_document_settings();
129
- $document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
130
- $settings = (array) $document_settings + (array) $common_settings;
131
- } else {
132
- $settings = WCX_Order::get_meta( $this->order, "_wcpdf_{$this->slug}_settings" );
133
- if ( empty( $settings ) ) {
134
- $common_settings = WPO_WCPDF()->settings->get_common_document_settings();
135
- $document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
136
- $settings = (array) $document_settings + (array) $common_settings;
137
- WCX_Order::update_meta_data( $this->order, "_wcpdf_{$this->slug}_settings", $settings );
138
- }
139
- }
140
-
141
- return $settings;
142
- }
143
-
144
- public function get_setting( $key, $default = '' ) {
145
- $setting = isset( $this->settings[$key] ) ? $this->settings[$key] : $default;
146
- return $setting;
147
- }
148
-
149
- public function get_attach_to_email_ids() {
150
- $email_ids = isset( $this->settings['attach_to_email_ids'] ) ? array_keys( $this->settings['attach_to_email_ids'] ) : array();
151
- return $email_ids;
152
- }
153
-
154
- public function get_type() {
155
- return $this->type;
156
- }
157
-
158
- public function is_enabled() {
159
- return apply_filters( 'wpo_wcpdf_document_is_enabled', $this->enabled, $this->type );
160
- }
161
-
162
- public function get_hook_prefix() {
163
- return 'wpo_wcpdf_' . $this->slug . '_get_';
164
- }
165
-
166
- public function read_data( $order ) {
167
- $number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number_data", true );
168
- // fallback to legacy data for number
169
- if ( empty( $number ) ) {
170
- $number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number", true );
171
- $formatted_number = WCX_Order::get_meta( $order, "_wcpdf_formatted_{$this->slug}_number", true );
172
- if (!empty($formatted_number)) {
173
- $number = compact( 'number', 'formatted_number' );
174
- }
175
- }
176
-
177
- // pass data to setter functions
178
- $this->set_data( array(
179
- // always load date before number, because date is used in number formatting
180
- 'date' => WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_date", true ),
181
- 'number' => $number,
182
- ), $order );
183
-
184
- return;
185
- }
186
-
187
- public function init() {
188
- // store settings in order
189
- if ( !empty( $this->order ) ) {
190
- $common_settings = WPO_WCPDF()->settings->get_common_document_settings();
191
- $document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
192
- $settings = (array) $document_settings + (array) $common_settings;
193
- WCX_Order::update_meta_data( $this->order, "_wcpdf_{$this->slug}_settings", $settings );
194
- }
195
-
196
- $this->set_date( current_time( 'timestamp', true ) );
197
- do_action( 'wpo_wcpdf_init_document', $this );
198
- }
199
-
200
- public function save( $order = null ) {
201
- $order = empty( $order ) ? $this->order : $order;
202
- if ( empty( $order ) ) {
203
- return; // nowhere to save to...
204
- }
205
-
206
- foreach ($this->data as $key => $value) {
207
- if ( empty( $value ) ) {
208
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}" );
209
- if ( $key == 'date' ) {
210
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted" );
211
- } elseif ( $key == 'number' ) {
212
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data" );
213
- // deleting the number = deleting the document, so also delete document settings
214
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_settings" );
215
- }
216
- } else {
217
- if ( $key == 'date' ) {
218
- // store dates as timestamp and formatted as mysql time
219
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->getTimestamp() );
220
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted", $value->date( 'Y-m-d H:i:s' ) );
221
- } elseif ( $key == 'number' ) {
222
- // store both formatted number and number data
223
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->formatted_number );
224
- WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data", $value->to_array() );
225
- }
226
- }
227
- }
228
- }
229
-
230
- public function delete( $order = null ) {
231
- $order = empty( $order ) ? $this->order : $order;
232
- if ( empty( $order ) ) {
233
- return; // nothing to delete
234
- }
235
-
236
- $data_to_remove = apply_filters( 'wpo_wcpdf_delete_document_data_keys', array(
237
- 'settings',
238
- 'date',
239
- 'date_formatted',
240
- 'number',
241
- 'number_data',
242
- ), $this );
243
- foreach ($data_to_remove as $data_key) {
244
- WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$data_key}" );
245
- }
246
-
247
- do_action( 'wpo_wcpdf_delete_document', $this );
248
- }
249
-
250
- public function exists() {
251
- return !empty( $this->data['number'] );
252
- }
253
-
254
- /*
255
- |--------------------------------------------------------------------------
256
- | Data getters
257
- |--------------------------------------------------------------------------
258
- */
259
-
260
- public function get_data( $key, $document_type = '', $order = null, $context = 'view' ) {
261
- $document_type = empty( $document_type ) ? $this->type : $document_type;
262
- $order = empty( $order ) ? $this->order : $order;
263
-
264
- // redirect get_data call for linked documents
265
- if ( $document_type != $this->type ) {
266
- if ( !isset( $this->linked_documents[ $document_type ] ) ) {
267
- // always assume parent for documents linked to credit notes
268
- if ($this->type == 'credit-note') {
269
- $order = $this->get_refund_parent( $order );
270
- }
271
- // order is not loaded to avoid overhead - we pass this by reference directly to the read_data method instead
272
- $this->linked_documents[ $document_type ] = wcpdf_get_document( $document_type, null );
273
- $this->linked_documents[ $document_type ]->read_data( $order );
274
- }
275
- return $this->linked_documents[ $document_type ]->get_data( $key, $document_type );
276
- }
277
-
278
- $value = null;
279
-
280
- if ( array_key_exists( $key, $this->data ) ) {
281
- $value = $this->data[ $key ];
282
-
283
- if ( 'view' === $context ) {
284
- $value = apply_filters( $this->get_hook_prefix() . $key, $value, $this );
285
- }
286
- }
287
-
288
- return $value;
289
- }
290
-
291
- public function get_number( $document_type = '', $order = null, $context = 'view' ) {
292
- return $this->get_data( 'number', $document_type, $order, $context );
293
- }
294
-
295
- public function get_date( $document_type = '', $order = null, $context = 'view' ) {
296
- return $this->get_data( 'date', $document_type, $order, $context );
297
- }
298
-
299
- public function get_title() {
300
- return apply_filters( "wpo_wcpdf_{$this->slug}_title", $this->title, $this );
301
- }
302
-
303
- /*
304
- |--------------------------------------------------------------------------
305
- | Data setters
306
- |--------------------------------------------------------------------------
307
- |
308
- | Functions for setting order data. These should not update anything in the
309
- | order itself and should only change what is stored in the class
310
- | object.
311
- */
312
-
313
- public function set_data( $data, $order ) {
314
- $order = empty( $order ) ? $this->order : $order;
315
- foreach ($data as $key => $value) {
316
- $setter = "set_$key";
317
- if ( is_callable( array( $this, $setter ) ) ) {
318
- $this->$setter( $value, $order );
319
- } else {
320
- $this->data[ $key ] = $value;
321
- }
322
- }
323
- }
324
-
325
- public function set_date( $value, $order = null ) {
326
- $order = empty( $order ) ? $this->order : $order;
327
- try {
328
- if ( empty( $value ) ) {
329
- $this->data[ 'date' ] = null;
330
- return;
331
- }
332
-
333
- if ( is_a( $value, 'WC_DateTime' ) ) {
334
- $datetime = $value;
335
- } elseif ( is_numeric( $value ) ) {
336
- // Timestamps are handled as UTC timestamps in all cases.
337
- $datetime = new WC_DateTime( "@{$value}", new \DateTimeZone( 'UTC' ) );
338
- } else {
339
- // Strings are defined in local WP timezone. Convert to UTC.
340
- 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 ) ) {
341
- $offset = ! empty( $date_bits[7] ) ? iso8601_timezone_to_offset( $date_bits[7] ) : wc_timezone_offset();
342
- $timestamp = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] ) - $offset;
343
- } else {
344
- $timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $value ) ) ) );
345
- }
346
- $datetime = new WC_DateTime( "@{$timestamp}", new \DateTimeZone( 'UTC' ) );
347
- }
348
-
349
- // Set local timezone or offset.
350
- if ( get_option( 'timezone_string' ) ) {
351
- $datetime->setTimezone( new \DateTimeZone( wc_timezone_string() ) );
352
- } else {
353
- $datetime->set_utc_offset( wc_timezone_offset() );
354
- }
355
-
356
- $this->data[ 'date' ] = $datetime;
357
- } catch ( \Exception $e ) {
358
- wcpdf_log_error( $e->getMessage() );
359
- } catch ( \Error $e ) {
360
- wcpdf_log_error( $e->getMessage() );
361
- }
362
-
363
- }
364
-
365
- public function set_number( $value, $order = null ) {
366
- $order = empty( $order ) ? $this->order : $order;
367
-
368
- if ( is_array( $value ) ) {
369
- $filtered_value = array_filter( $value );
370
- }
371
-
372
- if ( empty( $value ) || ( is_array( $value ) && empty( $filtered_value ) ) ) {
373
- $document_number = null;
374
- } elseif ( $value instanceof Document_Number ) {
375
- // WCPDF 2.0 number data
376
- $document_number = $value;
377
- } elseif ( is_array( $value ) ) {
378
- // WCPDF 2.0 number data as array
379
- $document_number = new Document_Number( $value, $this->get_number_settings(), $this, $order );
380
- } else {
381
- // plain number
382
- $document_number = new Document_Number( $value, $this->get_number_settings(), $this, $order );
383
- }
384
-
385
- $this->data[ 'number' ] = $document_number;
386
- }
387
-
388
- /*
389
- |--------------------------------------------------------------------------
390
- | Settings getters / outputters
391
- |--------------------------------------------------------------------------
392
- */
393
-
394
- public function get_number_settings() {
395
- if (empty($this->settings)) {
396
- $settings = $this->get_settings();
397
- $number_settings = isset($settings['number_format'])?$settings['number_format']:array();
398
- } else {
399
- $number_settings = isset($this->settings['number_format'])?$this->settings['number_format']:array();
400
- }
401
- return apply_filters( 'wpo_wcpdf_document_number_settings', $number_settings, $this );
402
- }
403
-
404
- /**
405
- * Output template styles
406
- */
407
- public function template_styles() {
408
- $css = apply_filters( 'wpo_wcpdf_template_styles_file', $this->locate_template_file( "style.css" ) );
409
-
410
- ob_start();
411
- if (file_exists($css)) {
412
- include($css);
413
- }
414
- $css = ob_get_clean();
415
- $css = apply_filters( 'wpo_wcpdf_template_styles', $css, $this );
416
-
417
- echo $css;
418
- }
419
-
420
- public function has_header_logo() {
421
- return !empty( $this->settings['header_logo'] );
422
- }
423
-
424
- /**
425
- * Return logo id
426
- */
427
- public function get_header_logo_id() {
428
- if ( !empty( $this->settings['header_logo'] ) ) {
429
- return apply_filters( 'wpo_wcpdf_header_logo_id', $this->settings['header_logo'], $this );
430
- }
431
- }
432
-
433
- /**
434
- * Show logo html
435
- */
436
- public function header_logo() {
437
- if ($this->get_header_logo_id()) {
438
- $attachment_id = $this->get_header_logo_id();
439
- $company = $this->get_shop_name();
440
- if( $attachment_id ) {
441
- $attachment = wp_get_attachment_image_src( $attachment_id, 'full', false );
442
-
443
- $attachment_src = $attachment[0];
444
- $attachment_width = $attachment[1];
445
- $attachment_height = $attachment[2];
446
-
447
- $attachment_path = get_attached_file( $attachment_id );
448
-
449
- if ( apply_filters('wpo_wcpdf_use_path', true) && file_exists($attachment_path) ) {
450
- $src = $attachment_path;
451
- } else {
452
- $src = $attachment_src;
453
- }
454
-
455
- printf('<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s" />', $src, $attachment_width, $attachment_height, esc_attr( $company ) );
456
- }
457
- }
458
- }
459
-
460
- public function get_settings_text( $settings_key, $default = false, $autop = true ) {
461
- if ( !empty( $this->settings[$settings_key]['default'] ) ) {
462
- $text = wptexturize( trim( $this->settings[$settings_key]['default'] ) );
463
- if ($autop === true) {
464
- $text = wpautop( $text );
465
- }
466
- } else {
467
- $text = $default;
468
- }
469
- // legacy filters
470
- if ( in_array( $settings_key, array( 'shop_name', 'shop_address', 'footer', 'extra_1', 'extra_2', 'extra_3' ) ) ) {
471
- $text = apply_filters( "wpo_wcpdf_{$settings_key}", $text, $this );
472
- }
473
-
474
- return apply_filters( "wpo_wcpdf_{$settings_key}_settings_text", $text, $this );
475
- }
476
-
477
- /**
478
- * Return/Show custom company name or default to blog name
479
- */
480
- public function get_shop_name() {
481
- $default = get_bloginfo( 'name' );
482
- return $this->get_settings_text( 'shop_name', $default, false );
483
- }
484
- public function shop_name() {
485
- echo $this->get_shop_name();
486
- }
487
-
488
- /**
489
- * Return/Show shop/company address if provided
490
- */
491
- public function get_shop_address() {
492
- return $this->get_settings_text( 'shop_address' );
493
- }
494
- public function shop_address() {
495
- echo $this->get_shop_address();
496
- }
497
-
498
- /**
499
- * Return/Show shop/company footer imprint, copyright etc.
500
- */
501
- public function get_footer() {
502
- return $this->get_settings_text( 'footer' );
503
- }
504
- public function footer() {
505
- echo $this->get_footer();
506
- }
507
-
508
- /**
509
- * Return/Show Extra field 1
510
- */
511
- public function get_extra_1() {
512
- return $this->get_settings_text( 'extra_1' );
513
-
514
- }
515
- public function extra_1() {
516
- echo $this->get_extra_1();
517
- }
518
-
519
- /**
520
- * Return/Show Extra field 2
521
- */
522
- public function get_extra_2() {
523
- return $this->get_settings_text( 'extra_2' );
524
- }
525
- public function extra_2() {
526
- echo $this->get_extra_2();
527
- }
528
-
529
- /**
530
- * Return/Show Extra field 3
531
- */
532
- public function get_extra_3() {
533
- return $this->get_settings_text( 'extra_3' );
534
- }
535
- public function extra_3() {
536
- echo $this->get_extra_3();
537
- }
538
-
539
- /*
540
- |--------------------------------------------------------------------------
541
- | Output functions
542
- |--------------------------------------------------------------------------
543
- */
544
-
545
- public function get_pdf() {
546
- do_action( 'wpo_wcpdf_before_pdf', $this->get_type(), $this );
547
-
548
- $pdf_settings = array(
549
- 'paper_size' => apply_filters( 'wpo_wcpdf_paper_format', $this->get_setting( 'paper_size', 'A4' ), $this->get_type() ),
550
- 'paper_orientation' => apply_filters( 'wpo_wcpdf_paper_orientation', 'portrait', $this->get_type() ),
551
- 'font_subsetting' => $this->get_setting( 'font_subsetting', false ),
552
- );
553
- $pdf_maker = wcpdf_get_pdf_maker( $this->get_html(), $pdf_settings );
554
- $pdf = $pdf_maker->output();
555
-
556
- do_action( 'wpo_wcpdf_after_pdf', $this->get_type(), $this );
557
- do_action( 'wpo_wcpdf_pdf_created', $pdf, $this );
558
-
559
- return apply_filters( 'wpo_wcpdf_get_pdf', $pdf, $this );
560
- }
561
-
562
- public function get_html( $args = array() ) {
563
- do_action( 'wpo_wcpdf_before_html', $this->get_type(), $this );
564
- $default_args = array (
565
- 'wrap_html_content' => true,
566
- );
567
- $args = $args + $default_args;
568
-
569
- $html = $this->render_template( $this->locate_template_file( "{$this->type}.php" ), array(
570
- 'order' => $this->order,
571
- 'order_id' => $this->order_id,
572
- )
573
- );
574
- if ($args['wrap_html_content']) {
575
- $html = $this->wrap_html_content( $html );
576
- }
577
-
578
- // clean up special characters
579
- if ( function_exists('utf8_decode') && function_exists('mb_convert_encoding') ) {
580
- $html = utf8_decode(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
581
- }
582
-
583
- do_action( 'wpo_wcpdf_after_html', $this->get_type(), $this );
584
-
585
- return apply_filters( 'wpo_wcpdf_get_html', $html, $this );
586
- }
587
-
588
- public function output_pdf( $output_mode = 'download' ) {
589
- $pdf = $this->get_pdf();
590
- wcpdf_pdf_headers( $this->get_filename(), $output_mode, $pdf );
591
- echo $pdf;
592
- die();
593
- }
594
-
595
- public function output_html() {
596
- echo $this->get_html();
597
- die();
598
- }
599
-
600
- public function wrap_html_content( $content ) {
601
- if ( WPO_WCPDF()->legacy_mode_enabled() ) {
602
- $GLOBALS['wpo_wcpdf']->export->output_body = $content;
603
- }
604
-
605
- $html = $this->render_template( $this->locate_template_file( "html-document-wrapper.php" ), array(
606
- 'content' => $content,
607
- )
608
- );
609
- return $html;
610
- }
611
-
612
- public function get_filename( $context = 'download', $args = array() ) {
613
- $order_count = isset($args['order_ids']) ? count($args['order_ids']) : 1;
614
-
615
- $name = $this->get_type();
616
- if ( get_post_type( $this->order_id ) == 'shop_order_refund' ) {
617
- $number = $this->order_id;
618
- } else {
619
- $number = method_exists( $this->order, 'get_order_number' ) ? $this->order->get_order_number() : '';
620
- }
621
-
622
- if ( $order_count == 1 ) {
623
- $suffix = $number;
624
- } else {
625
- $suffix = date('Y-m-d'); // 2020-11-11
626
- }
627
-
628
- $filename = $name . '-' . $suffix . '.pdf';
629
-
630
- // Filter filename
631
- $order_ids = isset($args['order_ids']) ? $args['order_ids'] : array( $this->order_id );
632
- $filename = apply_filters( 'wpo_wcpdf_filename', $filename, $this->get_type(), $order_ids, $context );
633
-
634
- // sanitize filename (after filters to prevent human errors)!
635
- return sanitize_file_name( $filename );
636
- }
637
-
638
- public function get_template_path() {
639
- return WPO_WCPDF()->settings->get_template_path();
640
- }
641
-
642
- public function locate_template_file( $file ) {
643
- if (empty($file)) {
644
- $file = $this->type.'.php';
645
- }
646
- $path = WPO_WCPDF()->settings->get_template_path( $file );
647
- $file_path = "{$path}/{$file}";
648
-
649
- $fallback_file_path = WPO_WCPDF()->plugin_path() . '/templates/Simple/' . $file;
650
- if ( !file_exists( $file_path ) && file_exists( $fallback_file_path ) ) {
651
- $file_path = $fallback_file_path;
652
- }
653
-
654
- $file_path = apply_filters( 'wpo_wcpdf_template_file', $file_path, $this->type, $this->order );
655
-
656
- return $file_path;
657
- }
658
-
659
- public function render_template( $file, $args = array() ) {
660
- do_action( 'wpo_wcpdf_process_template', $this->get_type(), $this );
661
-
662
- if ( ! empty( $args ) && is_array( $args ) ) {
663
- extract( $args );
664
- }
665
- ob_start();
666
- if (file_exists($file)) {
667
- include($file);
668
- }
669
- return ob_get_clean();
670
- }
671
-
672
- /*
673
- |--------------------------------------------------------------------------
674
- | Settings helper functions
675
- |--------------------------------------------------------------------------
676
- */
677
-
678
- /**
679
- * get all emails registered in WooCommerce
680
- * @param boolean $remove_defaults switch to remove default woocommerce emails
681
- * @return array $emails list of all email ids/slugs and names
682
- */
683
- public function get_wc_emails() {
684
- // get emails from WooCommerce
685
- global $woocommerce;
686
- $mailer = $woocommerce->mailer();
687
- $wc_emails = $mailer->get_emails();
688
-
689
- $non_order_emails = array(
690
- 'customer_note',
691
- 'customer_reset_password',
692
- 'customer_new_account'
693
- );
694
-
695
- $emails = array();
696
- foreach ($wc_emails as $class => $email) {
697
- if ( !in_array( $email->id, $non_order_emails ) ) {
698
- switch ($email->id) {
699
- case 'new_order':
700
- $emails[$email->id] = sprintf('%s (%s)', $email->title, __( 'Admin email', 'woocommerce-pdf-invoices-packing-slips' ) );
701
- break;
702
- case 'customer_invoice':
703
- $emails[$email->id] = sprintf('%s (%s)', $email->title, __( 'Manual email', 'woocommerce-pdf-invoices-packing-slips' ) );
704
- break;
705
- default:
706
- $emails[$email->id] = $email->title;
707
- break;
708
- }
709
- }
710
- }
711
-
712
- return apply_filters( 'wpo_wcpdf_wc_emails', $emails );
713
- }
714
-
715
- // get list of WooCommerce statuses
716
- public function get_wc_order_status_list() {
717
- if ( version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
718
- $statuses = (array) get_terms( 'shop_order_status', array( 'hide_empty' => 0, 'orderby' => 'id' ) );
719
- foreach ( $statuses as $status ) {
720
- $order_statuses[esc_attr( $status->slug )] = esc_html__( $status->name, 'woocommerce' );
721
- }
722
- } else {
723
- $statuses = wc_get_order_statuses();
724
- foreach ( $statuses as $status_slug => $status ) {
725
- $status_slug = 'wc-' === substr( $status_slug, 0, 3 ) ? substr( $status_slug, 3 ) : $status_slug;
726
- $order_statuses[$status_slug] = $status;
727
- }
728
- }
729
- return $order_statuses;
730
- }
731
-
732
-
733
- }
734
-
735
- endif; // class_exists
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ }
12
+
13
+ if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Order_Document' ) ) :
14
+
15
+ /**
16
+ * Abstract Document
17
+ *
18
+ * Handles generic pdf document & order data and database interaction
19
+ * which is extended by both Invoices & Packing Slips
20
+ *
21
+ * @class \WPO\WC\PDF_Invoices\Documents\Order_Document
22
+ * @version 2.0
23
+ * @category Class
24
+ * @author Ewout Fernhout
25
+ */
26
+
27
+ abstract class Order_Document {
28
+ /**
29
+ * Document type.
30
+ * @var String
31
+ */
32
+ public $type;
33
+
34
+ /**
35
+ * Document slug.
36
+ * @var String
37
+ */
38
+ public $slug;
39
+
40
+ /**
41
+ * Document title.
42
+ * @var string
43
+ */
44
+ public $title;
45
+
46
+ /**
47
+ * Document icon.
48
+ * @var string
49
+ */
50
+ public $icon;
51
+
52
+ /**
53
+ * WC Order object
54
+ * @var object
55
+ */
56
+ public $order;
57
+
58
+ /**
59
+ * WC Order ID
60
+ * @var object
61
+ */
62
+ public $order_id;
63
+
64
+ /**
65
+ * Document settings.
66
+ * @var array
67
+ */
68
+ public $settings;
69
+
70
+ /**
71
+ * TRUE if document is enabled.
72
+ * @var bool
73
+ */
74
+ public $enabled;
75
+
76
+ /**
77
+ * Linked documents, used for data retrieval
78
+ * @var array
79
+ */
80
+ protected $linked_documents = array();
81
+
82
+ /**
83
+ * Core data for this object. Name value pairs (name + default value).
84
+ * @var array
85
+ */
86
+ protected $data = array();
87
+
88
+ /**
89
+ * Init/load the order object.
90
+ *
91
+ * @param int|object|WC_Order $order Order to init.
92
+ */
93
+ public function __construct( $order = 0 ) {
94
+ if ( is_numeric( $order ) && $order > 0 ) {
95
+ $this->order_id = $order;
96
+ $this->order = WCX::get_order( $this->order_id );
97
+ } elseif ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) {
98
+ $this->order_id = WCX_Order::get_id( $order );
99
+ $this->order = $order;
100
+ }
101
+
102
+ // set properties
103
+ $this->slug = str_replace('-', '_', $this->type);
104
+
105
+ // load data
106
+ if ( $this->order ) {
107
+ $this->read_data( $this->order );
108
+ if ( WPO_WCPDF()->legacy_mode_enabled() ) {
109
+ global $wpo_wcpdf;
110
+ $wpo_wcpdf->export->order = $this->order;
111
+ $wpo_wcpdf->export->document = $this;
112
+ $wpo_wcpdf->export->order_id = $this->order_id;
113
+ $wpo_wcpdf->export->template_type = $this->type;
114
+ }
115
+ }
116
+
117
+ // load settings
118
+ $this->settings = $this->get_settings();
119
+ $this->enabled = $this->get_setting( 'enabled', false );
120
+ }
121
+
122
+ public function init_settings() {
123
+ return;
124
+ }
125
+
126
+ public function get_settings( $latest = false ) {
127
+ // get most current settings
128
+ $common_settings = WPO_WCPDF()->settings->get_common_document_settings();
129
+ $document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
130
+ $settings = (array) $document_settings + (array) $common_settings;
131
+
132
+ // return only most current if forced
133
+ if ( $latest == true ) {
134
+ return $settings;
135
+ }
136
+
137
+ // get historical settings if enabled
138
+ if ( !empty( $this->order ) && $this->use_historical_settings() == true ) {
139
+ $order_settings = WCX_Order::get_meta( $this->order, "_wcpdf_{$this->slug}_settings" );
140
+ // not sure what happens if combining with current settings will have unwanted side effects
141
+ // like unchecked options being enabled because missing = unchecked in historical - disabled for now
142
+ // $settings = (array) $order_settings + (array) $settings;
143
+ $settings = $order_settings;
144
+ }
145
+ if ( empty( $order_settings ) && !empty( $this->order ) ) {
146
+ // this is either the first time the document is generated, or historical settings are disabled
147
+ // in both cases, we store the document settings
148
+ WCX_Order::update_meta_data( $this->order, "_wcpdf_{$this->slug}_settings", $settings );
149
+ }
150
+
151
+ return $settings;
152
+ }
153
+
154
+ public function use_historical_settings() {
155
+ return apply_filters( 'wpo_wcpdf_document_use_historical_settings', false, $this );
156
+ }
157
+
158
+ public function get_setting( $key, $default = '' ) {
159
+ $setting = isset( $this->settings[$key] ) ? $this->settings[$key] : $default;
160
+ return $setting;
161
+ }
162
+
163
+ public function get_attach_to_email_ids() {
164
+ $email_ids = isset( $this->settings['attach_to_email_ids'] ) ? array_keys( $this->settings['attach_to_email_ids'] ) : array();
165
+ return $email_ids;
166
+ }
167
+
168
+ public function get_type() {
169
+ return $this->type;
170
+ }
171
+
172
+ public function is_enabled() {
173
+ return apply_filters( 'wpo_wcpdf_document_is_enabled', $this->enabled, $this->type );
174
+ }
175
+
176
+ public function get_hook_prefix() {
177
+ return 'wpo_wcpdf_' . $this->slug . '_get_';
178
+ }
179
+
180
+ public function read_data( $order ) {
181
+ $number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number_data", true );
182
+ // fallback to legacy data for number
183
+ if ( empty( $number ) ) {
184
+ $number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number", true );
185
+ $formatted_number = WCX_Order::get_meta( $order, "_wcpdf_formatted_{$this->slug}_number", true );
186
+ if (!empty($formatted_number)) {
187
+ $number = compact( 'number', 'formatted_number' );
188
+ }
189
+ }
190
+
191
+ // pass data to setter functions
192
+ $this->set_data( array(
193
+ // always load date before number, because date is used in number formatting
194
+ 'date' => WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_date", true ),
195
+ 'number' => $number,
196
+ ), $order );
197
+
198
+ return;
199
+ }
200
+
201
+ public function init() {
202
+ // store settings in order
203
+ if ( !empty( $this->order ) ) {
204
+ $common_settings = WPO_WCPDF()->settings->get_common_document_settings();
205
+ $document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
206
+ $settings = (array) $document_settings + (array) $common_settings;
207
+ WCX_Order::update_meta_data( $this->order, "_wcpdf_{$this->slug}_settings", $settings );
208
+ }
209
+
210
+ $this->set_date( current_time( 'timestamp', true ) );
211
+ do_action( 'wpo_wcpdf_init_document', $this );
212
+ }
213
+
214
+ public function save( $order = null ) {
215
+ $order = empty( $order ) ? $this->order : $order;
216
+ if ( empty( $order ) ) {
217
+ return; // nowhere to save to...
218
+ }
219
+
220
+ foreach ($this->data as $key => $value) {
221
+ if ( empty( $value ) ) {
222
+ WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}" );
223
+ if ( $key == 'date' ) {
224
+ WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted" );
225
+ } elseif ( $key == 'number' ) {
226
+ WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data" );
227
+ // deleting the number = deleting the document, so also delete document settings
228
+ WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_settings" );
229
+ }
230
+ } else {
231
+ if ( $key == 'date' ) {
232
+ // store dates as timestamp and formatted as mysql time
233
+ WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->getTimestamp() );
234
+ WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted", $value->date( 'Y-m-d H:i:s' ) );
235
+ } elseif ( $key == 'number' ) {
236
+ // store both formatted number and number data
237
+ WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->formatted_number );
238
+ WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data", $value->to_array() );
239
+ }
240
+ }
241
+ }
242
+ }
243
+
244
+ public function delete( $order = null ) {
245
+ $order = empty( $order ) ? $this->order : $order;
246
+ if ( empty( $order ) ) {
247
+ return; // nothing to delete
248
+ }
249
+
250
+ $data_to_remove = apply_filters( 'wpo_wcpdf_delete_document_data_keys', array(
251
+ 'settings',
252
+ 'date',
253
+ 'date_formatted',
254
+ 'number',
255
+ 'number_data',
256
+ ), $this );
257
+ foreach ($data_to_remove as $data_key) {
258
+ WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$data_key}" );
259
+ }
260
+
261
+ do_action( 'wpo_wcpdf_delete_document', $this );
262
+ }
263
+
264
+ public function exists() {
265
+ return !empty( $this->data['number'] );
266
+ }
267
+
268
+ /*
269
+ |--------------------------------------------------------------------------
270
+ | Data getters
271
+ |--------------------------------------------------------------------------
272
+ */
273
+
274
+ public function get_data( $key, $document_type = '', $order = null, $context = 'view' ) {
275
+ $document_type = empty( $document_type ) ? $this->type : $document_type;
276
+ $order = empty( $order ) ? $this->order : $order;
277
+
278
+ // redirect get_data call for linked documents
279
+ if ( $document_type != $this->type ) {
280
+ if ( !isset( $this->linked_documents[ $document_type ] ) ) {
281
+ // always assume parent for documents linked to credit notes
282
+ if ($this->type == 'credit-note') {
283
+ $order = $this->get_refund_parent( $order );
284
+ }
285
+ // order is not loaded to avoid overhead - we pass this by reference directly to the read_data method instead
286
+ $this->linked_documents[ $document_type ] = wcpdf_get_document( $document_type, null );
287
+ $this->linked_documents[ $document_type ]->read_data( $order );
288
+ }
289
+ return $this->linked_documents[ $document_type ]->get_data( $key, $document_type );
290
+ }
291
+
292
+ $value = null;
293
+
294
+ if ( array_key_exists( $key, $this->data ) ) {
295
+ $value = $this->data[ $key ];
296
+
297
+ if ( 'view' === $context ) {
298
+ $value = apply_filters( $this->get_hook_prefix() . $key, $value, $this );
299
+ }
300
+ }
301
+
302
+ return $value;
303
+ }
304
+
305
+ public function get_number( $document_type = '', $order = null, $context = 'view' ) {
306
+ return $this->get_data( 'number', $document_type, $order, $context );
307
+ }
308
+
309
+ public function get_date( $document_type = '', $order = null, $context = 'view' ) {
310
+ return $this->get_data( 'date', $document_type, $order, $context );
311
+ }
312
+
313
+ public function get_title() {
314
+ return apply_filters( "wpo_wcpdf_{$this->slug}_title", $this->title, $this );
315
+ }
316
+
317
+ /*
318
+ |--------------------------------------------------------------------------
319
+ | Data setters
320
+ |--------------------------------------------------------------------------
321
+ |
322
+ | Functions for setting order data. These should not update anything in the
323
+ | order itself and should only change what is stored in the class
324
+ | object.
325
+ */
326
+
327
+ public function set_data( $data, $order ) {
328
+ $order = empty( $order ) ? $this->order : $order;
329
+ foreach ($data as $key => $value) {
330
+ $setter = "set_$key";
331
+ if ( is_callable( array( $this, $setter ) ) ) {
332
+ $this->$setter( $value, $order );
333
+ } else {
334
+ $this->data[ $key ] = $value;
335
+ }
336
+ }
337
+ }
338
+
339
+ public function set_date( $value, $order = null ) {
340
+ $order = empty( $order ) ? $this->order : $order;
341
+ try {
342
+ if ( empty( $value ) ) {
343
+ $this->data[ 'date' ] = null;
344
+ return;
345
+ }
346
+
347
+ if ( is_a( $value, 'WC_DateTime' ) ) {
348
+ $datetime = $value;
349
+ } elseif ( is_numeric( $value ) ) {
350
+ // Timestamps are handled as UTC timestamps in all cases.
351
+ $datetime = new WC_DateTime( "@{$value}", new \DateTimeZone( 'UTC' ) );
352
+ } else {
353
+ // Strings are defined in local WP timezone. Convert to UTC.
354
+ 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 ) ) {
355
+ $offset = ! empty( $date_bits[7] ) ? iso8601_timezone_to_offset( $date_bits[7] ) : wc_timezone_offset();
356
+ $timestamp = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] ) - $offset;
357
+ } else {
358
+ $timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $value ) ) ) );
359
+ }
360
+ $datetime = new WC_DateTime( "@{$timestamp}", new \DateTimeZone( 'UTC' ) );
361
+ }
362
+
363
+ // Set local timezone or offset.
364
+ if ( get_option( 'timezone_string' ) ) {
365
+ $datetime->setTimezone( new \DateTimeZone( wc_timezone_string() ) );
366
+ } else {
367
+ $datetime->set_utc_offset( wc_timezone_offset() );
368
+ }
369
+
370
+ $this->data[ 'date' ] = $datetime;
371
+ } catch ( \Exception $e ) {
372
+ wcpdf_log_error( $e->getMessage() );
373
+ } catch ( \Error $e ) {
374
+ wcpdf_log_error( $e->getMessage() );
375
+ }
376
+
377
+ }
378
+
379
+ public function set_number( $value, $order = null ) {
380
+ $order = empty( $order ) ? $this->order : $order;
381
+
382
+ if ( is_array( $value ) ) {
383
+ $filtered_value = array_filter( $value );
384
+ }
385
+
386
+ if ( empty( $value ) || ( is_array( $value ) && empty( $filtered_value ) ) ) {
387
+ $document_number = null;
388
+ } elseif ( $value instanceof Document_Number ) {
389
+ // WCPDF 2.0 number data
390
+ $document_number = $value;
391
+ } elseif ( is_array( $value ) ) {
392
+ // WCPDF 2.0 number data as array
393
+ $document_number = new Document_Number( $value, $this->get_number_settings(), $this, $order );
394
+ } else {
395
+ // plain number
396
+ $document_number = new Document_Number( $value, $this->get_number_settings(), $this, $order );
397
+ }
398
+
399
+ $this->data[ 'number' ] = $document_number;
400
+ }
401
+
402
+ /*
403
+ |--------------------------------------------------------------------------
404
+ | Settings getters / outputters
405
+ |--------------------------------------------------------------------------
406
+ */
407
+
408
+ public function get_number_settings() {
409
+ if (empty($this->settings)) {
410
+ $settings = $this->get_settings();
411
+ $number_settings = isset($settings['number_format'])?$settings['number_format']:array();
412
+ } else {
413
+ $number_settings = isset($this->settings['number_format'])?$this->settings['number_format']:array();
414
+ }
415
+ return apply_filters( 'wpo_wcpdf_document_number_settings', $number_settings, $this );
416
+ }
417
+
418
+ /**
419
+ * Output template styles
420
+ */
421
+ public function template_styles() {
422
+ $css = apply_filters( 'wpo_wcpdf_template_styles_file', $this->locate_template_file( "style.css" ) );
423
+
424
+ ob_start();
425
+ if (file_exists($css)) {
426
+ include($css);
427
+ }
428
+ $css = ob_get_clean();
429
+ $css = apply_filters( 'wpo_wcpdf_template_styles', $css, $this );
430
+
431
+ echo $css;
432
+ }
433
+
434
+ public function has_header_logo() {
435
+ return !empty( $this->settings['header_logo'] );
436
+ }
437
+
438
+ /**
439
+ * Return logo id
440
+ */
441
+ public function get_header_logo_id() {
442
+ if ( !empty( $this->settings['header_logo'] ) ) {
443
+ return apply_filters( 'wpo_wcpdf_header_logo_id', $this->settings['header_logo'], $this );
444
+ }
445
+ }
446
+
447
+ /**
448
+ * Show logo html
449
+ */
450
+ public function header_logo() {
451
+ if ($this->get_header_logo_id()) {
452
+ $attachment_id = $this->get_header_logo_id();
453
+ $company = $this->get_shop_name();
454
+ if( $attachment_id ) {
455
+ $attachment = wp_get_attachment_image_src( $attachment_id, 'full', false );
456
+
457
+ $attachment_src = $attachment[0];
458
+ $attachment_width = $attachment[1];
459
+ $attachment_height = $attachment[2];
460
+
461
+ $attachment_path = get_attached_file( $attachment_id );
462
+
463
+ if ( apply_filters('wpo_wcpdf_use_path', true) && file_exists($attachment_path) ) {
464
+ $src = $attachment_path;
465
+ } else {
466
+ $src = $attachment_src;
467
+ }
468
+
469
+ printf('<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s" />', $src, $attachment_width, $attachment_height, esc_attr( $company ) );
470
+ }
471
+ }
472
+ }
473
+
474
+ public function get_settings_text( $settings_key, $default = false, $autop = true ) {
475
+ if ( !empty( $this->settings[$settings_key]['default'] ) ) {
476
+ $text = wptexturize( trim( $this->settings[$settings_key]['default'] ) );
477
+ if ($autop === true) {
478
+ $text = wpautop( $text );
479
+ }
480
+ } else {
481
+ $text = $default;
482
+ }
483
+ // legacy filters
484
+ if ( in_array( $settings_key, array( 'shop_name', 'shop_address', 'footer', 'extra_1', 'extra_2', 'extra_3' ) ) ) {
485
+ $text = apply_filters( "wpo_wcpdf_{$settings_key}", $text, $this );
486
+ }
487
+
488
+ return apply_filters( "wpo_wcpdf_{$settings_key}_settings_text", $text, $this );
489
+ }
490
+
491
+ /**
492
+ * Return/Show custom company name or default to blog name
493
+ */
494
+ public function get_shop_name() {
495
+ $default = get_bloginfo( 'name' );
496
+ return $this->get_settings_text( 'shop_name', $default, false );
497
+ }
498
+ public function shop_name() {
499
+ echo $this->get_shop_name();
500
+ }
501
+
502
+ /**
503
+ * Return/Show shop/company address if provided
504
+ */
505
+ public function get_shop_address() {
506
+ return $this->get_settings_text( 'shop_address' );
507
+ }
508
+ public function shop_address() {
509
+ echo $this->get_shop_address();
510
+ }
511
+
512
+ /**
513
+ * Return/Show shop/company footer imprint, copyright etc.
514
+ */
515
+ public function get_footer() {
516
+ return $this->get_settings_text( 'footer' );
517
+ }
518
+ public function footer() {
519
+ echo $this->get_footer();
520
+ }
521
+
522
+ /**
523
+ * Return/Show Extra field 1
524
+ */
525
+ public function get_extra_1() {
526
+ return $this->get_settings_text( 'extra_1' );
527
+
528
+ }
529
+ public function extra_1() {
530
+ echo $this->get_extra_1();
531
+ }
532
+
533
+ /**
534
+ * Return/Show Extra field 2
535
+ */
536
+ public function get_extra_2() {
537
+ return $this->get_settings_text( 'extra_2' );
538
+ }
539
+ public function extra_2() {
540
+ echo $this->get_extra_2();
541
+ }
542
+
543
+ /**
544
+ * Return/Show Extra field 3
545
+ */
546
+ public function get_extra_3() {
547
+ return $this->get_settings_text( 'extra_3' );
548
+ }
549
+ public function extra_3() {
550
+ echo $this->get_extra_3();
551
+ }
552
+
553
+ /*
554
+ |--------------------------------------------------------------------------
555
+ | Output functions
556
+ |--------------------------------------------------------------------------
557
+ */
558
+
559
+ public function get_pdf() {
560
+ do_action( 'wpo_wcpdf_before_pdf', $this->get_type(), $this );
561
+
562
+ $pdf_settings = array(
563
+ 'paper_size' => apply_filters( 'wpo_wcpdf_paper_format', $this->get_setting( 'paper_size', 'A4' ), $this->get_type() ),
564
+ 'paper_orientation' => apply_filters( 'wpo_wcpdf_paper_orientation', 'portrait', $this->get_type() ),
565
+ 'font_subsetting' => $this->get_setting( 'font_subsetting', false ),
566
+ );
567
+ $pdf_maker = wcpdf_get_pdf_maker( $this->get_html(), $pdf_settings );
568
+ $pdf = $pdf_maker->output();
569
+
570
+ do_action( 'wpo_wcpdf_after_pdf', $this->get_type(), $this );
571
+ do_action( 'wpo_wcpdf_pdf_created', $pdf, $this );
572
+
573
+ return apply_filters( 'wpo_wcpdf_get_pdf', $pdf, $this );
574
+ }
575
+
576
+ public function get_html( $args = array() ) {
577
+ do_action( 'wpo_wcpdf_before_html', $this->get_type(), $this );
578
+ $default_args = array (
579
+ 'wrap_html_content' => true,
580
+ );
581
+ $args = $args + $default_args;
582
+
583
+ $html = $this->render_template( $this->locate_template_file( "{$this->type}.php" ), array(
584
+ 'order' => $this->order,
585
+ 'order_id' => $this->order_id,
586
+ )
587
+ );
588
+ if ($args['wrap_html_content']) {
589
+ $html = $this->wrap_html_content( $html );
590
+ }
591
+
592
+ // clean up special characters
593
+ if ( function_exists('utf8_decode') && function_exists('mb_convert_encoding') ) {
594
+ $html = utf8_decode(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
595
+ }
596
+
597
+ do_action( 'wpo_wcpdf_after_html', $this->get_type(), $this );
598
+
599
+ return apply_filters( 'wpo_wcpdf_get_html', $html, $this );
600
+ }
601
+
602
+ public function output_pdf( $output_mode = 'download' ) {
603
+ $pdf = $this->get_pdf();
604
+ wcpdf_pdf_headers( $this->get_filename(), $output_mode, $pdf );
605
+ echo $pdf;
606
+ die();
607
+ }
608
+
609
+ public function output_html() {
610
+ echo $this->get_html();
611
+ die();
612
+ }
613
+
614
+ public function wrap_html_content( $content ) {
615
+ if ( WPO_WCPDF()->legacy_mode_enabled() ) {
616
+ $GLOBALS['wpo_wcpdf']->export->output_body = $content;
617
+ }
618
+
619
+ $html = $this->render_template( $this->locate_template_file( "html-document-wrapper.php" ), array(
620
+ 'content' => $content,
621
+ )
622
+ );
623
+ return $html;
624
+ }
625
+
626
+ public function get_filename( $context = 'download', $args = array() ) {
627
+ $order_count = isset($args['order_ids']) ? count($args['order_ids']) : 1;
628
+
629
+ $name = $this->get_type();
630
+ if ( get_post_type( $this->order_id ) == 'shop_order_refund' ) {
631
+ $number = $this->order_id;
632
+ } else {
633
+ $number = method_exists( $this->order, 'get_order_number' ) ? $this->order->get_order_number() : '';
634
+ }
635
+
636
+ if ( $order_count == 1 ) {
637
+ $suffix = $number;
638
+ } else {
639
+ $suffix = date('Y-m-d'); // 2020-11-11
640
+ }
641
+
642
+ $filename = $name . '-' . $suffix . '.pdf';
643
+
644
+ // Filter filename
645
+ $order_ids = isset($args['order_ids']) ? $args['order_ids'] : array( $this->order_id );
646
+ $filename = apply_filters( 'wpo_wcpdf_filename', $filename, $this->get_type(), $order_ids, $context );
647
+
648
+ // sanitize filename (after filters to prevent human errors)!
649
+ return sanitize_file_name( $filename );
650
+ }
651
+
652
+ public function get_template_path() {
653
+ return WPO_WCPDF()->settings->get_template_path();
654
+ }
655
+
656
+ public function locate_template_file( $file ) {
657
+ if (empty($file)) {
658
+ $file = $this->type.'.php';
659
+ }
660
+ $path = WPO_WCPDF()->settings->get_template_path( $file );
661
+ $file_path = "{$path}/{$file}";
662
+
663
+ $fallback_file_path = WPO_WCPDF()->plugin_path() . '/templates/Simple/' . $file;
664
+ if ( !file_exists( $file_path ) && file_exists( $fallback_file_path ) ) {
665
+ $file_path = $fallback_file_path;
666
+ }
667
+
668
+ $file_path = apply_filters( 'wpo_wcpdf_template_file', $file_path, $this->type, $this->order );
669
+
670
+ return $file_path;
671
+ }
672
+
673
+ public function render_template( $file, $args = array() ) {
674
+ do_action( 'wpo_wcpdf_process_template', $this->get_type(), $this );
675
+
676
+ if ( ! empty( $args ) && is_array( $args ) ) {
677
+ extract( $args );
678
+ }
679
+ ob_start();
680
+ if (file_exists($file)) {
681
+ include($file);
682
+ }
683
+ return ob_get_clean();
684
+ }
685
+
686
+ /*
687
+ |--------------------------------------------------------------------------
688
+ | Settings helper functions
689
+ |--------------------------------------------------------------------------
690
+ */
691
+
692
+ /**
693
+ * get all emails registered in WooCommerce
694
+ * @param boolean $remove_defaults switch to remove default woocommerce emails
695
+ * @return array $emails list of all email ids/slugs and names
696
+ */
697
+ public function get_wc_emails() {
698
+ // get emails from WooCommerce
699
+ global $woocommerce;
700
+ $mailer = $woocommerce->mailer();
701
+ $wc_emails = $mailer->get_emails();
702
+
703
+ $non_order_emails = array(
704
+ 'customer_note',
705
+ 'customer_reset_password',
706
+ 'customer_new_account'
707
+ );
708
+
709
+ $emails = array();
710
+ foreach ($wc_emails as $class => $email) {
711
+ if ( !in_array( $email->id, $non_order_emails ) ) {
712
+ switch ($email->id) {
713
+ case 'new_order':
714
+ $emails[$email->id] = sprintf('%s (%s)', $email->title, __( 'Admin email', 'woocommerce-pdf-invoices-packing-slips' ) );
715
+ break;
716
+ case 'customer_invoice':
717
+ $emails[$email->id] = sprintf('%s (%s)', $email->title, __( 'Manual email', 'woocommerce-pdf-invoices-packing-slips' ) );
718
+ break;
719
+ default:
720
+ $emails[$email->id] = $email->title;
721
+ break;
722
+ }
723
+ }
724
+ }
725
+
726
+ return apply_filters( 'wpo_wcpdf_wc_emails', $emails );
727
+ }
728
+
729
+ // get list of WooCommerce statuses
730
+ public function get_wc_order_status_list() {
731
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
732
+ $statuses = (array) get_terms( 'shop_order_status', array( 'hide_empty' => 0, 'orderby' => 'id' ) );
733
+ foreach ( $statuses as $status ) {
734
+ $order_statuses[esc_attr( $status->slug )] = esc_html__( $status->name, 'woocommerce' );
735
+ }
736
+ } else {
737
+ $statuses = wc_get_order_statuses();
738
+ foreach ( $statuses as $status_slug => $status ) {
739
+ $status_slug = 'wc-' === substr( $status_slug, 0, 3 ) ? substr( $status_slug, 3 ) : $status_slug;
740
+ $order_statuses[$status_slug] = $status;
741
+ }
742
+ }
743
+ return $order_statuses;
744
+ }
745
+
746
+
747
+ }
748
+
749
+ endif; // class_exists
includes/documents/class-wcpdf-document-number.php CHANGED
@@ -65,7 +65,7 @@ class Document_Number {
65
 
66
  public function __construct( $number, $settings = array(), $document = null, $order = null ) {
67
  $number = apply_filters( 'wpo_wcpdf_raw_document_number', $number, $settings, $document, $order );
68
- if ( !is_array( $number ) ) {
69
  // we're creating a new number with settings as passed
70
  $this->number = $number;
71
 
65
 
66
  public function __construct( $number, $settings = array(), $document = null, $order = null ) {
67
  $number = apply_filters( 'wpo_wcpdf_raw_document_number', $number, $settings, $document, $order );
68
+ if ( !is_array( $number ) && !empty( $number ) ) {
69
  // we're creating a new number with settings as passed
70
  $this->number = $number;
71
 
includes/documents/class-wcpdf-invoice.php CHANGED
@@ -36,6 +36,17 @@ class Invoice extends Order_Document_Methods {
36
  parent::__construct( $order );
37
  }
38
 
 
 
 
 
 
 
 
 
 
 
 
39
  public function get_title() {
40
  // override/not using $this->title to allow for language switching!
41
  return apply_filters( "wpo_wcpdf_{$this->slug}_title", __( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' ), $this );
@@ -321,9 +332,22 @@ class Invoice extends Order_Document_Methods {
321
  'description' => __( "Disable automatic creation/attachment when only free products are ordered", 'woocommerce-pdf-invoices-packing-slips' ),
322
  )
323
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  );
325
 
326
-
327
  // remove/rename some fields when invoice number is controlled externally
328
  if( apply_filters('woocommerce_invoice_number_by_plugin', false) ) {
329
  $remove_settings = array( 'next_invoice_number', 'number_format', 'reset_number_yearly' );
36
  parent::__construct( $order );
37
  }
38
 
39
+ public function use_historical_settings() {
40
+ $document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
41
+ // this setting is inverted on the frontend so that it needs to be actively/purposely enabled to be used
42
+ if (!empty($document_settings) && isset($document_settings['use_latest_settings'])) {
43
+ $use_historical_settings = false;
44
+ } else {
45
+ $use_historical_settings = true;
46
+ }
47
+ return apply_filters( 'wpo_wcpdf_document_use_historical_settings', $use_historical_settings, $this );
48
+ }
49
+
50
  public function get_title() {
51
  // override/not using $this->title to allow for language switching!
52
  return apply_filters( "wpo_wcpdf_{$this->slug}_title", __( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' ), $this );
332
  'description' => __( "Disable automatic creation/attachment when only free products are ordered", 'woocommerce-pdf-invoices-packing-slips' ),
333
  )
334
  ),
335
+ array(
336
+ 'type' => 'setting',
337
+ 'id' => 'use_latest_settings',
338
+ 'title' => __( 'Always use most current settings', 'woocommerce-pdf-invoices-packing-slips' ),
339
+ 'callback' => 'checkbox',
340
+ 'section' => 'invoice',
341
+ 'args' => array(
342
+ 'option_name' => $option_name,
343
+ 'id' => 'use_latest_settings',
344
+ 'description' => __( "When enabled, the document will always reflect the most current settings (such as footer text, document name, etc.) rather than using historical settings.", 'woocommerce-pdf-invoices-packing-slips' )
345
+ . "<br>"
346
+ . __( "<strong>Caution:</strong> enabling this will also mean that if you change your company name or address in the future, previously generated documents will also be affected.", 'woocommerce-pdf-invoices-packing-slips' ),
347
+ )
348
+ ),
349
  );
350
 
 
351
  // remove/rename some fields when invoice number is controlled externally
352
  if( apply_filters('woocommerce_invoice_number_by_plugin', false) ) {
353
  $remove_settings = array( 'next_invoice_number', 'number_format', 'reset_number_yearly' );
readme.txt CHANGED
@@ -1,282 +1,287 @@
1
- === WooCommerce PDF Invoices & Packing Slips ===
2
- 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: 4.9
7
- Requires PHP: 5.3
8
- Stable tag: 2.2.1
9
- License: GPLv2 or later
10
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
-
12
- Create, print & automatically email PDF invoices & packing slips for WooCommerce orders.
13
-
14
- == Description ==
15
-
16
- This WooCommerce extension automatically adds a PDF invoice to the order confirmation emails sent out to your customers. Includes a basic template (additional templates are available from [WP Overnight](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)) as well as the possibility to modify/create your own templates. In addition, you can choose to download or print invoices and packing slips from the WooCommerce order admin.
17
-
18
- = Main features =
19
- * Automatically attach invoice PDF to WooCommerce emails of your choice
20
- * Download the PDF invoice / packing slip from the order admin page
21
- * Generate PDF invoices / packings slips in bulk
22
- * **Fully customizable** HTML/CSS invoice templates
23
- * Download invoices from the My Account page
24
- * Sequential invoice numbers - with custom formatting
25
- * **Available in: Czech, Dutch, English, Finnish, French, German, Hungarian, Italian, Japanese (see FAQ for adding custom fonts!), Norwegian, Polish, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish & Ukrainian**
26
-
27
- In addition to this, we offer several premium extensions:
28
-
29
- * Create/email PDF Proforma Invoices, Credit Notes (for Refunds), email Packing Slips & more with [WooCommerce PDF Invoices & Packing Slips Professional](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
30
- * Upload all invoices automatically to Dropbox with [WooCommerce PDF Invoices & Packing Slips to Dropbox](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-dropbox/)
31
- * Automatically send new orders or packing slips to your printer, as soon as the customer orders! [WooCommerce Automatic Order Printing](https://www.simbahosting.co.uk/s3/product/woocommerce-automatic-order-printing/?affiliates=2) (from our partners at Simba Hosting)
32
- * More advanced & stylish templates with [WooCommerce PDF Invoices & Packing Slips Premium Templates](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)
33
-
34
- = Fully customizable =
35
- In addition to a number of default settings (including a custom header/logo) and several layout fields that you can use out of the box, the plugin contains HTML/CSS based templates that allow for customization & full control over the PDF output. Copy the templates to your theme folder and you don't have to worry that your customizations will be overwritten when you update the plugin.
36
-
37
- * Insert customer header image/logo
38
- * Modify shop data / footer / disclaimer etc. on the invoices & packing slips
39
- * Select paper size (Letter or A4)
40
- * Translation ready
41
-
42
- == Installation ==
43
-
44
- = Minimum Requirements =
45
-
46
- * WooCommerce 2.2 or later
47
- * WordPress 3.5 or later
48
-
49
- = Automatic installation =
50
- Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't even need to leave your web browser. To do an automatic install of WooCommerce PDF Invoices & Packing Slips, log in to your WordPress admin panel, navigate to the Plugins menu and click Add New.
51
-
52
- In the search field type "WooCommerce PDF Invoices & Packing Slips" and click Search Plugins. You can install it by simply clicking Install Now. After clicking that link you will be asked if you're sure you want to install the plugin. Click yes and WordPress will automatically complete the installation. After installation has finished, click the 'activate plugin' link.
53
-
54
- = Manual installation via the WordPress interface =
55
- 1. Download the plugin zip file to your computer
56
- 2. Go to the WordPress admin panel menu Plugins > Add New
57
- 3. Choose upload
58
- 4. Upload the plugin zip file, the plugin will now be installed
59
- 5. After installation has finished, click the 'activate plugin' link
60
-
61
- = Manual installation via FTP =
62
- 1. Download the plugin file to your computer and unzip it
63
- 2. Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress installation's wp-content/plugins/ directory.
64
- 3. Activate the plugin from the Plugins menu within the WordPress admin.
65
-
66
- == Frequently Asked Questions ==
67
-
68
- = Where can I find the documentation? =
69
-
70
- [WooCommerce PDF Invoices & Packing Slips documentation](http://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/)
71
-
72
- = It's not working! =
73
-
74
- Check out our step by step diagnostic instructions here: https://wordpress.org/support/topic/read-this-first-9/
75
-
76
-
77
-
78
-
79
-
80
- = Where can I find more templates? =
81
-
82
- Go to [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/) to checkout more templates! These include templates with more tax details and product thumbnails. Need a custom templates? Contact us at support@wpovernight.com for more information.
83
-
84
- = Can I create/send a proforma invoice or a credit note? =
85
- This is a feature of our Professional extension, which can be found at [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
86
-
87
- = Can I contribute to the code? =
88
- You're more than welcome! This plugin is hosted on github, where you can post issues or make pull requests.
89
- https://github.com/wpovernight/woocommerce-pdf-invoices-packing-slips
90
-
91
- = How can I display the HTML/CSS source for debugging/developing templates? =
92
- There's a setting on the Status tab of the settings page that allows you to toggle HTML output. Don't forget to turn if off after you're done testing!
93
-
94
-
95
- == Screenshots ==
96
-
97
- 1. Simple invoice PDF
98
- 2. Simple packing slip PDF
99
- 3. Quickly print individual invoices or packing slips from the order list
100
- 4. Print invoices or packing slips in bulk
101
- 5. Attach invoices to any WooCommerce email
102
- 6. Set shop name, address, header logo, etc.
103
-
104
- == Changelog ==
105
-
106
- = 2.2.1 =
107
- * Fix: potential number formatting issues with `wpo_wcpdf_raw_document_number` filter
108
- * Fix: prevent direct loading of template files
109
-
110
- = 2.2.0 =
111
- * Feature: Document settings are now saved per order - changing settings after a PDF has been created will no longer affect the output
112
- * Feature: Button to delete invoice or packing slip
113
- * Feature: Better error handling and logging via WC Logger (WooCommerce > Status > Logs)
114
- * Fix: Broader payment gateway compatibility (lower priority for documents initialization)
115
- * Fix: undefined variable in construct when loading document programmatically (props to Christopher)
116
- * Fix: compatibility with renamed WooCommerce plugins (settings page detection)
117
- * Tweak: Reload translations before creating attachment
118
- * Translations: Updated translations POT
119
-
120
- = 2.1.10 =
121
- * Feature: Include invoice number and date in WooCommerce data remover and exporter
122
- * Fix: Row class for Chained Products compatibility
123
- * Fix: Improved compatibility with Advanced Custom Fields
124
- * Fix: Setting for diabling for free invoices should be applied even when other plugins are applying rules
125
-
126
- = 2.1.9 =
127
- * Feature: Automatic cleanup of temporary attachments folder (settings in Status tab)
128
- * Fix: prevent infinite loop on sites without uploads folder
129
- * Fix: tag replacements for externally hosted images (CDN)
130
-
131
- = 2.1.8 =
132
- * Fix: Fatal error on PHP 5.X
133
-
134
- = 2.1.7 =
135
- * Feature: add [order_number] placeholder for number format
136
- * Feature: $order and $order_id variables now available directly template (without needing the document object)
137
- * Feature: add actions before & after addresses
138
- * Fix: Sorting orders by invoice number
139
- * Fix: Aelia Currency Switcher - use decimal & Thousand separator settings
140
- * Fix: fix jquery migrate warnings for media upload script
141
- * Tweak: add calculated tax rate to item data
142
-
143
- = 2.1.6 =
144
- * Fix: Extended currency symbol setting for WooCommerce Currency Switcher by realmag777
145
- * Fix: Apply WooCommerce decimal settings to tax rates with decimals
146
- * Tweak: Pass document object to `wpo_wcpdf_email_attachment` filter
147
-
148
- = 2.1.5 =
149
- * Feature: Filter for number store table (wpo_wcpdf_number_store_table_name)
150
- * Fix: prevent accessing order properties as custom field/order meta
151
- * Fix: prevent wrong application of wpo_wcpdf_filename filter
152
- * Fix: Improved tax rate calculation fallback
153
-
154
- = 2.1.4 =
155
- * Fix: WooCommerce 3.3 action buttons
156
- * Feature: Added row classes for WooCommerce Composite Products
157
-
158
- = 2.1.3 =
159
- * Fix: Fatal PHP error on My Account page.
160
-
161
- = 2.1.2 =
162
- * Feature: New action wpo_wcpdf_init_document
163
- * Fix: Use title getters for my-account and backend buttons
164
- * Fix: Legacy Premium Templates reference
165
- * Tweak: Skip documents overview in settings, default to invoice
166
-
167
- = 2.1.1 =
168
- * Fix: WooCommerce Order Status & Actions Manager emails compatibility
169
- * Feature: sort orders by invoice number column
170
- * Tweak: pass document object to title filters
171
- * Tweak: use title getter in template files (instead of title string)
172
-
173
- = 2.1.0 =
174
- * Feature: WooCommerce Order Status & Actions Manager emails compatibility
175
- * Fix: Better url fallback for images stored in cloud
176
- * Update: dompdf library updated to 0.8.2 - DOMDocument parser set to default again
177
-
178
- = 2.0.15 =
179
- * Fix: Prevent saving invoice number/date from order details page when not edited
180
-
181
- = 2.0.14 =
182
- * Feature: Manually resend specific order emails in WooCommerce 3.2+
183
- * Tweak: Show full size logo preview in settings
184
- * Tweak: Custom field fallback to underscore prefixed meta key
185
- * Dev: added `wpo_wcpdf_before_sequential_number_increment` action
186
-
187
- = 2.0.13 =
188
- * Fix: Minor XSS issue on settings screens by escaping and sanitizing 'tab' & 'section' GET variables. Discovered by Detectify.
189
- * Fix: Pakistani Rupee Symbol
190
- * Feature: Automatically enable extended currency symbol support for currencies not supported by Open Sans
191
- * Dev: added `wpo_wcpdf_document_number_settings` filter
192
-
193
- = 2.0.12 =
194
- * Option: Use different HTML parser (debug settings)
195
-
196
- = 2.0.11 =
197
- * Fix: Improved fonts update routine (now preserves custom fonts)
198
- * Fix: Enable HTML5 parser by default (fixes issues with libxml)
199
- * Tweak: Show both PHP & WP Memory limit in Status tab
200
-
201
- = 2.0.10 =
202
- * Fix: Set invoice number backend button
203
- * Fix: Thumbail paths
204
- * Tweak: Make dompdf options filterable
205
-
206
- = 2.0.9 =
207
- * Feature: use `[invoice_date="ymd"]` in invoice number prefix or suffix to include a specific date format in the invoice number
208
- * Fix: Postmeta table prefix for invoice counter
209
- * Fix: 0% tax rates
210
-
211
- = 2.0.8 =
212
- * Feature: Add support for Bedrock / alternative folder structures
213
- * Dev: Filter for merged documents
214
- * Fix: Better attributes fallback for product variations
215
-
216
- = 2.0.7 =
217
- * Feature: Added button to delete legacy settings
218
- * Feature: Option to enable font subsetting
219
- * Fix: Invoice number sequence for databases with alternative auto_increment_increment settings
220
- * Fix: Fallback function for MB String (mb_stripos)
221
-
222
- = 2.0.6 =
223
- * Feature: Improved third party invoice number filters (`wpo_wcpdf_external_invoice_number_enabled` & `wpo_wcpdf_external_invoice_number`)
224
- * Fix: Underline position for Open Sans font
225
- * Fix: Invoice number auto_increment for servers that restarted frequently
226
- * Fix: Dompdf log file location (preventing open base_dir notices breaking PDF header)
227
- * Fix: 1.6.6 Settings migration duplicates merging
228
- * Tweak: Clear fonts folder when manually reinstalling fonts
229
-
230
- = 2.0.5 =
231
- * Feature: Remove temporary files (Status tab)
232
- * Fix: Page number replacement
233
- * Tweak: Fallback functions for MB String extension
234
- * Tweak: Improved wpo_wcpdf_check_privs usability for my account privileges
235
- * Legacy support: added wc_price alias for format_price method in document
236
-
237
- = 2.0.4 =
238
- * Fix: Apply filters for custom invoice number formatting in document too
239
- * Fix: Parent fallback for missing dates from refunds
240
-
241
- = 2.0.3 =
242
- * Fix: Better support for legacy invoice number filter (`wpo_wcpdf_invoice_number` - replaced by `wpo_wcpdf_formatted_document_number`)
243
- * Fix: Document number formatting fallback to order date if no document date available
244
- * Fix: Updated classmap: PSR loading didn't work on some installations
245
- * Fix: Prevent order notes from all orders showing when document is not loaded properly in filter
246
- * Tweak: Disable deprecation notices during email sending
247
- * Tweak: ignore outdated language packs
248
-
249
- = 2.0.2 =
250
- * Fix: order notes using correct order_id
251
- * Fix: WC3.0 deprecation notice for currency
252
- * Fix: Avoid crashing on PHP5.2 and older
253
- * Fix: Only use PHP MB String when present
254
- * Fix: Remote images
255
- * Fix: Download option
256
-
257
- = 2.0.1 =
258
- * Fix: PHP 5.4 issue
259
-
260
- = 2.0.0 =
261
- * New: Better structured & more advanced settings for documents
262
- * New: Option to enable & disable Packing Slips or Invoices
263
- * New: Invoice number sequence stored separately for improved speed & performance
264
- * New: Completely rewritten codebase for more flexibility & better reliability
265
- * New: Updated PDF library to DOMPDF 0.8
266
- * New: PDF Library made pluggable (by using the `wpo_wcpdf_pdf_maker` filter)
267
- * New: lots of new functions & filters to allow developers to hook into the plugin
268
- * Changed: **$wpo_wcpdf variable is now deprecated** (legacy mode available & automatically enabled on update)
269
- * Fix: Improved PHP 7 & 7.1 support
270
- * Fix: Positive prices for refunds
271
- * Fix: Use parent for attributes retrieved for product variations
272
- * Fix: Set content type to PDF for download
273
-
274
- = 1.6.6 =
275
- * Feature: Facilitate downgrading from 2.0 (re-installing fonts & resetting version)
276
- * Fix: Update currencies font (added Georgian Lari)
277
- * Translations: Added Indonesian
278
-
279
- == Upgrade Notice ==
280
-
281
- = 2.1.10 =
 
 
 
 
 
282
  2.X is a BIG update! Make a full site backup before upgrading if you were using version 1.X!
1
+ === WooCommerce PDF Invoices & Packing Slips ===
2
+ 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: 4.9
7
+ Requires PHP: 5.3
8
+ Stable tag: 2.2.2
9
+ License: GPLv2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
+
12
+ Create, print & automatically email PDF invoices & packing slips for WooCommerce orders.
13
+
14
+ == Description ==
15
+
16
+ This WooCommerce extension automatically adds a PDF invoice to the order confirmation emails sent out to your customers. Includes a basic template (additional templates are available from [WP Overnight](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)) as well as the possibility to modify/create your own templates. In addition, you can choose to download or print invoices and packing slips from the WooCommerce order admin.
17
+
18
+ = Main features =
19
+ * Automatically attach invoice PDF to WooCommerce emails of your choice
20
+ * Download the PDF invoice / packing slip from the order admin page
21
+ * Generate PDF invoices / packings slips in bulk
22
+ * **Fully customizable** HTML/CSS invoice templates
23
+ * Download invoices from the My Account page
24
+ * Sequential invoice numbers - with custom formatting
25
+ * **Available in: Czech, Dutch, English, Finnish, French, German, Hungarian, Italian, Japanese (see FAQ for adding custom fonts!), Norwegian, Polish, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish & Ukrainian**
26
+
27
+ In addition to this, we offer several premium extensions:
28
+
29
+ * Create/email PDF Proforma Invoices, Credit Notes (for Refunds), email Packing Slips & more with [WooCommerce PDF Invoices & Packing Slips Professional](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
30
+ * Upload all invoices automatically to Dropbox with [WooCommerce PDF Invoices & Packing Slips to Dropbox](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-dropbox/)
31
+ * Automatically send new orders or packing slips to your printer, as soon as the customer orders! [WooCommerce Automatic Order Printing](https://www.simbahosting.co.uk/s3/product/woocommerce-automatic-order-printing/?affiliates=2) (from our partners at Simba Hosting)
32
+ * More advanced & stylish templates with [WooCommerce PDF Invoices & Packing Slips Premium Templates](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)
33
+
34
+ = Fully customizable =
35
+ In addition to a number of default settings (including a custom header/logo) and several layout fields that you can use out of the box, the plugin contains HTML/CSS based templates that allow for customization & full control over the PDF output. Copy the templates to your theme folder and you don't have to worry that your customizations will be overwritten when you update the plugin.
36
+
37
+ * Insert customer header image/logo
38
+ * Modify shop data / footer / disclaimer etc. on the invoices & packing slips
39
+ * Select paper size (Letter or A4)
40
+ * Translation ready
41
+
42
+ == Installation ==
43
+
44
+ = Minimum Requirements =
45
+
46
+ * WooCommerce 2.2 or later
47
+ * WordPress 3.5 or later
48
+
49
+ = Automatic installation =
50
+ Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't even need to leave your web browser. To do an automatic install of WooCommerce PDF Invoices & Packing Slips, log in to your WordPress admin panel, navigate to the Plugins menu and click Add New.
51
+
52
+ In the search field type "WooCommerce PDF Invoices & Packing Slips" and click Search Plugins. You can install it by simply clicking Install Now. After clicking that link you will be asked if you're sure you want to install the plugin. Click yes and WordPress will automatically complete the installation. After installation has finished, click the 'activate plugin' link.
53
+
54
+ = Manual installation via the WordPress interface =
55
+ 1. Download the plugin zip file to your computer
56
+ 2. Go to the WordPress admin panel menu Plugins > Add New
57
+ 3. Choose upload
58
+ 4. Upload the plugin zip file, the plugin will now be installed
59
+ 5. After installation has finished, click the 'activate plugin' link
60
+
61
+ = Manual installation via FTP =
62
+ 1. Download the plugin file to your computer and unzip it
63
+ 2. Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress installation's wp-content/plugins/ directory.
64
+ 3. Activate the plugin from the Plugins menu within the WordPress admin.
65
+
66
+ == Frequently Asked Questions ==
67
+
68
+ = Where can I find the documentation? =
69
+
70
+ [WooCommerce PDF Invoices & Packing Slips documentation](http://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/)
71
+
72
+ = It's not working! =
73
+
74
+ Check out our step by step diagnostic instructions here: https://wordpress.org/support/topic/read-this-first-9/
75
+
76
+
77
+
78
+
79
+
80
+ = Where can I find more templates? =
81
+
82
+ Go to [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/) to checkout more templates! These include templates with more tax details and product thumbnails. Need a custom templates? Contact us at support@wpovernight.com for more information.
83
+
84
+ = Can I create/send a proforma invoice or a credit note? =
85
+ This is a feature of our Professional extension, which can be found at [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
86
+
87
+ = Can I contribute to the code? =
88
+ You're more than welcome! This plugin is hosted on github, where you can post issues or make pull requests.
89
+ https://github.com/wpovernight/woocommerce-pdf-invoices-packing-slips
90
+
91
+ = How can I display the HTML/CSS source for debugging/developing templates? =
92
+ There's a setting on the Status tab of the settings page that allows you to toggle HTML output. Don't forget to turn if off after you're done testing!
93
+
94
+
95
+ == Screenshots ==
96
+
97
+ 1. Simple invoice PDF
98
+ 2. Simple packing slip PDF
99
+ 3. Quickly print individual invoices or packing slips from the order list
100
+ 4. Print invoices or packing slips in bulk
101
+ 5. Attach invoices to any WooCommerce email
102
+ 6. Set shop name, address, header logo, etc.
103
+
104
+ == Changelog ==
105
+
106
+ = 2.2.2 =
107
+ * Feature: Added option to always use most current settings for the invoice
108
+ * Fix: Double check for empty document numbers on initialization
109
+ * New filter: `wpo_wcpdf_output_format` to set output per document type
110
+
111
+ = 2.2.1 =
112
+ * Fix: potential number formatting issues with `wpo_wcpdf_raw_document_number` filter
113
+ * Fix: prevent direct loading of template files
114
+
115
+ = 2.2.0 =
116
+ * Feature: Document settings are now saved per order - changing settings after a PDF has been created will no longer affect the output
117
+ * Feature: Button to delete invoice or packing slip
118
+ * Feature: Better error handling and logging via WC Logger (WooCommerce > Status > Logs)
119
+ * Fix: Broader payment gateway compatibility (lower priority for documents initialization)
120
+ * Fix: undefined variable in construct when loading document programmatically (props to Christopher)
121
+ * Fix: compatibility with renamed WooCommerce plugins (settings page detection)
122
+ * Tweak: Reload translations before creating attachment
123
+ * Translations: Updated translations POT
124
+
125
+ = 2.1.10 =
126
+ * Feature: Include invoice number and date in WooCommerce data remover and exporter
127
+ * Fix: Row class for Chained Products compatibility
128
+ * Fix: Improved compatibility with Advanced Custom Fields
129
+ * Fix: Setting for diabling for free invoices should be applied even when other plugins are applying rules
130
+
131
+ = 2.1.9 =
132
+ * Feature: Automatic cleanup of temporary attachments folder (settings in Status tab)
133
+ * Fix: prevent infinite loop on sites without uploads folder
134
+ * Fix: tag replacements for externally hosted images (CDN)
135
+
136
+ = 2.1.8 =
137
+ * Fix: Fatal error on PHP 5.X
138
+
139
+ = 2.1.7 =
140
+ * Feature: add [order_number] placeholder for number format
141
+ * Feature: $order and $order_id variables now available directly template (without needing the document object)
142
+ * Feature: add actions before & after addresses
143
+ * Fix: Sorting orders by invoice number
144
+ * Fix: Aelia Currency Switcher - use decimal & Thousand separator settings
145
+ * Fix: fix jquery migrate warnings for media upload script
146
+ * Tweak: add calculated tax rate to item data
147
+
148
+ = 2.1.6 =
149
+ * Fix: Extended currency symbol setting for WooCommerce Currency Switcher by realmag777
150
+ * Fix: Apply WooCommerce decimal settings to tax rates with decimals
151
+ * Tweak: Pass document object to `wpo_wcpdf_email_attachment` filter
152
+
153
+ = 2.1.5 =
154
+ * Feature: Filter for number store table (wpo_wcpdf_number_store_table_name)
155
+ * Fix: prevent accessing order properties as custom field/order meta
156
+ * Fix: prevent wrong application of wpo_wcpdf_filename filter
157
+ * Fix: Improved tax rate calculation fallback
158
+
159
+ = 2.1.4 =
160
+ * Fix: WooCommerce 3.3 action buttons
161
+ * Feature: Added row classes for WooCommerce Composite Products
162
+
163
+ = 2.1.3 =
164
+ * Fix: Fatal PHP error on My Account page.
165
+
166
+ = 2.1.2 =
167
+ * Feature: New action wpo_wcpdf_init_document
168
+ * Fix: Use title getters for my-account and backend buttons
169
+ * Fix: Legacy Premium Templates reference
170
+ * Tweak: Skip documents overview in settings, default to invoice
171
+
172
+ = 2.1.1 =
173
+ * Fix: WooCommerce Order Status & Actions Manager emails compatibility
174
+ * Feature: sort orders by invoice number column
175
+ * Tweak: pass document object to title filters
176
+ * Tweak: use title getter in template files (instead of title string)
177
+
178
+ = 2.1.0 =
179
+ * Feature: WooCommerce Order Status & Actions Manager emails compatibility
180
+ * Fix: Better url fallback for images stored in cloud
181
+ * Update: dompdf library updated to 0.8.2 - DOMDocument parser set to default again
182
+
183
+ = 2.0.15 =
184
+ * Fix: Prevent saving invoice number/date from order details page when not edited
185
+
186
+ = 2.0.14 =
187
+ * Feature: Manually resend specific order emails in WooCommerce 3.2+
188
+ * Tweak: Show full size logo preview in settings
189
+ * Tweak: Custom field fallback to underscore prefixed meta key
190
+ * Dev: added `wpo_wcpdf_before_sequential_number_increment` action
191
+
192
+ = 2.0.13 =
193
+ * Fix: Minor XSS issue on settings screens by escaping and sanitizing 'tab' & 'section' GET variables. Discovered by Detectify.
194
+ * Fix: Pakistani Rupee Symbol
195
+ * Feature: Automatically enable extended currency symbol support for currencies not supported by Open Sans
196
+ * Dev: added `wpo_wcpdf_document_number_settings` filter
197
+
198
+ = 2.0.12 =
199
+ * Option: Use different HTML parser (debug settings)
200
+
201
+ = 2.0.11 =
202
+ * Fix: Improved fonts update routine (now preserves custom fonts)
203
+ * Fix: Enable HTML5 parser by default (fixes issues with libxml)
204
+ * Tweak: Show both PHP & WP Memory limit in Status tab
205
+
206
+ = 2.0.10 =
207
+ * Fix: Set invoice number backend button
208
+ * Fix: Thumbail paths
209
+ * Tweak: Make dompdf options filterable
210
+
211
+ = 2.0.9 =
212
+ * Feature: use `[invoice_date="ymd"]` in invoice number prefix or suffix to include a specific date format in the invoice number
213
+ * Fix: Postmeta table prefix for invoice counter
214
+ * Fix: 0% tax rates
215
+
216
+ = 2.0.8 =
217
+ * Feature: Add support for Bedrock / alternative folder structures
218
+ * Dev: Filter for merged documents
219
+ * Fix: Better attributes fallback for product variations
220
+
221
+ = 2.0.7 =
222
+ * Feature: Added button to delete legacy settings
223
+ * Feature: Option to enable font subsetting
224
+ * Fix: Invoice number sequence for databases with alternative auto_increment_increment settings
225
+ * Fix: Fallback function for MB String (mb_stripos)
226
+
227
+ = 2.0.6 =
228
+ * Feature: Improved third party invoice number filters (`wpo_wcpdf_external_invoice_number_enabled` & `wpo_wcpdf_external_invoice_number`)
229
+ * Fix: Underline position for Open Sans font
230
+ * Fix: Invoice number auto_increment for servers that restarted frequently
231
+ * Fix: Dompdf log file location (preventing open base_dir notices breaking PDF header)
232
+ * Fix: 1.6.6 Settings migration duplicates merging
233
+ * Tweak: Clear fonts folder when manually reinstalling fonts
234
+
235
+ = 2.0.5 =
236
+ * Feature: Remove temporary files (Status tab)
237
+ * Fix: Page number replacement
238
+ * Tweak: Fallback functions for MB String extension
239
+ * Tweak: Improved wpo_wcpdf_check_privs usability for my account privileges
240
+ * Legacy support: added wc_price alias for format_price method in document
241
+
242
+ = 2.0.4 =
243
+ * Fix: Apply filters for custom invoice number formatting in document too
244
+ * Fix: Parent fallback for missing dates from refunds
245
+
246
+ = 2.0.3 =
247
+ * Fix: Better support for legacy invoice number filter (`wpo_wcpdf_invoice_number` - replaced by `wpo_wcpdf_formatted_document_number`)
248
+ * Fix: Document number formatting fallback to order date if no document date available
249
+ * Fix: Updated classmap: PSR loading didn't work on some installations
250
+ * Fix: Prevent order notes from all orders showing when document is not loaded properly in filter
251
+ * Tweak: Disable deprecation notices during email sending
252
+ * Tweak: ignore outdated language packs
253
+
254
+ = 2.0.2 =
255
+ * Fix: order notes using correct order_id
256
+ * Fix: WC3.0 deprecation notice for currency
257
+ * Fix: Avoid crashing on PHP5.2 and older
258
+ * Fix: Only use PHP MB String when present
259
+ * Fix: Remote images
260
+ * Fix: Download option
261
+
262
+ = 2.0.1 =
263
+ * Fix: PHP 5.4 issue
264
+
265
+ = 2.0.0 =
266
+ * New: Better structured & more advanced settings for documents
267
+ * New: Option to enable & disable Packing Slips or Invoices
268
+ * New: Invoice number sequence stored separately for improved speed & performance
269
+ * New: Completely rewritten codebase for more flexibility & better reliability
270
+ * New: Updated PDF library to DOMPDF 0.8
271
+ * New: PDF Library made pluggable (by using the `wpo_wcpdf_pdf_maker` filter)
272
+ * New: lots of new functions & filters to allow developers to hook into the plugin
273
+ * Changed: **$wpo_wcpdf variable is now deprecated** (legacy mode available & automatically enabled on update)
274
+ * Fix: Improved PHP 7 & 7.1 support
275
+ * Fix: Positive prices for refunds
276
+ * Fix: Use parent for attributes retrieved for product variations
277
+ * Fix: Set content type to PDF for download
278
+
279
+ = 1.6.6 =
280
+ * Feature: Facilitate downgrading from 2.0 (re-installing fonts & resetting version)
281
+ * Fix: Update currencies font (added Georgian Lari)
282
+ * Translations: Added Indonesian
283
+
284
+ == Upgrade Notice ==
285
+
286
+ = 2.1.10 =
287
  2.X is a BIG update! Make a full site backup before upgrading if you were using version 1.X!
templates/Simple/html-document-wrapper.php CHANGED
@@ -1,13 +1,13 @@
1
- <?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
2
- <!DOCTYPE html>
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>
10
- <body class="<?php echo $this->get_type(); ?>">
11
- <?php echo $content; ?>
12
- </body>
13
  </html>
1
+ <?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
2
+ <!DOCTYPE html>
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>
10
+ <body class="<?php echo $this->get_type(); ?>">
11
+ <?php echo $content; ?>
12
+ </body>
13
  </html>
templates/Simple/invoice.php CHANGED
@@ -1,149 +1,149 @@
1
- <?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
2
- <?php do_action( 'wpo_wcpdf_before_document', $this->type, $this->order ); ?>
3
-
4
- <table class="head container">
5
- <tr>
6
- <td class="header">
7
- <?php
8
- if( $this->has_header_logo() ) {
9
- $this->header_logo();
10
- } else {
11
- echo $this->get_title();
12
- }
13
- ?>
14
- </td>
15
- <td class="shop-info">
16
- <div class="shop-name"><h3><?php $this->shop_name(); ?></h3></div>
17
- <div class="shop-address"><?php $this->shop_address(); ?></div>
18
- </td>
19
- </tr>
20
- </table>
21
-
22
- <h1 class="document-type-label">
23
- <?php if( $this->has_header_logo() ) echo $this->get_title(); ?>
24
- </h1>
25
-
26
- <?php do_action( 'wpo_wcpdf_after_document_label', $this->type, $this->order ); ?>
27
-
28
- <table class="order-data-addresses">
29
- <tr>
30
- <td class="address billing-address">
31
- <!-- <h3><?php _e( 'Billing Address:', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3> -->
32
- <?php do_action( 'wpo_wcpdf_before_billing_address', $this->type, $this->order ); ?>
33
- <?php $this->billing_address(); ?>
34
- <?php do_action( 'wpo_wcpdf_after_billing_address', $this->type, $this->order ); ?>
35
- <?php if ( isset($this->settings['display_email']) ) { ?>
36
- <div class="billing-email"><?php $this->billing_email(); ?></div>
37
- <?php } ?>
38
- <?php if ( isset($this->settings['display_phone']) ) { ?>
39
- <div class="billing-phone"><?php $this->billing_phone(); ?></div>
40
- <?php } ?>
41
- </td>
42
- <td class="address shipping-address">
43
- <?php if ( isset($this->settings['display_shipping_address']) && $this->ships_to_different_address()) { ?>
44
- <h3><?php _e( 'Ship To:', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
45
- <?php do_action( 'wpo_wcpdf_before_shipping_address', $this->type, $this->order ); ?>
46
- <?php $this->shipping_address(); ?>
47
- <?php do_action( 'wpo_wcpdf_after_shipping_address', $this->type, $this->order ); ?>
48
- <?php } ?>
49
- </td>
50
- <td class="order-data">
51
- <table>
52
- <?php do_action( 'wpo_wcpdf_before_order_data', $this->type, $this->order ); ?>
53
- <?php if ( isset($this->settings['display_number']) ) { ?>
54
- <tr class="invoice-number">
55
- <th><?php _e( 'Invoice Number:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
56
- <td><?php $this->invoice_number(); ?></td>
57
- </tr>
58
- <?php } ?>
59
- <?php if ( isset($this->settings['display_date']) ) { ?>
60
- <tr class="invoice-date">
61
- <th><?php _e( 'Invoice Date:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
62
- <td><?php $this->invoice_date(); ?></td>
63
- </tr>
64
- <?php } ?>
65
- <tr class="order-number">
66
- <th><?php _e( 'Order Number:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
67
- <td><?php $this->order_number(); ?></td>
68
- </tr>
69
- <tr class="order-date">
70
- <th><?php _e( 'Order Date:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
71
- <td><?php $this->order_date(); ?></td>
72
- </tr>
73
- <tr class="payment-method">
74
- <th><?php _e( 'Payment Method:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
75
- <td><?php $this->payment_method(); ?></td>
76
- </tr>
77
- <?php do_action( 'wpo_wcpdf_after_order_data', $this->type, $this->order ); ?>
78
- </table>
79
- </td>
80
- </tr>
81
- </table>
82
-
83
- <?php do_action( 'wpo_wcpdf_before_order_details', $this->type, $this->order ); ?>
84
-
85
- <table class="order-details">
86
- <thead>
87
- <tr>
88
- <th class="product"><?php _e('Product', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
89
- <th class="quantity"><?php _e('Quantity', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
90
- <th class="price"><?php _e('Price', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
91
- </tr>
92
- </thead>
93
- <tbody>
94
- <?php $items = $this->get_order_items(); if( sizeof( $items ) > 0 ) : foreach( $items as $item_id => $item ) : ?>
95
- <tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', $item_id, $this->type, $this->order, $item_id ); ?>">
96
- <td class="product">
97
- <?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
98
- <span class="item-name"><?php echo $item['name']; ?></span>
99
- <?php do_action( 'wpo_wcpdf_before_item_meta', $this->type, $item, $this->order ); ?>
100
- <span class="item-meta"><?php echo $item['meta']; ?></span>
101
- <dl class="meta">
102
- <?php $description_label = __( 'SKU', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
103
- <?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; ?>
104
- <?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; ?>
105
- </dl>
106
- <?php do_action( 'wpo_wcpdf_after_item_meta', $this->type, $item, $this->order ); ?>
107
- </td>
108
- <td class="quantity"><?php echo $item['quantity']; ?></td>
109
- <td class="price"><?php echo $item['order_price']; ?></td>
110
- </tr>
111
- <?php endforeach; endif; ?>
112
- </tbody>
113
- <tfoot>
114
- <tr class="no-borders">
115
- <td class="no-borders">
116
- <div class="customer-notes">
117
- <?php do_action( 'wpo_wcpdf_before_customer_notes', $this->type, $this->order ); ?>
118
- <?php if ( $this->get_shipping_notes() ) : ?>
119
- <h3><?php _e( 'Customer Notes', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
120
- <?php $this->shipping_notes(); ?>
121
- <?php endif; ?>
122
- <?php do_action( 'wpo_wcpdf_after_customer_notes', $this->type, $this->order ); ?>
123
- </div>
124
- </td>
125
- <td class="no-borders" colspan="2">
126
- <table class="totals">
127
- <tfoot>
128
- <?php foreach( $this->get_woocommerce_totals() as $key => $total ) : ?>
129
- <tr class="<?php echo $key; ?>">
130
- <td class="no-borders"></td>
131
- <th class="description"><?php echo $total['label']; ?></th>
132
- <td class="price"><span class="totals-price"><?php echo $total['value']; ?></span></td>
133
- </tr>
134
- <?php endforeach; ?>
135
- </tfoot>
136
- </table>
137
- </td>
138
- </tr>
139
- </tfoot>
140
- </table>
141
-
142
- <?php do_action( 'wpo_wcpdf_after_order_details', $this->type, $this->order ); ?>
143
-
144
- <?php if ( $this->get_footer() ): ?>
145
- <div id="footer">
146
- <?php $this->footer(); ?>
147
- </div><!-- #letter-footer -->
148
- <?php endif; ?>
149
- <?php do_action( 'wpo_wcpdf_after_document', $this->type, $this->order ); ?>
1
+ <?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
2
+ <?php do_action( 'wpo_wcpdf_before_document', $this->type, $this->order ); ?>
3
+
4
+ <table class="head container">
5
+ <tr>
6
+ <td class="header">
7
+ <?php
8
+ if( $this->has_header_logo() ) {
9
+ $this->header_logo();
10
+ } else {
11
+ echo $this->get_title();
12
+ }
13
+ ?>
14
+ </td>
15
+ <td class="shop-info">
16
+ <div class="shop-name"><h3><?php $this->shop_name(); ?></h3></div>
17
+ <div class="shop-address"><?php $this->shop_address(); ?></div>
18
+ </td>
19
+ </tr>
20
+ </table>
21
+
22
+ <h1 class="document-type-label">
23
+ <?php if( $this->has_header_logo() ) echo $this->get_title(); ?>
24
+ </h1>
25
+
26
+ <?php do_action( 'wpo_wcpdf_after_document_label', $this->type, $this->order ); ?>
27
+
28
+ <table class="order-data-addresses">
29
+ <tr>
30
+ <td class="address billing-address">
31
+ <!-- <h3><?php _e( 'Billing Address:', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3> -->
32
+ <?php do_action( 'wpo_wcpdf_before_billing_address', $this->type, $this->order ); ?>
33
+ <?php $this->billing_address(); ?>
34
+ <?php do_action( 'wpo_wcpdf_after_billing_address', $this->type, $this->order ); ?>
35
+ <?php if ( isset($this->settings['display_email']) ) { ?>
36
+ <div class="billing-email"><?php $this->billing_email(); ?></div>
37
+ <?php } ?>
38
+ <?php if ( isset($this->settings['display_phone']) ) { ?>
39
+ <div class="billing-phone"><?php $this->billing_phone(); ?></div>
40
+ <?php } ?>
41
+ </td>
42
+ <td class="address shipping-address">
43
+ <?php if ( isset($this->settings['display_shipping_address']) && $this->ships_to_different_address()) { ?>
44
+ <h3><?php _e( 'Ship To:', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
45
+ <?php do_action( 'wpo_wcpdf_before_shipping_address', $this->type, $this->order ); ?>
46
+ <?php $this->shipping_address(); ?>
47
+ <?php do_action( 'wpo_wcpdf_after_shipping_address', $this->type, $this->order ); ?>
48
+ <?php } ?>
49
+ </td>
50
+ <td class="order-data">
51
+ <table>
52
+ <?php do_action( 'wpo_wcpdf_before_order_data', $this->type, $this->order ); ?>
53
+ <?php if ( isset($this->settings['display_number']) ) { ?>
54
+ <tr class="invoice-number">
55
+ <th><?php _e( 'Invoice Number:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
56
+ <td><?php $this->invoice_number(); ?></td>
57
+ </tr>
58
+ <?php } ?>
59
+ <?php if ( isset($this->settings['display_date']) ) { ?>
60
+ <tr class="invoice-date">
61
+ <th><?php _e( 'Invoice Date:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
62
+ <td><?php $this->invoice_date(); ?></td>
63
+ </tr>
64
+ <?php } ?>
65
+ <tr class="order-number">
66
+ <th><?php _e( 'Order Number:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
67
+ <td><?php $this->order_number(); ?></td>
68
+ </tr>
69
+ <tr class="order-date">
70
+ <th><?php _e( 'Order Date:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
71
+ <td><?php $this->order_date(); ?></td>
72
+ </tr>
73
+ <tr class="payment-method">
74
+ <th><?php _e( 'Payment Method:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
75
+ <td><?php $this->payment_method(); ?></td>
76
+ </tr>
77
+ <?php do_action( 'wpo_wcpdf_after_order_data', $this->type, $this->order ); ?>
78
+ </table>
79
+ </td>
80
+ </tr>
81
+ </table>
82
+
83
+ <?php do_action( 'wpo_wcpdf_before_order_details', $this->type, $this->order ); ?>
84
+
85
+ <table class="order-details">
86
+ <thead>
87
+ <tr>
88
+ <th class="product"><?php _e('Product', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
89
+ <th class="quantity"><?php _e('Quantity', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
90
+ <th class="price"><?php _e('Price', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
91
+ </tr>
92
+ </thead>
93
+ <tbody>
94
+ <?php $items = $this->get_order_items(); if( sizeof( $items ) > 0 ) : foreach( $items as $item_id => $item ) : ?>
95
+ <tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', $item_id, $this->type, $this->order, $item_id ); ?>">
96
+ <td class="product">
97
+ <?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
98
+ <span class="item-name"><?php echo $item['name']; ?></span>
99
+ <?php do_action( 'wpo_wcpdf_before_item_meta', $this->type, $item, $this->order ); ?>
100
+ <span class="item-meta"><?php echo $item['meta']; ?></span>
101
+ <dl class="meta">
102
+ <?php $description_label = __( 'SKU', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
103
+ <?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; ?>
104
+ <?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; ?>
105
+ </dl>
106
+ <?php do_action( 'wpo_wcpdf_after_item_meta', $this->type, $item, $this->order ); ?>
107
+ </td>
108
+ <td class="quantity"><?php echo $item['quantity']; ?></td>
109
+ <td class="price"><?php echo $item['order_price']; ?></td>
110
+ </tr>
111
+ <?php endforeach; endif; ?>
112
+ </tbody>
113
+ <tfoot>
114
+ <tr class="no-borders">
115
+ <td class="no-borders">
116
+ <div class="customer-notes">
117
+ <?php do_action( 'wpo_wcpdf_before_customer_notes', $this->type, $this->order ); ?>
118
+ <?php if ( $this->get_shipping_notes() ) : ?>
119
+ <h3><?php _e( 'Customer Notes', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
120
+ <?php $this->shipping_notes(); ?>
121
+ <?php endif; ?>
122
+ <?php do_action( 'wpo_wcpdf_after_customer_notes', $this->type, $this->order ); ?>
123
+ </div>
124
+ </td>
125
+ <td class="no-borders" colspan="2">
126
+ <table class="totals">
127
+ <tfoot>
128
+ <?php foreach( $this->get_woocommerce_totals() as $key => $total ) : ?>
129
+ <tr class="<?php echo $key; ?>">
130
+ <td class="no-borders"></td>
131
+ <th class="description"><?php echo $total['label']; ?></th>
132
+ <td class="price"><span class="totals-price"><?php echo $total['value']; ?></span></td>
133
+ </tr>
134
+ <?php endforeach; ?>
135
+ </tfoot>
136
+ </table>
137
+ </td>
138
+ </tr>
139
+ </tfoot>
140
+ </table>
141
+
142
+ <?php do_action( 'wpo_wcpdf_after_order_details', $this->type, $this->order ); ?>
143
+
144
+ <?php if ( $this->get_footer() ): ?>
145
+ <div id="footer">
146
+ <?php $this->footer(); ?>
147
+ </div><!-- #letter-footer -->
148
+ <?php endif; ?>
149
+ <?php do_action( 'wpo_wcpdf_after_document', $this->type, $this->order ); ?>
templates/Simple/packing-slip.php CHANGED
@@ -1,118 +1,118 @@
1
- <?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
2
- <?php do_action( 'wpo_wcpdf_before_document', $this->type, $this->order ); ?>
3
-
4
- <table class="head container">
5
- <tr>
6
- <td class="header">
7
- <?php
8
- if( $this->has_header_logo() ) {
9
- $this->header_logo();
10
- } else {
11
- echo $this->get_title();
12
- }
13
- ?>
14
- </td>
15
- <td class="shop-info">
16
- <div class="shop-name"><h3><?php $this->shop_name(); ?></h3></div>
17
- <div class="shop-address"><?php $this->shop_address(); ?></div>
18
- </td>
19
- </tr>
20
- </table>
21
-
22
- <h1 class="document-type-label">
23
- <?php if( $this->has_header_logo() ) echo $this->get_title(); ?>
24
- </h1>
25
-
26
- <?php do_action( 'wpo_wcpdf_after_document_label', $this->type, $this->order ); ?>
27
-
28
- <table class="order-data-addresses">
29
- <tr>
30
- <td class="address shipping-address">
31
- <!-- <h3><?php _e( 'Shipping Address:', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3> -->
32
- <?php do_action( 'wpo_wcpdf_before_shipping_address', $this->type, $this->order ); ?>
33
- <?php $this->shipping_address(); ?>
34
- <?php do_action( 'wpo_wcpdf_after_shipping_address', $this->type, $this->order ); ?>
35
- <?php if ( isset($this->settings['display_email']) ) { ?>
36
- <div class="billing-email"><?php $this->billing_email(); ?></div>
37
- <?php } ?>
38
- <?php if ( isset($this->settings['display_phone']) ) { ?>
39
- <div class="billing-phone"><?php $this->billing_phone(); ?></div>
40
- <?php } ?>
41
- </td>
42
- <td class="address billing-address">
43
- <?php if ( isset($this->settings['display_billing_address']) && $this->ships_to_different_address()) { ?>
44
- <h3><?php _e( 'Billing Address:', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
45
- <?php do_action( 'wpo_wcpdf_before_billing_address', $this->type, $this->order ); ?>
46
- <?php $this->billing_address(); ?>
47
- <?php do_action( 'wpo_wcpdf_after_billing_address', $this->type, $this->order ); ?>
48
- <?php } ?>
49
- </td>
50
- <td class="order-data">
51
- <table>
52
- <?php do_action( 'wpo_wcpdf_before_order_data', $this->type, $this->order ); ?>
53
- <tr class="order-number">
54
- <th><?php _e( 'Order Number:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
55
- <td><?php $this->order_number(); ?></td>
56
- </tr>
57
- <tr class="order-date">
58
- <th><?php _e( 'Order Date:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
59
- <td><?php $this->order_date(); ?></td>
60
- </tr>
61
- <tr class="shipping-method">
62
- <th><?php _e( 'Shipping Method:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
63
- <td><?php $this->shipping_method(); ?></td>
64
- </tr>
65
- <?php do_action( 'wpo_wcpdf_after_order_data', $this->type, $this->order ); ?>
66
- </table>
67
- </td>
68
- </tr>
69
- </table>
70
-
71
- <?php do_action( 'wpo_wcpdf_before_order_details', $this->type, $this->order ); ?>
72
-
73
- <table class="order-details">
74
- <thead>
75
- <tr>
76
- <th class="product"><?php _e('Product', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
77
- <th class="quantity"><?php _e('Quantity', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
78
- </tr>
79
- </thead>
80
- <tbody>
81
- <?php $items = $this->get_order_items(); if( sizeof( $items ) > 0 ) : foreach( $items as $item_id => $item ) : ?>
82
- <tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', $item_id, $this->type, $this->order, $item_id ); ?>">
83
- <td class="product">
84
- <?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
85
- <span class="item-name"><?php echo $item['name']; ?></span>
86
- <?php do_action( 'wpo_wcpdf_before_item_meta', $this->type, $item, $this->order ); ?>
87
- <span class="item-meta"><?php echo $item['meta']; ?></span>
88
- <dl class="meta">
89
- <?php $description_label = __( 'SKU', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
90
- <?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; ?>
91
- <?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; ?>
92
- </dl>
93
- <?php do_action( 'wpo_wcpdf_after_item_meta', $this->type, $item, $this->order ); ?>
94
- </td>
95
- <td class="quantity"><?php echo $item['quantity']; ?></td>
96
- </tr>
97
- <?php endforeach; endif; ?>
98
- </tbody>
99
- </table>
100
-
101
- <?php do_action( 'wpo_wcpdf_after_order_details', $this->type, $this->order ); ?>
102
-
103
- <?php do_action( 'wpo_wcpdf_before_customer_notes', $this->type, $this->order ); ?>
104
- <div class="customer-notes">
105
- <?php if ( $this->get_shipping_notes() ) : ?>
106
- <h3><?php _e( 'Customer Notes', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
107
- <?php $this->shipping_notes(); ?>
108
- <?php endif; ?>
109
- </div>
110
- <?php do_action( 'wpo_wcpdf_after_customer_notes', $this->type, $this->order ); ?>
111
-
112
- <?php if ( $this->get_footer() ): ?>
113
- <div id="footer">
114
- <?php $this->footer(); ?>
115
- </div><!-- #letter-footer -->
116
- <?php endif; ?>
117
-
118
  <?php do_action( 'wpo_wcpdf_after_document', $this->type, $this->order ); ?>
1
+ <?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
2
+ <?php do_action( 'wpo_wcpdf_before_document', $this->type, $this->order ); ?>
3
+
4
+ <table class="head container">
5
+ <tr>
6
+ <td class="header">
7
+ <?php
8
+ if( $this->has_header_logo() ) {
9
+ $this->header_logo();
10
+ } else {
11
+ echo $this->get_title();
12
+ }
13
+ ?>
14
+ </td>
15
+ <td class="shop-info">
16
+ <div class="shop-name"><h3><?php $this->shop_name(); ?></h3></div>
17
+ <div class="shop-address"><?php $this->shop_address(); ?></div>
18
+ </td>
19
+ </tr>
20
+ </table>
21
+
22
+ <h1 class="document-type-label">
23
+ <?php if( $this->has_header_logo() ) echo $this->get_title(); ?>
24
+ </h1>
25
+
26
+ <?php do_action( 'wpo_wcpdf_after_document_label', $this->type, $this->order ); ?>
27
+
28
+ <table class="order-data-addresses">
29
+ <tr>
30
+ <td class="address shipping-address">
31
+ <!-- <h3><?php _e( 'Shipping Address:', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3> -->
32
+ <?php do_action( 'wpo_wcpdf_before_shipping_address', $this->type, $this->order ); ?>
33
+ <?php $this->shipping_address(); ?>
34
+ <?php do_action( 'wpo_wcpdf_after_shipping_address', $this->type, $this->order ); ?>
35
+ <?php if ( isset($this->settings['display_email']) ) { ?>
36
+ <div class="billing-email"><?php $this->billing_email(); ?></div>
37
+ <?php } ?>
38
+ <?php if ( isset($this->settings['display_phone']) ) { ?>
39
+ <div class="billing-phone"><?php $this->billing_phone(); ?></div>
40
+ <?php } ?>
41
+ </td>
42
+ <td class="address billing-address">
43
+ <?php if ( isset($this->settings['display_billing_address']) && $this->ships_to_different_address()) { ?>
44
+ <h3><?php _e( 'Billing Address:', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
45
+ <?php do_action( 'wpo_wcpdf_before_billing_address', $this->type, $this->order ); ?>
46
+ <?php $this->billing_address(); ?>
47
+ <?php do_action( 'wpo_wcpdf_after_billing_address', $this->type, $this->order ); ?>
48
+ <?php } ?>
49
+ </td>
50
+ <td class="order-data">
51
+ <table>
52
+ <?php do_action( 'wpo_wcpdf_before_order_data', $this->type, $this->order ); ?>
53
+ <tr class="order-number">
54
+ <th><?php _e( 'Order Number:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
55
+ <td><?php $this->order_number(); ?></td>
56
+ </tr>
57
+ <tr class="order-date">
58
+ <th><?php _e( 'Order Date:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
59
+ <td><?php $this->order_date(); ?></td>
60
+ </tr>
61
+ <tr class="shipping-method">
62
+ <th><?php _e( 'Shipping Method:', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
63
+ <td><?php $this->shipping_method(); ?></td>
64
+ </tr>
65
+ <?php do_action( 'wpo_wcpdf_after_order_data', $this->type, $this->order ); ?>
66
+ </table>
67
+ </td>
68
+ </tr>
69
+ </table>
70
+
71
+ <?php do_action( 'wpo_wcpdf_before_order_details', $this->type, $this->order ); ?>
72
+
73
+ <table class="order-details">
74
+ <thead>
75
+ <tr>
76
+ <th class="product"><?php _e('Product', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
77
+ <th class="quantity"><?php _e('Quantity', 'woocommerce-pdf-invoices-packing-slips' ); ?></th>
78
+ </tr>
79
+ </thead>
80
+ <tbody>
81
+ <?php $items = $this->get_order_items(); if( sizeof( $items ) > 0 ) : foreach( $items as $item_id => $item ) : ?>
82
+ <tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', $item_id, $this->type, $this->order, $item_id ); ?>">
83
+ <td class="product">
84
+ <?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
85
+ <span class="item-name"><?php echo $item['name']; ?></span>
86
+ <?php do_action( 'wpo_wcpdf_before_item_meta', $this->type, $item, $this->order ); ?>
87
+ <span class="item-meta"><?php echo $item['meta']; ?></span>
88
+ <dl class="meta">
89
+ <?php $description_label = __( 'SKU', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
90
+ <?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; ?>
91
+ <?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; ?>
92
+ </dl>
93
+ <?php do_action( 'wpo_wcpdf_after_item_meta', $this->type, $item, $this->order ); ?>
94
+ </td>
95
+ <td class="quantity"><?php echo $item['quantity']; ?></td>
96
+ </tr>
97
+ <?php endforeach; endif; ?>
98
+ </tbody>
99
+ </table>
100
+
101
+ <?php do_action( 'wpo_wcpdf_after_order_details', $this->type, $this->order ); ?>
102
+
103
+ <?php do_action( 'wpo_wcpdf_before_customer_notes', $this->type, $this->order ); ?>
104
+ <div class="customer-notes">
105
+ <?php if ( $this->get_shipping_notes() ) : ?>
106
+ <h3><?php _e( 'Customer Notes', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
107
+ <?php $this->shipping_notes(); ?>
108
+ <?php endif; ?>
109
+ </div>
110
+ <?php do_action( 'wpo_wcpdf_after_customer_notes', $this->type, $this->order ); ?>
111
+
112
+ <?php if ( $this->get_footer() ): ?>
113
+ <div id="footer">
114
+ <?php $this->footer(); ?>
115
+ </div><!-- #letter-footer -->
116
+ <?php endif; ?>
117
+
118
  <?php do_action( 'wpo_wcpdf_after_document', $this->type, $this->order ); ?>
woocommerce-pdf-invoices-packingslips.php CHANGED
@@ -1,358 +1,358 @@
1
- <?php
2
- /**
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.2.1
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.5.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 = '2.2.1';
25
- public $plugin_basename;
26
- public $legacy_mode;
27
-
28
- protected static $_instance = null;
29
-
30
- /**
31
- * Main Plugin Instance
32
- *
33
- * Ensures only one instance of plugin is loaded or can be loaded.
34
- */
35
- public static function instance() {
36
- if ( is_null( self::$_instance ) ) {
37
- self::$_instance = new self();
38
- }
39
- return self::$_instance;
40
- }
41
-
42
- /**
43
- * Constructor
44
- */
45
- public function __construct() {
46
- $this->plugin_basename = plugin_basename(__FILE__);
47
-
48
- $this->define( 'WPO_WCPDF_VERSION', $this->version );
49
-
50
- // load the localisation & classes
51
- add_action( 'plugins_loaded', array( $this, 'translations' ) );
52
- add_filter( 'load_textdomain_mofile', array( $this, 'textdomain_fallback' ), 10, 2 );
53
- add_action( 'plugins_loaded', array( $this, 'load_classes' ), 9 );
54
- add_action( 'in_plugin_update_message-'.$this->plugin_basename, array( $this, 'in_plugin_update_message' ) );
55
- }
56
-
57
- /**
58
- * Define constant if not already set
59
- * @param string $name
60
- * @param string|bool $value
61
- */
62
- private function define( $name, $value ) {
63
- if ( ! defined( $name ) ) {
64
- define( $name, $value );
65
- }
66
- }
67
-
68
-
69
- /**
70
- * Load the translation / textdomain files
71
- *
72
- * Note: the first-loaded translation file overrides any following ones if the same translation is present
73
- */
74
- public function translations() {
75
- $locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce-pdf-invoices-packing-slips' );
76
- $dir = trailingslashit( WP_LANG_DIR );
77
-
78
- $textdomains = array( 'woocommerce-pdf-invoices-packing-slips' );
79
- if ( $this->legacy_mode_enabled() === true ) {
80
- $textdomains[] = 'wpo_wcpdf';
81
- }
82
-
83
- /**
84
- * Frontend/global Locale. Looks in:
85
- *
86
- * - WP_LANG_DIR/woocommerce-pdf-invoices-packing-slips/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
87
- * - WP_LANG_DIR/plugins/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
88
- * - woocommerce-pdf-invoices-packing-slips-pro/languages/woocommerce-pdf-invoices-packing-slips-LOCALE.mo (which if not found falls back to:)
89
- * - WP_LANG_DIR/plugins/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
90
- */
91
- foreach ( $textdomains as $textdomain ) {
92
- unload_textdomain( $textdomain );
93
- load_textdomain( $textdomain, $dir . 'woocommerce-pdf-invoices-packing-slips/woocommerce-pdf-invoices-packing-slips-' . $locale . '.mo' );
94
- load_textdomain( $textdomain, $dir . 'plugins/woocommerce-pdf-invoices-packing-slips-' . $locale . '.mo' );
95
- load_plugin_textdomain( $textdomain, false, dirname( plugin_basename(__FILE__) ) . '/languages' );
96
- }
97
- }
98
-
99
- /**
100
- * Maintain backwards compatibility with old translation files
101
- * Uses old .mo file if it exists in any of the override locations
102
- */
103
- public function textdomain_fallback( $mofile, $textdomain ) {
104
- $plugin_domain = 'woocommerce-pdf-invoices-packing-slips';
105
- $old_domain = 'wpo_wcpdf';
106
-
107
- if ($textdomain == $old_domain) {
108
- $textdomain = $plugin_domain;
109
- $mofile = str_replace( "{$old_domain}-", "{$textdomain}-", $mofile ); // with trailing dash to target file and not folder
110
- }
111
-
112
- if ( $textdomain === $plugin_domain ) {
113
- $old_mofile = str_replace( "{$textdomain}-", "{$old_domain}-", $mofile ); // with trailing dash to target file and not folder
114
- if ( file_exists( $old_mofile ) ) {
115
- // we have an old override - use it
116
- return $old_mofile;
117
- }
118
-
119
- // prevent loading outdated language packs
120
- $pofile = str_replace('.mo', '.po', $mofile);
121
- if ( file_exists( $pofile ) ) {
122
- // load po file
123
- $podata = file_get_contents($pofile);
124
- // set revision date threshold
125
- $block_before = strtotime( '2017-05-15' );
126
- // read revision date
127
- preg_match('~PO-Revision-Date: (.*?)\\\n~s',$podata,$matches);
128
- if (isset($matches[1])) {
129
- $revision_date = $matches[1];
130
- if ( $revision_timestamp = strtotime($revision_date) ) {
131
- // check if revision is before threshold date
132
- if ( $revision_timestamp < $block_before ) {
133
- // try bundled
134
- $bundled_file = $this->plugin_path() . '/languages/'. basename( $mofile );
135
- if (file_exists($bundled_file)) {
136
- return $bundled_file;
137
- } else {
138
- return '';
139
- }
140
- // delete po & mo file if possible
141
- // @unlink($pofile);
142
- // @unlink($mofile);
143
- }
144
- }
145
- }
146
- }
147
- }
148
-
149
- return $mofile;
150
- }
151
-
152
- /**
153
- * Load the main plugin classes and functions
154
- */
155
- public function includes() {
156
- // WooCommerce compatibility classes
157
- include_once( $this->plugin_path() . '/includes/compatibility/abstract-wc-data-compatibility.php' );
158
- include_once( $this->plugin_path() . '/includes/compatibility/class-wc-date-compatibility.php' );
159
- include_once( $this->plugin_path() . '/includes/compatibility/class-wc-core-compatibility.php' );
160
- include_once( $this->plugin_path() . '/includes/compatibility/class-wc-order-compatibility.php' );
161
- include_once( $this->plugin_path() . '/includes/compatibility/class-wc-product-compatibility.php' );
162
- include_once( $this->plugin_path() . '/includes/compatibility/wc-datetime-functions-compatibility.php' );
163
-
164
- // Third party compatibility
165
- include_once( $this->plugin_path() . '/includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php' );
166
-
167
- // Plugin classes
168
- include_once( $this->plugin_path() . '/includes/wcpdf-functions.php' );
169
- $this->settings = include_once( $this->plugin_path() . '/includes/class-wcpdf-settings.php' );
170
- $this->documents = include_once( $this->plugin_path() . '/includes/class-wcpdf-documents.php' );
171
- $this->main = include_once( $this->plugin_path() . '/includes/class-wcpdf-main.php' );
172
- include_once( $this->plugin_path() . '/includes/class-wcpdf-assets.php' );
173
- include_once( $this->plugin_path() . '/includes/class-wcpdf-admin.php' );
174
- include_once( $this->plugin_path() . '/includes/class-wcpdf-frontend.php' );
175
- include_once( $this->plugin_path() . '/includes/class-wcpdf-install.php' );
176
-
177
- // Backwards compatibility with self
178
- include_once( $this->plugin_path() . '/includes/legacy/class-wcpdf-legacy.php' );
179
- include_once( $this->plugin_path() . '/includes/legacy/class-wcpdf-legacy-deprecated-hooks.php' );
180
-
181
- // PHP MB String fallback functions
182
- include_once( $this->plugin_path() . '/includes/compatibility/mb-string-compatibility.php' );
183
- }
184
-
185
-
186
- /**
187
- * Instantiate classes when woocommerce is activated
188
- */
189
- public function load_classes() {
190
- if ( $this->is_woocommerce_activated() === false ) {
191
- add_action( 'admin_notices', array ( $this, 'need_woocommerce' ) );
192
- return;
193
- }
194
-
195
- if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
196
- add_action( 'admin_notices', array ( $this, 'required_php_version' ) );
197
- return;
198
- }
199
-
200
- // all systems ready - GO!
201
- $this->includes();
202
- }
203
-
204
- /**
205
- * Check if legacy mode is enabled
206
- */
207
- public function legacy_mode_enabled() {
208
- if (!isset($this->legacy_mode)) {
209
- $debug_settings = get_option( 'wpo_wcpdf_settings_debug' );
210
- $this->legacy_mode = isset($debug_settings['legacy_mode']);
211
- }
212
- return $this->legacy_mode;
213
- }
214
-
215
-
216
- /**
217
- * Check if woocommerce is activated
218
- */
219
- public function is_woocommerce_activated() {
220
- $blog_plugins = get_option( 'active_plugins', array() );
221
- $site_plugins = is_multisite() ? (array) maybe_unserialize( get_site_option('active_sitewide_plugins' ) ) : array();
222
-
223
- if ( in_array( 'woocommerce/woocommerce.php', $blog_plugins ) || isset( $site_plugins['woocommerce/woocommerce.php'] ) ) {
224
- return true;
225
- } else {
226
- return false;
227
- }
228
- }
229
-
230
- /**
231
- * WooCommerce not active notice.
232
- *
233
- * @return string Fallack notice.
234
- */
235
-
236
- public function need_woocommerce() {
237
- $error = sprintf( __( 'WooCommerce PDF Invoices & Packing Slips requires %sWooCommerce%s to be installed & activated!' , 'woocommerce-pdf-invoices-packing-slips' ), '<a href="http://wordpress.org/extend/plugins/woocommerce/">', '</a>' );
238
-
239
- $message = '<div class="error"><p>' . $error . '</p></div>';
240
-
241
- echo $message;
242
- }
243
-
244
- /**
245
- * PHP version requirement notice
246
- */
247
-
248
- public function required_php_version() {
249
- $error = __( 'WooCommerce PDF Invoices & Packing Slips requires PHP 5.3 or higher (5.6 or higher recommended).', 'woocommerce-pdf-invoices-packing-slips' );
250
- $how_to_update = __( 'How to update your PHP version', 'woocommerce-pdf-invoices-packing-slips' );
251
- $message = sprintf('<div class="error"><p>%s</p><p><a href="%s">%s</a></p></div>', $error, 'http://docs.wpovernight.com/general/how-to-update-your-php-version/', $how_to_update);
252
-
253
- echo $message;
254
- }
255
-
256
- /**
257
- * Show plugin changes. Code adapted from W3 Total Cache.
258
- */
259
- public function in_plugin_update_message( $args ) {
260
- $transient_name = 'wpo_wcpdf_upgrade_notice_' . $args['Version'];
261
-
262
- if ( false === ( $upgrade_notice = get_transient( $transient_name ) ) ) {
263
- $response = wp_safe_remote_get( 'https://plugins.svn.wordpress.org/woocommerce-pdf-invoices-packing-slips/trunk/readme.txt' );
264
-
265
- if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
266
- $upgrade_notice = self::parse_update_notice( $response['body'], $args['new_version'] );
267
- set_transient( $transient_name, $upgrade_notice, DAY_IN_SECONDS );
268
- }
269
- }
270
-
271
- echo wp_kses_post( $upgrade_notice );
272
- }
273
-
274
- /**
275
- * Parse update notice from readme file.
276
- *
277
- * @param string $content
278
- * @param string $new_version
279
- * @return string
280
- */
281
- private function parse_update_notice( $content, $new_version ) {
282
- // Output Upgrade Notice.
283
- $matches = null;
284
- $regexp = '~==\s*Upgrade Notice\s*==\s*=\s*(.*)\s*=(.*)(=\s*' . preg_quote( $new_version ) . '\s*=|$)~Uis';
285
- $upgrade_notice = '';
286
-
287
-
288
- if ( preg_match( $regexp, $content, $matches ) ) {
289
- $notices = (array) preg_split( '~[\r\n]+~', trim( $matches[2] ) );
290
-
291
- // Convert the full version strings to minor versions.
292
- $notice_version_parts = explode( '.', trim( $matches[1] ) );
293
- $current_version_parts = explode( '.', $this->version );
294
-
295
- if ( 3 !== sizeof( $notice_version_parts ) ) {
296
- return;
297
- }
298
-
299
- $notice_version = $notice_version_parts[0] . '.' . $notice_version_parts[1];
300
- $current_version = $current_version_parts[0] . '.' . $current_version_parts[1];
301
-
302
- // Check the latest stable version and ignore trunk.
303
- if ( version_compare( $current_version, $notice_version, '<' ) ) {
304
-
305
- $upgrade_notice .= '</p><p class="wpo_wcpdf_upgrade_notice">';
306
-
307
- foreach ( $notices as $index => $line ) {
308
- $upgrade_notice .= preg_replace( '~\[([^\]]*)\]\(([^\)]*)\)~', '<a href="${2}">${1}</a>', $line );
309
- }
310
- }
311
- }
312
-
313
- return wp_kses_post( $upgrade_notice );
314
- }
315
-
316
- /**
317
- * Get the plugin url.
318
- * @return string
319
- */
320
- public function plugin_url() {
321
- return untrailingslashit( plugins_url( '/', __FILE__ ) );
322
- }
323
-
324
- /**
325
- * Get the plugin path.
326
- * @return string
327
- */
328
- public function plugin_path() {
329
- return untrailingslashit( plugin_dir_path( __FILE__ ) );
330
- }
331
-
332
- } // class WPO_WCPDF
333
-
334
- endif; // class_exists
335
-
336
- /**
337
- * Returns the main instance of WooCommerce PDF Invoices & Packing Slips to prevent the need to use globals.
338
- *
339
- * @since 1.6
340
- * @return WPO_WCPDF
341
- */
342
- function WPO_WCPDF() {
343
- return WPO_WCPDF::instance();
344
- }
345
-
346
- WPO_WCPDF(); // load plugin
347
-
348
- // legacy class for plugin detecting
349
- if ( !class_exists( 'WooCommerce_PDF_Invoices' ) ) {
350
- class WooCommerce_PDF_Invoices{
351
- public static $version;
352
-
353
- public function __construct() {
354
- self::$version = WPO_WCPDF()->version;
355
- }
356
- }
357
- new WooCommerce_PDF_Invoices();
358
- }
1
+ <?php
2
+ /**
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.2.2
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.5.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 = '2.2.2';
25
+ public $plugin_basename;
26
+ public $legacy_mode;
27
+
28
+ protected static $_instance = null;
29
+
30
+ /**
31
+ * Main Plugin Instance
32
+ *
33
+ * Ensures only one instance of plugin is loaded or can be loaded.
34
+ */
35
+ public static function instance() {
36
+ if ( is_null( self::$_instance ) ) {
37
+ self::$_instance = new self();
38
+ }
39
+ return self::$_instance;
40
+ }
41
+
42
+ /**
43
+ * Constructor
44
+ */
45
+ public function __construct() {
46
+ $this->plugin_basename = plugin_basename(__FILE__);
47
+
48
+ $this->define( 'WPO_WCPDF_VERSION', $this->version );
49
+
50
+ // load the localisation & classes
51
+ add_action( 'plugins_loaded', array( $this, 'translations' ) );
52
+ add_filter( 'load_textdomain_mofile', array( $this, 'textdomain_fallback' ), 10, 2 );
53
+ add_action( 'plugins_loaded', array( $this, 'load_classes' ), 9 );
54
+ add_action( 'in_plugin_update_message-'.$this->plugin_basename, array( $this, 'in_plugin_update_message' ) );
55
+ }
56
+
57
+ /**
58
+ * Define constant if not already set
59
+ * @param string $name
60
+ * @param string|bool $value
61
+ */
62
+ private function define( $name, $value ) {
63
+ if ( ! defined( $name ) ) {
64
+ define( $name, $value );
65
+ }
66
+ }
67
+
68
+
69
+ /**
70
+ * Load the translation / textdomain files
71
+ *
72
+ * Note: the first-loaded translation file overrides any following ones if the same translation is present
73
+ */
74
+ public function translations() {
75
+ $locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce-pdf-invoices-packing-slips' );
76
+ $dir = trailingslashit( WP_LANG_DIR );
77
+
78
+ $textdomains = array( 'woocommerce-pdf-invoices-packing-slips' );
79
+ if ( $this->legacy_mode_enabled() === true ) {
80
+ $textdomains[] = 'wpo_wcpdf';
81
+ }
82
+
83
+ /**
84
+ * Frontend/global Locale. Looks in:
85
+ *
86
+ * - WP_LANG_DIR/woocommerce-pdf-invoices-packing-slips/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
87
+ * - WP_LANG_DIR/plugins/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
88
+ * - woocommerce-pdf-invoices-packing-slips-pro/languages/woocommerce-pdf-invoices-packing-slips-LOCALE.mo (which if not found falls back to:)
89
+ * - WP_LANG_DIR/plugins/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
90
+ */
91
+ foreach ( $textdomains as $textdomain ) {
92
+ unload_textdomain( $textdomain );
93
+ load_textdomain( $textdomain, $dir . 'woocommerce-pdf-invoices-packing-slips/woocommerce-pdf-invoices-packing-slips-' . $locale . '.mo' );
94
+ load_textdomain( $textdomain, $dir . 'plugins/woocommerce-pdf-invoices-packing-slips-' . $locale . '.mo' );
95
+ load_plugin_textdomain( $textdomain, false, dirname( plugin_basename(__FILE__) ) . '/languages' );
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Maintain backwards compatibility with old translation files
101
+ * Uses old .mo file if it exists in any of the override locations
102
+ */
103
+ public function textdomain_fallback( $mofile, $textdomain ) {
104
+ $plugin_domain = 'woocommerce-pdf-invoices-packing-slips';
105
+ $old_domain = 'wpo_wcpdf';
106
+
107
+ if ($textdomain == $old_domain) {
108
+ $textdomain = $plugin_domain;
109
+ $mofile = str_replace( "{$old_domain}-", "{$textdomain}-", $mofile ); // with trailing dash to target file and not folder
110
+ }
111
+
112
+ if ( $textdomain === $plugin_domain ) {
113
+ $old_mofile = str_replace( "{$textdomain}-", "{$old_domain}-", $mofile ); // with trailing dash to target file and not folder
114
+ if ( file_exists( $old_mofile ) ) {
115
+ // we have an old override - use it
116
+ return $old_mofile;
117
+ }
118
+
119
+ // prevent loading outdated language packs
120
+ $pofile = str_replace('.mo', '.po', $mofile);
121
+ if ( file_exists( $pofile ) ) {
122
+ // load po file
123
+ $podata = file_get_contents($pofile);
124
+ // set revision date threshold
125
+ $block_before = strtotime( '2017-05-15' );
126
+ // read revision date
127
+ preg_match('~PO-Revision-Date: (.*?)\\\n~s',$podata,$matches);
128
+ if (isset($matches[1])) {
129
+ $revision_date = $matches[1];
130
+ if ( $revision_timestamp = strtotime($revision_date) ) {
131
+ // check if revision is before threshold date
132
+ if ( $revision_timestamp < $block_before ) {
133
+ // try bundled
134
+ $bundled_file = $this->plugin_path() . '/languages/'. basename( $mofile );
135
+ if (file_exists($bundled_file)) {
136
+ return $bundled_file;
137
+ } else {
138
+ return '';
139
+ }
140
+ // delete po & mo file if possible
141
+ // @unlink($pofile);
142
+ // @unlink($mofile);
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ return $mofile;
150
+ }
151
+
152
+ /**
153
+ * Load the main plugin classes and functions
154
+ */
155
+ public function includes() {
156
+ // WooCommerce compatibility classes
157
+ include_once( $this->plugin_path() . '/includes/compatibility/abstract-wc-data-compatibility.php' );
158
+ include_once( $this->plugin_path() . '/includes/compatibility/class-wc-date-compatibility.php' );
159
+ include_once( $this->plugin_path() . '/includes/compatibility/class-wc-core-compatibility.php' );
160
+ include_once( $this->plugin_path() . '/includes/compatibility/class-wc-order-compatibility.php' );
161
+ include_once( $this->plugin_path() . '/includes/compatibility/class-wc-product-compatibility.php' );
162
+ include_once( $this->plugin_path() . '/includes/compatibility/wc-datetime-functions-compatibility.php' );
163
+
164
+ // Third party compatibility
165
+ include_once( $this->plugin_path() . '/includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php' );
166
+
167
+ // Plugin classes
168
+ include_once( $this->plugin_path() . '/includes/wcpdf-functions.php' );
169
+ $this->settings = include_once( $this->plugin_path() . '/includes/class-wcpdf-settings.php' );
170
+ $this->documents = include_once( $this->plugin_path() . '/includes/class-wcpdf-documents.php' );
171
+ $this->main = include_once( $this->plugin_path() . '/includes/class-wcpdf-main.php' );
172
+ include_once( $this->plugin_path() . '/includes/class-wcpdf-assets.php' );
173
+ include_once( $this->plugin_path() . '/includes/class-wcpdf-admin.php' );
174
+ include_once( $this->plugin_path() . '/includes/class-wcpdf-frontend.php' );
175
+ include_once( $this->plugin_path() . '/includes/class-wcpdf-install.php' );
176
+
177
+ // Backwards compatibility with self
178
+ include_once( $this->plugin_path() . '/includes/legacy/class-wcpdf-legacy.php' );
179
+ include_once( $this->plugin_path() . '/includes/legacy/class-wcpdf-legacy-deprecated-hooks.php' );
180
+
181
+ // PHP MB String fallback functions
182
+ include_once( $this->plugin_path() . '/includes/compatibility/mb-string-compatibility.php' );
183
+ }
184
+
185
+
186
+ /**
187
+ * Instantiate classes when woocommerce is activated
188
+ */
189
+ public function load_classes() {
190
+ if ( $this->is_woocommerce_activated() === false ) {
191
+ add_action( 'admin_notices', array ( $this, 'need_woocommerce' ) );
192
+ return;
193
+ }
194
+
195
+ if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
196
+ add_action( 'admin_notices', array ( $this, 'required_php_version' ) );
197
+ return;
198
+ }
199
+
200
+ // all systems ready - GO!
201
+ $this->includes();
202
+ }
203
+
204
+ /**
205
+ * Check if legacy mode is enabled
206
+ */
207
+ public function legacy_mode_enabled() {
208
+ if (!isset($this->legacy_mode)) {
209
+ $debug_settings = get_option( 'wpo_wcpdf_settings_debug' );
210
+ $this->legacy_mode = isset($debug_settings['legacy_mode']);
211
+ }
212
+ return $this->legacy_mode;
213
+ }
214
+
215
+
216
+ /**
217
+ * Check if woocommerce is activated
218
+ */
219
+ public function is_woocommerce_activated() {
220
+ $blog_plugins = get_option( 'active_plugins', array() );
221
+ $site_plugins = is_multisite() ? (array) maybe_unserialize( get_site_option('active_sitewide_plugins' ) ) : array();
222
+
223
+ if ( in_array( 'woocommerce/woocommerce.php', $blog_plugins ) || isset( $site_plugins['woocommerce/woocommerce.php'] ) ) {
224
+ return true;
225
+ } else {
226
+ return false;
227
+ }
228
+ }
229
+
230
+ /**
231
+ * WooCommerce not active notice.
232
+ *
233
+ * @return string Fallack notice.
234
+ */
235
+
236
+ public function need_woocommerce() {
237
+ $error = sprintf( __( 'WooCommerce PDF Invoices & Packing Slips requires %sWooCommerce%s to be installed & activated!' , 'woocommerce-pdf-invoices-packing-slips' ), '<a href="http://wordpress.org/extend/plugins/woocommerce/">', '</a>' );
238
+
239
+ $message = '<div class="error"><p>' . $error . '</p></div>';
240
+
241
+ echo $message;
242
+ }
243
+
244
+ /**
245
+ * PHP version requirement notice
246
+ */
247
+
248
+ public function required_php_version() {
249
+ $error = __( 'WooCommerce PDF Invoices & Packing Slips requires PHP 5.3 or higher (5.6 or higher recommended).', 'woocommerce-pdf-invoices-packing-slips' );
250
+ $how_to_update = __( 'How to update your PHP version', 'woocommerce-pdf-invoices-packing-slips' );
251
+ $message = sprintf('<div class="error"><p>%s</p><p><a href="%s">%s</a></p></div>', $error, 'http://docs.wpovernight.com/general/how-to-update-your-php-version/', $how_to_update);
252
+
253
+ echo $message;
254
+ }
255
+
256
+ /**
257
+ * Show plugin changes. Code adapted from W3 Total Cache.
258
+ */
259
+ public function in_plugin_update_message( $args ) {
260
+ $transient_name = 'wpo_wcpdf_upgrade_notice_' . $args['Version'];
261
+
262
+ if ( false === ( $upgrade_notice = get_transient( $transient_name ) ) ) {
263
+ $response = wp_safe_remote_get( 'https://plugins.svn.wordpress.org/woocommerce-pdf-invoices-packing-slips/trunk/readme.txt' );
264
+
265
+ if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
266
+ $upgrade_notice = self::parse_update_notice( $response['body'], $args['new_version'] );
267
+ set_transient( $transient_name, $upgrade_notice, DAY_IN_SECONDS );
268
+ }
269
+ }
270
+
271
+ echo wp_kses_post( $upgrade_notice );
272
+ }
273
+
274
+ /**
275
+ * Parse update notice from readme file.
276
+ *
277
+ * @param string $content
278
+ * @param string $new_version
279
+ * @return string
280
+ */
281
+ private function parse_update_notice( $content, $new_version ) {
282
+ // Output Upgrade Notice.
283
+ $matches = null;
284
+ $regexp = '~==\s*Upgrade Notice\s*==\s*=\s*(.*)\s*=(.*)(=\s*' . preg_quote( $new_version ) . '\s*=|$)~Uis';
285
+ $upgrade_notice = '';
286
+
287
+
288
+ if ( preg_match( $regexp, $content, $matches ) ) {
289
+ $notices = (array) preg_split( '~[\r\n]+~', trim( $matches[2] ) );
290
+
291
+ // Convert the full version strings to minor versions.
292
+ $notice_version_parts = explode( '.', trim( $matches[1] ) );
293
+ $current_version_parts = explode( '.', $this->version );
294
+
295
+ if ( 3 !== sizeof( $notice_version_parts ) ) {
296
+ return;
297
+ }
298
+
299
+ $notice_version = $notice_version_parts[0] . '.' . $notice_version_parts[1];
300
+ $current_version = $current_version_parts[0] . '.' . $current_version_parts[1];
301
+
302
+ // Check the latest stable version and ignore trunk.
303
+ if ( version_compare( $current_version, $notice_version, '<' ) ) {
304
+
305
+ $upgrade_notice .= '</p><p class="wpo_wcpdf_upgrade_notice">';
306
+
307
+ foreach ( $notices as $index => $line ) {
308
+ $upgrade_notice .= preg_replace( '~\[([^\]]*)\]\(([^\)]*)\)~', '<a href="${2}">${1}</a>', $line );
309
+ }
310
+ }
311
+ }
312
+
313
+ return wp_kses_post( $upgrade_notice );
314
+ }
315
+
316
+ /**
317
+ * Get the plugin url.
318
+ * @return string
319
+ */
320
+ public function plugin_url() {
321
+ return untrailingslashit( plugins_url( '/', __FILE__ ) );
322
+ }
323
+
324
+ /**
325
+ * Get the plugin path.
326
+ * @return string
327
+ */
328
+ public function plugin_path() {
329
+ return untrailingslashit( plugin_dir_path( __FILE__ ) );
330
+ }
331
+
332
+ } // class WPO_WCPDF
333
+
334
+ endif; // class_exists
335
+
336
+ /**
337
+ * Returns the main instance of WooCommerce PDF Invoices & Packing Slips to prevent the need to use globals.
338
+ *
339
+ * @since 1.6
340
+ * @return WPO_WCPDF
341
+ */
342
+ function WPO_WCPDF() {
343
+ return WPO_WCPDF::instance();
344
+ }
345
+
346
+ WPO_WCPDF(); // load plugin
347
+
348
+ // legacy class for plugin detecting
349
+ if ( !class_exists( 'WooCommerce_PDF_Invoices' ) ) {
350
+ class WooCommerce_PDF_Invoices{
351
+ public static $version;
352
+
353
+ public function __construct() {
354
+ self::$version = WPO_WCPDF()->version;
355
+ }
356
+ }
357
+ new WooCommerce_PDF_Invoices();
358
+ }