WooCommerce PDF Invoices & Packing Slips - Version 2.7.1

Version Description

  • New: Redesigned action buttons
  • New: Randomized temporary folder name for easier protection
  • New: Setting to enable/disable customer notes
  • New: Completely disable free invoice when that setting is enabled (not just attachments)
  • New: Template action hooks before and after shop name and address
  • New: Filter to set starting number for yearly reset
  • Fix: Errors on third party products without weight/sku/dimensions
  • Fix: Uneven spacing between action icons
  • Fix: Missing $email_to_send parameter for woocommerce_before_resend_order_emails hook
  • Fix: Break long words in billing address
  • Tested up to WooCommerce 4.7
Download this release

Release Info

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

Code changes from version 2.7.0 to 2.7.1

assets/css/order-styles.css CHANGED
@@ -1,6 +1,6 @@
1
  /* Order list buttons: */
2
  .type-shop_order .column-wc_actions a.button.wpo_wcpdf {
3
- padding: 2px !important;
4
  }
5
 
6
  .type-shop_order .column-wc_actions a.button.wpo_wcpdf.exists::after {
1
  /* Order list buttons: */
2
  .type-shop_order .column-wc_actions a.button.wpo_wcpdf {
3
+ padding: 3px 2px 1px 1px !important;
4
  }
5
 
6
  .type-shop_order .column-wc_actions a.button.wpo_wcpdf.exists::after {
assets/images/invoice.png DELETED
Binary file
assets/images/invoice.svg ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect x="4" y="1" width="16" height="20" rx="2" stroke="#6C45A6" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
3
+ <path d="M0 4C0 3.44772 0.447715 3 1 3H7.5C8.05228 3 8.5 3.44772 8.5 4V6.5C8.5 7.05228 8.05228 7.5 7.5 7.5H1C0.447715 7.5 0 7.05228 0 6.5V4Z" fill="#ED1C24"/>
4
+ <path d="M11.5834 17.16C10.7727 17.16 9.75404 17.0747 8.52738 16.904V15.64C8.57004 15.64 8.76204 15.6773 9.10338 15.752C9.41271 15.816 9.66871 15.864 9.87138 15.896C10.0847 15.9173 10.33 15.9387 10.6074 15.96C10.938 15.992 11.2634 16.008 11.5834 16.008V12.36H11.1194C10.106 12.36 9.38604 12.1573 8.95938 11.752C8.53271 11.3467 8.31938 10.7173 8.31938 9.864V9.192C8.31938 8.424 8.56471 7.848 9.05538 7.464C9.54604 7.08 10.3887 6.856 11.5834 6.792V5.656H12.4954V6.776C13.1567 6.776 14.0154 6.83467 15.0714 6.952V8.088C13.7594 7.94933 12.9007 7.86933 12.4954 7.848V11.208H12.9754C13.69 11.208 14.2447 11.2933 14.6394 11.464C15.0447 11.6347 15.3274 11.896 15.4874 12.248C15.658 12.5893 15.7434 13.0533 15.7434 13.64V14.232C15.7434 15.2027 15.482 15.912 14.9594 16.36C14.4367 16.808 13.6154 17.064 12.4954 17.128V19.24H11.5834V17.16ZM11.5834 7.864C10.9007 7.90667 10.4367 8.024 10.1914 8.216C9.94604 8.408 9.82338 8.71733 9.82338 9.144V10.168C9.82338 10.5307 9.95671 10.7973 10.2234 10.968C10.49 11.128 10.9434 11.208 11.5834 11.208V7.864ZM12.4954 15.976C13.0714 15.944 13.5034 15.8373 13.7914 15.656C14.0794 15.464 14.2234 15.1653 14.2234 14.76V13.576C14.2234 13.128 14.0954 12.8133 13.8394 12.632C13.5834 12.4507 13.1354 12.36 12.4954 12.36V15.976Z" fill="#6C45A6"/>
5
+ </svg>
assets/images/packing-slip.png DELETED
Binary file
assets/images/packing-slip.svg ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect x="4" y="1" width="16" height="20" rx="2" stroke="#6C45A6" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
3
+ <path d="M0 4C0 3.44772 0.447715 3 1 3H7.5C8.05228 3 8.5 3.44772 8.5 4V6.5C8.5 7.05228 8.05228 7.5 7.5 7.5H1C0.447715 7.5 0 7.05228 0 6.5V4Z" fill="#ED1C24"/>
4
+ <path d="M8 9H16" stroke="#6C45A6" stroke-width="1.5"/>
5
+ <path d="M8 13H16" stroke="#6C45A6" stroke-width="1.5"/>
6
+ <path d="M8 17H16" stroke="#6C45A6" stroke-width="1.5"/>
7
+ </svg>
includes/class-wcpdf-admin.php CHANGED
@@ -194,11 +194,9 @@ class Admin {
194
  $listing_actions = apply_filters( 'wpo_wcpdf_listing_actions', $listing_actions, $order );
195
 
196
  foreach ($listing_actions as $action => $data) {
197
- ?>
198
- <a href="<?php echo $data['url']; ?>" class="button tips wpo_wcpdf <?php echo $data['exists'] == true ? "exists " . $action : $action; ?>" target="_blank" alt="<?php echo $data['alt']; ?>" data-tip="<?php echo $data['alt']; ?>">
199
  <img src="<?php echo $data['img']; ?>" alt="<?php echo $data['alt']; ?>" width="16">
200
- </a>
201
- <?php
202
  }
203
  }
204
 
@@ -623,15 +621,15 @@ class Admin {
623
  $order = wc_get_order( $post_id );
624
  $action = wc_clean( $_POST['wpo_wcpdf_send_emails'] );
625
  if ( strstr( $action, 'send_email_' ) ) {
 
626
  // Switch back to the site locale.
627
  wc_switch_to_site_locale();
628
- do_action( 'woocommerce_before_resend_order_emails', $order );
629
  // Ensure gateways are loaded in case they need to insert data into the emails.
630
  WC()->payment_gateways();
631
  WC()->shipping();
632
  // Load mailer.
633
  $mailer = WC()->mailer();
634
- $email_to_send = str_replace( 'send_email_', '', $action );
635
  $mails = $mailer->get_emails();
636
  if ( ! empty( $mails ) ) {
637
  foreach ( $mails as $mail ) {
194
  $listing_actions = apply_filters( 'wpo_wcpdf_listing_actions', $listing_actions, $order );
195
 
196
  foreach ($listing_actions as $action => $data) {
197
+ ?><a href="<?php echo $data['url']; ?>" class="button tips wpo_wcpdf <?php echo $data['exists'] == true ? "exists " . $action : $action; ?>" target="_blank" alt="<?php echo $data['alt']; ?>" data-tip="<?php echo $data['alt']; ?>">
 
198
  <img src="<?php echo $data['img']; ?>" alt="<?php echo $data['alt']; ?>" width="16">
199
+ </a><?php
 
200
  }
201
  }
202
 
621
  $order = wc_get_order( $post_id );
622
  $action = wc_clean( $_POST['wpo_wcpdf_send_emails'] );
623
  if ( strstr( $action, 'send_email_' ) ) {
624
+ $email_to_send = str_replace( 'send_email_', '', $action );
625
  // Switch back to the site locale.
626
  wc_switch_to_site_locale();
627
+ do_action( 'woocommerce_before_resend_order_emails', $order, $email_to_send );
628
  // Ensure gateways are loaded in case they need to insert data into the emails.
629
  WC()->payment_gateways();
630
  WC()->shipping();
631
  // Load mailer.
632
  $mailer = WC()->mailer();
 
633
  $mails = $mailer->get_emails();
634
  if ( ! empty( $mails ) ) {
635
  foreach ( $mails as $mail ) {
includes/class-wcpdf-install.php CHANGED
@@ -1,378 +1,378 @@
1
- <?php
2
- namespace WPO\WC\PDF_Invoices;
3
-
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly
10
- }
11
-
12
- if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Install' ) ) :
13
-
14
- class Install {
15
-
16
- function __construct() {
17
- // run lifecycle methods
18
- if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
19
- add_action( 'wp_loaded', array( $this, 'do_install' ) );
20
- }
21
- }
22
-
23
- /** Lifecycle methods *******************************************************
24
- * Because register_activation_hook only runs when the plugin is manually
25
- * activated by the user, we're checking the current version against the
26
- * version stored in the database
27
- ****************************************************************************/
28
-
29
- /**
30
- * Handles version checking
31
- */
32
- public function do_install() {
33
- // only install when woocommerce is active
34
- if ( !WPO_WCPDF()->is_woocommerce_activated() ) {
35
- return;
36
- }
37
-
38
- $version_setting = 'wpo_wcpdf_version';
39
- $installed_version = get_option( $version_setting );
40
-
41
- // installed version lower than plugin version?
42
- if ( version_compare( $installed_version, WPO_WCPDF_VERSION, '<' ) ) {
43
-
44
- if ( ! $installed_version ) {
45
- $this->install();
46
- } else {
47
- $this->upgrade( $installed_version );
48
- }
49
-
50
- // new version number
51
- update_option( $version_setting, WPO_WCPDF_VERSION );
52
- } elseif ( $installed_version && version_compare( $installed_version, WPO_WCPDF_VERSION, '>' ) ) {
53
- $this->downgrade( $installed_version );
54
- // downgrade version number
55
- update_option( $version_setting, WPO_WCPDF_VERSION );
56
- }
57
- }
58
-
59
-
60
- /**
61
- * Plugin install method. Perform any installation tasks here
62
- */
63
- protected function install() {
64
- // only install when php 5.3 or higher
65
- if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
66
- return;
67
- }
68
-
69
- // check if upgrading from versionless (1.4.14 and older)
70
- if ( get_option('wpo_wcpdf_general_settings') ) {
71
- $this->upgrade( 'versionless' );
72
- return;
73
- }
74
-
75
- // Create temp folders
76
- $tmp_base = WPO_WCPDF()->main->get_tmp_base();
77
-
78
- // check if tmp folder exists => if not, initialize
79
- if ( $tmp_base !== false && !@is_dir( $tmp_base ) ) {
80
- WPO_WCPDF()->main->init_tmp( $tmp_base );
81
- }
82
-
83
- // Unsupported currency symbols
84
- $unsupported_symbols = array (
85
- 'AED',
86
- 'AFN',
87
- 'BDT',
88
- 'BHD',
89
- 'BTC',
90
- 'CRC',
91
- 'DZD',
92
- 'GEL',
93
- 'GHS',
94
- 'ILS',
95
- 'INR',
96
- 'IQD',
97
- 'IRR',
98
- 'IRT',
99
- 'JOD',
100
- 'KHR',
101
- 'KPW',
102
- 'KRW',
103
- 'KWD',
104
- 'LAK',
105
- 'LBP',
106
- 'LKR',
107
- 'LYD',
108
- 'MAD',
109
- 'MNT',
110
- 'MUR',
111
- 'MVR',
112
- 'NPR',
113
- 'OMR',
114
- 'PHP',
115
- 'PKR',
116
- 'PYG',
117
- 'QAR',
118
- 'RUB',
119
- 'SAR',
120
- 'SCR',
121
- 'SDG',
122
- 'SYP',
123
- 'THB',
124
- 'TND',
125
- 'TRY',
126
- 'UAH',
127
- 'YER',
128
- );
129
-
130
- // set default settings
131
- $settings_defaults = array(
132
- 'wpo_wcpdf_settings_general' => array(
133
- 'download_display' => 'display',
134
- 'template_path' => WPO_WCPDF()->plugin_path() . '/templates/Simple',
135
- 'currency_font' => ( in_array( get_woocommerce_currency(), $unsupported_symbols ) ) ? 1 : '',
136
- 'paper_size' => 'a4',
137
- // 'header_logo' => '',
138
- // 'shop_name' => array(),
139
- // 'shop_address' => array(),
140
- // 'footer' => array(),
141
- // 'extra_1' => array(),
142
- // 'extra_2' => array(),
143
- // 'extra_3' => array(),
144
- ),
145
- 'wpo_wcpdf_documents_settings_invoice' => array(
146
- 'enabled' => 1,
147
- // 'attach_to_email_ids' => array(),
148
- // 'display_shipping_address' => '',
149
- // 'display_email' => '',
150
- // 'display_phone' => '',
151
- // 'display_date' => '',
152
- // 'display_number' => '',
153
- // 'number_format' => array(),
154
- // 'reset_number_yearly' => '',
155
- // 'my_account_buttons' => '',
156
- // 'invoice_number_column' => '',
157
- // 'disable_free' => '',
158
- ),
159
- 'wpo_wcpdf_documents_settings_packing-slip' => array(
160
- 'enabled' => 1,
161
- // 'display_billing_address' => '',
162
- // 'display_email' => '',
163
- // 'display_phone' => '',
164
- ),
165
- 'wpo_wcpdf_settings_debug' => array(
166
- // 'legacy_mode' => '',
167
- // 'enable_debug' => '',
168
- // 'html_output' => '',
169
- // 'html_output' => '',
170
- 'enable_cleanup' => 1,
171
- 'cleanup_days' => 7,
172
- ),
173
- );
174
- foreach ($settings_defaults as $option => $defaults) {
175
- update_option( $option, $defaults );
176
- }
177
-
178
- // set transient for wizard notification
179
- set_transient( 'wpo_wcpdf_new_install', 'yes', DAY_IN_SECONDS * 2 );
180
- }
181
-
182
- /**
183
- * Plugin upgrade method. Perform any required upgrades here
184
- *
185
- * @param string $installed_version the currently installed ('old') version
186
- */
187
- protected function upgrade( $installed_version ) {
188
- // only upgrade when php 5.3 or higher
189
- if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
190
- return;
191
- }
192
-
193
- // sync fonts on every upgrade!
194
- $tmp_base = WPO_WCPDF()->main->get_tmp_base();
195
-
196
- // check if tmp folder exists => if not, initialize
197
- if ( $tmp_base !== false && !@is_dir( $tmp_base ) ) {
198
- WPO_WCPDF()->main->init_tmp( $tmp_base );
199
- } else {
200
- $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
201
- // don't try merging fonts with local when updating pre 2.0
202
- $pre_2 = ( $installed_version == 'versionless' || version_compare( $installed_version, '2.0-dev', '<' ) );
203
- $merge_with_local = $pre_2 ? false : true;
204
- WPO_WCPDF()->main->copy_fonts( $font_path, $merge_with_local );
205
- }
206
-
207
- // 1.5.28 update: copy next invoice number to separate setting
208
- if ( $installed_version == 'versionless' || version_compare( $installed_version, '1.5.28', '<' ) ) {
209
- $template_settings = get_option( 'wpo_wcpdf_template_settings' );
210
- $next_invoice_number = isset($template_settings['next_invoice_number'])?$template_settings['next_invoice_number']:'';
211
- update_option( 'wpo_wcpdf_next_invoice_number', $next_invoice_number );
212
- }
213
-
214
- // 2.0-dev update: reorganize settings
215
- if ( $installed_version == 'versionless' || version_compare( $installed_version, '2.0-dev', '<' ) ) {
216
- $old_settings = array(
217
- 'wpo_wcpdf_general_settings' => get_option( 'wpo_wcpdf_general_settings' ),
218
- 'wpo_wcpdf_template_settings' => get_option( 'wpo_wcpdf_template_settings' ),
219
- 'wpo_wcpdf_debug_settings' => get_option( 'wpo_wcpdf_debug_settings' ),
220
- );
221
-
222
- // combine invoice number formatting in array
223
- $old_settings['wpo_wcpdf_template_settings']['invoice_number_formatting'] = array();
224
- $format_option_keys = array('padding','suffix','prefix');
225
- foreach ($format_option_keys as $format_option_key) {
226
- if (isset($old_settings['wpo_wcpdf_template_settings']["invoice_number_formatting_{$format_option_key}"])) {
227
- $old_settings['wpo_wcpdf_template_settings']['invoice_number_formatting'][$format_option_key] = $old_settings['wpo_wcpdf_template_settings']["invoice_number_formatting_{$format_option_key}"];
228
- }
229
- }
230
-
231
- // convert abbreviated email_ids
232
- if (isset($old_settings['wpo_wcpdf_general_settings']['email_pdf'])) {
233
- foreach ($old_settings['wpo_wcpdf_general_settings']['email_pdf'] as $email_id => $value) {
234
- if ($email_id == 'completed' || $email_id == 'processing') {
235
- $old_settings['wpo_wcpdf_general_settings']['email_pdf']["customer_{$email_id}_order"] = $value;
236
- unset($old_settings['wpo_wcpdf_general_settings']['email_pdf'][$email_id]);
237
- }
238
- }
239
- }
240
-
241
- // Migrate template path
242
- // forward slash for consistency/compatibility
243
- $template_path = str_replace('\\','/', $old_settings['wpo_wcpdf_template_settings']['template_path']);
244
- // strip abspath (forward slashed) if included
245
- $template_path = str_replace( str_replace('\\','/', ABSPATH), '', $template_path );
246
- // strip pdf subfolder from templates path
247
- $template_path = str_replace( '/templates/pdf/', '/templates/', $template_path );
248
- $old_settings['wpo_wcpdf_template_settings']['template_path'] = $template_path;
249
-
250
- // map new settings to old
251
- $settings_map = array(
252
- 'wpo_wcpdf_settings_general' => array(
253
- 'download_display' => array( 'wpo_wcpdf_general_settings' => 'download_display' ),
254
- 'template_path' => array( 'wpo_wcpdf_template_settings' => 'template_path' ),
255
- 'currency_font' => array( 'wpo_wcpdf_template_settings' => 'currency_font' ),
256
- 'paper_size' => array( 'wpo_wcpdf_template_settings' => 'paper_size' ),
257
- 'header_logo' => array( 'wpo_wcpdf_template_settings' => 'header_logo' ),
258
- 'shop_name' => array( 'wpo_wcpdf_template_settings' => 'shop_name' ),
259
- 'shop_address' => array( 'wpo_wcpdf_template_settings' => 'shop_address' ),
260
- 'footer' => array( 'wpo_wcpdf_template_settings' => 'footer' ),
261
- 'extra_1' => array( 'wpo_wcpdf_template_settings' => 'extra_1' ),
262
- 'extra_2' => array( 'wpo_wcpdf_template_settings' => 'extra_2' ),
263
- 'extra_3' => array( 'wpo_wcpdf_template_settings' => 'extra_3' ),
264
- ),
265
- 'wpo_wcpdf_documents_settings_invoice' => array(
266
- 'attach_to_email_ids' => array( 'wpo_wcpdf_general_settings' => 'email_pdf' ),
267
- 'display_shipping_address' => array( 'wpo_wcpdf_template_settings' => 'invoice_shipping_address' ),
268
- 'display_email' => array( 'wpo_wcpdf_template_settings' => 'invoice_email' ),
269
- 'display_phone' => array( 'wpo_wcpdf_template_settings' => 'invoice_phone' ),
270
- 'display_date' => array( 'wpo_wcpdf_template_settings' => 'display_date' ),
271
- 'display_number' => array( 'wpo_wcpdf_template_settings' => 'display_number' ),
272
- 'number_format' => array( 'wpo_wcpdf_template_settings' => 'invoice_number_formatting' ),
273
- 'reset_number_yearly' => array( 'wpo_wcpdf_template_settings' => 'yearly_reset_invoice_number' ),
274
- 'my_account_buttons' => array( 'wpo_wcpdf_general_settings' => 'my_account_buttons' ),
275
- 'invoice_number_column' => array( 'wpo_wcpdf_general_settings' => 'invoice_number_column' ),
276
- 'disable_free' => array( 'wpo_wcpdf_general_settings' => 'disable_free' ),
277
- ),
278
- 'wpo_wcpdf_documents_settings_packing-slip' => array(
279
- 'display_billing_address' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_billing_address' ),
280
- 'display_email' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_email' ),
281
- 'display_phone' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_phone' ),
282
- ),
283
- 'wpo_wcpdf_settings_debug' => array(
284
- 'enable_debug' => array( 'wpo_wcpdf_debug_settings' => 'enable_debug' ),
285
- 'html_output' => array( 'wpo_wcpdf_debug_settings' => 'html_output' ),
286
- ),
287
- );
288
-
289
- // walk through map
290
- foreach ($settings_map as $new_option => $new_settings_keys) {
291
- ${$new_option} = array();
292
- foreach ($new_settings_keys as $new_key => $old_setting ) {
293
- $old_key = reset($old_setting);
294
- $old_option = key($old_setting);
295
- if (!empty($old_settings[$old_option][$old_key])) {
296
- // turn translatable fields into array
297
- $translatable_fields = array('shop_name','shop_address','footer','extra_1','extra_2','extra_3');
298
- if (in_array($new_key, $translatable_fields)) {
299
- ${$new_option}[$new_key] = array( 'default' => $old_settings[$old_option][$old_key] );
300
- } else {
301
- ${$new_option}[$new_key] = $old_settings[$old_option][$old_key];
302
- }
303
- }
304
- }
305
-
306
- // auto enable invoice & packing slip
307
- $enabled = array( 'wpo_wcpdf_documents_settings_invoice', 'wpo_wcpdf_documents_settings_packing-slip' );
308
- if ( in_array( $new_option, $enabled ) ) {
309
- ${$new_option}['enabled'] = 1;
310
- }
311
-
312
- // auto enable legacy mode
313
- if ( $new_option == 'wpo_wcpdf_settings_debug' ) {
314
- ${$new_option}['legacy_mode'] = 1;
315
- }
316
-
317
- // merge with existing settings
318
- ${$new_option."_old"} = get_option( $new_option, ${$new_option} ); // second argument loads new as default in case the settings did not exist yet
319
- ${$new_option} = (array) ${$new_option} + (array) ${$new_option."_old"}; // duplicate options take new options as default
320
-
321
- // store new option values
322
- update_option( $new_option, ${$new_option} );
323
- }
324
- }
325
-
326
- // 2.0-beta-2 update: copy next number to separate db store
327
- if ( version_compare( $installed_version, '2.0-beta-2', '<' ) ) {
328
- // load number store class (just in case)
329
- include_once( WPO_WCPDF()->plugin_path() . '/includes/documents/class-wcpdf-sequential-number-store.php' );
330
-
331
- $next_number = get_option( 'wpo_wcpdf_next_invoice_number' );
332
- if (!empty($next_number)) {
333
- $number_store = new \WPO\WC\PDF_Invoices\Documents\Sequential_Number_Store( 'invoice_number' );
334
- $number_store->set_next( (int) $next_number );
335
- }
336
- // we're not deleting this option yet to make downgrading possible
337
- // delete_option( 'wpo_wcpdf_next_invoice_number' ); // clean up after ourselves
338
- }
339
-
340
- // 2.1.9: set cleanup defaults
341
- if ( $installed_version == 'versionless' || version_compare( $installed_version, '2.1.9', '<' ) ) {
342
- $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() );
343
- $debug_settings['enable_cleanup'] = 1;
344
- $debug_settings['cleanup_days'] = 7;
345
- update_option( 'wpo_wcpdf_settings_debug', $debug_settings );
346
- }
347
-
348
- }
349
-
350
- /**
351
- * Plugin downgrade method. Perform any required downgrades here
352
- *
353
- *
354
- * @param string $installed_version the currently installed ('old') version (actually higher since this is a downgrade)
355
- */
356
- protected function downgrade( $installed_version ) {
357
- // make sure fonts match with version: copy from plugin folder
358
- $tmp_base = WPO_WCPDF()->main->get_tmp_base();
359
-
360
- // don't continue if we don't have an upload dir
361
- if ($tmp_base === false) {
362
- return false;
363
- }
364
-
365
- // check if tmp folder exists => if not, initialize
366
- if ( !@is_dir( $tmp_base ) ) {
367
- WPO_WCPDF()->main->init_tmp( $tmp_base );
368
- } else {
369
- $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
370
- WPO_WCPDF()->main->copy_fonts( $font_path );
371
- }
372
- }
373
-
374
- }
375
-
376
- endif; // class_exists
377
-
378
  return new Install();
1
+ <?php
2
+ namespace WPO\WC\PDF_Invoices;
3
+
4
+ use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
+ use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
+ use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly
10
+ }
11
+
12
+ if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Install' ) ) :
13
+
14
+ class Install {
15
+
16
+ function __construct() {
17
+ // run lifecycle methods
18
+ if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
19
+ add_action( 'wp_loaded', array( $this, 'do_install' ) );
20
+ }
21
+ }
22
+
23
+ /** Lifecycle methods *******************************************************
24
+ * Because register_activation_hook only runs when the plugin is manually
25
+ * activated by the user, we're checking the current version against the
26
+ * version stored in the database
27
+ ****************************************************************************/
28
+
29
+ /**
30
+ * Handles version checking
31
+ */
32
+ public function do_install() {
33
+ // only install when woocommerce is active
34
+ if ( !WPO_WCPDF()->is_woocommerce_activated() ) {
35
+ return;
36
+ }
37
+
38
+ $version_setting = 'wpo_wcpdf_version';
39
+ $installed_version = get_option( $version_setting );
40
+
41
+ // installed version lower than plugin version?
42
+ if ( version_compare( $installed_version, WPO_WCPDF_VERSION, '<' ) ) {
43
+
44
+ if ( ! $installed_version ) {
45
+ $this->install();
46
+ } else {
47
+ $this->upgrade( $installed_version );
48
+ }
49
+
50
+ // new version number
51
+ update_option( $version_setting, WPO_WCPDF_VERSION );
52
+ } elseif ( $installed_version && version_compare( $installed_version, WPO_WCPDF_VERSION, '>' ) ) {
53
+ $this->downgrade( $installed_version );
54
+ // downgrade version number
55
+ update_option( $version_setting, WPO_WCPDF_VERSION );
56
+ }
57
+ }
58
+
59
+
60
+ /**
61
+ * Plugin install method. Perform any installation tasks here
62
+ */
63
+ protected function install() {
64
+ // only install when php 5.3 or higher
65
+ if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
66
+ return;
67
+ }
68
+
69
+ // check if upgrading from versionless (1.4.14 and older)
70
+ if ( get_option('wpo_wcpdf_general_settings') ) {
71
+ $this->upgrade( 'versionless' );
72
+ return;
73
+ }
74
+
75
+ // Get tmp folders
76
+ $tmp_base = WPO_WCPDF()->main->get_tmp_base();
77
+
78
+ // check if tmp folder exists => if not, initialize
79
+ if ( $tmp_base !== false && !@is_dir( $tmp_base ) ) {
80
+ WPO_WCPDF()->main->init_tmp();
81
+ }
82
+
83
+ // Unsupported currency symbols
84
+ $unsupported_symbols = array (
85
+ 'AED',
86
+ 'AFN',
87
+ 'BDT',
88
+ 'BHD',
89
+ 'BTC',
90
+ 'CRC',
91
+ 'DZD',
92
+ 'GEL',
93
+ 'GHS',
94
+ 'ILS',
95
+ 'INR',
96
+ 'IQD',
97
+ 'IRR',
98
+ 'IRT',
99
+ 'JOD',
100
+ 'KHR',
101
+ 'KPW',
102
+ 'KRW',
103
+ 'KWD',
104
+ 'LAK',
105
+ 'LBP',
106
+ 'LKR',
107
+ 'LYD',
108
+ 'MAD',
109
+ 'MNT',
110
+ 'MUR',
111
+ 'MVR',
112
+ 'NPR',
113
+ 'OMR',
114
+ 'PHP',
115
+ 'PKR',
116
+ 'PYG',
117
+ 'QAR',
118
+ 'RUB',
119
+ 'SAR',
120
+ 'SCR',
121
+ 'SDG',
122
+ 'SYP',
123
+ 'THB',
124
+ 'TND',
125
+ 'TRY',
126
+ 'UAH',
127
+ 'YER',
128
+ );
129
+
130
+ // set default settings
131
+ $settings_defaults = array(
132
+ 'wpo_wcpdf_settings_general' => array(
133
+ 'download_display' => 'display',
134
+ 'template_path' => WPO_WCPDF()->plugin_path() . '/templates/Simple',
135
+ 'currency_font' => ( in_array( get_woocommerce_currency(), $unsupported_symbols ) ) ? 1 : '',
136
+ 'paper_size' => 'a4',
137
+ // 'header_logo' => '',
138
+ // 'shop_name' => array(),
139
+ // 'shop_address' => array(),
140
+ // 'footer' => array(),
141
+ // 'extra_1' => array(),
142
+ // 'extra_2' => array(),
143
+ // 'extra_3' => array(),
144
+ ),
145
+ 'wpo_wcpdf_documents_settings_invoice' => array(
146
+ 'enabled' => 1,
147
+ // 'attach_to_email_ids' => array(),
148
+ // 'display_shipping_address' => '',
149
+ // 'display_email' => '',
150
+ // 'display_phone' => '',
151
+ // 'display_date' => '',
152
+ // 'display_number' => '',
153
+ // 'number_format' => array(),
154
+ // 'reset_number_yearly' => '',
155
+ // 'my_account_buttons' => '',
156
+ // 'invoice_number_column' => '',
157
+ // 'disable_free' => '',
158
+ ),
159
+ 'wpo_wcpdf_documents_settings_packing-slip' => array(
160
+ 'enabled' => 1,
161
+ // 'display_billing_address' => '',
162
+ // 'display_email' => '',
163
+ // 'display_phone' => '',
164
+ ),
165
+ 'wpo_wcpdf_settings_debug' => array(
166
+ // 'legacy_mode' => '',
167
+ // 'enable_debug' => '',
168
+ // 'html_output' => '',
169
+ // 'html_output' => '',
170
+ 'enable_cleanup' => 1,
171
+ 'cleanup_days' => 7,
172
+ ),
173
+ );
174
+ foreach ($settings_defaults as $option => $defaults) {
175
+ update_option( $option, $defaults );
176
+ }
177
+
178
+ // set transient for wizard notification
179
+ set_transient( 'wpo_wcpdf_new_install', 'yes', DAY_IN_SECONDS * 2 );
180
+ }
181
+
182
+ /**
183
+ * Plugin upgrade method. Perform any required upgrades here
184
+ *
185
+ * @param string $installed_version the currently installed ('old') version
186
+ */
187
+ protected function upgrade( $installed_version ) {
188
+ // only upgrade when php 5.3 or higher
189
+ if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
190
+ return;
191
+ }
192
+
193
+ // sync fonts on every upgrade!
194
+ $tmp_base = WPO_WCPDF()->main->get_tmp_base();
195
+
196
+ // check if tmp folder exists => if not, initialize
197
+ if ( $tmp_base !== false && !@is_dir( $tmp_base ) ) {
198
+ WPO_WCPDF()->main->init_tmp();
199
+ } else {
200
+ $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
201
+ // don't try merging fonts with local when updating pre 2.0
202
+ $pre_2 = ( $installed_version == 'versionless' || version_compare( $installed_version, '2.0-dev', '<' ) );
203
+ $merge_with_local = $pre_2 ? false : true;
204
+ WPO_WCPDF()->main->copy_fonts( $font_path, $merge_with_local );
205
+ }
206
+
207
+ // 1.5.28 update: copy next invoice number to separate setting
208
+ if ( $installed_version == 'versionless' || version_compare( $installed_version, '1.5.28', '<' ) ) {
209
+ $template_settings = get_option( 'wpo_wcpdf_template_settings' );
210
+ $next_invoice_number = isset($template_settings['next_invoice_number'])?$template_settings['next_invoice_number']:'';
211
+ update_option( 'wpo_wcpdf_next_invoice_number', $next_invoice_number );
212
+ }
213
+
214
+ // 2.0-dev update: reorganize settings
215
+ if ( $installed_version == 'versionless' || version_compare( $installed_version, '2.0-dev', '<' ) ) {
216
+ $old_settings = array(
217
+ 'wpo_wcpdf_general_settings' => get_option( 'wpo_wcpdf_general_settings' ),
218
+ 'wpo_wcpdf_template_settings' => get_option( 'wpo_wcpdf_template_settings' ),
219
+ 'wpo_wcpdf_debug_settings' => get_option( 'wpo_wcpdf_debug_settings' ),
220
+ );
221
+
222
+ // combine invoice number formatting in array
223
+ $old_settings['wpo_wcpdf_template_settings']['invoice_number_formatting'] = array();
224
+ $format_option_keys = array('padding','suffix','prefix');
225
+ foreach ($format_option_keys as $format_option_key) {
226
+ if (isset($old_settings['wpo_wcpdf_template_settings']["invoice_number_formatting_{$format_option_key}"])) {
227
+ $old_settings['wpo_wcpdf_template_settings']['invoice_number_formatting'][$format_option_key] = $old_settings['wpo_wcpdf_template_settings']["invoice_number_formatting_{$format_option_key}"];
228
+ }
229
+ }
230
+
231
+ // convert abbreviated email_ids
232
+ if (isset($old_settings['wpo_wcpdf_general_settings']['email_pdf'])) {
233
+ foreach ($old_settings['wpo_wcpdf_general_settings']['email_pdf'] as $email_id => $value) {
234
+ if ($email_id == 'completed' || $email_id == 'processing') {
235
+ $old_settings['wpo_wcpdf_general_settings']['email_pdf']["customer_{$email_id}_order"] = $value;
236
+ unset($old_settings['wpo_wcpdf_general_settings']['email_pdf'][$email_id]);
237
+ }
238
+ }
239
+ }
240
+
241
+ // Migrate template path
242
+ // forward slash for consistency/compatibility
243
+ $template_path = str_replace('\\','/', $old_settings['wpo_wcpdf_template_settings']['template_path']);
244
+ // strip abspath (forward slashed) if included
245
+ $template_path = str_replace( str_replace('\\','/', ABSPATH), '', $template_path );
246
+ // strip pdf subfolder from templates path
247
+ $template_path = str_replace( '/templates/pdf/', '/templates/', $template_path );
248
+ $old_settings['wpo_wcpdf_template_settings']['template_path'] = $template_path;
249
+
250
+ // map new settings to old
251
+ $settings_map = array(
252
+ 'wpo_wcpdf_settings_general' => array(
253
+ 'download_display' => array( 'wpo_wcpdf_general_settings' => 'download_display' ),
254
+ 'template_path' => array( 'wpo_wcpdf_template_settings' => 'template_path' ),
255
+ 'currency_font' => array( 'wpo_wcpdf_template_settings' => 'currency_font' ),
256
+ 'paper_size' => array( 'wpo_wcpdf_template_settings' => 'paper_size' ),
257
+ 'header_logo' => array( 'wpo_wcpdf_template_settings' => 'header_logo' ),
258
+ 'shop_name' => array( 'wpo_wcpdf_template_settings' => 'shop_name' ),
259
+ 'shop_address' => array( 'wpo_wcpdf_template_settings' => 'shop_address' ),
260
+ 'footer' => array( 'wpo_wcpdf_template_settings' => 'footer' ),
261
+ 'extra_1' => array( 'wpo_wcpdf_template_settings' => 'extra_1' ),
262
+ 'extra_2' => array( 'wpo_wcpdf_template_settings' => 'extra_2' ),
263
+ 'extra_3' => array( 'wpo_wcpdf_template_settings' => 'extra_3' ),
264
+ ),
265
+ 'wpo_wcpdf_documents_settings_invoice' => array(
266
+ 'attach_to_email_ids' => array( 'wpo_wcpdf_general_settings' => 'email_pdf' ),
267
+ 'display_shipping_address' => array( 'wpo_wcpdf_template_settings' => 'invoice_shipping_address' ),
268
+ 'display_email' => array( 'wpo_wcpdf_template_settings' => 'invoice_email' ),
269
+ 'display_phone' => array( 'wpo_wcpdf_template_settings' => 'invoice_phone' ),
270
+ 'display_date' => array( 'wpo_wcpdf_template_settings' => 'display_date' ),
271
+ 'display_number' => array( 'wpo_wcpdf_template_settings' => 'display_number' ),
272
+ 'number_format' => array( 'wpo_wcpdf_template_settings' => 'invoice_number_formatting' ),
273
+ 'reset_number_yearly' => array( 'wpo_wcpdf_template_settings' => 'yearly_reset_invoice_number' ),
274
+ 'my_account_buttons' => array( 'wpo_wcpdf_general_settings' => 'my_account_buttons' ),
275
+ 'invoice_number_column' => array( 'wpo_wcpdf_general_settings' => 'invoice_number_column' ),
276
+ 'disable_free' => array( 'wpo_wcpdf_general_settings' => 'disable_free' ),
277
+ ),
278
+ 'wpo_wcpdf_documents_settings_packing-slip' => array(
279
+ 'display_billing_address' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_billing_address' ),
280
+ 'display_email' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_email' ),
281
+ 'display_phone' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_phone' ),
282
+ ),
283
+ 'wpo_wcpdf_settings_debug' => array(
284
+ 'enable_debug' => array( 'wpo_wcpdf_debug_settings' => 'enable_debug' ),
285
+ 'html_output' => array( 'wpo_wcpdf_debug_settings' => 'html_output' ),
286
+ ),
287
+ );
288
+
289
+ // walk through map
290
+ foreach ($settings_map as $new_option => $new_settings_keys) {
291
+ ${$new_option} = array();
292
+ foreach ($new_settings_keys as $new_key => $old_setting ) {
293
+ $old_key = reset($old_setting);
294
+ $old_option = key($old_setting);
295
+ if (!empty($old_settings[$old_option][$old_key])) {
296
+ // turn translatable fields into array
297
+ $translatable_fields = array('shop_name','shop_address','footer','extra_1','extra_2','extra_3');
298
+ if (in_array($new_key, $translatable_fields)) {
299
+ ${$new_option}[$new_key] = array( 'default' => $old_settings[$old_option][$old_key] );
300
+ } else {
301
+ ${$new_option}[$new_key] = $old_settings[$old_option][$old_key];
302
+ }
303
+ }
304
+ }
305
+
306
+ // auto enable invoice & packing slip
307
+ $enabled = array( 'wpo_wcpdf_documents_settings_invoice', 'wpo_wcpdf_documents_settings_packing-slip' );
308
+ if ( in_array( $new_option, $enabled ) ) {
309
+ ${$new_option}['enabled'] = 1;
310
+ }
311
+
312
+ // auto enable legacy mode
313
+ if ( $new_option == 'wpo_wcpdf_settings_debug' ) {
314
+ ${$new_option}['legacy_mode'] = 1;
315
+ }
316
+
317
+ // merge with existing settings
318
+ ${$new_option."_old"} = get_option( $new_option, ${$new_option} ); // second argument loads new as default in case the settings did not exist yet
319
+ ${$new_option} = (array) ${$new_option} + (array) ${$new_option."_old"}; // duplicate options take new options as default
320
+
321
+ // store new option values
322
+ update_option( $new_option, ${$new_option} );
323
+ }
324
+ }
325
+
326
+ // 2.0-beta-2 update: copy next number to separate db store
327
+ if ( version_compare( $installed_version, '2.0-beta-2', '<' ) ) {
328
+ // load number store class (just in case)
329
+ include_once( WPO_WCPDF()->plugin_path() . '/includes/documents/class-wcpdf-sequential-number-store.php' );
330
+
331
+ $next_number = get_option( 'wpo_wcpdf_next_invoice_number' );
332
+ if (!empty($next_number)) {
333
+ $number_store = new \WPO\WC\PDF_Invoices\Documents\Sequential_Number_Store( 'invoice_number' );
334
+ $number_store->set_next( (int) $next_number );
335
+ }
336
+ // we're not deleting this option yet to make downgrading possible
337
+ // delete_option( 'wpo_wcpdf_next_invoice_number' ); // clean up after ourselves
338
+ }
339
+
340
+ // 2.1.9: set cleanup defaults
341
+ if ( $installed_version == 'versionless' || version_compare( $installed_version, '2.1.9', '<' ) ) {
342
+ $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() );
343
+ $debug_settings['enable_cleanup'] = 1;
344
+ $debug_settings['cleanup_days'] = 7;
345
+ update_option( 'wpo_wcpdf_settings_debug', $debug_settings );
346
+ }
347
+
348
+ }
349
+
350
+ /**
351
+ * Plugin downgrade method. Perform any required downgrades here
352
+ *
353
+ *
354
+ * @param string $installed_version the currently installed ('old') version (actually higher since this is a downgrade)
355
+ */
356
+ protected function downgrade( $installed_version ) {
357
+ // make sure fonts match with version: copy from plugin folder
358
+ $tmp_base = WPO_WCPDF()->main->get_tmp_base();
359
+
360
+ // don't continue if we don't have an upload dir
361
+ if ($tmp_base === false) {
362
+ return false;
363
+ }
364
+
365
+ // check if tmp folder exists => if not, initialize
366
+ if ( !@is_dir( $tmp_base ) ) {
367
+ WPO_WCPDF()->main->init_tmp();
368
+ } else {
369
+ $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
370
+ WPO_WCPDF()->main->copy_fonts( $font_path );
371
+ }
372
+ }
373
+
374
+ }
375
+
376
+ endif; // class_exists
377
+
378
  return new Install();
includes/class-wcpdf-main.php CHANGED
@@ -19,7 +19,7 @@ class Main {
19
 
20
  // email
21
  add_filter( 'woocommerce_email_attachments', array( $this, 'attach_pdf_to_email' ), 99, 4 );
22
- add_filter( 'wpo_wcpdf_custom_attachment_condition', array( $this, 'disable_free_attachment'), 1001, 4 );
23
  add_filter( 'wp_mail', array( $this, 'set_phpmailer_validator'), 10, 1 );
24
 
25
  if ( isset(WPO_WCPDF()->settings->debug_settings['enable_debug']) ) {
@@ -374,7 +374,7 @@ class Main {
374
 
375
  // check if tmp folder exists => if not, initialize
376
  if ( !@is_dir( $tmp_base ) ) {
377
- $this->init_tmp( $tmp_base );
378
  }
379
 
380
  if ( empty( $type ) ) {
@@ -408,7 +408,7 @@ class Main {
408
  /**
409
  * return the base tmp folder (usually uploads)
410
  */
411
- public function get_tmp_base () {
412
  // wp_upload_dir() is used to set the base temp folder, under which a
413
  // 'wpo_wcpdf' folder and several subfolders are created
414
  //
@@ -417,13 +417,16 @@ class Main {
417
  // * UNLESS the ‘UPLOADS’ constant is defined in wp-config (http://codex.wordpress.org/Editing_wp-config.php#Moving_uploads_folder)
418
  //
419
  // May also be overridden by the wpo_wcpdf_tmp_path filter
420
-
421
- $upload_dir = wp_upload_dir();
422
- if (!empty($upload_dir['error'])) {
423
- $tmp_base = false;
 
 
 
 
424
  } else {
425
- $upload_base = trailingslashit( $upload_dir['basedir'] );
426
- $tmp_base = $upload_base . 'wpo_wcpdf/';
427
  }
428
 
429
  $tmp_base = apply_filters( 'wpo_wcpdf_tmp_path', $tmp_base );
@@ -434,10 +437,57 @@ class Main {
434
  return $tmp_base;
435
  }
436
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  /**
438
  * Install/create plugin tmp folders
439
  */
440
- public function init_tmp ( $tmp_base ) {
 
 
 
 
 
 
 
 
441
  // create plugin base temp folder
442
  mkdir( $tmp_base );
443
 
@@ -462,7 +512,34 @@ class Main {
462
  file_put_contents( $path . '.htaccess', 'deny from all' );
463
  touch( $path . 'index.php' );
464
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465
 
 
 
 
 
 
 
 
 
 
 
 
466
  }
467
 
468
  /**
@@ -543,21 +620,21 @@ class Main {
543
  }
544
  }
545
 
546
- public function disable_free_attachment( $attach, $order, $email_id, $document_type ) {
547
- // prevent fatal error for non-order objects
548
- if ( !method_exists( $order, 'get_total' ) ) {
549
- return false;
550
- }
551
-
552
- $document_settings = WPO_WCPDF()->settings->get_document_settings( $document_type );
553
-
554
- // check order total & setting
555
- $order_total = $order->get_total();
556
- if ( $order_total == 0 && isset( $document_settings['disable_free'] ) ) {
557
- return false;
 
 
558
  }
559
-
560
- return $attach;
561
  }
562
 
563
  public function test_mode_settings( $use_historical_settings, $document ) {
19
 
20
  // email
21
  add_filter( 'woocommerce_email_attachments', array( $this, 'attach_pdf_to_email' ), 99, 4 );
22
+ add_filter( 'wpo_wcpdf_document_is_allowed', array( $this, 'disable_free'), 10, 2 );
23
  add_filter( 'wp_mail', array( $this, 'set_phpmailer_validator'), 10, 1 );
24
 
25
  if ( isset(WPO_WCPDF()->settings->debug_settings['enable_debug']) ) {
374
 
375
  // check if tmp folder exists => if not, initialize
376
  if ( !@is_dir( $tmp_base ) ) {
377
+ $this->init_tmp();
378
  }
379
 
380
  if ( empty( $type ) ) {
408
  /**
409
  * return the base tmp folder (usually uploads)
410
  */
411
+ public function get_tmp_base ( $append_random_string = true ) {
412
  // wp_upload_dir() is used to set the base temp folder, under which a
413
  // 'wpo_wcpdf' folder and several subfolders are created
414
  //
417
  // * UNLESS the ‘UPLOADS’ constant is defined in wp-config (http://codex.wordpress.org/Editing_wp-config.php#Moving_uploads_folder)
418
  //
419
  // May also be overridden by the wpo_wcpdf_tmp_path filter
420
+
421
+ $wp_upload_base = $this->get_wp_upload_base();
422
+ if( $wp_upload_base ) {
423
+ if( $append_random_string && $code = $this->get_random_string() ) {
424
+ $tmp_base = $wp_upload_base . 'wpo_wcpdf_'.$code.'/';
425
+ } else {
426
+ $tmp_base = $wp_upload_base . 'wpo_wcpdf/';
427
+ }
428
  } else {
429
+ $tmp_base = false;
 
430
  }
431
 
432
  $tmp_base = apply_filters( 'wpo_wcpdf_tmp_path', $tmp_base );
437
  return $tmp_base;
438
  }
439
 
440
+ /**
441
+ * Get WordPress uploads folder base
442
+ */
443
+ public function get_wp_upload_base () {
444
+ $upload_dir = wp_upload_dir();
445
+ if ( ! empty($upload_dir['error']) ) {
446
+ $wp_upload_base = false;
447
+ } else {
448
+ $upload_base = trailingslashit( $upload_dir['basedir'] );
449
+ $wp_upload_base = $upload_base;
450
+ }
451
+ return $wp_upload_base;
452
+ }
453
+
454
+ /**
455
+ * Generate random string
456
+ */
457
+ public function generate_random_string () {
458
+ if ( function_exists( 'random_bytes' ) ) { // PHP7+
459
+ $code = bin2hex(random_bytes(16));
460
+ } else {
461
+ $code = md5(uniqid(rand(), true));
462
+ }
463
+ // create option
464
+ update_option( 'wpo_wcpdf_random_string', $code );
465
+ }
466
+
467
+ /**
468
+ * Get random string
469
+ */
470
+ public function get_random_string () {
471
+ $code = sanitize_text_field( get_option( 'wpo_wcpdf_random_string' ) );
472
+ if( $code ) {
473
+ return $code;
474
+ } else {
475
+ return false;
476
+ }
477
+ }
478
+
479
  /**
480
  * Install/create plugin tmp folders
481
  */
482
+ public function init_tmp () {
483
+ // generate random string if don't exist
484
+ if( ! $this->get_random_string() ) {
485
+ $this->generate_random_string();
486
+ }
487
+
488
+ // get tmp base
489
+ $tmp_base = $this->get_tmp_base();
490
+
491
  // create plugin base temp folder
492
  mkdir( $tmp_base );
493
 
512
  file_put_contents( $path . '.htaccess', 'deny from all' );
513
  touch( $path . 'index.php' );
514
  }
515
+ }
516
+
517
+ /**
518
+ * Copy contents from one directory to another
519
+ */
520
+ public function copy_directory ( $old_path, $new_path ) {
521
+ if( empty($old_path) || empty($new_path) ) return;
522
+ if( ! is_dir($old_path) ) return;
523
+ if( ! is_dir($new_path) ) mkdir($new_path);
524
+
525
+ global $wp_filesystem;
526
+
527
+ // check for WP_Filesystem(), is required for copy_dir()
528
+ if ( ! WP_Filesystem() ) {
529
+ WP_Filesystem();
530
+ }
531
 
532
+ // we have the directories, let's try to copy
533
+ try {
534
+ $result = copy_dir( $old_path, $new_path );
535
+ // delete old directory with contents
536
+ if( $result ) {
537
+ $wp_filesystem->delete( $old_path, true );
538
+ }
539
+ } catch ( \Error $e ) {
540
+ wcpdf_log_error( "Unable to copy directory contents: ".$e->getMessage(), 'critical', $e );
541
+ return;
542
+ }
543
  }
544
 
545
  /**
620
  }
621
  }
622
 
623
+ public function disable_free( $allowed, $document ) {
624
+ if( ! $document->exists() && ! empty($order = $document->order) ) {
625
+ if ( ! is_callable( array($order, 'get_total') ) ) {
626
+ return false;
627
+ }
628
+ // check order total & setting
629
+ $order_total = $order->get_total();
630
+ if ( $order_total == 0 && $document->get_setting('disable_free') ) {
631
+ return false;
632
+ } else {
633
+ return $allowed;
634
+ }
635
+ } else {
636
+ return $allowed;
637
  }
 
 
638
  }
639
 
640
  public function test_mode_settings( $use_historical_settings, $document ) {
includes/class-wcpdf-settings-callbacks.php CHANGED
@@ -53,6 +53,11 @@ class Settings_Callbacks {
53
 
54
  // output checkbox
55
  printf( '<input type="checkbox" id="%1$s" name="%2$s" value="%3$s" %4$s %5$s/>', $id, $setting_name, $value, checked( $value, $current, false ), !empty($disabled) ? 'disabled="disabled"' : '' );
 
 
 
 
 
56
 
57
  // output description.
58
  if ( isset( $description ) ) {
@@ -495,6 +500,7 @@ class Settings_Callbacks {
495
  $args['value'] = isset( $args['value'] ) ? $args['value'] : 1;
496
 
497
  $args['placeholder'] = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
 
498
 
499
  // get main settings array
500
  $option = get_option( $args['option_name'] );
@@ -566,6 +572,15 @@ class Settings_Callbacks {
566
  if (empty($input) || !is_array($input)) {
567
  return $input;
568
  }
 
 
 
 
 
 
 
 
 
569
 
570
  // Loop through each of the incoming options.
571
  foreach ( $input as $key => $value ) {
53
 
54
  // output checkbox
55
  printf( '<input type="checkbox" id="%1$s" name="%2$s" value="%3$s" %4$s %5$s/>', $id, $setting_name, $value, checked( $value, $current, false ), !empty($disabled) ? 'disabled="disabled"' : '' );
56
+
57
+ // print store empty input if true
58
+ if( $store_unchecked ) {
59
+ printf( '<input type="hidden" name="%s[wpo_wcpdf_setting_store_empty][]" value="%s"/>', $option_name, $id );
60
+ }
61
 
62
  // output description.
63
  if ( isset( $description ) ) {
500
  $args['value'] = isset( $args['value'] ) ? $args['value'] : 1;
501
 
502
  $args['placeholder'] = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
503
+ $args['store_unchecked'] = isset( $args['store_unchecked'] ) && $args['store_unchecked'] ? true : false;
504
 
505
  // get main settings array
506
  $option = get_option( $args['option_name'] );
572
  if (empty($input) || !is_array($input)) {
573
  return $input;
574
  }
575
+
576
+ if (!empty($input['wpo_wcpdf_setting_store_empty'])) { //perhaps we should use a more unique/specific name for this
577
+ foreach ($input['wpo_wcpdf_setting_store_empty'] as $key) {
578
+ if (empty($input[$key])) {
579
+ $output[$key] = 0;
580
+ }
581
+ }
582
+ unset($input['wpo_wcpdf_setting_store_empty']);
583
+ }
584
 
585
  // Loop through each of the incoming options.
586
  foreach ( $input as $key => $value ) {
includes/class-wcpdf-settings-debug.php CHANGED
@@ -36,101 +36,133 @@ class Settings_Debug {
36
  return;
37
  }
38
  ?>
39
- <form method="post">
40
- <?php wp_nonce_field( 'wpo_wcpdf_debug_tools_action', 'security' ); ?>
41
- <input type="hidden" name="wpo_wcpdf_debug_tools_action" value="install_fonts">
42
- <input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Reinstall fonts', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
43
- <?php
44
- if ( !empty($_POST) && isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'install_fonts' ) {
45
- // check permissions
46
- if ( !check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
47
- return;
48
- }
49
-
50
- $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
51
-
52
- // clear folder first
53
- if ( function_exists("glob") && $files = glob( $font_path.'/*.*' ) ) {
54
- $exclude_files = array( 'index.php', '.htaccess' );
55
- foreach($files as $file) {
56
- if( is_file($file) && !in_array( basename($file), $exclude_files ) ) {
57
- unlink($file);
58
  }
 
 
 
 
 
 
59
  }
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- WPO_WCPDF()->main->copy_fonts( $font_path );
63
- printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Fonts reinstalled!', 'woocommerce-pdf-invoices-packing-slips' ) );
64
- }
65
- ?>
66
- </form>
67
- <form method="post">
68
- <?php wp_nonce_field( 'wpo_wcpdf_debug_tools_action', 'security' ); ?>
69
- <input type="hidden" name="wpo_wcpdf_debug_tools_action" value="clear_tmp">
70
- <input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Remove temporary files', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
71
- <?php
72
- if ( !empty($_POST) && isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'clear_tmp' ) {
73
- // check permissions
74
- if ( !check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
75
- return;
76
- }
77
- $tmp_path = WPO_WCPDF()->main->get_tmp_path('attachments');
78
 
79
- if ( !function_exists("glob") ) {
80
- // glob is disabled
81
- printf('<div class="notice notice-error"><p>%s<br><code>%s</code></p></div>', __( "Unable to read temporary folder contents!", 'woocommerce-pdf-invoices-packing-slips' ), $tmp_path);
82
- } else {
83
- $success = 0;
84
- $error = 0;
85
- if ( $files = glob($tmp_path.'*.pdf') ) { // get all pdf files
86
- foreach($files as $file) {
87
- if(is_file($file)) {
88
- // delete file
89
- if ( unlink($file) === true ) {
90
- $success++;
91
- } else {
92
- $error++;
93
  }
94
  }
95
  }
96
 
97
- if ($error > 0) {
98
- $message = sprintf( __( 'Unable to delete %d files! (deleted %d)', 'woocommerce-pdf-invoices-packing-slips' ), $error, $success);
99
- printf('<div class="notice notice-error"><p>%s</p></div>', $message);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  } else {
101
- $message = sprintf( __( 'Successfully deleted %d files!', 'woocommerce-pdf-invoices-packing-slips' ), $success );
102
- printf('<div class="notice notice-success"><p>%s</p></div>', $message);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
- } else {
105
- printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Nothing to delete!', 'woocommerce-pdf-invoices-packing-slips' ) );
106
  }
107
- }
108
- }
109
- ?>
110
- </form>
111
- <form method="post">
112
- <?php wp_nonce_field( 'wpo_wcpdf_debug_tools_action', 'security' ); ?>
113
- <input type="hidden" name="wpo_wcpdf_debug_tools_action" value="delete_legacy_settings">
114
- <input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Delete legacy (1.X) settings', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
115
- <?php
116
- if ( !empty($_POST) && isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'delete_legacy_settings' ) {
117
- // check permissions
118
- if ( !check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
119
- return;
120
- }
121
- // delete options
122
- delete_option( 'wpo_wcpdf_general_settings' );
123
- delete_option( 'wpo_wcpdf_template_settings' );
124
- delete_option( 'wpo_wcpdf_debug_settings' );
125
- // and delete cache of these options, just in case...
126
- wp_cache_delete( 'wpo_wcpdf_general_settings','options' );
127
- wp_cache_delete( 'wpo_wcpdf_template_settings','options' );
128
- wp_cache_delete( 'wpo_wcpdf_debug_settings','options' );
129
 
130
- printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Legacy settings deleted!', 'woocommerce-pdf-invoices-packing-slips' ) );
131
- }
132
- ?>
133
- </form>
 
 
 
134
  <?php
135
  }
136
 
36
  return;
37
  }
38
  ?>
39
+ <div>
40
+ <?php if( ! WPO_WCPDF()->main->get_random_string() ) : ?>
41
+ <p>
42
+ <form method="post">
43
+ <?php wp_nonce_field( 'wpo_wcpdf_debug_tools_action', 'security' ); ?>
44
+ <input type="hidden" name="wpo_wcpdf_debug_tools_action" value="generate_random_string">
45
+ <input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Generate random temporary folder name', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
46
+ <?php
47
+ if ( !empty($_POST) && isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'generate_random_string' ) {
48
+ // check permissions
49
+ if ( !check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
50
+ return;
 
 
 
 
 
 
 
51
  }
52
+
53
+ WPO_WCPDF()->main->generate_random_string();
54
+ $old_path = WPO_WCPDF()->main->get_tmp_base( false );
55
+ $new_path = WPO_WCPDF()->main->get_tmp_base();
56
+ WPO_WCPDF()->main->copy_directory( $old_path, $new_path );
57
+ printf('<div class="notice notice-success"><p>%s</p></div>', sprintf( __( 'Temporary folder moved to %s', 'woocommerce-pdf-invoices-packing-slips' ), '<code>'.$new_path.'</code>' ) );
58
  }
59
+ ?>
60
+ </form>
61
+ </p>
62
+ <?php endif; ?>
63
+ <p>
64
+ <form method="post">
65
+ <?php wp_nonce_field( 'wpo_wcpdf_debug_tools_action', 'security' ); ?>
66
+ <input type="hidden" name="wpo_wcpdf_debug_tools_action" value="install_fonts">
67
+ <input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Reinstall fonts', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
68
+ <?php
69
+ if ( !empty($_POST) && isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'install_fonts' ) {
70
+ // check permissions
71
+ if ( !check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
72
+ return;
73
+ }
74
 
75
+ $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
+ // clear folder first
78
+ if ( function_exists("glob") && $files = glob( $font_path.'/*.*' ) ) {
79
+ $exclude_files = array( 'index.php', '.htaccess' );
80
+ foreach($files as $file) {
81
+ if( is_file($file) && !in_array( basename($file), $exclude_files ) ) {
82
+ unlink($file);
 
 
 
 
 
 
 
 
83
  }
84
  }
85
  }
86
 
87
+ WPO_WCPDF()->main->copy_fonts( $font_path );
88
+ printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Fonts reinstalled!', 'woocommerce-pdf-invoices-packing-slips' ) );
89
+ }
90
+ ?>
91
+ </form>
92
+ </p>
93
+ <p>
94
+ <form method="post">
95
+ <?php wp_nonce_field( 'wpo_wcpdf_debug_tools_action', 'security' ); ?>
96
+ <input type="hidden" name="wpo_wcpdf_debug_tools_action" value="clear_tmp">
97
+ <input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Remove temporary files', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
98
+ <?php
99
+ if ( !empty($_POST) && isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'clear_tmp' ) {
100
+ // check permissions
101
+ if ( !check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
102
+ return;
103
+ }
104
+ $tmp_path = WPO_WCPDF()->main->get_tmp_path('attachments');
105
+
106
+ if ( !function_exists("glob") ) {
107
+ // glob is disabled
108
+ printf('<div class="notice notice-error"><p>%s<br><code>%s</code></p></div>', __( "Unable to read temporary folder contents!", 'woocommerce-pdf-invoices-packing-slips' ), $tmp_path);
109
  } else {
110
+ $success = 0;
111
+ $error = 0;
112
+ if ( $files = glob($tmp_path.'*.pdf') ) { // get all pdf files
113
+ foreach($files as $file) {
114
+ if(is_file($file)) {
115
+ // delete file
116
+ if ( unlink($file) === true ) {
117
+ $success++;
118
+ } else {
119
+ $error++;
120
+ }
121
+ }
122
+ }
123
+
124
+ if ($error > 0) {
125
+ $message = sprintf( __( 'Unable to delete %d files! (deleted %d)', 'woocommerce-pdf-invoices-packing-slips' ), $error, $success);
126
+ printf('<div class="notice notice-error"><p>%s</p></div>', $message);
127
+ } else {
128
+ $message = sprintf( __( 'Successfully deleted %d files!', 'woocommerce-pdf-invoices-packing-slips' ), $success );
129
+ printf('<div class="notice notice-success"><p>%s</p></div>', $message);
130
+ }
131
+ } else {
132
+ printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Nothing to delete!', 'woocommerce-pdf-invoices-packing-slips' ) );
133
+ }
134
  }
 
 
135
  }
136
+ ?>
137
+ </form>
138
+ </p>
139
+ <p>
140
+ <form method="post">
141
+ <?php wp_nonce_field( 'wpo_wcpdf_debug_tools_action', 'security' ); ?>
142
+ <input type="hidden" name="wpo_wcpdf_debug_tools_action" value="delete_legacy_settings">
143
+ <input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Delete legacy (1.X) settings', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
144
+ <?php
145
+ if ( !empty($_POST) && isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'delete_legacy_settings' ) {
146
+ // check permissions
147
+ if ( !check_admin_referer( 'wpo_wcpdf_debug_tools_action', 'security' ) ) {
148
+ return;
149
+ }
150
+ // delete options
151
+ delete_option( 'wpo_wcpdf_general_settings' );
152
+ delete_option( 'wpo_wcpdf_template_settings' );
153
+ delete_option( 'wpo_wcpdf_debug_settings' );
154
+ // and delete cache of these options, just in case...
155
+ wp_cache_delete( 'wpo_wcpdf_general_settings','options' );
156
+ wp_cache_delete( 'wpo_wcpdf_template_settings','options' );
157
+ wp_cache_delete( 'wpo_wcpdf_debug_settings','options' );
158
 
159
+ printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Legacy settings deleted!', 'woocommerce-pdf-invoices-packing-slips' ) );
160
+ }
161
+ ?>
162
+ </form>
163
+ </p>
164
+ </div>
165
+ <br>
166
  <?php
167
  }
168
 
includes/documents/abstract-wcpdf-order-document-methods.php CHANGED
@@ -558,13 +558,13 @@ abstract class Order_Document_Methods extends Order_Document {
558
  $data['thumbnail'] = $this->get_thumbnail( $product );
559
 
560
  // Set item SKU
561
- $data['sku'] = $product->get_sku();
562
 
563
  // Set item weight
564
- $data['weight'] = $product->get_weight();
565
 
566
  // Set item dimensions
567
- $data['dimensions'] = WCX_Product::get_dimensions( $product );
568
 
569
  // Pass complete product object
570
  $data['product'] = $product;
@@ -1131,6 +1131,12 @@ abstract class Order_Document_Methods extends Order_Document {
1131
  } else {
1132
  $shipping_notes = wpautop( wptexturize( WCX_Order::get_prop( $this->order, 'customer_note', 'view' ) ) );
1133
  }
 
 
 
 
 
 
1134
  return apply_filters( 'wpo_wcpdf_shipping_notes', $shipping_notes, $this );
1135
  }
1136
  public function shipping_notes() {
558
  $data['thumbnail'] = $this->get_thumbnail( $product );
559
 
560
  // Set item SKU
561
+ $data['sku'] = is_callable( array( $product, 'get_sku' ) ) ? $product->get_sku() : '';
562
 
563
  // Set item weight
564
+ $data['weight'] = is_callable( array( $product, 'get_weight' ) ) ? $product->get_weight() : '';
565
 
566
  // Set item dimensions
567
+ $data['dimensions'] = $product instanceof \WC_Product ? WCX_Product::get_dimensions( $product ) : '';
568
 
569
  // Pass complete product object
570
  $data['product'] = $product;
1131
  } else {
1132
  $shipping_notes = wpautop( wptexturize( WCX_Order::get_prop( $this->order, 'customer_note', 'view' ) ) );
1133
  }
1134
+
1135
+ // check document specific setting
1136
+ if( isset($this->settings['display_customer_notes']) && $this->settings['display_customer_notes'] == 0 ) {
1137
+ $shipping_notes = false;
1138
+ }
1139
+
1140
  return apply_filters( 'wpo_wcpdf_shipping_notes', $shipping_notes, $this );
1141
  }
1142
  public function shipping_notes() {
includes/documents/class-wcpdf-invoice.php CHANGED
@@ -30,7 +30,7 @@ class Invoice extends Order_Document_Methods {
30
  // set properties
31
  $this->type = 'invoice';
32
  $this->title = __( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' );
33
- $this->icon = WPO_WCPDF()->plugin_url() . "/assets/images/invoice.png";
34
 
35
  // Call parent constructor
36
  parent::__construct( $order );
@@ -112,7 +112,7 @@ class Invoice extends Order_Document_Methods {
112
  $last_number_year = $number_store->get_last_date('Y');
113
  // check if we need to reset
114
  if ( $current_year != $last_number_year ) {
115
- $number_store->set_next( 1 );
116
  }
117
  }
118
 
@@ -247,6 +247,19 @@ class Invoice extends Order_Document_Methods {
247
  'id' => 'display_phone',
248
  )
249
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  array(
251
  'type' => 'setting',
252
  'id' => 'display_date',
@@ -383,7 +396,7 @@ class Invoice extends Order_Document_Methods {
383
  'args' => array(
384
  'option_name' => $option_name,
385
  'id' => 'disable_free',
386
- 'description' => sprintf(__( "Disable automatic creation/attachment when the order total is %s", 'woocommerce-pdf-invoices-packing-slips' ), function_exists('wc_price') ? wc_price( 0 ) : 0 ),
387
  )
388
  ),
389
  array(
30
  // set properties
31
  $this->type = 'invoice';
32
  $this->title = __( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' );
33
+ $this->icon = WPO_WCPDF()->plugin_url() . "/assets/images/invoice.svg";
34
 
35
  // Call parent constructor
36
  parent::__construct( $order );
112
  $last_number_year = $number_store->get_last_date('Y');
113
  // check if we need to reset
114
  if ( $current_year != $last_number_year ) {
115
+ $number_store->set_next( apply_filters( 'wpo_wcpdf_reset_number_yearly_start', 1, $this ) );
116
  }
117
  }
118
 
247
  'id' => 'display_phone',
248
  )
249
  ),
250
+ array(
251
+ 'type' => 'setting',
252
+ 'id' => 'display_customer_notes',
253
+ 'title' => __( 'Display customer notes', 'woocommerce-pdf-invoices-packing-slips' ),
254
+ 'callback' => 'checkbox',
255
+ 'section' => 'invoice',
256
+ 'args' => array(
257
+ 'option_name' => $option_name,
258
+ 'id' => 'display_customer_notes',
259
+ 'store_unchecked' => true,
260
+ 'default' => 1,
261
+ )
262
+ ),
263
  array(
264
  'type' => 'setting',
265
  'id' => 'display_date',
396
  'args' => array(
397
  'option_name' => $option_name,
398
  'id' => 'disable_free',
399
+ 'description' => sprintf(__( "Disable document when the order total is %s", 'woocommerce-pdf-invoices-packing-slips' ), function_exists('wc_price') ? wc_price( 0 ) : 0 ),
400
  )
401
  ),
402
  array(
includes/documents/class-wcpdf-packing-slip.php CHANGED
@@ -30,7 +30,7 @@ class Packing_Slip extends Order_Document_Methods {
30
  // set properties
31
  $this->type = 'packing-slip';
32
  $this->title = __( 'Packing Slip', 'woocommerce-pdf-invoices-packing-slips' );
33
- $this->icon = WPO_WCPDF()->plugin_url() . "/assets/images/packing-slip.png";
34
 
35
  // Call parent constructor
36
  parent::__construct( $order );
@@ -132,6 +132,19 @@ class Packing_Slip extends Order_Document_Methods {
132
  'id' => 'display_phone',
133
  )
134
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  );
136
 
137
 
30
  // set properties
31
  $this->type = 'packing-slip';
32
  $this->title = __( 'Packing Slip', 'woocommerce-pdf-invoices-packing-slips' );
33
+ $this->icon = WPO_WCPDF()->plugin_url() . "/assets/images/packing-slip.svg";
34
 
35
  // Call parent constructor
36
  parent::__construct( $order );
132
  'id' => 'display_phone',
133
  )
134
  ),
135
+ array(
136
+ 'type' => 'setting',
137
+ 'id' => 'display_customer_notes',
138
+ 'title' => __( 'Display customer notes', 'woocommerce-pdf-invoices-packing-slips' ),
139
+ 'callback' => 'checkbox',
140
+ 'section' => 'packing_slip',
141
+ 'args' => array(
142
+ 'option_name' => $option_name,
143
+ 'id' => 'display_customer_notes',
144
+ 'store_unchecked' => true,
145
+ 'default' => 1,
146
+ )
147
+ ),
148
  );
149
 
150
 
includes/legacy/class-wcpdf-legacy-document.php CHANGED
@@ -1,52 +1,52 @@
1
- <?php
2
- namespace WPO\WC\PDF_Invoices\Documents;
3
-
4
- use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
- use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
- use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly
10
- }
11
-
12
- if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Legacy_Document' ) ) :
13
-
14
- /**
15
- * Packing Slip Document
16
- *
17
- * @class \WPO\WC\PDF_Invoices\Documents\Legacy_Document
18
- * @version 2.0
19
- * @category Class
20
- * @author Ewout Fernhout
21
- */
22
-
23
- class Legacy_Document extends Order_Document_Methods {
24
- /**
25
- * Init/load the order object.
26
- *
27
- * @param int|object|WC_Order $order Order to init.
28
- */
29
- public function __construct( $order = 0 ) {
30
- // set properties
31
- $this->type = 'legacy-document';
32
- $this->title = __( 'Legacy Document', 'woocommerce-pdf-invoices-packing-slips' );
33
- $this->icon = WPO_WCPDF()->plugin_url() . "/assets/images/packing-slip.png";
34
- }
35
-
36
- public function set_props( $props, $call_parent_constructor = true ) {
37
- foreach ($props as $prop => $value) {
38
- $this->{$prop} = $value;
39
- }
40
-
41
- if ( $call_parent_constructor ) {
42
- // Call parent constructor
43
- $order = ( empty( $props['order'] ) && !empty( $this->order ) ) ? $this->order : $props['order'];
44
- parent::__construct( $order );
45
- }
46
- }
47
-
48
- }
49
-
50
- endif; // class_exists
51
-
52
  return new Legacy_Document();
1
+ <?php
2
+ namespace WPO\WC\PDF_Invoices\Documents;
3
+
4
+ use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
5
+ use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
6
+ use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly
10
+ }
11
+
12
+ if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Legacy_Document' ) ) :
13
+
14
+ /**
15
+ * Packing Slip Document
16
+ *
17
+ * @class \WPO\WC\PDF_Invoices\Documents\Legacy_Document
18
+ * @version 2.0
19
+ * @category Class
20
+ * @author Ewout Fernhout
21
+ */
22
+
23
+ class Legacy_Document extends Order_Document_Methods {
24
+ /**
25
+ * Init/load the order object.
26
+ *
27
+ * @param int|object|WC_Order $order Order to init.
28
+ */
29
+ public function __construct( $order = 0 ) {
30
+ // set properties
31
+ $this->type = 'legacy-document';
32
+ $this->title = __( 'Legacy Document', 'woocommerce-pdf-invoices-packing-slips' );
33
+ $this->icon = WPO_WCPDF()->plugin_url() . "/assets/images/packing-slip.svg";
34
+ }
35
+
36
+ public function set_props( $props, $call_parent_constructor = true ) {
37
+ foreach ($props as $prop => $value) {
38
+ $this->{$prop} = $value;
39
+ }
40
+
41
+ if ( $call_parent_constructor ) {
42
+ // Call parent constructor
43
+ $order = ( empty( $props['order'] ) && !empty( $this->order ) ) ? $this->order : $props['order'];
44
+ parent::__construct( $order );
45
+ }
46
+ }
47
+
48
+ }
49
+
50
+ endif; // class_exists
51
+
52
  return new Legacy_Document();
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice,
5
  Requires at least: 3.5
6
  Tested up to: 5.5
7
  Requires PHP: 5.3
8
- Stable tag: 2.7.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -102,6 +102,19 @@ There's a setting on the Status tab of the settings page that allows you to togg
102
 
103
  == Changelog ==
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  = 2.7.0 =
106
  * New: Add per-order notes to invoices (requires template update if you have a custom template)
107
  * New: Show notice with instructions for protecting the invoice folder on NGINX setups
5
  Requires at least: 3.5
6
  Tested up to: 5.5
7
  Requires PHP: 5.3
8
+ Stable tag: 2.7.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
102
 
103
  == Changelog ==
104
 
105
+ = 2.7.1 =
106
+ * New: Redesigned action buttons
107
+ * New: Randomized temporary folder name for easier protection
108
+ * New: Setting to enable/disable customer notes
109
+ * New: Completely disable free invoice when that setting is enabled (not just attachments)
110
+ * New: Template action hooks before and after shop name and address
111
+ * New: Filter to set starting number for yearly reset
112
+ * Fix: Errors on third party products without weight/sku/dimensions
113
+ * Fix: Uneven spacing between action icons
114
+ * Fix: Missing `$email_to_send` parameter for `woocommerce_before_resend_order_emails` hook
115
+ * Fix: Break long words in billing address
116
+ * Tested up to WooCommerce 4.7
117
+
118
  = 2.7.0 =
119
  * New: Add per-order notes to invoices (requires template update if you have a custom template)
120
  * New: Show notice with instructions for protecting the invoice folder on NGINX setups
templates/Simple/invoice.php CHANGED
@@ -13,8 +13,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>
13
  ?>
14
  </td>
15
  <td class="shop-info">
16
+ <?php do_action( 'wpo_wcpdf_before_shop_name', $this->type, $this->order ); ?>
17
  <div class="shop-name"><h3><?php $this->shop_name(); ?></h3></div>
18
+ <?php do_action( 'wpo_wcpdf_after_shop_name', $this->type, $this->order ); ?>
19
+ <?php do_action( 'wpo_wcpdf_before_shop_address', $this->type, $this->order ); ?>
20
  <div class="shop-address"><?php $this->shop_address(); ?></div>
21
+ <?php do_action( 'wpo_wcpdf_after_shop_address', $this->type, $this->order ); ?>
22
  </td>
23
  </tr>
24
  </table>
templates/Simple/packing-slip.php CHANGED
@@ -13,8 +13,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>
13
  ?>
14
  </td>
15
  <td class="shop-info">
16
+ <?php do_action( 'wpo_wcpdf_before_shop_name', $this->type, $this->order ); ?>
17
  <div class="shop-name"><h3><?php $this->shop_name(); ?></h3></div>
18
+ <?php do_action( 'wpo_wcpdf_after_shop_name', $this->type, $this->order ); ?>
19
+ <?php do_action( 'wpo_wcpdf_before_shop_address', $this->type, $this->order ); ?>
20
  <div class="shop-address"><?php $this->shop_address(); ?></div>
21
+ <?php do_action( 'wpo_wcpdf_after_shop_address', $this->type, $this->order ); ?>
22
  </td>
23
  </tr>
24
  </table>
templates/Simple/style.css CHANGED
@@ -73,6 +73,7 @@ table {
73
  th, td {
74
  vertical-align: top;
75
  text-align: left;
 
76
  }
77
 
78
  table.container {
73
  th, td {
74
  vertical-align: top;
75
  text-align: left;
76
+ word-wrap: break-word;
77
  }
78
 
79
  table.container {
woocommerce-pdf-invoices-packingslips.php CHANGED
@@ -3,14 +3,14 @@
3
  * Plugin Name: WooCommerce PDF Invoices & Packing Slips
4
  * Plugin URI: http://www.wpovernight.com
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
- * Version: 2.7.0
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: 4.6.0
14
  */
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
@@ -21,7 +21,7 @@ if ( !class_exists( 'WPO_WCPDF' ) ) :
21
 
22
  class WPO_WCPDF {
23
 
24
- public $version = '2.7.0';
25
  public $plugin_basename;
26
  public $legacy_mode;
27
 
@@ -332,21 +332,35 @@ class WPO_WCPDF {
332
  return;
333
  }
334
  $tmp_path = $this->main->get_tmp_path('attachments');
335
- $server_software = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : false;
336
- if ( stristr( $server_software, 'nginx' ) && ( current_user_can( 'manage_shop_settings' ) || current_user_can( 'manage_woocommerce' ) ) && ! get_option('wpo_wcpdf_hide_nginx_notice') ) {
 
 
337
  ob_start();
338
  ?>
339
  <div class="error">
340
- <img src="<?php echo WPO_WCPDF()->plugin_url() . "/assets/images/nginx.svg"; ?>" style="margin-top:10px;">
341
  <p><?php printf( __( 'The PDF files in %s are not currently protected due to your site running on <strong>NGINX</strong>.', 'woocommerce-pdf-invoices-packing-slips' ), '<strong>' . $tmp_path . '</strong>' ); ?></p>
342
- <p><?php _e( 'To protect them, you must either use a filter to change the folder to a more secure location (outside of the site root folder) or add a Virtual Host location rule as explained in <a href="https://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/protect-the-attachments-directory-on-nginx/" target="_blank">this guide</a>.', 'woocommerce-pdf-invoices-packing-slips' ); ?></p>
343
- <p><?php _e( 'If you have already added the filter or the vhost rule, you may safely hide this message.', 'woocommerce-pdf-invoices-packing-slips' ); ?></p>
344
  <p><a href="<?php echo esc_url( add_query_arg( 'wpo_wcpdf_hide_nginx_notice', 'true' ) ); ?>"><?php _e( 'Hide this message', 'woocommerce-pdf-invoices-packing-slips' ); ?></a></p>
345
  </div>
346
  <?php
347
  echo ob_get_clean();
348
  }
349
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  // save option to hide nginx notice
351
  if ( isset( $_GET['wpo_wcpdf_hide_nginx_notice'] ) ) {
352
  update_option( 'wpo_wcpdf_hide_nginx_notice', true );
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.7.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: 4.7.0
14
  */
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
21
 
22
  class WPO_WCPDF {
23
 
24
+ public $version = '2.7.1';
25
  public $plugin_basename;
26
  public $legacy_mode;
27
 
332
  return;
333
  }
334
  $tmp_path = $this->main->get_tmp_path('attachments');
335
+ $server_software = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';
336
+ $random_string = $this->main->get_random_string();
337
+
338
+ if ( stristr( $server_software, 'nginx' ) && ( current_user_can( 'manage_shop_settings' ) || current_user_can( 'manage_woocommerce' ) ) && ! get_option('wpo_wcpdf_hide_nginx_notice') && ! $random_string ) {
339
  ob_start();
340
  ?>
341
  <div class="error">
342
+ <img src="<?php echo $this->plugin_url() . "/assets/images/nginx.svg"; ?>" style="margin-top:10px;">
343
  <p><?php printf( __( 'The PDF files in %s are not currently protected due to your site running on <strong>NGINX</strong>.', 'woocommerce-pdf-invoices-packing-slips' ), '<strong>' . $tmp_path . '</strong>' ); ?></p>
344
+ <p><?php _e( 'To protect them, you must click the button below.', 'woocommerce-pdf-invoices-packing-slips' ); ?></p>
345
+ <p><a class="button" href="<?php echo esc_url( add_query_arg( 'wpo_wcpdf_protect_pdf_directory', 'true' ) ); ?>"><?php _e( 'Generate random temporary folder name', 'woocommerce-pdf-invoices-packing-slips' ); ?></a></p>
346
  <p><a href="<?php echo esc_url( add_query_arg( 'wpo_wcpdf_hide_nginx_notice', 'true' ) ); ?>"><?php _e( 'Hide this message', 'woocommerce-pdf-invoices-packing-slips' ); ?></a></p>
347
  </div>
348
  <?php
349
  echo ob_get_clean();
350
  }
351
 
352
+ // protect PDF directory
353
+ if ( isset( $_GET['wpo_wcpdf_protect_pdf_directory'] ) ) {
354
+ $this->main->generate_random_string();
355
+ $old_path = $this->main->get_tmp_base( false );
356
+ $new_path = $this->main->get_tmp_base();
357
+ $this->main->copy_directory( $old_path, $new_path );
358
+ // save option to hide nginx notice
359
+ update_option( 'wpo_wcpdf_hide_nginx_notice', true );
360
+ wp_redirect( 'admin.php?page=wpo_wcpdf_options_page' );
361
+ exit;
362
+ }
363
+
364
  // save option to hide nginx notice
365
  if ( isset( $_GET['wpo_wcpdf_hide_nginx_notice'] ) ) {
366
  update_option( 'wpo_wcpdf_hide_nginx_notice', true );