WooCommerce PDF Invoices & Packing Slips - Version 1.5.37

Version Description

  • Feature: Added support for third party invoice numbers
  • Feature: Enable pre-invoice number click-to-edit
  • Fix: Review link for custom admins
  • Fix: PHP7 compatibility
  • Fix: Invoice date hour/minute pattern
  • Tweak: Multisite WooCommerce check optimization
Download this release

Release Info

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

Code changes from version 1.5.36 to 1.5.37

includes/class-wcpdf-export.php CHANGED
@@ -625,6 +625,13 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
625
  // first check: get invoice number from post meta
626
  $invoice_number = get_post_meta( $order_id, '_wcpdf_invoice_number', true );
627
 
 
 
 
 
 
 
 
628
  // add invoice number if it doesn't exist
629
  if ( empty($invoice_number) || !isset($invoice_number) ) {
630
  global $wpdb;
@@ -692,6 +699,13 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
692
  }
693
 
694
  public function get_invoice_number( $order_id ) {
 
 
 
 
 
 
 
695
  // get invoice number from post meta
696
  if ( $invoice_number = get_post_meta( $order_id, '_wcpdf_invoice_number', true ) ) {
697
  // check if we have already loaded this order
625
  // first check: get invoice number from post meta
626
  $invoice_number = get_post_meta( $order_id, '_wcpdf_invoice_number', true );
627
 
628
+ // If a third-party plugin claims to generate invoice numbers, use it instead
629
+ $third_party = apply_filters('woocommerce_invoice_number_by_plugin', false);
630
+ if ($third_party) {
631
+ $order = new WC_Order($order_id);
632
+ $invoice_number = apply_filters('woocommerce_generate_invoice_number', null, $order);
633
+ }
634
+
635
  // add invoice number if it doesn't exist
636
  if ( empty($invoice_number) || !isset($invoice_number) ) {
637
  global $wpdb;
699
  }
700
 
701
  public function get_invoice_number( $order_id ) {
702
+ // Call the woocommerce_invoice_number filter and let third-party plugins set a number.
703
+ // Default is null, so we can detect whether a plugin has set the invoice number
704
+ $third_party_invoice_number = apply_filters( 'woocommerce_invoice_number', null, $order_id );
705
+ if ($third_party_invoice_number !== null) {
706
+ return $third_party_invoice_number;
707
+ }
708
+
709
  // get invoice number from post meta
710
  if ( $invoice_number = get_post_meta( $order_id, '_wcpdf_invoice_number', true ) ) {
711
  // check if we have already loaded this order
includes/class-wcpdf-settings.php CHANGED
@@ -1,1412 +1,1429 @@
1
- <?php
2
-
3
- /**
4
- * Settings class
5
- */
6
- if ( ! class_exists( 'WooCommerce_PDF_Invoices_Settings' ) ) {
7
-
8
- class WooCommerce_PDF_Invoices_Settings {
9
-
10
- public $options_page_hook;
11
- public $general_settings;
12
- public $template_settings;
13
-
14
- public function __construct() {
15
- add_action( 'admin_menu', array( &$this, 'menu' ) ); // Add menu.
16
- add_action( 'admin_init', array( &$this, 'init_settings' ) ); // Registers settings
17
- add_filter( 'option_page_capability_wpo_wcpdf_template_settings', array( &$this, 'settings_capabilities' ) );
18
- add_filter( 'option_page_capability_wpo_wcpdf_general_settings', array( &$this, 'settings_capabilities' ) );
19
- add_action( 'admin_enqueue_scripts', array( &$this, 'load_scripts_styles' ) ); // Load scripts
20
-
21
- // Add links to WordPress plugins page
22
- add_filter( 'plugin_action_links_'.WooCommerce_PDF_Invoices::$plugin_basename, array( &$this, 'wpo_wcpdf_add_settings_link' ) );
23
- add_filter( 'plugin_row_meta', array( $this, 'add_support_links' ), 10, 2 );
24
-
25
- $this->general_settings = get_option('wpo_wcpdf_general_settings');
26
- $this->template_settings = get_option('wpo_wcpdf_template_settings');
27
-
28
- // WooCommerce Order Status & Actions Manager emails compatibility
29
- add_filter( 'wpo_wcpdf_wc_emails', array( $this, 'wc_order_status_actions_emails' ), 10, 1 );
30
- }
31
-
32
- public function menu() {
33
- $parent_slug = 'woocommerce';
34
-
35
- $this->options_page_hook = add_submenu_page(
36
- $parent_slug,
37
- __( 'PDF Invoices', 'wpo_wcpdf' ),
38
- __( 'PDF Invoices', 'wpo_wcpdf' ),
39
- 'manage_woocommerce',
40
- 'wpo_wcpdf_options_page',
41
- array( $this, 'settings_page' )
42
- );
43
- }
44
-
45
- /**
46
- * Set capability for settings page
47
- */
48
- public function settings_capabilities() {
49
- return 'manage_woocommerce';
50
- }
51
-
52
- /**
53
- * Styles for settings page
54
- */
55
- public function load_scripts_styles ( $hook ) {
56
- if( $hook != $this->options_page_hook )
57
- return;
58
-
59
- wp_enqueue_script(
60
- 'wcpdf-upload-js',
61
- plugins_url( 'js/media-upload.js' , dirname(__FILE__) ),
62
- array( 'jquery' ),
63
- WooCommerce_PDF_Invoices::$version
64
- );
65
-
66
- wp_enqueue_style(
67
- 'wpo-wcpdf',
68
- WooCommerce_PDF_Invoices::$plugin_url . 'css/style.css',
69
- array(),
70
- WooCommerce_PDF_Invoices::$version
71
- );
72
- wp_enqueue_media();
73
- }
74
-
75
- /**
76
- * Add settings link to plugins page
77
- */
78
- public function wpo_wcpdf_add_settings_link( $links ) {
79
- $settings_link = '<a href="admin.php?page=wpo_wcpdf_options_page">'. __( 'Settings', 'woocommerce' ) . '</a>';
80
- array_push( $links, $settings_link );
81
- return $links;
82
- }
83
-
84
- /**
85
- * Add various support links to plugin page
86
- * after meta (version, authors, site)
87
- */
88
- public function add_support_links( $links, $file ) {
89
- if ( !current_user_can( 'install_plugins' ) ) {
90
- return $links;
91
- }
92
-
93
- if ( $file == WooCommerce_PDF_Invoices::$plugin_basename ) {
94
- // $links[] = '<a href="..." target="_blank" title="' . __( '...', 'wpo_wcpdf' ) . '">' . __( '...', 'wpo_wcpdf' ) . '</a>';
95
- }
96
- return $links;
97
- }
98
-
99
- public function settings_page() {
100
- $settings_tabs = apply_filters( 'wpo_wcpdf_settings_tabs', array (
101
- 'general' => __('General','wpo_wcpdf'),
102
- 'template' => __('Template','wpo_wcpdf'),
103
- )
104
- );
105
-
106
- // add status tab last in row
107
- $settings_tabs['debug'] = __('Status','wpo_wcpdf');
108
-
109
- $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'general';
110
-
111
- ?>
112
- <script type="text/javascript">
113
- window.onload = function () {
114
- document.getElementById("footer-thankyou").innerHTML = "If you like <strong>WooCommerce PDF Invoices & Packing Slips</strong> please leave us a <a href='https://wordpress.org/support/view/plugin-reviews/woocommerce-pdf-invoices-packing-slips?rate=5#postform'>★★★★★</a> rating. A huge thank you in advance!";
115
- };
116
- </script>
117
- <div class="wrap">
118
- <div class="icon32" id="icon-options-general"><br /></div>
119
- <h2><?php _e( 'WooCommerce PDF Invoices', 'wpo_wcpdf' ); ?></h2>
120
- <h2 class="nav-tab-wrapper">
121
- <?php
122
- foreach ($settings_tabs as $tab_slug => $tab_title ) {
123
- printf('<a href="?page=wpo_wcpdf_options_page&tab=%1$s" class="nav-tab nav-tab-%1$s %2$s">%3$s</a>', $tab_slug, (($active_tab == $tab_slug) ? 'nav-tab-active' : ''), $tab_title);
124
- }
125
- ?>
126
- </h2>
127
-
128
- <?php
129
- do_action( 'wpo_wcpdf_before_settings_page', $active_tab );
130
-
131
- // save or check option to hide extensions ad
132
- if ( isset( $_GET['wpo_wcpdf_hide_extensions_ad'] ) ) {
133
- update_option( 'wpo_wcpdf_hide_extensions_ad', true );
134
- $hide_ad = true;
135
- } else {
136
- $hide_ad = get_option( 'wpo_wcpdf_hide_extensions_ad' );
137
- }
138
-
139
- if ( !$hide_ad && !( class_exists('WooCommerce_PDF_IPS_Pro') && class_exists('WooCommerce_PDF_IPS_Dropbox') && class_exists('WooCommerce_PDF_IPS_Templates') && class_exists('WooCommerce_Ext_PrintOrders') ) ) {
140
- include('wcpdf-extensions.php');
141
- }
142
-
143
- ?>
144
- <form method="post" action="options.php" id="wpo-wcpdf-settings">
145
- <?php
146
- do_action( 'wpo_wcpdf_before_settings', $active_tab );
147
- settings_fields( 'wpo_wcpdf_'.$active_tab.'_settings' );
148
- do_settings_sections( 'wpo_wcpdf_'.$active_tab.'_settings' );
149
- do_action( 'wpo_wcpdf_after_settings', $active_tab );
150
-
151
- submit_button();
152
- ?>
153
-
154
- </form>
155
- <?php
156
-
157
- if ( $active_tab=='debug' ) {
158
- $this->status_page();
159
- }
160
-
161
- do_action( 'wpo_wcpdf_after_settings_page', $active_tab ); ?>
162
-
163
- </div>
164
-
165
- <?php
166
- }
167
-
168
- public function status_page() {
169
- ?>
170
- <?php include('dompdf-status.php'); ?>
171
- <?php
172
- }
173
-
174
- /**
175
- * User settings.
176
- *
177
- */
178
-
179
- public function init_settings() {
180
- global $woocommerce, $wpo_wcpdf;
181
-
182
- /**************************************/
183
- /*********** GENERAL SETTINGS *********/
184
- /**************************************/
185
-
186
- $option = 'wpo_wcpdf_general_settings';
187
-
188
- // Create option in wp_options.
189
- if ( false === get_option( $option ) ) {
190
- $this->default_settings( $option );
191
- }
192
-
193
- // Section.
194
- add_settings_section(
195
- 'general_settings',
196
- __( 'General settings', 'wpo_wcpdf' ),
197
- array( &$this, 'section_options_callback' ),
198
- $option
199
- );
200
-
201
- add_settings_field(
202
- 'download_display',
203
- __( 'How do you want to view the PDF?', 'wpo_wcpdf' ),
204
- array( &$this, 'select_element_callback' ),
205
- $option,
206
- 'general_settings',
207
- array(
208
- 'menu' => $option,
209
- 'id' => 'download_display',
210
- 'options' => array(
211
- 'download' => __( 'Download the PDF' , 'wpo_wcpdf' ),
212
- 'display' => __( 'Open the PDF in a new browser tab/window' , 'wpo_wcpdf' ),
213
- ),
214
- )
215
- );
216
-
217
- $tmp_path = $wpo_wcpdf->export->tmp_path( 'attachments' );
218
- $tmp_path_check = !is_writable( $tmp_path );
219
-
220
- $wc_emails = array(
221
- 'new_order' => __( 'Admin New Order email' , 'wpo_wcpdf' ),
222
- 'processing' => __( 'Customer Processing Order email' , 'wpo_wcpdf' ),
223
- 'completed' => __( 'Customer Completed Order email' , 'wpo_wcpdf' ),
224
- 'customer_invoice' => __( 'Customer Invoice email' , 'wpo_wcpdf' ),
225
- );
226
-
227
- // load custom emails
228
- $extra_emails = $this->get_wc_emails();
229
- $wc_emails = array_merge( $wc_emails, $extra_emails );
230
-
231
- add_settings_field(
232
- 'email_pdf',
233
- __( 'Attach invoice to:', 'wpo_wcpdf' ),
234
- array( &$this, 'multiple_checkbox_element_callback' ),
235
- $option,
236
- 'general_settings',
237
- array(
238
- 'menu' => $option,
239
- 'id' => 'email_pdf',
240
- 'options' => apply_filters( 'wpo_wcpdf_wc_emails', $wc_emails ),
241
- 'description' => $tmp_path_check ? '<span class="wpo-warning">' . sprintf( __( 'It looks like the temp folder (<code>%s</code>) is not writable, check the permissions for this folder! Without having write access to this folder, the plugin will not be able to email invoices.', 'wpo_wcpdf' ), $tmp_path ).'</span>':'',
242
- )
243
- );
244
-
245
- add_settings_field(
246
- 'disable_free',
247
- __( 'Disable for free products', 'wpo_wcpdf' ),
248
- array( &$this, 'checkbox_element_callback' ),
249
- $option,
250
- 'general_settings',
251
- array(
252
- 'menu' => $option,
253
- 'id' => 'disable_free',
254
- 'description' => __( "Disable automatic creation/attachment of invoices when only free products are ordered", 'wpo_wcpdf' ),
255
- )
256
- );
257
-
258
- // Section.
259
- add_settings_section(
260
- 'interface',
261
- __( 'Interface', 'wpo_wcpdf' ),
262
- array( &$this, 'section_options_callback' ),
263
- $option
264
- );
265
-
266
- // $documents = array(
267
- // 'invoice' => __( 'Invoice', 'wpo_wcpdf' ),
268
- // 'packing-slip' => __( 'Packing Slip', 'wpo_wcpdf' ),
269
- // );
270
-
271
- // $contexts = array(
272
- // 'orders-list' => __( 'Orders list', 'wpo_wcpdf' ),
273
- // 'orders-bulk' => __( 'Bulk order actions', 'wpo_wcpdf' ),
274
- // 'order-single' => __( 'Single order page', 'wpo_wcpdf' ),
275
- // 'my-account' => __( 'My Account page', 'wpo_wcpdf' ),
276
- // );
277
-
278
- // add_settings_field(
279
- // 'buttons',
280
- // __( 'Show download buttons', 'wpo_wcpdf' ),
281
- // array( &$this, 'checkbox_table_callback' ),
282
- // $option,
283
- // 'interface',
284
- // array(
285
- // 'menu' => $option,
286
- // 'id' => 'buttons',
287
- // 'rows' => $contexts,
288
- // 'columns' => apply_filters( 'wpo_wcpdf_documents_buttons', $documents ),
289
- // )
290
- // );
291
-
292
- // get list of WooCommerce statuses
293
- if ( version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
294
- $statuses = (array) get_terms( 'shop_order_status', array( 'hide_empty' => 0, 'orderby' => 'id' ) );
295
- foreach ( $statuses as $status ) {
296
- $order_statuses[esc_attr( $status->slug )] = esc_html__( $status->name, 'woocommerce' );
297
- }
298
- } else {
299
- $statuses = wc_get_order_statuses();
300
- foreach ( $statuses as $status_slug => $status ) {
301
- $status_slug = 'wc-' === substr( $status_slug, 0, 3 ) ? substr( $status_slug, 3 ) : $status_slug;
302
- $order_statuses[$status_slug] = $status;
303
- }
304
-
305
- }
306
-
307
- add_settings_field(
308
- 'my_account_buttons',
309
- __( 'Allow My Account invoice download', 'wpo_wcpdf' ),
310
- array( &$this, 'select_element_callback' ),
311
- $option,
312
- 'interface',
313
- array(
314
- 'menu' => $option,
315
- 'id' => 'my_account_buttons',
316
- 'options' => array(
317
- 'available' => __( 'Only when an invoice is already created/emailed' , 'wpo_wcpdf' ),
318
- 'custom' => __( 'Only for specific order statuses (define below)' , 'wpo_wcpdf' ),
319
- 'always' => __( 'Always' , 'wpo_wcpdf' ),
320
- 'never' => __( 'Never' , 'wpo_wcpdf' ),
321
- ),
322
- 'custom' => array(
323
- 'type' => 'multiple_checkbox_element_callback',
324
- 'args' => array(
325
- 'menu' => $option,
326
- 'id' => 'my_account_restrict',
327
- 'options' => $order_statuses,
328
- ),
329
- ),
330
- )
331
- );
332
-
333
- add_settings_field(
334
- 'invoice_number_column',
335
- __( 'Enable invoice number column in the orders list', 'wpo_wcpdf' ),
336
- array( &$this, 'checkbox_element_callback' ),
337
- $option,
338
- 'interface',
339
- array(
340
- 'menu' => $option,
341
- 'id' => 'invoice_number_column',
342
- )
343
- );
344
-
345
- // Register settings.
346
- register_setting( $option, $option, array( &$this, 'validate_options' ) );
347
-
348
- $option_values = get_option($option);
349
- // convert old 'statusless' setting to new status array
350
- if ( isset( $option_values['email_pdf'] ) && !is_array( $option_values['email_pdf'] ) ) {
351
- $default_status = apply_filters( 'wpo_wcpdf_attach_to_status', 'completed' );
352
- $option_values['email_pdf'] = array (
353
- $default_status => 1,
354
- 'customer_invoice' => 1,
355
- );
356
- update_option( $option, $option_values );
357
- }
358
-
359
- /**************************************/
360
- /********** TEMPLATE SETTINGS *********/
361
- /**************************************/
362
-
363
- $option = 'wpo_wcpdf_template_settings';
364
-
365
- // Create option in wp_options.
366
- if ( false === get_option( $option ) ) {
367
- $this->default_settings( $option );
368
- }
369
-
370
- // Section.
371
- add_settings_section(
372
- 'template_settings',
373
- __( 'PDF Template settings', 'wpo_wcpdf' ),
374
- array( &$this, 'section_options_callback' ),
375
- $option
376
- );
377
-
378
-
379
- $theme_path = get_stylesheet_directory() . '/' . $wpo_wcpdf->export->template_base_path;
380
- $theme_template_path = substr($theme_path, strpos($theme_path, 'wp-content')) . 'yourtemplate';
381
- $plugin_template_path = 'wp-content/plugins/woocommerce-pdf-invoices-packing-slips/templates/pdf/Simple';
382
-
383
- add_settings_field(
384
- 'template_path',
385
- __( 'Choose a template', 'wpo_wcpdf' ),
386
- array( &$this, 'template_select_element_callback' ),
387
- $option,
388
- 'template_settings',
389
- array(
390
- 'menu' => $option,
391
- 'id' => 'template_path',
392
- 'options' => $this->find_templates(),
393
- 'description' => sprintf( __( 'Want to use your own template? Copy all the files from <code>%s</code> to your (child) theme in <code>%s</code> to customize them' , 'wpo_wcpdf' ), $plugin_template_path, $theme_template_path),
394
- )
395
- );
396
-
397
- add_settings_field(
398
- 'paper_size',
399
- __( 'Paper size', 'wpo_wcpdf' ),
400
- array( &$this, 'select_element_callback' ),
401
- $option,
402
- 'template_settings',
403
- array(
404
- 'menu' => $option,
405
- 'id' => 'paper_size',
406
- 'options' => apply_filters( 'wpo_wcpdf_template_settings_paper_size', array(
407
- 'a4' => __( 'A4' , 'wpo_wcpdf' ),
408
- 'letter' => __( 'Letter' , 'wpo_wcpdf' ),
409
- ) ),
410
- )
411
- );
412
-
413
- add_settings_field(
414
- 'header_logo',
415
- __( 'Shop header/logo', 'wpo_wcpdf' ),
416
- array( &$this, 'media_upload_callback' ),
417
- $option,
418
- 'template_settings',
419
- array(
420
- 'menu' => $option,
421
- 'id' => 'header_logo',
422
- 'uploader_title' => __( 'Select or upload your invoice header/logo', 'wpo_wcpdf' ),
423
- 'uploader_button_text' => __( 'Set image', 'wpo_wcpdf' ),
424
- 'remove_button_text' => __( 'Remove image', 'wpo_wcpdf' ),
425
- //'description' => __( '...', 'wpo_wcpdf' ),
426
- )
427
- );
428
-
429
- add_settings_field(
430
- 'shop_name',
431
- __( 'Shop Name', 'wpo_wcpdf' ),
432
- array( &$this, 'text_element_callback' ),
433
- $option,
434
- 'template_settings',
435
- array(
436
- 'menu' => $option,
437
- 'id' => 'shop_name',
438
- 'size' => '72',
439
- 'translatable' => true,
440
- )
441
- );
442
-
443
- add_settings_field(
444
- 'shop_address',
445
- __( 'Shop Address', 'wpo_wcpdf' ),
446
- array( &$this, 'textarea_element_callback' ),
447
- $option,
448
- 'template_settings',
449
- array(
450
- 'menu' => $option,
451
- 'id' => 'shop_address',
452
- 'width' => '72',
453
- 'height' => '8',
454
- 'translatable' => true,
455
- //'description' => __( '...', 'wpo_wcpdf' ),
456
- )
457
- );
458
-
459
- add_settings_field(
460
- 'footer',
461
- __( 'Footer: terms & conditions, policies, etc.', 'wpo_wcpdf' ),
462
- array( &$this, 'textarea_element_callback' ),
463
- $option,
464
- 'template_settings',
465
- array(
466
- 'menu' => $option,
467
- 'id' => 'footer',
468
- 'width' => '72',
469
- 'height' => '4',
470
- 'translatable' => true,
471
- //'description' => __( '...', 'wpo_wcpdf' ),
472
- )
473
- );
474
-
475
- // Section.
476
- add_settings_section(
477
- 'invoice',
478
- __( 'Invoice', 'wpo_wcpdf' ),
479
- array( &$this, 'section_options_callback' ),
480
- $option
481
- );
482
-
483
- add_settings_field(
484
- 'invoice_shipping_address',
485
- __( 'Display shipping address', 'wpo_wcpdf' ),
486
- array( &$this, 'checkbox_element_callback' ),
487
- $option,
488
- 'invoice',
489
- array(
490
- 'menu' => $option,
491
- 'id' => 'invoice_shipping_address',
492
- 'description' => __( 'Display shipping address on invoice (in addition to the default billing address) if different from billing address', 'wpo_wcpdf' ),
493
- )
494
- );
495
-
496
- add_settings_field(
497
- 'invoice_email',
498
- __( 'Display email address', 'wpo_wcpdf' ),
499
- array( &$this, 'checkbox_element_callback' ),
500
- $option,
501
- 'invoice',
502
- array(
503
- 'menu' => $option,
504
- 'id' => 'invoice_email',
505
- )
506
- );
507
-
508
- add_settings_field(
509
- 'invoice_phone',
510
- __( 'Display phone number', 'wpo_wcpdf' ),
511
- array( &$this, 'checkbox_element_callback' ),
512
- $option,
513
- 'invoice',
514
- array(
515
- 'menu' => $option,
516
- 'id' => 'invoice_phone',
517
- )
518
- );
519
-
520
- add_settings_field(
521
- 'display_date',
522
- __( 'Display invoice date', 'wpo_wcpdf' ),
523
- array( &$this, 'checkbox_element_callback' ),
524
- $option,
525
- 'invoice',
526
- array(
527
- 'menu' => $option,
528
- 'id' => 'display_date',
529
- 'value' => 'invoice_date',
530
- )
531
- );
532
-
533
- add_settings_field(
534
- 'display_number',
535
- __( 'Display built-in sequential invoice number', 'wpo_wcpdf' ),
536
- array( &$this, 'checkbox_element_callback' ),
537
- $option,
538
- 'invoice',
539
- array(
540
- 'menu' => $option,
541
- 'id' => 'display_number',
542
- 'value' => 'invoice_number',
543
- )
544
- );
545
-
546
- // invoice number is stored separately for direct retrieval
547
- register_setting( $option, 'wpo_wcpdf_next_invoice_number', array( &$this, 'validate_options' ) );
548
- add_settings_field(
549
- 'next_invoice_number',
550
- __( 'Next invoice number (without prefix/suffix etc.)', 'wpo_wcpdf' ),
551
- array( &$this, 'singular_text_element_callback' ),
552
- $option,
553
- 'invoice',
554
- array(
555
- 'menu' => 'wpo_wcpdf_next_invoice_number',
556
- 'id' => 'next_invoice_number',
557
- 'size' => '10',
558
- 'description' => __( 'This is the number that will be used on the next invoice that is created. By default, numbering starts from the WooCommerce Order Number of the first invoice that is created and increases for every new invoice. Note that if you override this and set it lower than the highest (PDF) invoice number, this could create double invoice numbers!', 'wpo_wcpdf' ),
559
- )
560
- );
561
-
562
- // first time invoice number
563
- $next_invoice_number = get_option('wpo_wcpdf_next_invoice_number');
564
- // determine highest invoice number if option not set
565
- if ( !isset( $next_invoice_number ) ) {
566
- // Based on code from WooCommerce Sequential Order Numbers
567
- global $wpdb;
568
- // get highest invoice_number in postmeta table
569
- $max_invoice_number = $wpdb->get_var( 'SELECT max(cast(meta_value as UNSIGNED)) from ' . $wpdb->postmeta . ' where meta_key="_wcpdf_invoice_number"' );
570
-
571
- if ( !empty($max_invoice_number) ) {
572
- $next_invoice_number = $max_invoice_number+1;
573
- } else {
574
- $next_invoice_number = '';
575
- }
576
-
577
- update_option( 'wpo_wcpdf_next_invoice_number', $next_invoice_number );
578
- }
579
-
580
- add_settings_field(
581
- 'invoice_number_formatting',
582
- __( 'Invoice number format', 'wpo_wcpdf' ),
583
- array( &$this, 'invoice_number_formatting_callback' ),
584
- $option,
585
- 'invoice',
586
- array(
587
- 'menu' => $option,
588
- 'id' => 'invoice_number_formatting',
589
- 'fields' => array(
590
- 'prefix' => array(
591
- 'title' => __( 'Prefix' , 'wpo_wcpdf' ),
592
- 'size' => 20,
593
- 'description' => __( 'to use the invoice year and/or month, use [invoice_year] or [invoice_month] respectively' , 'wpo_wcpdf' ),
594
- ),
595
- 'suffix' => array(
596
- 'title' => __( 'Suffix' , 'wpo_wcpdf' ),
597
- 'size' => 20,
598
- 'description' => '',
599
- ),
600
- 'padding' => array(
601
- 'title' => __( 'Padding' , 'wpo_wcpdf' ),
602
- 'size' => 2,
603
- 'description' => __( 'enter the number of digits here - enter "6" to display 42 as 000042' , 'wpo_wcpdf' ),
604
- ),
605
- ),
606
- 'description' => __( 'note: if you have already created a custom invoice number format with a filter, the above settings will be ignored' , 'wpo_wcpdf' ),
607
- )
608
- );
609
-
610
- add_settings_field(
611
- 'yearly_reset_invoice_number',
612
- __( 'Reset invoice number yearly', 'wpo_wcpdf' ),
613
- array( &$this, 'checkbox_element_callback' ),
614
- $option,
615
- 'invoice',
616
- array(
617
- 'menu' => $option,
618
- 'id' => 'yearly_reset_invoice_number',
619
- )
620
- );
621
-
622
- add_settings_field(
623
- 'currency_font',
624
- __( 'Extended currency symbol support', 'wpo_wcpdf' ),
625
- array( &$this, 'checkbox_element_callback' ),
626
- $option,
627
- 'invoice',
628
- array(
629
- 'menu' => $option,
630
- 'id' => 'currency_font',
631
- 'description' => __( 'Enable this if your currency symbol is not displaying properly' , 'wpo_wcpdf' ),
632
- )
633
- );
634
-
635
- // Section.
636
- add_settings_section(
637
- 'packing_slip',
638
- __( 'Packing Slip', 'wpo_wcpdf' ),
639
- array( &$this, 'section_options_callback' ),
640
- $option
641
- );
642
-
643
- add_settings_field(
644
- 'packing_slip_billing_address',
645
- __( 'Display billing address', 'wpo_wcpdf' ),
646
- array( &$this, 'checkbox_element_callback' ),
647
- $option,
648
- 'packing_slip',
649
- array(
650
- 'menu' => $option,
651
- 'id' => 'packing_slip_billing_address',
652
- 'description' => __( 'Display billing address on packing slip (in addition to the default shipping address) if different from shipping address', 'wpo_wcpdf' ),
653
- )
654
- );
655
-
656
- add_settings_field(
657
- 'packing_slip_email',
658
- __( 'Display email address', 'wpo_wcpdf' ),
659
- array( &$this, 'checkbox_element_callback' ),
660
- $option,
661
- 'packing_slip',
662
- array(
663
- 'menu' => $option,
664
- 'id' => 'packing_slip_email',
665
- )
666
- );
667
-
668
- add_settings_field(
669
- 'packing_slip_phone',
670
- __( 'Display phone number', 'wpo_wcpdf' ),
671
- array( &$this, 'checkbox_element_callback' ),
672
- $option,
673
- 'packing_slip',
674
- array(
675
- 'menu' => $option,
676
- 'id' => 'packing_slip_phone',
677
- )
678
- );
679
-
680
- // Section.
681
- add_settings_section(
682
- 'extra_template_fields',
683
- __( 'Extra template fields', 'wpo_wcpdf' ),
684
- array( &$this, 'custom_fields_section' ),
685
- $option
686
- );
687
-
688
- add_settings_field(
689
- 'extra_1',
690
- __( 'Extra field 1', 'wpo_wcpdf' ),
691
- array( &$this, 'textarea_element_callback' ),
692
- $option,
693
- 'extra_template_fields',
694
- array(
695
- 'menu' => $option,
696
- 'id' => 'extra_1',
697
- 'width' => '72',
698
- 'height' => '8',
699
- 'description' => __( 'This is footer column 1 in the <i>Modern (Premium)</i> template', 'wpo_wcpdf' ),
700
- 'translatable' => true,
701
- )
702
- );
703
-
704
- add_settings_field(
705
- 'extra_2',
706
- __( 'Extra field 2', 'wpo_wcpdf' ),
707
- array( &$this, 'textarea_element_callback' ),
708
- $option,
709
- 'extra_template_fields',
710
- array(
711
- 'menu' => $option,
712
- 'id' => 'extra_2',
713
- 'width' => '72',
714
- 'height' => '8',
715
- 'description' => __( 'This is footer column 2 in the <i>Modern (Premium)</i> template', 'wpo_wcpdf' ),
716
- 'translatable' => true,
717
- )
718
- );
719
-
720
- add_settings_field(
721
- 'extra_3',
722
- __( 'Extra field 3', 'wpo_wcpdf' ),
723
- array( &$this, 'textarea_element_callback' ),
724
- $option,
725
- 'extra_template_fields',
726
- array(
727
- 'menu' => $option,
728
- 'id' => 'extra_3',
729
- 'width' => '72',
730
- 'height' => '8',
731
- 'description' => __( 'This is footer column 3 in the <i>Modern (Premium)</i> template', 'wpo_wcpdf' ),
732
- 'translatable' => true,
733
- )
734
- );
735
-
736
- // Register settings.
737
- register_setting( $option, $option, array( &$this, 'validate_options' ) );
738
-
739
- /**************************************/
740
- /******** DEBUG/STATUS SETTINGS *******/
741
- /**************************************/
742
-
743
- $option = 'wpo_wcpdf_debug_settings';
744
-
745
- // Create option in wp_options.
746
- if ( false === get_option( $option ) ) {
747
- $this->default_settings( $option );
748
- }
749
-
750
- // Section.
751
- add_settings_section(
752
- 'debug_settings',
753
- __( 'Debug settings', 'wpo_wcpdf' ),
754
- array( &$this, 'debug_section' ),
755
- $option
756
- );
757
-
758
- add_settings_field(
759
- 'enable_debug',
760
- __( 'Enable debug output', 'wpo_wcpdf' ),
761
- array( &$this, 'checkbox_element_callback' ),
762
- $option,
763
- 'debug_settings',
764
- array(
765
- 'menu' => $option,
766
- 'id' => 'enable_debug',
767
- 'description' => __( "Enable this option to output plugin errors if you're getting a blank page or other PDF generation issues", 'wpo_wcpdf' ),
768
- )
769
- );
770
-
771
- add_settings_field(
772
- 'html_output',
773
- __( 'Output to HTML', 'wpo_wcpdf' ),
774
- array( &$this, 'checkbox_element_callback' ),
775
- $option,
776
- 'debug_settings',
777
- array(
778
- 'menu' => $option,
779
- 'id' => 'html_output',
780
- 'description' => __( 'Send the template output as HTML to the browser instead of creating a PDF.', 'wpo_wcpdf' ),
781
- )
782
- );
783
-
784
- add_settings_field(
785
- 'old_tmp',
786
- __( 'Use old tmp folder', 'wpo_wcpdf' ),
787
- array( &$this, 'checkbox_element_callback' ),
788
- $option,
789
- 'debug_settings',
790
- array(
791
- 'menu' => $option,
792
- 'id' => 'old_tmp',
793
- 'description' => __( 'Before version 1.5 of PDF Invoices, temporary files were stored in the plugin folder. This setting is only intended for backwards compatibility, not recommended on new installs!', 'wpo_wcpdf' ),
794
- )
795
- );
796
-
797
- // Register settings.
798
- register_setting( $option, $option, array( &$this, 'validate_options' ) );
799
-
800
- }
801
-
802
- /**
803
- * get all emails registered in WooCommerce
804
- * @param boolean $remove_defaults switch to remove default woocommerce emails
805
- * @return array $emails list of all email ids/slugs and names
806
- */
807
- public function get_wc_emails ( $remove_defaults = true ) {
808
- // get emails from WooCommerce
809
- global $woocommerce;
810
- $mailer = $woocommerce->mailer();
811
- $wc_emails = $mailer->get_emails();
812
-
813
- $default_emails = array(
814
- 'new_order',
815
- 'customer_processing_order',
816
- 'customer_completed_order',
817
- 'customer_invoice',
818
- 'customer_note',
819
- 'customer_reset_password',
820
- 'customer_new_account'
821
- );
822
-
823
- $emails = array();
824
- foreach ($wc_emails as $name => $template) {
825
- if ( !( $remove_defaults && in_array( $template->id, $default_emails ) ) ) {
826
- $emails[$template->id] = $template->title;
827
- }
828
- }
829
-
830
- return $emails;
831
- }
832
-
833
- /**
834
- * WooCommerce Order Status & Actions Manager emails compatibility
835
- */
836
- public function wc_order_status_actions_emails ( $emails ) {
837
- // check if WC_Custom_Status class is loaded!
838
- if (class_exists('WC_Custom_Status')) {
839
- // get list of custom statuses from WooCommerce Custom Order Status & Actions
840
- // status slug => status name
841
- $custom_statuses = WC_Custom_Status::get_status_list_names();
842
- // append _email to slug (=email_id) and add to emails list
843
- foreach ($custom_statuses as $status_slug => $status_name) {
844
- $emails[$status_slug.'_email'] = $status_name;
845
- }
846
- }
847
- return $emails;
848
- }
849
-
850
- /**
851
- * Set default settings.
852
- */
853
- public function default_settings( $option ) {
854
- global $wpo_wcpdf;
855
-
856
- switch ( $option ) {
857
- case 'wpo_wcpdf_general_settings':
858
- $default = array(
859
- 'download_display' => 'download',
860
- );
861
- break;
862
- case 'wpo_wcpdf_template_settings':
863
- $default = array(
864
- 'paper_size' => 'a4',
865
- 'template_path' => $wpo_wcpdf->export->template_default_base_path . 'Simple',
866
- // 'invoice_shipping_address' => '1',
867
- );
868
- break;
869
- default:
870
- $default = array();
871
- break;
872
- }
873
-
874
- if ( false === get_option( $option ) ) {
875
- add_option( $option, $default );
876
- } else {
877
- update_option( $option, $default );
878
-
879
- }
880
- }
881
-
882
- // Text element callback.
883
- public function text_element_callback( $args ) {
884
- $menu = $args['menu'];
885
- $id = $args['id'];
886
- $size = isset( $args['size'] ) ? $args['size'] : '25';
887
- $class = isset( $args['translatable'] ) && $args['translatable'] === true ? 'translatable' : '';
888
-
889
- $options = get_option( $menu );
890
-
891
- if ( isset( $options[$id] ) ) {
892
- $current = $options[$id];
893
- } else {
894
- $current = isset( $args['default'] ) ? $args['default'] : '';
895
- }
896
-
897
- $html = sprintf( '<input type="text" id="%1$s" name="%2$s[%1$s]" value="%3$s" size="%4$s" class="%5$s"/>', $id, $menu, $current, $size, $class );
898
-
899
- // Displays option description.
900
- if ( isset( $args['description'] ) ) {
901
- $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
902
- }
903
-
904
- echo $html;
905
- }
906
-
907
- // Single text option (not part of any settings array)
908
- public function singular_text_element_callback( $args ) {
909
- $menu = $args['menu'];
910
- $id = $args['id'];
911
- $size = isset( $args['size'] ) ? $args['size'] : '25';
912
- $class = isset( $args['translatable'] ) && $args['translatable'] === true ? 'translatable' : '';
913
-
914
- $option = get_option( $menu );
915
-
916
- if ( isset( $option ) ) {
917
- $current = $option;
918
- } else {
919
- $current = isset( $args['default'] ) ? $args['default'] : '';
920
- }
921
-
922
- $html = sprintf( '<input type="text" id="%1$s" name="%2$s" value="%3$s" size="%4$s" class="%5$s"/>', $id, $menu, $current, $size, $class );
923
-
924
- // Displays option description.
925
- if ( isset( $args['description'] ) ) {
926
- $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
927
- }
928
-
929
- echo $html;
930
- }
931
-
932
- // Text element callback.
933
- public function textarea_element_callback( $args ) {
934
- $menu = $args['menu'];
935
- $id = $args['id'];
936
- $width = $args['width'];
937
- $height = $args['height'];
938
- $class = isset( $args['translatable'] ) && $args['translatable'] === true ? 'translatable' : '';
939
-
940
- $options = get_option( $menu );
941
-
942
- if ( isset( $options[$id] ) ) {
943
- $current = $options[$id];
944
- } else {
945
- $current = isset( $args['default'] ) ? $args['default'] : '';
946
- }
947
-
948
- $html = sprintf( '<textarea id="%1$s" name="%2$s[%1$s]" cols="%4$s" rows="%5$s" class="%6$s"/>%3$s</textarea>', $id, $menu, $current, $width, $height, $class );
949
-
950
- // Displays option description.
951
- if ( isset( $args['description'] ) ) {
952
- $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
953
- }
954
-
955
- echo $html;
956
- }
957
-
958
-
959
- /**
960
- * Checkbox field callback.
961
- *
962
- * @param array $args Field arguments.
963
- *
964
- * @return string Checkbox field.
965
- */
966
- public function checkbox_element_callback( $args ) {
967
- $menu = $args['menu'];
968
- $id = $args['id'];
969
- $value = isset( $args['value'] ) ? $args['value'] : 1;
970
-
971
- $options = get_option( $menu );
972
-
973
- if ( isset( $options[$id] ) ) {
974
- $current = $options[$id];
975
- } else {
976
- $current = isset( $args['default'] ) ? $args['default'] : '';
977
- }
978
-
979
- $html = sprintf( '<input type="checkbox" id="%1$s" name="%2$s[%1$s]" value="%3$s"%4$s />', $id, $menu, $value, checked( $value, $current, false ) );
980
-
981
- // Displays option description.
982
- if ( isset( $args['description'] ) ) {
983
- $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
984
- }
985
-
986
- echo $html;
987
- }
988
-
989
- /**
990
- * Multiple Checkbox field callback.
991
- *
992
- * @param array $args Field arguments.
993
- *
994
- * @return string Checkbox field.
995
- */
996
- public function multiple_checkbox_element_callback( $args ) {
997
- $menu = $args['menu'];
998
- $id = $args['id'];
999
-
1000
- $options = get_option( $menu );
1001
-
1002
-
1003
- foreach ( $args['options'] as $key => $label ) {
1004
- $current = ( isset( $options[$id][$key] ) ) ? $options[$id][$key] : '';
1005
- printf( '<input type="checkbox" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="1"%4$s /> %5$s<br/>', $menu, $id, $key, checked( 1, $current, false ), $label );
1006
- }
1007
-
1008
- // Displays option description.
1009
- if ( isset( $args['description'] ) ) {
1010
- printf( '<p class="description">%s</p>', $args['description'] );
1011
- }
1012
- }
1013
-
1014
- /**
1015
- * Checkbox fields table callback.
1016
- *
1017
- * @param array $args Field arguments.
1018
- *
1019
- * @return string Checkbox field.
1020
- */
1021
- public function checkbox_table_callback( $args ) {
1022
- $menu = $args['menu'];
1023
- $id = $args['id'];
1024
-
1025
- $options = get_option( $menu );
1026
-
1027
- $rows = $args['rows'];
1028
- $columns = $args['columns'];
1029
-
1030
- ?>
1031
- <table style="">
1032
- <tr>
1033
- <td style="padding:0 10px 5px 0;">&nbsp;</td>
1034
- <?php foreach ( $columns as $column => $title ) { ?>
1035
- <td style="padding:0 10px 5px 0;"><?php echo $title; ?></td>
1036
- <?php } ?>
1037
- </tr>
1038
- <tr>
1039
- <td style="padding: 0;">
1040
- <?php foreach ($rows as $row) {
1041
- echo $row.'<br/>';
1042
- } ?>
1043
- </td>
1044
- <?php foreach ( $columns as $column => $title ) { ?>
1045
- <td style="text-align:center; padding: 0;">
1046
- <?php foreach ( $rows as $row => $title ) {
1047
- $current = ( isset( $options[$id.'_'.$column][$row] ) ) ? $options[$id.'_'.$column][$row] : '';
1048
- $name = sprintf('%1$s[%2$s_%3$s][%4$s]', $menu, $id, $column, $row);
1049
- printf( '<input type="checkbox" id="%1$s" name="%1$s" value="1"%2$s /><br/>', $name, checked( 1, $current, false ) );
1050
- } ?>
1051
- </td>
1052
- <?php } ?>
1053
- </tr>
1054
- </table>
1055
-
1056
- <?php
1057
- // Displays option description.
1058
- if ( isset( $args['description'] ) ) {
1059
- printf( '<p class="description">%s</p>', $args['description'] );
1060
- }
1061
- }
1062
-
1063
- /**
1064
- * Select element callback.
1065
- *
1066
- * @param array $args Field arguments.
1067
- *
1068
- * @return string Select field.
1069
- */
1070
- public function select_element_callback( $args ) {
1071
- $menu = $args['menu'];
1072
- $id = $args['id'];
1073
-
1074
- $options = get_option( $menu );
1075
-
1076
- if ( isset( $options[$id] ) ) {
1077
- $current = $options[$id];
1078
- } else {
1079
- $current = isset( $args['default'] ) ? $args['default'] : '';
1080
- }
1081
-
1082
- printf( '<select id="%1$s" name="%2$s[%1$s]">', $id, $menu );
1083
-
1084
- foreach ( $args['options'] as $key => $label ) {
1085
- printf( '<option value="%s"%s>%s</option>', $key, selected( $current, $key, false ), $label );
1086
- }
1087
-
1088
- echo '</select>';
1089
-
1090
-
1091
- if (isset($args['custom'])) {
1092
- $custom = $args['custom'];
1093
-
1094
- $custom_id = $id.'_custom';
1095
-
1096
- printf( '<br/><br/><div id="%s" style="display:none;">', $custom_id );
1097
-
1098
- switch ($custom['type']) {
1099
- case 'text_element_callback':
1100
- $this->text_element_callback( $custom['args'] );
1101
- break;
1102
- case 'multiple_text_element_callback':
1103
- $this->multiple_text_element_callback( $custom['args'] );
1104
- break;
1105
- case 'multiple_checkbox_element_callback':
1106
- $this->multiple_checkbox_element_callback( $custom['args'] );
1107
- break;
1108
- default:
1109
- break;
1110
- }
1111
-
1112
- echo '</div>';
1113
-
1114
- ?>
1115
- <script type="text/javascript">
1116
- jQuery(document).ready(function($) {
1117
- function check_<?php echo $id; ?>_custom() {
1118
- var custom = $('#<?php echo $id; ?>').val();
1119
- if (custom == 'custom') {
1120
- $( '#<?php echo $custom_id; ?>').show();
1121
- } else {
1122
- $( '#<?php echo $custom_id; ?>').hide();
1123
- }
1124
- }
1125
-
1126
- check_<?php echo $id; ?>_custom();
1127
-
1128
- $( '#<?php echo $id; ?>' ).change(function() {
1129
- check_<?php echo $id; ?>_custom();
1130
- });
1131
-
1132
- });
1133
- </script>
1134
- <?php
1135
- }
1136
-
1137
- // Displays option description.
1138
- if ( isset( $args['description'] ) ) {
1139
- printf( '<p class="description">%s</p>', $args['description'] );
1140
- }
1141
-
1142
- }
1143
-
1144
- /**
1145
- * Displays a radio settings field
1146
- *
1147
- * @param array $args settings field args
1148
- */
1149
- public function radio_element_callback( $args ) {
1150
- $menu = $args['menu'];
1151
- $id = $args['id'];
1152
-
1153
- $options = get_option( $menu );
1154
-
1155
- if ( isset( $options[$id] ) ) {
1156
- $current = $options[$id];
1157
- } else {
1158
- $current = isset( $args['default'] ) ? $args['default'] : '';
1159
- }
1160
-
1161
- $html = '';
1162
- foreach ( $args['options'] as $key => $label ) {
1163
- $html .= sprintf( '<input type="radio" class="radio" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s]" value="%3$s"%4$s />', $menu, $id, $key, checked( $current, $key, false ) );
1164
- $html .= sprintf( '<label for="%1$s[%2$s][%3$s]"> %4$s</label><br>', $menu, $id, $key, $label);
1165
- }
1166
-
1167
- // Displays option description.
1168
- if ( isset( $args['description'] ) ) {
1169
- $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
1170
- }
1171
-
1172
- echo $html;
1173
- }
1174
-
1175
- /**
1176
- * Media upload callback.
1177
- *
1178
- * @param array $args Field arguments.
1179
- *
1180
- * @return string Media upload button & preview.
1181
- */
1182
- public function media_upload_callback( $args ) {
1183
- $menu = $args['menu'];
1184
- $id = $args['id'];
1185
- $options = get_option( $menu );
1186
-
1187
- if ( isset( $options[$id] ) ) {
1188
- $current = $options[$id];
1189
- } else {
1190
- $current = isset( $args['default'] ) ? $args['default'] : '';
1191
- }
1192
-
1193
- $uploader_title = $args['uploader_title'];
1194
- $uploader_button_text = $args['uploader_button_text'];
1195
- $remove_button_text = $args['remove_button_text'];
1196
-
1197
- $html = '';
1198
- if( !empty($current) ) {
1199
- $attachment = wp_get_attachment_image_src( $current, 'full', false );
1200
-
1201
- $attachment_src = $attachment[0];
1202
- $attachment_width = $attachment[1];
1203
- $attachment_height = $attachment[2];
1204
-
1205
- $attachment_resolution = round($attachment_height/(3/2.54));
1206
-
1207
- $html .= sprintf('<img src="%1$s" style="display:block" id="img-%4$s"/>', $attachment_src, $attachment_width, $attachment_height, $id );
1208
- $html .= '<div class="attachment-resolution"><p class="description">'.__('Image resolution').': '.$attachment_resolution.'dpi (default height = 3cm)</p></div>';
1209
- $html .= sprintf('<span class="button wpo_remove_image_button" data-input_id="%1$s">%2$s</span>', $id, $remove_button_text );
1210
- }
1211
-
1212
- $html .= sprintf( '<input id="%1$s" name="%2$s[%1$s]" type="hidden" value="%3$s" />', $id, $menu, $current );
1213
-
1214
- $html .= sprintf( '<span class="button wpo_upload_image_button %4$s" data-uploader_title="%1$s" data-uploader_button_text="%2$s" data-remove_button_text="%3$s" data-input_id="%4$s">%2$s</span>', $uploader_title, $uploader_button_text, $remove_button_text, $id );
1215
-
1216
- // Displays option description.
1217
- if ( isset( $args['description'] ) ) {
1218
- $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
1219
- }
1220
-
1221
- echo $html;
1222
- }
1223
-
1224
- /**
1225
- * Invoice number formatting callback.
1226
- *
1227
- * @param array $args Field arguments.
1228
- *
1229
- * @return string Media upload button & preview.
1230
- */
1231
- public function invoice_number_formatting_callback( $args ) {
1232
- $menu = $args['menu'];
1233
- $fields = $args['fields'];
1234
- $options = get_option( $menu );
1235
-
1236
- echo '<table>';
1237
- foreach ($fields as $key => $field) {
1238
- $id = $args['id'] . '_' . $key;
1239
-
1240
- if ( isset( $options[$id] ) ) {
1241
- $current = $options[$id];
1242
- } else {
1243
- $current = '';
1244
- }
1245
-
1246
- $title = $field['title'];
1247
- $size = $field['size'];
1248
- $description = isset( $field['description'] ) ? '<span style="font-style:italic;">'.$field['description'].'</span>' : '';
1249
-
1250
- echo '<tr>';
1251
- printf( '<td style="padding:0 1em 0 0; ">%1$s:</td><td style="padding:0;"><input type="text" id="%2$s" name="%3$s[%2$s]" value="%4$s" size="%5$s"/></td><td style="padding:0 0 0 1em;">%6$s</td>', $title, $id, $menu, $current, $size, $description );
1252
- echo '</tr>';
1253
- }
1254
- echo '</table>';
1255
-
1256
-
1257
- // Displays option description.
1258
- if ( isset( $args['description'] ) ) {
1259
- printf( '<p class="description">%s</p>', $args['description'] );
1260
- }
1261
-
1262
- // echo $html;
1263
- }
1264
-
1265
-
1266
- /**
1267
- * Template select element callback.
1268
- *
1269
- * @param array $args Field arguments.
1270
- *
1271
- * @return string Select field.
1272
- */
1273
- public function template_select_element_callback( $args ) {
1274
- $menu = $args['menu'];
1275
- $id = $args['id'];
1276
-
1277
- $options = get_option( $menu );
1278
-
1279
- if ( isset( $options[$id] ) ) {
1280
- $current = $options[$id];
1281
- } else {
1282
- $current = isset( $args['default'] ) ? $args['default'] : '';
1283
- }
1284
-
1285
- $html = sprintf( '<select id="%1$s" name="%2$s[%1$s]">', $id, $menu );
1286
-
1287
- // backwards compatible template path (1.4.4+ uses relative paths instead of absolute)
1288
- if (strpos($current, ABSPATH) !== false) {
1289
- // check if folder exists, then strip site base path.
1290
- if ( file_exists( $current ) ) {
1291
- $current = str_replace( ABSPATH, '', $current );
1292
- }
1293
- }
1294
-
1295
- foreach ( $args['options'] as $key => $label ) {
1296
- $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $current, $key, false ), $label );
1297
- }
1298
-
1299
- $html .= '</select>';
1300
-
1301
- // Displays option description.
1302
- if ( isset( $args['description'] ) ) {
1303
- $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
1304
- }
1305
-
1306
- echo $html;
1307
-
1308
- }
1309
-
1310
- /**
1311
- * Section null callback.
1312
- *
1313
- * @return void.
1314
- */
1315
- public function section_options_callback() {
1316
- }
1317
-
1318
- /**
1319
- * Debug section callback.
1320
- *
1321
- * @return void.
1322
- */
1323
- public function debug_section() {
1324
- _e( '<b>Warning!</b> The settings below are meant for debugging/development only. Do not use them on a live website!' , 'wpo_wcpdf' );
1325
- }
1326
-
1327
- /**
1328
- * Custom fields section callback.
1329
- *
1330
- * @return void.
1331
- */
1332
- public function custom_fields_section() {
1333
- _e( 'These are used for the (optional) footer columns in the <em>Modern (Premium)</em> template, but can also be used for other elements in your custom template' , 'wpo_wcpdf' );
1334
- }
1335
-
1336
- /**
1337
- * Validate options.
1338
- *
1339
- * @param array $input options to valid.
1340
- *
1341
- * @return array validated options.
1342
- */
1343
- public function validate_options( $input ) {
1344
- // Create our array for storing the validated options.
1345
- $output = array();
1346
-
1347
- if (empty($input) || !is_array($input)) {
1348
- return $input;
1349
- }
1350
-
1351
- // Loop through each of the incoming options.
1352
- foreach ( $input as $key => $value ) {
1353
-
1354
- // Check to see if the current option has a value. If so, process it.
1355
- if ( isset( $input[$key] ) ) {
1356
- if ( is_array( $input[$key] ) ) {
1357
- foreach ( $input[$key] as $sub_key => $sub_value ) {
1358
- $output[$key][$sub_key] = $input[$key][$sub_key];
1359
- }
1360
- } else {
1361
- $output[$key] = $input[$key];
1362
- }
1363
- }
1364
- }
1365
-
1366
- // Return the array processing any additional functions filtered by this action.
1367
- return apply_filters( 'wpo_wcpdf_validate_input', $output, $input );
1368
- }
1369
-
1370
- /**
1371
- * List templates in plugin folder, theme folder & child theme folder
1372
- * @return array template path => template name
1373
- */
1374
- public function find_templates() {
1375
- global $wpo_wcpdf;
1376
- $installed_templates = array();
1377
-
1378
- // get base paths
1379
- $template_paths = array (
1380
- // note the order: child-theme before theme, so that array_unique filters out parent doubles
1381
- 'default' => $wpo_wcpdf->export->template_default_base_path,
1382
- 'child-theme' => get_stylesheet_directory() . '/' . $wpo_wcpdf->export->template_base_path,
1383
- 'theme' => get_template_directory() . '/' . $wpo_wcpdf->export->template_base_path,
1384
- );
1385
-
1386
- $template_paths = apply_filters( 'wpo_wcpdf_template_paths', $template_paths );
1387
-
1388
- foreach ($template_paths as $template_source => $template_path) {
1389
- $dirs = (array) glob( $template_path . '*' , GLOB_ONLYDIR);
1390
-
1391
- foreach ($dirs as $dir) {
1392
- if ( file_exists($dir."/invoice.php") && file_exists($dir."/packing-slip.php"))
1393
- // we're stripping abspath to make the plugin settings more portable
1394
- $installed_templates[ str_replace( ABSPATH, '', $dir )] = basename($dir);
1395
- }
1396
- }
1397
-
1398
- // remove parent doubles
1399
- $installed_templates = array_unique($installed_templates);
1400
-
1401
- if (empty($installed_templates)) {
1402
- // fallback to Simple template for servers with glob() disabled
1403
- $simple_template_path = str_replace( ABSPATH, '', $template_paths['default'] . 'Simple' );
1404
- $installed_templates[$simple_template_path] = 'Simple';
1405
- }
1406
-
1407
- return apply_filters( 'wpo_wcpdf_templates', $installed_templates );
1408
- }
1409
-
1410
- } // end class WooCommerce_PDF_Invoices_Settings
1411
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1412
  } // end class_exists
1
+ <?php
2
+
3
+ /**
4
+ * Settings class
5
+ */
6
+ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Settings' ) ) {
7
+
8
+ class WooCommerce_PDF_Invoices_Settings {
9
+
10
+ public $options_page_hook;
11
+ public $general_settings;
12
+ public $template_settings;
13
+
14
+ public function __construct() {
15
+ add_action( 'admin_menu', array( &$this, 'menu' ) ); // Add menu.
16
+ add_action( 'admin_init', array( &$this, 'init_settings' ) ); // Registers settings
17
+ add_filter( 'option_page_capability_wpo_wcpdf_template_settings', array( &$this, 'settings_capabilities' ) );
18
+ add_filter( 'option_page_capability_wpo_wcpdf_general_settings', array( &$this, 'settings_capabilities' ) );
19
+ add_action( 'admin_enqueue_scripts', array( &$this, 'load_scripts_styles' ) ); // Load scripts
20
+
21
+ // Add links to WordPress plugins page
22
+ add_filter( 'plugin_action_links_'.WooCommerce_PDF_Invoices::$plugin_basename, array( &$this, 'wpo_wcpdf_add_settings_link' ) );
23
+ add_filter( 'plugin_row_meta', array( $this, 'add_support_links' ), 10, 2 );
24
+
25
+ $this->general_settings = get_option('wpo_wcpdf_general_settings');
26
+ $this->template_settings = get_option('wpo_wcpdf_template_settings');
27
+
28
+ // WooCommerce Order Status & Actions Manager emails compatibility
29
+ add_filter( 'wpo_wcpdf_wc_emails', array( $this, 'wc_order_status_actions_emails' ), 10, 1 );
30
+ }
31
+
32
+ public function menu() {
33
+ $parent_slug = 'woocommerce';
34
+
35
+ $this->options_page_hook = add_submenu_page(
36
+ $parent_slug,
37
+ __( 'PDF Invoices', 'wpo_wcpdf' ),
38
+ __( 'PDF Invoices', 'wpo_wcpdf' ),
39
+ 'manage_woocommerce',
40
+ 'wpo_wcpdf_options_page',
41
+ array( $this, 'settings_page' )
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Set capability for settings page
47
+ */
48
+ public function settings_capabilities() {
49
+ return 'manage_woocommerce';
50
+ }
51
+
52
+ /**
53
+ * Styles for settings page
54
+ */
55
+ public function load_scripts_styles ( $hook ) {
56
+ if( $hook != $this->options_page_hook )
57
+ return;
58
+
59
+ wp_enqueue_script(
60
+ 'wcpdf-upload-js',
61
+ plugins_url( 'js/media-upload.js' , dirname(__FILE__) ),
62
+ array( 'jquery' ),
63
+ WooCommerce_PDF_Invoices::$version
64
+ );
65
+
66
+ wp_enqueue_style(
67
+ 'wpo-wcpdf',
68
+ WooCommerce_PDF_Invoices::$plugin_url . 'css/style.css',
69
+ array(),
70
+ WooCommerce_PDF_Invoices::$version
71
+ );
72
+ wp_enqueue_media();
73
+ }
74
+
75
+ /**
76
+ * Add settings link to plugins page
77
+ */
78
+ public function wpo_wcpdf_add_settings_link( $links ) {
79
+ $settings_link = '<a href="admin.php?page=wpo_wcpdf_options_page">'. __( 'Settings', 'woocommerce' ) . '</a>';
80
+ array_push( $links, $settings_link );
81
+ return $links;
82
+ }
83
+
84
+ /**
85
+ * Add various support links to plugin page
86
+ * after meta (version, authors, site)
87
+ */
88
+ public function add_support_links( $links, $file ) {
89
+ if ( !current_user_can( 'install_plugins' ) ) {
90
+ return $links;
91
+ }
92
+
93
+ if ( $file == WooCommerce_PDF_Invoices::$plugin_basename ) {
94
+ // $links[] = '<a href="..." target="_blank" title="' . __( '...', 'wpo_wcpdf' ) . '">' . __( '...', 'wpo_wcpdf' ) . '</a>';
95
+ }
96
+ return $links;
97
+ }
98
+
99
+ public function settings_page() {
100
+ $settings_tabs = apply_filters( 'wpo_wcpdf_settings_tabs', array (
101
+ 'general' => __('General','wpo_wcpdf'),
102
+ 'template' => __('Template','wpo_wcpdf'),
103
+ )
104
+ );
105
+
106
+ // add status tab last in row
107
+ $settings_tabs['debug'] = __('Status','wpo_wcpdf');
108
+
109
+ $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'general';
110
+
111
+ ?>
112
+ <script type="text/javascript">
113
+ jQuery( function( $ ) {
114
+ $("#footer-thankyou").html("If you like <strong>WooCommerce PDF Invoices & Packing Slips</strong> please leave us a <a href='https://wordpress.org/support/view/plugin-reviews/woocommerce-pdf-invoices-packing-slips?rate=5#postform'>★★★★★</a> rating. A huge thank you in advance!");
115
+ });
116
+ </script>
117
+ <div class="wrap">
118
+ <div class="icon32" id="icon-options-general"><br /></div>
119
+ <h2><?php _e( 'WooCommerce PDF Invoices', 'wpo_wcpdf' ); ?></h2>
120
+ <h2 class="nav-tab-wrapper">
121
+ <?php
122
+ foreach ($settings_tabs as $tab_slug => $tab_title ) {
123
+ printf('<a href="?page=wpo_wcpdf_options_page&tab=%1$s" class="nav-tab nav-tab-%1$s %2$s">%3$s</a>', $tab_slug, (($active_tab == $tab_slug) ? 'nav-tab-active' : ''), $tab_title);
124
+ }
125
+ ?>
126
+ </h2>
127
+
128
+ <?php
129
+ do_action( 'wpo_wcpdf_before_settings_page', $active_tab );
130
+
131
+ // save or check option to hide extensions ad
132
+ if ( isset( $_GET['wpo_wcpdf_hide_extensions_ad'] ) ) {
133
+ update_option( 'wpo_wcpdf_hide_extensions_ad', true );
134
+ $hide_ad = true;
135
+ } else {
136
+ $hide_ad = get_option( 'wpo_wcpdf_hide_extensions_ad' );
137
+ }
138
+
139
+ if ( !$hide_ad && !( class_exists('WooCommerce_PDF_IPS_Pro') && class_exists('WooCommerce_PDF_IPS_Dropbox') && class_exists('WooCommerce_PDF_IPS_Templates') && class_exists('WooCommerce_Ext_PrintOrders') ) ) {
140
+ include('wcpdf-extensions.php');
141
+ }
142
+
143
+ ?>
144
+ <form method="post" action="options.php" id="wpo-wcpdf-settings">
145
+ <?php
146
+ do_action( 'wpo_wcpdf_before_settings', $active_tab );
147
+ settings_fields( 'wpo_wcpdf_'.$active_tab.'_settings' );
148
+ do_settings_sections( 'wpo_wcpdf_'.$active_tab.'_settings' );
149
+ do_action( 'wpo_wcpdf_after_settings', $active_tab );
150
+
151
+ submit_button();
152
+ ?>
153
+
154
+ </form>
155
+ <?php
156
+
157
+ if ( $active_tab=='debug' ) {
158
+ $this->status_page();
159
+ }
160
+
161
+ do_action( 'wpo_wcpdf_after_settings_page', $active_tab ); ?>
162
+
163
+ </div>
164
+
165
+ <?php
166
+ }
167
+
168
+ public function status_page() {
169
+ ?>
170
+ <?php include('dompdf-status.php'); ?>
171
+ <?php
172
+ }
173
+
174
+ /**
175
+ * User settings.
176
+ *
177
+ */
178
+
179
+ public function init_settings() {
180
+ global $woocommerce, $wpo_wcpdf;
181
+
182
+ // Whether a third-party plugin claims responsibility for generating invoice numbers
183
+ $invoicenumber_thirdparty = apply_filters('woocommerce_invoice_number_by_plugin', false);
184
+
185
+ /**************************************/
186
+ /*********** GENERAL SETTINGS *********/
187
+ /**************************************/
188
+
189
+ $option = 'wpo_wcpdf_general_settings';
190
+
191
+ // Create option in wp_options.
192
+ if ( false === get_option( $option ) ) {
193
+ $this->default_settings( $option );
194
+ }
195
+
196
+ // Section.
197
+ add_settings_section(
198
+ 'general_settings',
199
+ __( 'General settings', 'wpo_wcpdf' ),
200
+ array( &$this, 'section_options_callback' ),
201
+ $option
202
+ );
203
+
204
+ add_settings_field(
205
+ 'download_display',
206
+ __( 'How do you want to view the PDF?', 'wpo_wcpdf' ),
207
+ array( &$this, 'select_element_callback' ),
208
+ $option,
209
+ 'general_settings',
210
+ array(
211
+ 'menu' => $option,
212
+ 'id' => 'download_display',
213
+ 'options' => array(
214
+ 'download' => __( 'Download the PDF' , 'wpo_wcpdf' ),
215
+ 'display' => __( 'Open the PDF in a new browser tab/window' , 'wpo_wcpdf' ),
216
+ ),
217
+ )
218
+ );
219
+
220
+ $tmp_path = $wpo_wcpdf->export->tmp_path( 'attachments' );
221
+ $tmp_path_check = !is_writable( $tmp_path );
222
+
223
+ $wc_emails = array(
224
+ 'new_order' => __( 'Admin New Order email' , 'wpo_wcpdf' ),
225
+ 'processing' => __( 'Customer Processing Order email' , 'wpo_wcpdf' ),
226
+ 'completed' => __( 'Customer Completed Order email' , 'wpo_wcpdf' ),
227
+ 'customer_invoice' => __( 'Customer Invoice email' , 'wpo_wcpdf' ),
228
+ );
229
+
230
+ // load custom emails
231
+ $extra_emails = $this->get_wc_emails();
232
+ $wc_emails = array_merge( $wc_emails, $extra_emails );
233
+
234
+ add_settings_field(
235
+ 'email_pdf',
236
+ __( 'Attach invoice to:', 'wpo_wcpdf' ),
237
+ array( &$this, 'multiple_checkbox_element_callback' ),
238
+ $option,
239
+ 'general_settings',
240
+ array(
241
+ 'menu' => $option,
242
+ 'id' => 'email_pdf',
243
+ 'options' => apply_filters( 'wpo_wcpdf_wc_emails', $wc_emails ),
244
+ 'description' => $tmp_path_check ? '<span class="wpo-warning">' . sprintf( __( 'It looks like the temp folder (<code>%s</code>) is not writable, check the permissions for this folder! Without having write access to this folder, the plugin will not be able to email invoices.', 'wpo_wcpdf' ), $tmp_path ).'</span>':'',
245
+ )
246
+ );
247
+
248
+ add_settings_field(
249
+ 'disable_free',
250
+ __( 'Disable for free products', 'wpo_wcpdf' ),
251
+ array( &$this, 'checkbox_element_callback' ),
252
+ $option,
253
+ 'general_settings',
254
+ array(
255
+ 'menu' => $option,
256
+ 'id' => 'disable_free',
257
+ 'description' => __( "Disable automatic creation/attachment of invoices when only free products are ordered", 'wpo_wcpdf' ),
258
+ )
259
+ );
260
+
261
+ // Section.
262
+ add_settings_section(
263
+ 'interface',
264
+ __( 'Interface', 'wpo_wcpdf' ),
265
+ array( &$this, 'section_options_callback' ),
266
+ $option
267
+ );
268
+
269
+ // $documents = array(
270
+ // 'invoice' => __( 'Invoice', 'wpo_wcpdf' ),
271
+ // 'packing-slip' => __( 'Packing Slip', 'wpo_wcpdf' ),
272
+ // );
273
+
274
+ // $contexts = array(
275
+ // 'orders-list' => __( 'Orders list', 'wpo_wcpdf' ),
276
+ // 'orders-bulk' => __( 'Bulk order actions', 'wpo_wcpdf' ),
277
+ // 'order-single' => __( 'Single order page', 'wpo_wcpdf' ),
278
+ // 'my-account' => __( 'My Account page', 'wpo_wcpdf' ),
279
+ // );
280
+
281
+ // add_settings_field(
282
+ // 'buttons',
283
+ // __( 'Show download buttons', 'wpo_wcpdf' ),
284
+ // array( &$this, 'checkbox_table_callback' ),
285
+ // $option,
286
+ // 'interface',
287
+ // array(
288
+ // 'menu' => $option,
289
+ // 'id' => 'buttons',
290
+ // 'rows' => $contexts,
291
+ // 'columns' => apply_filters( 'wpo_wcpdf_documents_buttons', $documents ),
292
+ // )
293
+ // );
294
+
295
+ // get list of WooCommerce statuses
296
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
297
+ $statuses = (array) get_terms( 'shop_order_status', array( 'hide_empty' => 0, 'orderby' => 'id' ) );
298
+ foreach ( $statuses as $status ) {
299
+ $order_statuses[esc_attr( $status->slug )] = esc_html__( $status->name, 'woocommerce' );
300
+ }
301
+ } else {
302
+ $statuses = wc_get_order_statuses();
303
+ foreach ( $statuses as $status_slug => $status ) {
304
+ $status_slug = 'wc-' === substr( $status_slug, 0, 3 ) ? substr( $status_slug, 3 ) : $status_slug;
305
+ $order_statuses[$status_slug] = $status;
306
+ }
307
+
308
+ }
309
+
310
+ add_settings_field(
311
+ 'my_account_buttons',
312
+ __( 'Allow My Account invoice download', 'wpo_wcpdf' ),
313
+ array( &$this, 'select_element_callback' ),
314
+ $option,
315
+ 'interface',
316
+ array(
317
+ 'menu' => $option,
318
+ 'id' => 'my_account_buttons',
319
+ 'options' => array(
320
+ 'available' => __( 'Only when an invoice is already created/emailed' , 'wpo_wcpdf' ),
321
+ 'custom' => __( 'Only for specific order statuses (define below)' , 'wpo_wcpdf' ),
322
+ 'always' => __( 'Always' , 'wpo_wcpdf' ),
323
+ 'never' => __( 'Never' , 'wpo_wcpdf' ),
324
+ ),
325
+ 'custom' => array(
326
+ 'type' => 'multiple_checkbox_element_callback',
327
+ 'args' => array(
328
+ 'menu' => $option,
329
+ 'id' => 'my_account_restrict',
330
+ 'options' => $order_statuses,
331
+ ),
332
+ ),
333
+ )
334
+ );
335
+
336
+ add_settings_field(
337
+ 'invoice_number_column',
338
+ __( 'Enable invoice number column in the orders list', 'wpo_wcpdf' ),
339
+ array( &$this, 'checkbox_element_callback' ),
340
+ $option,
341
+ 'interface',
342
+ array(
343
+ 'menu' => $option,
344
+ 'id' => 'invoice_number_column',
345
+ )
346
+ );
347
+
348
+ // Register settings.
349
+ register_setting( $option, $option, array( &$this, 'validate_options' ) );
350
+
351
+ $option_values = get_option($option);
352
+ // convert old 'statusless' setting to new status array
353
+ if ( isset( $option_values['email_pdf'] ) && !is_array( $option_values['email_pdf'] ) ) {
354
+ $default_status = apply_filters( 'wpo_wcpdf_attach_to_status', 'completed' );
355
+ $option_values['email_pdf'] = array (
356
+ $default_status => 1,
357
+ 'customer_invoice' => 1,
358
+ );
359
+ update_option( $option, $option_values );
360
+ }
361
+
362
+ /**************************************/
363
+ /********** TEMPLATE SETTINGS *********/
364
+ /**************************************/
365
+
366
+ $option = 'wpo_wcpdf_template_settings';
367
+
368
+ // Create option in wp_options.
369
+ if ( false === get_option( $option ) ) {
370
+ $this->default_settings( $option );
371
+ }
372
+
373
+ // Section.
374
+ add_settings_section(
375
+ 'template_settings',
376
+ __( 'PDF Template settings', 'wpo_wcpdf' ),
377
+ array( &$this, 'section_options_callback' ),
378
+ $option
379
+ );
380
+
381
+
382
+ $theme_path = get_stylesheet_directory() . '/' . $wpo_wcpdf->export->template_base_path;
383
+ $theme_template_path = substr($theme_path, strpos($theme_path, 'wp-content')) . 'yourtemplate';
384
+ $plugin_template_path = 'wp-content/plugins/woocommerce-pdf-invoices-packing-slips/templates/pdf/Simple';
385
+
386
+ add_settings_field(
387
+ 'template_path',
388
+ __( 'Choose a template', 'wpo_wcpdf' ),
389
+ array( &$this, 'template_select_element_callback' ),
390
+ $option,
391
+ 'template_settings',
392
+ array(
393
+ 'menu' => $option,
394
+ 'id' => 'template_path',
395
+ 'options' => $this->find_templates(),
396
+ 'description' => sprintf( __( 'Want to use your own template? Copy all the files from <code>%s</code> to your (child) theme in <code>%s</code> to customize them' , 'wpo_wcpdf' ), $plugin_template_path, $theme_template_path),
397
+ )
398
+ );
399
+
400
+ add_settings_field(
401
+ 'paper_size',
402
+ __( 'Paper size', 'wpo_wcpdf' ),
403
+ array( &$this, 'select_element_callback' ),
404
+ $option,
405
+ 'template_settings',
406
+ array(
407
+ 'menu' => $option,
408
+ 'id' => 'paper_size',
409
+ 'options' => apply_filters( 'wpo_wcpdf_template_settings_paper_size', array(
410
+ 'a4' => __( 'A4' , 'wpo_wcpdf' ),
411
+ 'letter' => __( 'Letter' , 'wpo_wcpdf' ),
412
+ ) ),
413
+ )
414
+ );
415
+
416
+ add_settings_field(
417
+ 'header_logo',
418
+ __( 'Shop header/logo', 'wpo_wcpdf' ),
419
+ array( &$this, 'media_upload_callback' ),
420
+ $option,
421
+ 'template_settings',
422
+ array(
423
+ 'menu' => $option,
424
+ 'id' => 'header_logo',
425
+ 'uploader_title' => __( 'Select or upload your invoice header/logo', 'wpo_wcpdf' ),
426
+ 'uploader_button_text' => __( 'Set image', 'wpo_wcpdf' ),
427
+ 'remove_button_text' => __( 'Remove image', 'wpo_wcpdf' ),
428
+ //'description' => __( '...', 'wpo_wcpdf' ),
429
+ )
430
+ );
431
+
432
+ add_settings_field(
433
+ 'shop_name',
434
+ __( 'Shop Name', 'wpo_wcpdf' ),
435
+ array( &$this, 'text_element_callback' ),
436
+ $option,
437
+ 'template_settings',
438
+ array(
439
+ 'menu' => $option,
440
+ 'id' => 'shop_name',
441
+ 'size' => '72',
442
+ 'translatable' => true,
443
+ )
444
+ );
445
+
446
+ add_settings_field(
447
+ 'shop_address',
448
+ __( 'Shop Address', 'wpo_wcpdf' ),
449
+ array( &$this, 'textarea_element_callback' ),
450
+ $option,
451
+ 'template_settings',
452
+ array(
453
+ 'menu' => $option,
454
+ 'id' => 'shop_address',
455
+ 'width' => '72',
456
+ 'height' => '8',
457
+ 'translatable' => true,
458
+ //'description' => __( '...', 'wpo_wcpdf' ),
459
+ )
460
+ );
461
+
462
+ add_settings_field(
463
+ 'footer',
464
+ __( 'Footer: terms & conditions, policies, etc.', 'wpo_wcpdf' ),
465
+ array( &$this, 'textarea_element_callback' ),
466
+ $option,
467
+ 'template_settings',
468
+ array(
469
+ 'menu' => $option,
470
+ 'id' => 'footer',
471
+ 'width' => '72',
472
+ 'height' => '4',
473
+ 'translatable' => true,
474
+ //'description' => __( '...', 'wpo_wcpdf' ),
475
+ )
476
+ );
477
+
478
+ // Section.
479
+ add_settings_section(
480
+ 'invoice',
481
+ __( 'Invoice', 'wpo_wcpdf' ),
482
+ array( &$this, 'section_options_callback' ),
483
+ $option
484
+ );
485
+
486
+ add_settings_field(
487
+ 'invoice_shipping_address',
488
+ __( 'Display shipping address', 'wpo_wcpdf' ),
489
+ array( &$this, 'checkbox_element_callback' ),
490
+ $option,
491
+ 'invoice',
492
+ array(
493
+ 'menu' => $option,
494
+ 'id' => 'invoice_shipping_address',
495
+ 'description' => __( 'Display shipping address on invoice (in addition to the default billing address) if different from billing address', 'wpo_wcpdf' ),
496
+ )
497
+ );
498
+
499
+ add_settings_field(
500
+ 'invoice_email',
501
+ __( 'Display email address', 'wpo_wcpdf' ),
502
+ array( &$this, 'checkbox_element_callback' ),
503
+ $option,
504
+ 'invoice',
505
+ array(
506
+ 'menu' => $option,
507
+ 'id' => 'invoice_email',
508
+ )
509
+ );
510
+
511
+ add_settings_field(
512
+ 'invoice_phone',
513
+ __( 'Display phone number', 'wpo_wcpdf' ),
514
+ array( &$this, 'checkbox_element_callback' ),
515
+ $option,
516
+ 'invoice',
517
+ array(
518
+ 'menu' => $option,
519
+ 'id' => 'invoice_phone',
520
+ )
521
+ );
522
+
523
+ add_settings_field(
524
+ 'display_date',
525
+ __( 'Display invoice date', 'wpo_wcpdf' ),
526
+ array( &$this, 'checkbox_element_callback' ),
527
+ $option,
528
+ 'invoice',
529
+ array(
530
+ 'menu' => $option,
531
+ 'id' => 'display_date',
532
+ 'value' => 'invoice_date',
533
+ )
534
+ );
535
+
536
+ if ($invoicenumber_thirdparty) {
537
+ $invoice_number_desc = __( 'Invoice numbers are created by a third-party extension.', 'yith-woocommerce-pdf-invoice');
538
+ $config_link = esc_attr(apply_filters('woocommerce_invoice_number_configuration_link', null));
539
+ if ($config_link) {
540
+ $invoice_number_desc .= ' '.sprintf(__( 'Configure it <a href="%s">here</a>.', 'yith-woocommerce-pdf-invoice'), $config_link);
541
+ }
542
+ $invoice_number_desc = '<i>'.$invoice_number_desc.'</i>';
543
+ } else {
544
+ $invoice_number_desc = null;
545
+ }
546
+
547
+ add_settings_field(
548
+ 'display_number',
549
+ $invoicenumber_thirdparty ? __( 'Display invoice number', 'wpo_wcpdf' ) : __( 'Display built-in sequential invoice number', 'wpo_wcpdf' ),
550
+ array( &$this, 'checkbox_element_callback' ),
551
+ $option,
552
+ 'invoice',
553
+ array(
554
+ 'menu' => $option,
555
+ 'id' => 'display_number',
556
+ 'value' => 'invoice_number',
557
+ 'description' => $invoice_number_desc,
558
+ )
559
+ );
560
+
561
+ if (!$invoicenumber_thirdparty) {
562
+ // invoice number is stored separately for direct retrieval
563
+ register_setting( $option, 'wpo_wcpdf_next_invoice_number', array( &$this, 'validate_options' ) );
564
+ add_settings_field(
565
+ 'next_invoice_number',
566
+ __( 'Next invoice number (without prefix/suffix etc.)', 'wpo_wcpdf' ),
567
+ array( &$this, 'singular_text_element_callback' ),
568
+ $option,
569
+ 'invoice',
570
+ array(
571
+ 'menu' => 'wpo_wcpdf_next_invoice_number',
572
+ 'id' => 'next_invoice_number',
573
+ 'size' => '10',
574
+ 'description' => __( 'This is the number that will be used on the next invoice that is created. By default, numbering starts from the WooCommerce Order Number of the first invoice that is created and increases for every new invoice. Note that if you override this and set it lower than the highest (PDF) invoice number, this could create double invoice numbers!', 'wpo_wcpdf' ),
575
+ )
576
+ );
577
+
578
+ // first time invoice number
579
+ $next_invoice_number = get_option('wpo_wcpdf_next_invoice_number');
580
+ // determine highest invoice number if option not set
581
+ if ( !isset( $next_invoice_number ) ) {
582
+ // Based on code from WooCommerce Sequential Order Numbers
583
+ global $wpdb;
584
+ // get highest invoice_number in postmeta table
585
+ $max_invoice_number = $wpdb->get_var( 'SELECT max(cast(meta_value as UNSIGNED)) from ' . $wpdb->postmeta . ' where meta_key="_wcpdf_invoice_number"' );
586
+
587
+ if ( !empty($max_invoice_number) ) {
588
+ $next_invoice_number = $max_invoice_number+1;
589
+ } else {
590
+ $next_invoice_number = '';
591
+ }
592
+
593
+ update_option( 'wpo_wcpdf_next_invoice_number', $next_invoice_number );
594
+ }
595
+
596
+ add_settings_field(
597
+ 'invoice_number_formatting',
598
+ __( 'Invoice number format', 'wpo_wcpdf' ),
599
+ array( &$this, 'invoice_number_formatting_callback' ),
600
+ $option,
601
+ 'invoice',
602
+ array(
603
+ 'menu' => $option,
604
+ 'id' => 'invoice_number_formatting',
605
+ 'fields' => array(
606
+ 'prefix' => array(
607
+ 'title' => __( 'Prefix' , 'wpo_wcpdf' ),
608
+ 'size' => 20,
609
+ 'description' => __( 'to use the invoice year and/or month, use [invoice_year] or [invoice_month] respectively' , 'wpo_wcpdf' ),
610
+ ),
611
+ 'suffix' => array(
612
+ 'title' => __( 'Suffix' , 'wpo_wcpdf' ),
613
+ 'size' => 20,
614
+ 'description' => '',
615
+ ),
616
+ 'padding' => array(
617
+ 'title' => __( 'Padding' , 'wpo_wcpdf' ),
618
+ 'size' => 2,
619
+ 'description' => __( 'enter the number of digits here - enter "6" to display 42 as 000042' , 'wpo_wcpdf' ),
620
+ ),
621
+ ),
622
+ 'description' => __( 'note: if you have already created a custom invoice number format with a filter, the above settings will be ignored' , 'wpo_wcpdf' ),
623
+ )
624
+ );
625
+
626
+ add_settings_field(
627
+ 'yearly_reset_invoice_number',
628
+ __( 'Reset invoice number yearly', 'wpo_wcpdf' ),
629
+ array( &$this, 'checkbox_element_callback' ),
630
+ $option,
631
+ 'invoice',
632
+ array(
633
+ 'menu' => $option,
634
+ 'id' => 'yearly_reset_invoice_number',
635
+ )
636
+ );
637
+ } // End if ($invoicenumber_thirdparty)
638
+
639
+ add_settings_field(
640
+ 'currency_font',
641
+ __( 'Extended currency symbol support', 'wpo_wcpdf' ),
642
+ array( &$this, 'checkbox_element_callback' ),
643
+ $option,
644
+ 'invoice',
645
+ array(
646
+ 'menu' => $option,
647
+ 'id' => 'currency_font',
648
+ 'description' => __( 'Enable this if your currency symbol is not displaying properly' , 'wpo_wcpdf' ),
649
+ )
650
+ );
651
+
652
+ // Section.
653
+ add_settings_section(
654
+ 'packing_slip',
655
+ __( 'Packing Slip', 'wpo_wcpdf' ),
656
+ array( &$this, 'section_options_callback' ),
657
+ $option
658
+ );
659
+
660
+ add_settings_field(
661
+ 'packing_slip_billing_address',
662
+ __( 'Display billing address', 'wpo_wcpdf' ),
663
+ array( &$this, 'checkbox_element_callback' ),
664
+ $option,
665
+ 'packing_slip',
666
+ array(
667
+ 'menu' => $option,
668
+ 'id' => 'packing_slip_billing_address',
669
+ 'description' => __( 'Display billing address on packing slip (in addition to the default shipping address) if different from shipping address', 'wpo_wcpdf' ),
670
+ )
671
+ );
672
+
673
+ add_settings_field(
674
+ 'packing_slip_email',
675
+ __( 'Display email address', 'wpo_wcpdf' ),
676
+ array( &$this, 'checkbox_element_callback' ),
677
+ $option,
678
+ 'packing_slip',
679
+ array(
680
+ 'menu' => $option,
681
+ 'id' => 'packing_slip_email',
682
+ )
683
+ );
684
+
685
+ add_settings_field(
686
+ 'packing_slip_phone',
687
+ __( 'Display phone number', 'wpo_wcpdf' ),
688
+ array( &$this, 'checkbox_element_callback' ),
689
+ $option,
690
+ 'packing_slip',
691
+ array(
692
+ 'menu' => $option,
693
+ 'id' => 'packing_slip_phone',
694
+ )
695
+ );
696
+
697
+ // Section.
698
+ add_settings_section(
699
+ 'extra_template_fields',
700
+ __( 'Extra template fields', 'wpo_wcpdf' ),
701
+ array( &$this, 'custom_fields_section' ),
702
+ $option
703
+ );
704
+
705
+ add_settings_field(
706
+ 'extra_1',
707
+ __( 'Extra field 1', 'wpo_wcpdf' ),
708
+ array( &$this, 'textarea_element_callback' ),
709
+ $option,
710
+ 'extra_template_fields',
711
+ array(
712
+ 'menu' => $option,
713
+ 'id' => 'extra_1',
714
+ 'width' => '72',
715
+ 'height' => '8',
716
+ 'description' => __( 'This is footer column 1 in the <i>Modern (Premium)</i> template', 'wpo_wcpdf' ),
717
+ 'translatable' => true,
718
+ )
719
+ );
720
+
721
+ add_settings_field(
722
+ 'extra_2',
723
+ __( 'Extra field 2', 'wpo_wcpdf' ),
724
+ array( &$this, 'textarea_element_callback' ),
725
+ $option,
726
+ 'extra_template_fields',
727
+ array(
728
+ 'menu' => $option,
729
+ 'id' => 'extra_2',
730
+ 'width' => '72',
731
+ 'height' => '8',
732
+ 'description' => __( 'This is footer column 2 in the <i>Modern (Premium)</i> template', 'wpo_wcpdf' ),
733
+ 'translatable' => true,
734
+ )
735
+ );
736
+
737
+ add_settings_field(
738
+ 'extra_3',
739
+ __( 'Extra field 3', 'wpo_wcpdf' ),
740
+ array( &$this, 'textarea_element_callback' ),
741
+ $option,
742
+ 'extra_template_fields',
743
+ array(
744
+ 'menu' => $option,
745
+ 'id' => 'extra_3',
746
+ 'width' => '72',
747
+ 'height' => '8',
748
+ 'description' => __( 'This is footer column 3 in the <i>Modern (Premium)</i> template', 'wpo_wcpdf' ),
749
+ 'translatable' => true,
750
+ )
751
+ );
752
+
753
+ // Register settings.
754
+ register_setting( $option, $option, array( &$this, 'validate_options' ) );
755
+
756
+ /**************************************/
757
+ /******** DEBUG/STATUS SETTINGS *******/
758
+ /**************************************/
759
+
760
+ $option = 'wpo_wcpdf_debug_settings';
761
+
762
+ // Create option in wp_options.
763
+ if ( false === get_option( $option ) ) {
764
+ $this->default_settings( $option );
765
+ }
766
+
767
+ // Section.
768
+ add_settings_section(
769
+ 'debug_settings',
770
+ __( 'Debug settings', 'wpo_wcpdf' ),
771
+ array( &$this, 'debug_section' ),
772
+ $option
773
+ );
774
+
775
+ add_settings_field(
776
+ 'enable_debug',
777
+ __( 'Enable debug output', 'wpo_wcpdf' ),
778
+ array( &$this, 'checkbox_element_callback' ),
779
+ $option,
780
+ 'debug_settings',
781
+ array(
782
+ 'menu' => $option,
783
+ 'id' => 'enable_debug',
784
+ 'description' => __( "Enable this option to output plugin errors if you're getting a blank page or other PDF generation issues", 'wpo_wcpdf' ),
785
+ )
786
+ );
787
+
788
+ add_settings_field(
789
+ 'html_output',
790
+ __( 'Output to HTML', 'wpo_wcpdf' ),
791
+ array( &$this, 'checkbox_element_callback' ),
792
+ $option,
793
+ 'debug_settings',
794
+ array(
795
+ 'menu' => $option,
796
+ 'id' => 'html_output',
797
+ 'description' => __( 'Send the template output as HTML to the browser instead of creating a PDF.', 'wpo_wcpdf' ),
798
+ )
799
+ );
800
+
801
+ add_settings_field(
802
+ 'old_tmp',
803
+ __( 'Use old tmp folder', 'wpo_wcpdf' ),
804
+ array( &$this, 'checkbox_element_callback' ),
805
+ $option,
806
+ 'debug_settings',
807
+ array(
808
+ 'menu' => $option,
809
+ 'id' => 'old_tmp',
810
+ 'description' => __( 'Before version 1.5 of PDF Invoices, temporary files were stored in the plugin folder. This setting is only intended for backwards compatibility, not recommended on new installs!', 'wpo_wcpdf' ),
811
+ )
812
+ );
813
+
814
+ // Register settings.
815
+ register_setting( $option, $option, array( &$this, 'validate_options' ) );
816
+
817
+ }
818
+
819
+ /**
820
+ * get all emails registered in WooCommerce
821
+ * @param boolean $remove_defaults switch to remove default woocommerce emails
822
+ * @return array $emails list of all email ids/slugs and names
823
+ */
824
+ public function get_wc_emails ( $remove_defaults = true ) {
825
+ // get emails from WooCommerce
826
+ global $woocommerce;
827
+ $mailer = $woocommerce->mailer();
828
+ $wc_emails = $mailer->get_emails();
829
+
830
+ $default_emails = array(
831
+ 'new_order',
832
+ 'customer_processing_order',
833
+ 'customer_completed_order',
834
+ 'customer_invoice',
835
+ 'customer_note',
836
+ 'customer_reset_password',
837
+ 'customer_new_account'
838
+ );
839
+
840
+ $emails = array();
841
+ foreach ($wc_emails as $name => $template) {
842
+ if ( !( $remove_defaults && in_array( $template->id, $default_emails ) ) ) {
843
+ $emails[$template->id] = $template->title;
844
+ }
845
+ }
846
+
847
+ return $emails;
848
+ }
849
+
850
+ /**
851
+ * WooCommerce Order Status & Actions Manager emails compatibility
852
+ */
853
+ public function wc_order_status_actions_emails ( $emails ) {
854
+ // check if WC_Custom_Status class is loaded!
855
+ if (class_exists('WC_Custom_Status')) {
856
+ // get list of custom statuses from WooCommerce Custom Order Status & Actions
857
+ // status slug => status name
858
+ $custom_statuses = WC_Custom_Status::get_status_list_names();
859
+ // append _email to slug (=email_id) and add to emails list
860
+ foreach ($custom_statuses as $status_slug => $status_name) {
861
+ $emails[$status_slug.'_email'] = $status_name;
862
+ }
863
+ }
864
+ return $emails;
865
+ }
866
+
867
+ /**
868
+ * Set default settings.
869
+ */
870
+ public function default_settings( $option ) {
871
+ global $wpo_wcpdf;
872
+
873
+ switch ( $option ) {
874
+ case 'wpo_wcpdf_general_settings':
875
+ $default = array(
876
+ 'download_display' => 'download',
877
+ );
878
+ break;
879
+ case 'wpo_wcpdf_template_settings':
880
+ $default = array(
881
+ 'paper_size' => 'a4',
882
+ 'template_path' => $wpo_wcpdf->export->template_default_base_path . 'Simple',
883
+ // 'invoice_shipping_address' => '1',
884
+ );
885
+ break;
886
+ default:
887
+ $default = array();
888
+ break;
889
+ }
890
+
891
+ if ( false === get_option( $option ) ) {
892
+ add_option( $option, $default );
893
+ } else {
894
+ update_option( $option, $default );
895
+
896
+ }
897
+ }
898
+
899
+ // Text element callback.
900
+ public function text_element_callback( $args ) {
901
+ $menu = $args['menu'];
902
+ $id = $args['id'];
903
+ $size = isset( $args['size'] ) ? $args['size'] : '25';
904
+ $class = isset( $args['translatable'] ) && $args['translatable'] === true ? 'translatable' : '';
905
+
906
+ $options = get_option( $menu );
907
+
908
+ if ( isset( $options[$id] ) ) {
909
+ $current = $options[$id];
910
+ } else {
911
+ $current = isset( $args['default'] ) ? $args['default'] : '';
912
+ }
913
+
914
+ $html = sprintf( '<input type="text" id="%1$s" name="%2$s[%1$s]" value="%3$s" size="%4$s" class="%5$s"/>', $id, $menu, $current, $size, $class );
915
+
916
+ // Displays option description.
917
+ if ( isset( $args['description'] ) ) {
918
+ $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
919
+ }
920
+
921
+ echo $html;
922
+ }
923
+
924
+ // Single text option (not part of any settings array)
925
+ public function singular_text_element_callback( $args ) {
926
+ $menu = $args['menu'];
927
+ $id = $args['id'];
928
+ $size = isset( $args['size'] ) ? $args['size'] : '25';
929
+ $class = isset( $args['translatable'] ) && $args['translatable'] === true ? 'translatable' : '';
930
+
931
+ $option = get_option( $menu );
932
+
933
+ if ( isset( $option ) ) {
934
+ $current = $option;
935
+ } else {
936
+ $current = isset( $args['default'] ) ? $args['default'] : '';
937
+ }
938
+
939
+ $html = sprintf( '<input type="text" id="%1$s" name="%2$s" value="%3$s" size="%4$s" class="%5$s"/>', $id, $menu, $current, $size, $class );
940
+
941
+ // Displays option description.
942
+ if ( isset( $args['description'] ) ) {
943
+ $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
944
+ }
945
+
946
+ echo $html;
947
+ }
948
+
949
+ // Text element callback.
950
+ public function textarea_element_callback( $args ) {
951
+ $menu = $args['menu'];
952
+ $id = $args['id'];
953
+ $width = $args['width'];
954
+ $height = $args['height'];
955
+ $class = isset( $args['translatable'] ) && $args['translatable'] === true ? 'translatable' : '';
956
+
957
+ $options = get_option( $menu );
958
+
959
+ if ( isset( $options[$id] ) ) {
960
+ $current = $options[$id];
961
+ } else {
962
+ $current = isset( $args['default'] ) ? $args['default'] : '';
963
+ }
964
+
965
+ $html = sprintf( '<textarea id="%1$s" name="%2$s[%1$s]" cols="%4$s" rows="%5$s" class="%6$s"/>%3$s</textarea>', $id, $menu, $current, $width, $height, $class );
966
+
967
+ // Displays option description.
968
+ if ( isset( $args['description'] ) ) {
969
+ $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
970
+ }
971
+
972
+ echo $html;
973
+ }
974
+
975
+
976
+ /**
977
+ * Checkbox field callback.
978
+ *
979
+ * @param array $args Field arguments.
980
+ *
981
+ * @return string Checkbox field.
982
+ */
983
+ public function checkbox_element_callback( $args ) {
984
+ $menu = $args['menu'];
985
+ $id = $args['id'];
986
+ $value = isset( $args['value'] ) ? $args['value'] : 1;
987
+
988
+ $options = get_option( $menu );
989
+
990
+ if ( isset( $options[$id] ) ) {
991
+ $current = $options[$id];
992
+ } else {
993
+ $current = isset( $args['default'] ) ? $args['default'] : '';
994
+ }
995
+
996
+ $html = sprintf( '<input type="checkbox" id="%1$s" name="%2$s[%1$s]" value="%3$s"%4$s />', $id, $menu, $value, checked( $value, $current, false ) );
997
+
998
+ // Displays option description.
999
+ if ( isset( $args['description'] ) ) {
1000
+ $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
1001
+ }
1002
+
1003
+ echo $html;
1004
+ }
1005
+
1006
+ /**
1007
+ * Multiple Checkbox field callback.
1008
+ *
1009
+ * @param array $args Field arguments.
1010
+ *
1011
+ * @return string Checkbox field.
1012
+ */
1013
+ public function multiple_checkbox_element_callback( $args ) {
1014
+ $menu = $args['menu'];
1015
+ $id = $args['id'];
1016
+
1017
+ $options = get_option( $menu );
1018
+
1019
+
1020
+ foreach ( $args['options'] as $key => $label ) {
1021
+ $current = ( isset( $options[$id][$key] ) ) ? $options[$id][$key] : '';
1022
+ printf( '<input type="checkbox" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="1"%4$s /> %5$s<br/>', $menu, $id, $key, checked( 1, $current, false ), $label );
1023
+ }
1024
+
1025
+ // Displays option description.
1026
+ if ( isset( $args['description'] ) ) {
1027
+ printf( '<p class="description">%s</p>', $args['description'] );
1028
+ }
1029
+ }
1030
+
1031
+ /**
1032
+ * Checkbox fields table callback.
1033
+ *
1034
+ * @param array $args Field arguments.
1035
+ *
1036
+ * @return string Checkbox field.
1037
+ */
1038
+ public function checkbox_table_callback( $args ) {
1039
+ $menu = $args['menu'];
1040
+ $id = $args['id'];
1041
+
1042
+ $options = get_option( $menu );
1043
+
1044
+ $rows = $args['rows'];
1045
+ $columns = $args['columns'];
1046
+
1047
+ ?>
1048
+ <table style="">
1049
+ <tr>
1050
+ <td style="padding:0 10px 5px 0;">&nbsp;</td>
1051
+ <?php foreach ( $columns as $column => $title ) { ?>
1052
+ <td style="padding:0 10px 5px 0;"><?php echo $title; ?></td>
1053
+ <?php } ?>
1054
+ </tr>
1055
+ <tr>
1056
+ <td style="padding: 0;">
1057
+ <?php foreach ($rows as $row) {
1058
+ echo $row.'<br/>';
1059
+ } ?>
1060
+ </td>
1061
+ <?php foreach ( $columns as $column => $title ) { ?>
1062
+ <td style="text-align:center; padding: 0;">
1063
+ <?php foreach ( $rows as $row => $title ) {
1064
+ $current = ( isset( $options[$id.'_'.$column][$row] ) ) ? $options[$id.'_'.$column][$row] : '';
1065
+ $name = sprintf('%1$s[%2$s_%3$s][%4$s]', $menu, $id, $column, $row);
1066
+ printf( '<input type="checkbox" id="%1$s" name="%1$s" value="1"%2$s /><br/>', $name, checked( 1, $current, false ) );
1067
+ } ?>
1068
+ </td>
1069
+ <?php } ?>
1070
+ </tr>
1071
+ </table>
1072
+
1073
+ <?php
1074
+ // Displays option description.
1075
+ if ( isset( $args['description'] ) ) {
1076
+ printf( '<p class="description">%s</p>', $args['description'] );
1077
+ }
1078
+ }
1079
+
1080
+ /**
1081
+ * Select element callback.
1082
+ *
1083
+ * @param array $args Field arguments.
1084
+ *
1085
+ * @return string Select field.
1086
+ */
1087
+ public function select_element_callback( $args ) {
1088
+ $menu = $args['menu'];
1089
+ $id = $args['id'];
1090
+
1091
+ $options = get_option( $menu );
1092
+
1093
+ if ( isset( $options[$id] ) ) {
1094
+ $current = $options[$id];
1095
+ } else {
1096
+ $current = isset( $args['default'] ) ? $args['default'] : '';
1097
+ }
1098
+
1099
+ printf( '<select id="%1$s" name="%2$s[%1$s]">', $id, $menu );
1100
+
1101
+ foreach ( $args['options'] as $key => $label ) {
1102
+ printf( '<option value="%s"%s>%s</option>', $key, selected( $current, $key, false ), $label );
1103
+ }
1104
+
1105
+ echo '</select>';
1106
+
1107
+
1108
+ if (isset($args['custom'])) {
1109
+ $custom = $args['custom'];
1110
+
1111
+ $custom_id = $id.'_custom';
1112
+
1113
+ printf( '<br/><br/><div id="%s" style="display:none;">', $custom_id );
1114
+
1115
+ switch ($custom['type']) {
1116
+ case 'text_element_callback':
1117
+ $this->text_element_callback( $custom['args'] );
1118
+ break;
1119
+ case 'multiple_text_element_callback':
1120
+ $this->multiple_text_element_callback( $custom['args'] );
1121
+ break;
1122
+ case 'multiple_checkbox_element_callback':
1123
+ $this->multiple_checkbox_element_callback( $custom['args'] );
1124
+ break;
1125
+ default:
1126
+ break;
1127
+ }
1128
+
1129
+ echo '</div>';
1130
+
1131
+ ?>
1132
+ <script type="text/javascript">
1133
+ jQuery(document).ready(function($) {
1134
+ function check_<?php echo $id; ?>_custom() {
1135
+ var custom = $('#<?php echo $id; ?>').val();
1136
+ if (custom == 'custom') {
1137
+ $( '#<?php echo $custom_id; ?>').show();
1138
+ } else {
1139
+ $( '#<?php echo $custom_id; ?>').hide();
1140
+ }
1141
+ }
1142
+
1143
+ check_<?php echo $id; ?>_custom();
1144
+
1145
+ $( '#<?php echo $id; ?>' ).change(function() {
1146
+ check_<?php echo $id; ?>_custom();
1147
+ });
1148
+
1149
+ });
1150
+ </script>
1151
+ <?php
1152
+ }
1153
+
1154
+ // Displays option description.
1155
+ if ( isset( $args['description'] ) ) {
1156
+ printf( '<p class="description">%s</p>', $args['description'] );
1157
+ }
1158
+
1159
+ }
1160
+
1161
+ /**
1162
+ * Displays a radio settings field
1163
+ *
1164
+ * @param array $args settings field args
1165
+ */
1166
+ public function radio_element_callback( $args ) {
1167
+ $menu = $args['menu'];
1168
+ $id = $args['id'];
1169
+
1170
+ $options = get_option( $menu );
1171
+
1172
+ if ( isset( $options[$id] ) ) {
1173
+ $current = $options[$id];
1174
+ } else {
1175
+ $current = isset( $args['default'] ) ? $args['default'] : '';
1176
+ }
1177
+
1178
+ $html = '';
1179
+ foreach ( $args['options'] as $key => $label ) {
1180
+ $html .= sprintf( '<input type="radio" class="radio" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s]" value="%3$s"%4$s />', $menu, $id, $key, checked( $current, $key, false ) );
1181
+ $html .= sprintf( '<label for="%1$s[%2$s][%3$s]"> %4$s</label><br>', $menu, $id, $key, $label);
1182
+ }
1183
+
1184
+ // Displays option description.
1185
+ if ( isset( $args['description'] ) ) {
1186
+ $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
1187
+ }
1188
+
1189
+ echo $html;
1190
+ }
1191
+
1192
+ /**
1193
+ * Media upload callback.
1194
+ *
1195
+ * @param array $args Field arguments.
1196
+ *
1197
+ * @return string Media upload button & preview.
1198
+ */
1199
+ public function media_upload_callback( $args ) {
1200
+ $menu = $args['menu'];
1201
+ $id = $args['id'];
1202
+ $options = get_option( $menu );
1203
+
1204
+ if ( isset( $options[$id] ) ) {
1205
+ $current = $options[$id];
1206
+ } else {
1207
+ $current = isset( $args['default'] ) ? $args['default'] : '';
1208
+ }
1209
+
1210
+ $uploader_title = $args['uploader_title'];
1211
+ $uploader_button_text = $args['uploader_button_text'];
1212
+ $remove_button_text = $args['remove_button_text'];
1213
+
1214
+ $html = '';
1215
+ if( !empty($current) ) {
1216
+ $attachment = wp_get_attachment_image_src( $current, 'full', false );
1217
+
1218
+ $attachment_src = $attachment[0];
1219
+ $attachment_width = $attachment[1];
1220
+ $attachment_height = $attachment[2];
1221
+
1222
+ $attachment_resolution = round($attachment_height/(3/2.54));
1223
+
1224
+ $html .= sprintf('<img src="%1$s" style="display:block" id="img-%4$s"/>', $attachment_src, $attachment_width, $attachment_height, $id );
1225
+ $html .= '<div class="attachment-resolution"><p class="description">'.__('Image resolution').': '.$attachment_resolution.'dpi (default height = 3cm)</p></div>';
1226
+ $html .= sprintf('<span class="button wpo_remove_image_button" data-input_id="%1$s">%2$s</span>', $id, $remove_button_text );
1227
+ }
1228
+
1229
+ $html .= sprintf( '<input id="%1$s" name="%2$s[%1$s]" type="hidden" value="%3$s" />', $id, $menu, $current );
1230
+
1231
+ $html .= sprintf( '<span class="button wpo_upload_image_button %4$s" data-uploader_title="%1$s" data-uploader_button_text="%2$s" data-remove_button_text="%3$s" data-input_id="%4$s">%2$s</span>', $uploader_title, $uploader_button_text, $remove_button_text, $id );
1232
+
1233
+ // Displays option description.
1234
+ if ( isset( $args['description'] ) ) {
1235
+ $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
1236
+ }
1237
+
1238
+ echo $html;
1239
+ }
1240
+
1241
+ /**
1242
+ * Invoice number formatting callback.
1243
+ *
1244
+ * @param array $args Field arguments.
1245
+ *
1246
+ * @return string Media upload button & preview.
1247
+ */
1248
+ public function invoice_number_formatting_callback( $args ) {
1249
+ $menu = $args['menu'];
1250
+ $fields = $args['fields'];
1251
+ $options = get_option( $menu );
1252
+
1253
+ echo '<table>';
1254
+ foreach ($fields as $key => $field) {
1255
+ $id = $args['id'] . '_' . $key;
1256
+
1257
+ if ( isset( $options[$id] ) ) {
1258
+ $current = $options[$id];
1259
+ } else {
1260
+ $current = '';
1261
+ }
1262
+
1263
+ $title = $field['title'];
1264
+ $size = $field['size'];
1265
+ $description = isset( $field['description'] ) ? '<span style="font-style:italic;">'.$field['description'].'</span>' : '';
1266
+
1267
+ echo '<tr>';
1268
+ printf( '<td style="padding:0 1em 0 0; ">%1$s:</td><td style="padding:0;"><input type="text" id="%2$s" name="%3$s[%2$s]" value="%4$s" size="%5$s"/></td><td style="padding:0 0 0 1em;">%6$s</td>', $title, $id, $menu, $current, $size, $description );
1269
+ echo '</tr>';
1270
+ }
1271
+ echo '</table>';
1272
+
1273
+
1274
+ // Displays option description.
1275
+ if ( isset( $args['description'] ) ) {
1276
+ printf( '<p class="description">%s</p>', $args['description'] );
1277
+ }
1278
+
1279
+ // echo $html;
1280
+ }
1281
+
1282
+
1283
+ /**
1284
+ * Template select element callback.
1285
+ *
1286
+ * @param array $args Field arguments.
1287
+ *
1288
+ * @return string Select field.
1289
+ */
1290
+ public function template_select_element_callback( $args ) {
1291
+ $menu = $args['menu'];
1292
+ $id = $args['id'];
1293
+
1294
+ $options = get_option( $menu );
1295
+
1296
+ if ( isset( $options[$id] ) ) {
1297
+ $current = $options[$id];
1298
+ } else {
1299
+ $current = isset( $args['default'] ) ? $args['default'] : '';
1300
+ }
1301
+
1302
+ $html = sprintf( '<select id="%1$s" name="%2$s[%1$s]">', $id, $menu );
1303
+
1304
+ // backwards compatible template path (1.4.4+ uses relative paths instead of absolute)
1305
+ if (strpos($current, ABSPATH) !== false) {
1306
+ // check if folder exists, then strip site base path.
1307
+ if ( file_exists( $current ) ) {
1308
+ $current = str_replace( ABSPATH, '', $current );
1309
+ }
1310
+ }
1311
+
1312
+ foreach ( $args['options'] as $key => $label ) {
1313
+ $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $current, $key, false ), $label );
1314
+ }
1315
+
1316
+ $html .= '</select>';
1317
+
1318
+ // Displays option description.
1319
+ if ( isset( $args['description'] ) ) {
1320
+ $html .= sprintf( '<p class="description">%s</p>', $args['description'] );
1321
+ }
1322
+
1323
+ echo $html;
1324
+
1325
+ }
1326
+
1327
+ /**
1328
+ * Section null callback.
1329
+ *
1330
+ * @return void.
1331
+ */
1332
+ public function section_options_callback() {
1333
+ }
1334
+
1335
+ /**
1336
+ * Debug section callback.
1337
+ *
1338
+ * @return void.
1339
+ */
1340
+ public function debug_section() {
1341
+ _e( '<b>Warning!</b> The settings below are meant for debugging/development only. Do not use them on a live website!' , 'wpo_wcpdf' );
1342
+ }
1343
+
1344
+ /**
1345
+ * Custom fields section callback.
1346
+ *
1347
+ * @return void.
1348
+ */
1349
+ public function custom_fields_section() {
1350
+ _e( 'These are used for the (optional) footer columns in the <em>Modern (Premium)</em> template, but can also be used for other elements in your custom template' , 'wpo_wcpdf' );
1351
+ }
1352
+
1353
+ /**
1354
+ * Validate options.
1355
+ *
1356
+ * @param array $input options to valid.
1357
+ *
1358
+ * @return array validated options.
1359
+ */
1360
+ public function validate_options( $input ) {
1361
+ // Create our array for storing the validated options.
1362
+ $output = array();
1363
+
1364
+ if (empty($input) || !is_array($input)) {
1365
+ return $input;
1366
+ }
1367
+
1368
+ // Loop through each of the incoming options.
1369
+ foreach ( $input as $key => $value ) {
1370
+
1371
+ // Check to see if the current option has a value. If so, process it.
1372
+ if ( isset( $input[$key] ) ) {
1373
+ if ( is_array( $input[$key] ) ) {
1374
+ foreach ( $input[$key] as $sub_key => $sub_value ) {
1375
+ $output[$key][$sub_key] = $input[$key][$sub_key];
1376
+ }
1377
+ } else {
1378
+ $output[$key] = $input[$key];
1379
+ }
1380
+ }
1381
+ }
1382
+
1383
+ // Return the array processing any additional functions filtered by this action.
1384
+ return apply_filters( 'wpo_wcpdf_validate_input', $output, $input );
1385
+ }
1386
+
1387
+ /**
1388
+ * List templates in plugin folder, theme folder & child theme folder
1389
+ * @return array template path => template name
1390
+ */
1391
+ public function find_templates() {
1392
+ global $wpo_wcpdf;
1393
+ $installed_templates = array();
1394
+
1395
+ // get base paths
1396
+ $template_paths = array (
1397
+ // note the order: child-theme before theme, so that array_unique filters out parent doubles
1398
+ 'default' => $wpo_wcpdf->export->template_default_base_path,
1399
+ 'child-theme' => get_stylesheet_directory() . '/' . $wpo_wcpdf->export->template_base_path,
1400
+ 'theme' => get_template_directory() . '/' . $wpo_wcpdf->export->template_base_path,
1401
+ );
1402
+
1403
+ $template_paths = apply_filters( 'wpo_wcpdf_template_paths', $template_paths );
1404
+
1405
+ foreach ($template_paths as $template_source => $template_path) {
1406
+ $dirs = (array) glob( $template_path . '*' , GLOB_ONLYDIR);
1407
+
1408
+ foreach ($dirs as $dir) {
1409
+ if ( file_exists($dir."/invoice.php") && file_exists($dir."/packing-slip.php"))
1410
+ // we're stripping abspath to make the plugin settings more portable
1411
+ $installed_templates[ str_replace( ABSPATH, '', $dir )] = basename($dir);
1412
+ }
1413
+ }
1414
+
1415
+ // remove parent doubles
1416
+ $installed_templates = array_unique($installed_templates);
1417
+
1418
+ if (empty($installed_templates)) {
1419
+ // fallback to Simple template for servers with glob() disabled
1420
+ $simple_template_path = str_replace( ABSPATH, '', $template_paths['default'] . 'Simple' );
1421
+ $installed_templates[$simple_template_path] = 'Simple';
1422
+ }
1423
+
1424
+ return apply_filters( 'wpo_wcpdf_templates', $installed_templates );
1425
+ }
1426
+
1427
+ } // end class WooCommerce_PDF_Invoices_Settings
1428
+
1429
  } // end class_exists
includes/class-wcpdf-writepanels.php CHANGED
@@ -1,363 +1,370 @@
1
- <?php
2
-
3
- /**
4
- * Writepanel class
5
- */
6
- if ( !class_exists( 'WooCommerce_PDF_Invoices_Writepanels' ) ) {
7
-
8
- class WooCommerce_PDF_Invoices_Writepanels {
9
- public $bulk_actions;
10
-
11
- /**
12
- * Constructor
13
- */
14
- public function __construct() {
15
- $this->general_settings = get_option('wpo_wcpdf_general_settings');
16
- $this->template_settings = get_option('wpo_wcpdf_template_settings');
17
-
18
- add_action( 'woocommerce_admin_order_actions_end', array( $this, 'add_listing_actions' ) );
19
- add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_invoice_number_column' ), 999 );
20
- add_action( 'manage_shop_order_posts_custom_column', array( $this, 'invoice_number_column_data' ), 2 );
21
- add_action( 'add_meta_boxes_shop_order', array( $this, 'add_meta_boxes' ) );
22
- add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'my_account_pdf_link' ), 10, 2 );
23
- add_action( 'admin_print_scripts', array( $this, 'add_scripts' ) );
24
- add_action( 'admin_print_styles', array( $this, 'add_styles' ) );
25
- add_action( 'admin_footer', array( $this, 'bulk_actions' ) );
26
-
27
- add_action( 'save_post', array( $this,'save_invoice_number_date' ) );
28
-
29
- add_filter( 'woocommerce_shop_order_search_fields', array( $this, 'search_fields' ) );
30
-
31
- $this->bulk_actions = array(
32
- 'invoice' => __( 'PDF Invoices', 'wpo_wcpdf' ),
33
- 'packing-slip' => __( 'PDF Packing Slips', 'wpo_wcpdf' ),
34
- );
35
- }
36
-
37
- /**
38
- * Add the styles
39
- */
40
- public function add_styles() {
41
- if( $this->is_order_edit_page() ) {
42
- wp_enqueue_style( 'thickbox' );
43
-
44
- wp_enqueue_style(
45
- 'wpo-wcpdf',
46
- WooCommerce_PDF_Invoices::$plugin_url . 'css/style.css',
47
- array(),
48
- WooCommerce_PDF_Invoices::$version
49
- );
50
-
51
- if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) {
52
- // WC 2.1 or newer (MP6) is used: bigger buttons
53
- wp_enqueue_style(
54
- 'wpo-wcpdf-buttons',
55
- WooCommerce_PDF_Invoices::$plugin_url . 'css/style-buttons.css',
56
- array(),
57
- WooCommerce_PDF_Invoices::$version
58
- );
59
- } else {
60
- // legacy WC 2.0 styles
61
- wp_enqueue_style(
62
- 'wpo-wcpdf-buttons',
63
- WooCommerce_PDF_Invoices::$plugin_url . 'css/style-buttons-wc20.css',
64
- array(),
65
- WooCommerce_PDF_Invoices::$version
66
- );
67
- }
68
- }
69
- }
70
-
71
- /**
72
- * Add the scripts
73
- */
74
- public function add_scripts() {
75
- if( $this->is_order_edit_page() ) {
76
- wp_enqueue_script(
77
- 'wpo-wcpdf',
78
- WooCommerce_PDF_Invoices::$plugin_url . 'js/script.js',
79
- array( 'jquery' ),
80
- WooCommerce_PDF_Invoices::$version
81
- );
82
- wp_localize_script(
83
- 'wpo-wcpdf',
84
- 'wpo_wcpdf_ajax',
85
- array(
86
- // 'ajaxurl' => add_query_arg( 'action', 'generate_wpo_wcpdf', admin_url( 'admin-ajax.php' ) ), // URL to WordPress ajax handling page
87
- 'ajaxurl' => admin_url( 'admin-ajax.php' ), // URL to WordPress ajax handling page
88
- 'nonce' => wp_create_nonce('generate_wpo_wcpdf'),
89
- 'bulk_actions' => array_keys( apply_filters( 'wpo_wcpdf_bulk_actions', $this->bulk_actions ) ),
90
- )
91
- );
92
- }
93
- }
94
-
95
- /**
96
- * Is order page
97
- */
98
- public function is_order_edit_page() {
99
- global $post_type;
100
- if( $post_type == 'shop_order' ) {
101
- return true;
102
- } else {
103
- return false;
104
- }
105
- }
106
-
107
- /**
108
- * Add PDF actions to the orders listing
109
- */
110
- public function add_listing_actions( $order ) {
111
- // do not show buttons for trashed orders
112
- if ( $order->status == 'trash' ) {
113
- return;
114
- }
115
-
116
- $listing_actions = array(
117
- 'invoice' => array (
118
- 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . $order->id ), 'generate_wpo_wcpdf' ),
119
- 'img' => WooCommerce_PDF_Invoices::$plugin_url . 'images/invoice.png',
120
- 'alt' => __( 'PDF Invoice', 'wpo_wcpdf' ),
121
- ),
122
- 'packing-slip' => array (
123
- 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=packing-slip&order_ids=' . $order->id ), 'generate_wpo_wcpdf' ),
124
- 'img' => WooCommerce_PDF_Invoices::$plugin_url . 'images/packing-slip.png',
125
- 'alt' => __( 'PDF Packing Slip', 'wpo_wcpdf' ),
126
- ),
127
- );
128
-
129
- $listing_actions = apply_filters( 'wpo_wcpdf_listing_actions', $listing_actions, $order );
130
-
131
- foreach ($listing_actions as $action => $data) {
132
- ?>
133
- <a href="<?php echo $data['url']; ?>" class="button tips wpo_wcpdf <?php echo $action; ?>" target="_blank" alt="<?php echo $data['alt']; ?>" data-tip="<?php echo $data['alt']; ?>">
134
- <img src="<?php echo $data['img']; ?>" alt="<?php echo $data['alt']; ?>" width="16">
135
- </a>
136
- <?php
137
- }
138
- }
139
-
140
- /**
141
- * Create additional Shop Order column for Invoice Numbers
142
- * @param array $columns shop order columns
143
- */
144
- public function add_invoice_number_column( $columns ) {
145
- // Check user setting
146
- if ( !isset($this->general_settings['invoice_number_column'] ) ) {
147
- return $columns;
148
- }
149
-
150
- // put the column after the Status column
151
- $new_columns = array_slice($columns, 0, 2, true) +
152
- array( 'pdf_invoice_number' => __( 'Invoice Number', 'wpo_wcpdf' ) ) +
153
- array_slice($columns, 2, count($columns) - 1, true) ;
154
- return $new_columns;
155
- }
156
-
157
- /**
158
- * Display Invoice Number in Shop Order column (if available)
159
- * @param string $column column slug
160
- */
161
- public function invoice_number_column_data( $column ) {
162
- global $post, $the_order, $wpo_wcpdf;
163
-
164
- if ( $column == 'pdf_invoice_number' ) {
165
- if ( empty( $the_order ) || $the_order->id != $post->ID ) {
166
- $order = new WC_Order( $post->ID );
167
- echo $wpo_wcpdf->export->get_invoice_number( $order->id );
168
- do_action( 'wcpdf_invoice_number_column_end', $order );
169
- } else {
170
- echo $wpo_wcpdf->export->get_invoice_number( $the_order->id );
171
- do_action( 'wcpdf_invoice_number_column_end', $the_order );
172
- }
173
- }
174
- }
175
-
176
- /**
177
- * Display download link on My Account page
178
- */
179
- public function my_account_pdf_link( $actions, $order ) {
180
- $pdf_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . $order->id . '&my-account'), 'generate_wpo_wcpdf' );
181
-
182
- // check my account button settings
183
- if (isset($this->general_settings['my_account_buttons'])) {
184
- switch ($this->general_settings['my_account_buttons']) {
185
- case 'available':
186
- $invoice_allowed = get_post_meta($order->id,'_wcpdf_invoice_exists',true);
187
- break;
188
- case 'always':
189
- $invoice_allowed = true;
190
- break;
191
- case 'never':
192
- $invoice_allowed = false;
193
- break;
194
- case 'custom':
195
- if ( isset( $this->general_settings['my_account_restrict'] ) && in_array( $order->status, array_keys( $this->general_settings['my_account_restrict'] ) ) ) {
196
- $invoice_allowed = true;
197
- } else {
198
- $invoice_allowed = false;
199
- }
200
- break;
201
- }
202
- } else {
203
- // backwards compatibility
204
- $invoice_allowed = get_post_meta($order->id,'_wcpdf_invoice_exists',true);
205
- }
206
-
207
- // Check if invoice has been created already or if status allows download (filter your own array of allowed statuses)
208
- if ( $invoice_allowed || in_array($order->status, apply_filters( 'wpo_wcpdf_myaccount_allowed_order_statuses', array() ) ) ) {
209
- $actions['invoice'] = array(
210
- 'url' => $pdf_url,
211
- 'name' => apply_filters( 'wpo_wcpdf_myaccount_button_text', __( 'Download invoice (PDF)', 'wpo_wcpdf' ) )
212
- );
213
- }
214
-
215
- return apply_filters( 'wpo_wcpdf_myaccount_actions', $actions, $order );
216
- }
217
-
218
- /**
219
- * Add the meta box on the single order page
220
- */
221
- public function add_meta_boxes() {
222
- // create PDF buttons
223
- add_meta_box(
224
- 'wpo_wcpdf-box',
225
- __( 'Create PDF', 'wpo_wcpdf' ),
226
- array( $this, 'sidebar_box_content' ),
227
- 'shop_order',
228
- 'side',
229
- 'default'
230
- );
231
-
232
- // Invoice number & date
233
- add_meta_box(
234
- 'wpo_wcpdf-data-input-box',
235
- __( 'PDF Invoice data', 'wpo_wcpdf' ),
236
- array( $this, 'data_input_box_content' ),
237
- 'shop_order',
238
- 'normal',
239
- 'default'
240
- );
241
- }
242
-
243
- /**
244
- * Create the meta box content on the single order page
245
- */
246
- public function sidebar_box_content( $post ) {
247
- global $post_id;
248
-
249
- $meta_actions = array(
250
- 'invoice' => array (
251
- 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . $post_id ), 'generate_wpo_wcpdf' ),
252
- 'alt' => esc_attr__( 'PDF Invoice', 'wpo_wcpdf' ),
253
- 'title' => __( 'PDF Invoice', 'wpo_wcpdf' ),
254
- ),
255
- 'packing-slip' => array (
256
- 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=packing-slip&order_ids=' . $post_id ), 'generate_wpo_wcpdf' ),
257
- 'alt' => esc_attr__( 'PDF Packing Slip', 'wpo_wcpdf' ),
258
- 'title' => __( 'PDF Packing Slip', 'wpo_wcpdf' ),
259
- ),
260
- );
261
-
262
- $meta_actions = apply_filters( 'wpo_wcpdf_meta_box_actions', $meta_actions, $post_id );
263
-
264
- ?>
265
- <ul class="wpo_wcpdf-actions">
266
- <?php
267
- foreach ($meta_actions as $action => $data) {
268
- printf('<li><a href="%1$s" class="button" target="_blank" alt="%2$s">%3$s</a></li>', $data['url'], $data['alt'],$data['title']);
269
- }
270
- ?>
271
- </ul>
272
- <?php
273
- }
274
-
275
- /**
276
- * Add metabox for invoice number & date
277
- */
278
- public function data_input_box_content ( $post ) {
279
- $invoice_exists = get_post_meta( $post->ID, '_wcpdf_invoice_exists', true );
280
- $invoice_number = get_post_meta($post->ID,'_wcpdf_invoice_number',true);
281
- $invoice_date = get_post_meta($post->ID,'_wcpdf_invoice_date',true);
282
-
283
- do_action( 'wpo_wcpdf_meta_box_start', $post->ID );
284
-
285
- ?>
286
- <h4><?php _e( 'Invoice', 'wpo_wcpdf' ) ?></h4>
287
- <p class="form-field _wcpdf_invoice_number_field ">
288
- <label for="_wcpdf_invoice_number"><?php _e( 'Invoice Number (unformatted!)', 'wpo_wcpdf' ); ?>:</label>
289
- <?php if (!empty($invoice_exists)) : ?>
290
- <input type="text" class="short" style="" name="_wcpdf_invoice_number" id="_wcpdf_invoice_number" value="<?php echo $invoice_number ?>">
291
- <?php else : ?>
292
- <input type="text" class="short" style="" name="" id="_wcpdf_invoice_number" value="" disabled="disabled" >
293
- <?php endif; ?>
294
- </p>
295
- <p class="form-field form-field-wide">
296
- <label for="wcpdf_invoice_date"><?php _e( 'Invoice Date:', 'wpo_wcpdf' ); ?></label>
297
- <?php if (!empty($invoice_exists)) : ?>
298
- <input type="text" class="date-picker-field" name="wcpdf_invoice_date" id="wcpdf_invoice_date" maxlength="10" value="<?php echo date_i18n( 'Y-m-d', strtotime( $invoice_date ) ); ?>" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />@<input type="text" class="hour" placeholder="<?php _e( 'h', 'woocommerce' ) ?>" name="wcpdf_invoice_date_hour" id="wcpdf_invoice_date_hour" maxlength="2" size="2" value="<?php echo date_i18n( 'H', strtotime( $invoice_date ) ); ?>" pattern="\-?\d+(\.\d{0,})?" />:<input type="text" class="minute" placeholder="<?php _e( 'm', 'woocommerce' ) ?>" name="wcpdf_invoice_date_minute" id="wcpdf_invoice_date_minute" maxlength="2" size="2" value="<?php echo date_i18n( 'i', strtotime( $invoice_date ) ); ?>" pattern="\-?\d+(\.\d{0,})?" />
299
- <?php else : ?>
300
- <input type="text" class="date-picker-field" id="wcpdf_invoice_date" maxlength="10" disabled="disabled" >@<input type="text" class="hour" id="wcpdf_invoice_date_hour" maxlength="2" size="2" disabled="disabled" />:<input type="text" class="minute" id="wcpdf_invoice_date_minute" maxlength="2" size="2" disabled="disabled" />
301
- <?php endif; ?>
302
- </p>
303
- <?php
304
-
305
- do_action( 'wpo_wcpdf_meta_box_end', $post->ID );
306
- }
307
-
308
- /**
309
- * Add actions to menu
310
- */
311
- public function bulk_actions() {
312
- global $post_type;
313
- $bulk_actions = apply_filters( 'wpo_wcpdf_bulk_actions', $this->bulk_actions );
314
-
315
- if ( 'shop_order' == $post_type ) {
316
- ?>
317
- <script type="text/javascript">
318
- jQuery(document).ready(function() {
319
- <?php foreach ($bulk_actions as $action => $title) { ?>
320
- jQuery('<option>').val('<?php echo $action; ?>').html('<?php echo esc_attr( $title ); ?>').appendTo("select[name='action'], select[name='action2']");
321
- <?php } ?>
322
- });
323
- </script>
324
- <?php
325
- }
326
- }
327
-
328
- /**
329
- * Save invoice number
330
- */
331
- public function save_invoice_number_date($post_id) {
332
- global $post_type;
333
- if( $post_type == 'shop_order' ) {
334
- if ( isset($_POST['_wcpdf_invoice_number']) ) {
335
- update_post_meta( $post_id, '_wcpdf_invoice_number', stripslashes( $_POST['_wcpdf_invoice_number'] ));
336
- }
337
-
338
- if ( isset($_POST['wcpdf_invoice_date']) ) {
339
- if ( empty($_POST['wcpdf_invoice_date']) ) {
340
- delete_post_meta( $post_id, '_wcpdf_invoice_date' );
341
- } else {
342
- $invoice_date = strtotime( $_POST['wcpdf_invoice_date'] . ' ' . (int) $_POST['wcpdf_invoice_date_hour'] . ':' . (int) $_POST['wcpdf_invoice_date_minute'] . ':00' );
343
- $invoice_date = date_i18n( 'Y-m-d H:i:s', $invoice_date );
344
- update_post_meta( $post_id, '_wcpdf_invoice_date', $invoice_date );
345
- }
346
- }
347
-
348
- if ( empty($_POST['wcpdf_invoice_date']) && empty($_POST['wcpdf_invoice_number'])) {
349
- delete_post_meta( $post_id, '_wcpdf_invoice_exists' );
350
- }
351
- }
352
- }
353
-
354
- /**
355
- * Add invoice number to order search scope
356
- */
357
- public function search_fields ( $custom_fields ) {
358
- $custom_fields[] = '_wcpdf_invoice_number';
359
- $custom_fields[] = '_wcpdf_formatted_invoice_number';
360
- return $custom_fields;
361
- }
362
- }
 
 
 
 
 
 
 
363
  }
1
+ <?php
2
+
3
+ /**
4
+ * Writepanel class
5
+ */
6
+ if ( !class_exists( 'WooCommerce_PDF_Invoices_Writepanels' ) ) {
7
+
8
+ class WooCommerce_PDF_Invoices_Writepanels {
9
+ public $bulk_actions;
10
+
11
+ /**
12
+ * Constructor
13
+ */
14
+ public function __construct() {
15
+ $this->general_settings = get_option('wpo_wcpdf_general_settings');
16
+ $this->template_settings = get_option('wpo_wcpdf_template_settings');
17
+
18
+ add_action( 'woocommerce_admin_order_actions_end', array( $this, 'add_listing_actions' ) );
19
+ add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_invoice_number_column' ), 999 );
20
+ add_action( 'manage_shop_order_posts_custom_column', array( $this, 'invoice_number_column_data' ), 2 );
21
+ add_action( 'add_meta_boxes_shop_order', array( $this, 'add_meta_boxes' ) );
22
+ add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'my_account_pdf_link' ), 10, 2 );
23
+ add_action( 'admin_print_scripts', array( $this, 'add_scripts' ) );
24
+ add_action( 'admin_print_styles', array( $this, 'add_styles' ) );
25
+ add_action( 'admin_footer', array( $this, 'bulk_actions' ) );
26
+
27
+ add_action( 'save_post', array( $this,'save_invoice_number_date' ) );
28
+
29
+ add_filter( 'woocommerce_shop_order_search_fields', array( $this, 'search_fields' ) );
30
+
31
+ $this->bulk_actions = array(
32
+ 'invoice' => __( 'PDF Invoices', 'wpo_wcpdf' ),
33
+ 'packing-slip' => __( 'PDF Packing Slips', 'wpo_wcpdf' ),
34
+ );
35
+ }
36
+
37
+ /**
38
+ * Add the styles
39
+ */
40
+ public function add_styles() {
41
+ if( $this->is_order_edit_page() ) {
42
+ wp_enqueue_style( 'thickbox' );
43
+
44
+ wp_enqueue_style(
45
+ 'wpo-wcpdf',
46
+ WooCommerce_PDF_Invoices::$plugin_url . 'css/style.css',
47
+ array(),
48
+ WooCommerce_PDF_Invoices::$version
49
+ );
50
+
51
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) {
52
+ // WC 2.1 or newer (MP6) is used: bigger buttons
53
+ wp_enqueue_style(
54
+ 'wpo-wcpdf-buttons',
55
+ WooCommerce_PDF_Invoices::$plugin_url . 'css/style-buttons.css',
56
+ array(),
57
+ WooCommerce_PDF_Invoices::$version
58
+ );
59
+ } else {
60
+ // legacy WC 2.0 styles
61
+ wp_enqueue_style(
62
+ 'wpo-wcpdf-buttons',
63
+ WooCommerce_PDF_Invoices::$plugin_url . 'css/style-buttons-wc20.css',
64
+ array(),
65
+ WooCommerce_PDF_Invoices::$version
66
+ );
67
+ }
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Add the scripts
73
+ */
74
+ public function add_scripts() {
75
+ if( $this->is_order_edit_page() ) {
76
+ wp_enqueue_script(
77
+ 'wpo-wcpdf',
78
+ WooCommerce_PDF_Invoices::$plugin_url . 'js/script.js',
79
+ array( 'jquery' ),
80
+ WooCommerce_PDF_Invoices::$version
81
+ );
82
+ wp_localize_script(
83
+ 'wpo-wcpdf',
84
+ 'wpo_wcpdf_ajax',
85
+ array(
86
+ // 'ajaxurl' => add_query_arg( 'action', 'generate_wpo_wcpdf', admin_url( 'admin-ajax.php' ) ), // URL to WordPress ajax handling page
87
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ), // URL to WordPress ajax handling page
88
+ 'nonce' => wp_create_nonce('generate_wpo_wcpdf'),
89
+ 'bulk_actions' => array_keys( apply_filters( 'wpo_wcpdf_bulk_actions', $this->bulk_actions ) ),
90
+ )
91
+ );
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Is order page
97
+ */
98
+ public function is_order_edit_page() {
99
+ global $post_type;
100
+ if( $post_type == 'shop_order' ) {
101
+ return true;
102
+ } else {
103
+ return false;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Add PDF actions to the orders listing
109
+ */
110
+ public function add_listing_actions( $order ) {
111
+ // do not show buttons for trashed orders
112
+ if ( $order->status == 'trash' ) {
113
+ return;
114
+ }
115
+
116
+ $listing_actions = array(
117
+ 'invoice' => array (
118
+ 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . $order->id ), 'generate_wpo_wcpdf' ),
119
+ 'img' => WooCommerce_PDF_Invoices::$plugin_url . 'images/invoice.png',
120
+ 'alt' => __( 'PDF Invoice', 'wpo_wcpdf' ),
121
+ ),
122
+ 'packing-slip' => array (
123
+ 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=packing-slip&order_ids=' . $order->id ), 'generate_wpo_wcpdf' ),
124
+ 'img' => WooCommerce_PDF_Invoices::$plugin_url . 'images/packing-slip.png',
125
+ 'alt' => __( 'PDF Packing Slip', 'wpo_wcpdf' ),
126
+ ),
127
+ );
128
+
129
+ $listing_actions = apply_filters( 'wpo_wcpdf_listing_actions', $listing_actions, $order );
130
+
131
+ foreach ($listing_actions as $action => $data) {
132
+ ?>
133
+ <a href="<?php echo $data['url']; ?>" class="button tips wpo_wcpdf <?php echo $action; ?>" target="_blank" alt="<?php echo $data['alt']; ?>" data-tip="<?php echo $data['alt']; ?>">
134
+ <img src="<?php echo $data['img']; ?>" alt="<?php echo $data['alt']; ?>" width="16">
135
+ </a>
136
+ <?php
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Create additional Shop Order column for Invoice Numbers
142
+ * @param array $columns shop order columns
143
+ */
144
+ public function add_invoice_number_column( $columns ) {
145
+ // Check user setting
146
+ if ( !isset($this->general_settings['invoice_number_column'] ) ) {
147
+ return $columns;
148
+ }
149
+
150
+ // put the column after the Status column
151
+ $new_columns = array_slice($columns, 0, 2, true) +
152
+ array( 'pdf_invoice_number' => __( 'Invoice Number', 'wpo_wcpdf' ) ) +
153
+ array_slice($columns, 2, count($columns) - 1, true) ;
154
+ return $new_columns;
155
+ }
156
+
157
+ /**
158
+ * Display Invoice Number in Shop Order column (if available)
159
+ * @param string $column column slug
160
+ */
161
+ public function invoice_number_column_data( $column ) {
162
+ global $post, $the_order, $wpo_wcpdf;
163
+
164
+ if ( $column == 'pdf_invoice_number' ) {
165
+ if ( empty( $the_order ) || $the_order->id != $post->ID ) {
166
+ $order = new WC_Order( $post->ID );
167
+ echo $wpo_wcpdf->export->get_invoice_number( $order->id );
168
+ do_action( 'wcpdf_invoice_number_column_end', $order );
169
+ } else {
170
+ echo $wpo_wcpdf->export->get_invoice_number( $the_order->id );
171
+ do_action( 'wcpdf_invoice_number_column_end', $the_order );
172
+ }
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Display download link on My Account page
178
+ */
179
+ public function my_account_pdf_link( $actions, $order ) {
180
+ $pdf_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . $order->id . '&my-account'), 'generate_wpo_wcpdf' );
181
+
182
+ // check my account button settings
183
+ if (isset($this->general_settings['my_account_buttons'])) {
184
+ switch ($this->general_settings['my_account_buttons']) {
185
+ case 'available':
186
+ $invoice_allowed = get_post_meta($order->id,'_wcpdf_invoice_exists',true);
187
+ break;
188
+ case 'always':
189
+ $invoice_allowed = true;
190
+ break;
191
+ case 'never':
192
+ $invoice_allowed = false;
193
+ break;
194
+ case 'custom':
195
+ if ( isset( $this->general_settings['my_account_restrict'] ) && in_array( $order->status, array_keys( $this->general_settings['my_account_restrict'] ) ) ) {
196
+ $invoice_allowed = true;
197
+ } else {
198
+ $invoice_allowed = false;
199
+ }
200
+ break;
201
+ }
202
+ } else {
203
+ // backwards compatibility
204
+ $invoice_allowed = get_post_meta($order->id,'_wcpdf_invoice_exists',true);
205
+ }
206
+
207
+ // Check if invoice has been created already or if status allows download (filter your own array of allowed statuses)
208
+ if ( $invoice_allowed || in_array($order->status, apply_filters( 'wpo_wcpdf_myaccount_allowed_order_statuses', array() ) ) ) {
209
+ $actions['invoice'] = array(
210
+ 'url' => $pdf_url,
211
+ 'name' => apply_filters( 'wpo_wcpdf_myaccount_button_text', __( 'Download invoice (PDF)', 'wpo_wcpdf' ) )
212
+ );
213
+ }
214
+
215
+ return apply_filters( 'wpo_wcpdf_myaccount_actions', $actions, $order );
216
+ }
217
+
218
+ /**
219
+ * Add the meta box on the single order page
220
+ */
221
+ public function add_meta_boxes() {
222
+ // create PDF buttons
223
+ add_meta_box(
224
+ 'wpo_wcpdf-box',
225
+ __( 'Create PDF', 'wpo_wcpdf' ),
226
+ array( $this, 'sidebar_box_content' ),
227
+ 'shop_order',
228
+ 'side',
229
+ 'default'
230
+ );
231
+
232
+ // Invoice number & date
233
+ add_meta_box(
234
+ 'wpo_wcpdf-data-input-box',
235
+ __( 'PDF Invoice data', 'wpo_wcpdf' ),
236
+ array( $this, 'data_input_box_content' ),
237
+ 'shop_order',
238
+ 'normal',
239
+ 'default'
240
+ );
241
+ }
242
+
243
+ /**
244
+ * Create the meta box content on the single order page
245
+ */
246
+ public function sidebar_box_content( $post ) {
247
+ global $post_id;
248
+
249
+ $meta_actions = array(
250
+ 'invoice' => array (
251
+ 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . $post_id ), 'generate_wpo_wcpdf' ),
252
+ 'alt' => esc_attr__( 'PDF Invoice', 'wpo_wcpdf' ),
253
+ 'title' => __( 'PDF Invoice', 'wpo_wcpdf' ),
254
+ ),
255
+ 'packing-slip' => array (
256
+ 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=packing-slip&order_ids=' . $post_id ), 'generate_wpo_wcpdf' ),
257
+ 'alt' => esc_attr__( 'PDF Packing Slip', 'wpo_wcpdf' ),
258
+ 'title' => __( 'PDF Packing Slip', 'wpo_wcpdf' ),
259
+ ),
260
+ );
261
+
262
+ $meta_actions = apply_filters( 'wpo_wcpdf_meta_box_actions', $meta_actions, $post_id );
263
+
264
+ ?>
265
+ <ul class="wpo_wcpdf-actions">
266
+ <?php
267
+ foreach ($meta_actions as $action => $data) {
268
+ printf('<li><a href="%1$s" class="button" target="_blank" alt="%2$s">%3$s</a></li>', $data['url'], $data['alt'],$data['title']);
269
+ }
270
+ ?>
271
+ </ul>
272
+ <?php
273
+ }
274
+
275
+ /**
276
+ * Add metabox for invoice number & date
277
+ */
278
+ public function data_input_box_content ( $post ) {
279
+ $invoice_exists = get_post_meta( $post->ID, '_wcpdf_invoice_exists', true );
280
+ $invoice_number = get_post_meta($post->ID,'_wcpdf_invoice_number',true);
281
+ $invoice_date = get_post_meta($post->ID,'_wcpdf_invoice_date',true);
282
+
283
+ do_action( 'wpo_wcpdf_meta_box_start', $post->ID );
284
+
285
+ ?>
286
+ <h4><?php _e( 'Invoice', 'wpo_wcpdf' ) ?></h4>
287
+ <p class="form-field _wcpdf_invoice_number_field ">
288
+ <label for="_wcpdf_invoice_number"><?php _e( 'Invoice Number (unformatted!)', 'wpo_wcpdf' ); ?>:</label>
289
+ <?php if (!empty($invoice_exists)) : ?>
290
+ <input type="text" class="short" style="" name="_wcpdf_invoice_number" id="_wcpdf_invoice_number" value="<?php echo $invoice_number ?>">
291
+ <?php else : ?>
292
+ <input type="text" class="short" style="" name="_wcpdf_invoice_number" id="_wcpdf_invoice_number" value="<?php echo $invoice_number ?>" disabled="disabled" >
293
+ <?php endif; ?>
294
+ </p>
295
+ <p class="form-field form-field-wide">
296
+ <label for="wcpdf_invoice_date"><?php _e( 'Invoice Date:', 'wpo_wcpdf' ); ?></label>
297
+ <?php if (!empty($invoice_exists)) : ?>
298
+ <input type="text" class="date-picker-field" name="wcpdf_invoice_date" id="wcpdf_invoice_date" maxlength="10" value="<?php echo date_i18n( 'Y-m-d', strtotime( $invoice_date ) ); ?>" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />@<input type="text" class="hour" placeholder="<?php _e( 'h', 'woocommerce' ) ?>" name="wcpdf_invoice_date_hour" id="wcpdf_invoice_date_hour" maxlength="2" size="2" value="<?php echo date_i18n( 'H', strtotime( $invoice_date ) ); ?>" pattern="([01]?[0-9]{1}|2[0-3]{1})" />:<input type="text" class="minute" placeholder="<?php _e( 'm', 'woocommerce' ) ?>" name="wcpdf_invoice_date_minute" id="wcpdf_invoice_date_minute" maxlength="2" size="2" value="<?php echo date_i18n( 'i', strtotime( $invoice_date ) ); ?>" pattern="[0-5]{1}[0-9]{1}" />
299
+ <?php else : ?>
300
+ <input type="text" class="date-picker-field" name="wcpdf_invoice_date" id="wcpdf_invoice_date" maxlength="10" disabled="disabled" value="" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />@<input type="text" class="hour" disabled="disabled" placeholder="<?php _e( 'h', 'woocommerce' ) ?>" name="wcpdf_invoice_date_hour" id="wcpdf_invoice_date_hour" maxlength="2" size="2" value="" pattern="([01]?[0-9]{1}|2[0-3]{1})" />:<input type="text" class="minute" placeholder="<?php _e( 'm', 'woocommerce' ) ?>" name="wcpdf_invoice_date_minute" id="wcpdf_invoice_date_minute" maxlength="2" size="2" value="" pattern="[0-5]{1}[0-9]{1}" disabled="disabled" />
301
+ <?php endif; ?>
302
+ </p>
303
+ <?php
304
+
305
+ do_action( 'wpo_wcpdf_meta_box_end', $post->ID );
306
+ }
307
+
308
+ /**
309
+ * Add actions to menu
310
+ */
311
+ public function bulk_actions() {
312
+ global $post_type;
313
+ $bulk_actions = apply_filters( 'wpo_wcpdf_bulk_actions', $this->bulk_actions );
314
+
315
+ if ( 'shop_order' == $post_type ) {
316
+ ?>
317
+ <script type="text/javascript">
318
+ jQuery(document).ready(function() {
319
+ <?php foreach ($bulk_actions as $action => $title) { ?>
320
+ jQuery('<option>').val('<?php echo $action; ?>').html('<?php echo esc_attr( $title ); ?>').appendTo("select[name='action'], select[name='action2']");
321
+ <?php } ?>
322
+ });
323
+ </script>
324
+ <?php
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Save invoice number
330
+ */
331
+ public function save_invoice_number_date($post_id) {
332
+ global $post_type;
333
+ if( $post_type == 'shop_order' ) {
334
+ if ( isset($_POST['_wcpdf_invoice_number']) ) {
335
+ update_post_meta( $post_id, '_wcpdf_invoice_number', stripslashes( $_POST['_wcpdf_invoice_number'] ));
336
+ update_post_meta( $post_id, '_wcpdf_invoice_exists', 1 );
337
+ }
338
+
339
+ if ( isset($_POST['wcpdf_invoice_date']) ) {
340
+ if ( empty($_POST['wcpdf_invoice_date']) ) {
341
+ delete_post_meta( $post_id, '_wcpdf_invoice_date' );
342
+ } else {
343
+ $invoice_date = strtotime( $_POST['wcpdf_invoice_date'] . ' ' . (int) $_POST['wcpdf_invoice_date_hour'] . ':' . (int) $_POST['wcpdf_invoice_date_minute'] . ':00' );
344
+ $invoice_date = date_i18n( 'Y-m-d H:i:s', $invoice_date );
345
+ update_post_meta( $post_id, '_wcpdf_invoice_date', $invoice_date );
346
+ update_post_meta( $post_id, '_wcpdf_invoice_exists', 1 );
347
+ }
348
+ }
349
+
350
+ if (empty($_POST['wcpdf_invoice_date']) && isset($_POST['_wcpdf_invoice_number'])) {
351
+ $invoice_date = date_i18n( 'Y-m-d H:i:s', time() );
352
+ update_post_meta( $post_id, '_wcpdf_invoice_date', $invoice_date );
353
+ }
354
+
355
+ if ( empty($_POST['wcpdf_invoice_date']) && empty($_POST['_wcpdf_invoice_number'])) {
356
+ delete_post_meta( $post_id, '_wcpdf_invoice_exists' );
357
+ }
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Add invoice number to order search scope
363
+ */
364
+ public function search_fields ( $custom_fields ) {
365
+ $custom_fields[] = '_wcpdf_invoice_number';
366
+ $custom_fields[] = '_wcpdf_formatted_invoice_number';
367
+ return $custom_fields;
368
+ }
369
+ }
370
  }
js/script.js CHANGED
@@ -1,34 +1,43 @@
1
- jQuery(document).ready(function($) {
2
- $("#doaction, #doaction2").click(function (event) {
3
- var actionselected = $(this).attr("id").substr(2);
4
- var action = $('select[name="' + actionselected + '"]').val();
5
- if ( $.inArray(action, wpo_wcpdf_ajax.bulk_actions) !== -1 ) {
6
- event.preventDefault();
7
- var template = action;
8
- var checked = [];
9
- $('tbody th.check-column input[type="checkbox"]:checked').each(
10
- function() {
11
- checked.push($(this).val());
12
- }
13
- );
14
-
15
- if (!checked.length) {
16
- alert('You have to select order(s) first!');
17
- return;
18
- }
19
-
20
- var order_ids=checked.join('x');
21
-
22
- if (wpo_wcpdf_ajax.ajaxurl.indexOf("?") != -1) {
23
- url = wpo_wcpdf_ajax.ajaxurl+'&action=generate_wpo_wcpdf&template_type='+template+'&order_ids='+order_ids+'&_wpnonce='+wpo_wcpdf_ajax.nonce;
24
- } else {
25
- url = wpo_wcpdf_ajax.ajaxurl+'?action=generate_wpo_wcpdf&template_type='+template+'&order_ids='+order_ids+'&_wpnonce='+wpo_wcpdf_ajax.nonce;
26
- }
27
-
28
- window.open(url,'_blank');
29
- }
30
- });
31
-
32
- $('#wpo_wcpdf-data-input-box').insertAfter('#woocommerce-order-data');
33
- });
34
-
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($) {
2
+ $("#doaction, #doaction2").click(function (event) {
3
+ var actionselected = $(this).attr("id").substr(2);
4
+ var action = $('select[name="' + actionselected + '"]').val();
5
+ if ( $.inArray(action, wpo_wcpdf_ajax.bulk_actions) !== -1 ) {
6
+ event.preventDefault();
7
+ var template = action;
8
+ var checked = [];
9
+ $('tbody th.check-column input[type="checkbox"]:checked').each(
10
+ function() {
11
+ checked.push($(this).val());
12
+ }
13
+ );
14
+
15
+ if (!checked.length) {
16
+ alert('You have to select order(s) first!');
17
+ return;
18
+ }
19
+
20
+ var order_ids=checked.join('x');
21
+
22
+ if (wpo_wcpdf_ajax.ajaxurl.indexOf("?") != -1) {
23
+ url = wpo_wcpdf_ajax.ajaxurl+'&action=generate_wpo_wcpdf&template_type='+template+'&order_ids='+order_ids+'&_wpnonce='+wpo_wcpdf_ajax.nonce;
24
+ } else {
25
+ url = wpo_wcpdf_ajax.ajaxurl+'?action=generate_wpo_wcpdf&template_type='+template+'&order_ids='+order_ids+'&_wpnonce='+wpo_wcpdf_ajax.nonce;
26
+ }
27
+
28
+ window.open(url,'_blank');
29
+ }
30
+ });
31
+
32
+ $('#wpo_wcpdf-data-input-box').insertAfter('#woocommerce-order-data');
33
+
34
+ // enable invoice number edit if user initiated
35
+ $('#wpo_wcpdf-data-input-box label').click(function (event) {
36
+ input = $(this).attr('for');
37
+ $('#'+input).prop('disabled', false);
38
+ });
39
+ $( "#_wcpdf_invoice_number" ).on( "click", function() {
40
+ console.log( this );
41
+ });
42
+ });
43
+
lib/dompdf/dompdf.php CHANGED
@@ -1,289 +1,289 @@
1
- <?php
2
- /**
3
- * Command line utility to use dompdf.
4
- * Can also be used with HTTP GET parameters
5
- *
6
- * @package dompdf
7
- * @link http://dompdf.github.com/
8
- * @author Benj Carson <benjcarson@digitaljunkies.ca>
9
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
10
- */
11
-
12
- /**
13
- * Display command line usage
14
- */
15
- function dompdf_usage() {
16
- $default_paper_size = DOMPDF_DEFAULT_PAPER_SIZE;
17
-
18
- echo <<<EOD
19
-
20
- Usage: {$_SERVER["argv"][0]} [options] html_file
21
-
22
- html_file can be a filename, a url if fopen_wrappers are enabled, or the '-' character to read from standard input.
23
-
24
- Options:
25
- -h Show this message
26
- -l List available paper sizes
27
- -p size Paper size; something like 'letter', 'A4', 'legal', etc.
28
- The default is '$default_paper_size'
29
- -o orientation Either 'portrait' or 'landscape'. Default is 'portrait'
30
- -b path Set the 'document root' of the html_file.
31
- Relative urls (for stylesheets) are resolved using this directory.
32
- Default is the directory of html_file.
33
- -f file The output filename. Default is the input [html_file].pdf
34
- -v Verbose: display html parsing warnings and file not found errors.
35
- -d Very verbose: display oodles of debugging output: every frame
36
- in the tree printed to stdout.
37
- -t Comma separated list of debugging types (page-break,reflow,split)
38
-
39
- EOD;
40
- exit;
41
- }
42
-
43
- /**
44
- * Parses command line options
45
- *
46
- * @return array The command line options
47
- */
48
- function getoptions() {
49
-
50
- $opts = array();
51
-
52
- if ( $_SERVER["argc"] == 1 )
53
- return $opts;
54
-
55
- $i = 1;
56
- while ($i < $_SERVER["argc"]) {
57
-
58
- switch ($_SERVER["argv"][$i]) {
59
-
60
- case "--help":
61
- case "-h":
62
- $opts["h"] = true;
63
- $i++;
64
- break;
65
-
66
- case "-l":
67
- $opts["l"] = true;
68
- $i++;
69
- break;
70
-
71
- case "-p":
72
- if ( !isset($_SERVER["argv"][$i+1]) )
73
- die("-p switch requires a size parameter\n");
74
- $opts["p"] = $_SERVER["argv"][$i+1];
75
- $i += 2;
76
- break;
77
-
78
- case "-o":
79
- if ( !isset($_SERVER["argv"][$i+1]) )
80
- die("-o switch requires an orientation parameter\n");
81
- $opts["o"] = $_SERVER["argv"][$i+1];
82
- $i += 2;
83
- break;
84
-
85
- case "-b":
86
- if ( !isset($_SERVER["argv"][$i+1]) )
87
- die("-b switch requires a path parameter\n");
88
- $opts["b"] = $_SERVER["argv"][$i+1];
89
- $i += 2;
90
- break;
91
-
92
- case "-f":
93
- if ( !isset($_SERVER["argv"][$i+1]) )
94
- die("-f switch requires a filename parameter\n");
95
- $opts["f"] = $_SERVER["argv"][$i+1];
96
- $i += 2;
97
- break;
98
-
99
- case "-v":
100
- $opts["v"] = true;
101
- $i++;
102
- break;
103
-
104
- case "-d":
105
- $opts["d"] = true;
106
- $i++;
107
- break;
108
-
109
- case "-t":
110
- if ( !isset($_SERVER['argv'][$i + 1]) )
111
- die("-t switch requires a comma separated list of types\n");
112
- $opts["t"] = $_SERVER['argv'][$i+1];
113
- $i += 2;
114
- break;
115
-
116
- default:
117
- $opts["filename"] = $_SERVER["argv"][$i];
118
- $i++;
119
- break;
120
- }
121
-
122
- }
123
- return $opts;
124
- }
125
-
126
- require_once("dompdf_config.inc.php");
127
- global $_dompdf_show_warnings, $_dompdf_debug, $_DOMPDF_DEBUG_TYPES;
128
-
129
- $sapi = php_sapi_name();
130
- $options = array();
131
-
132
- switch ( $sapi ) {
133
-
134
- case "cli":
135
-
136
- $opts = getoptions();
137
-
138
- if ( isset($opts["h"]) || (!isset($opts["filename"]) && !isset($opts["l"])) ) {
139
- dompdf_usage();
140
- exit;
141
- }
142
-
143
- if ( isset($opts["l"]) ) {
144
- echo "\nUnderstood paper sizes:\n";
145
-
146
- foreach (array_keys(CPDF_Adapter::$PAPER_SIZES) as $size)
147
- echo " " . mb_strtoupper($size) . "\n";
148
- exit;
149
- }
150
- $file = $opts["filename"];
151
-
152
- if ( isset($opts["p"]) )
153
- $paper = $opts["p"];
154
- else
155
- $paper = DOMPDF_DEFAULT_PAPER_SIZE;
156
-
157
- if ( isset($opts["o"]) )
158
- $orientation = $opts["o"];
159
- else
160
- $orientation = "portrait";
161
-
162
- if ( isset($opts["b"]) )
163
- $base_path = $opts["b"];
164
-
165
- if ( isset($opts["f"]) )
166
- $outfile = $opts["f"];
167
- else {
168
- if ( $file === "-" )
169
- $outfile = "dompdf_out.pdf";
170
- else
171
- $outfile = str_ireplace(array(".html", ".htm", ".php"), "", $file) . ".pdf";
172
- }
173
-
174
- if ( isset($opts["v"]) )
175
- $_dompdf_show_warnings = true;
176
-
177
- if ( isset($opts["d"]) ) {
178
- $_dompdf_show_warnings = true;
179
- $_dompdf_debug = true;
180
- }
181
-
182
- if ( isset($opts['t']) ) {
183
- $arr = split(',',$opts['t']);
184
- $types = array();
185
- foreach ($arr as $type)
186
- $types[ trim($type) ] = 1;
187
- $_DOMPDF_DEBUG_TYPES = $types;
188
- }
189
-
190
- $save_file = true;
191
-
192
- break;
193
-
194
- default:
195
-
196
- if ( isset($_GET["input_file"]) )
197
- $file = rawurldecode($_GET["input_file"]);
198
- else
199
- throw new DOMPDF_Exception("An input file is required (i.e. input_file _GET variable).");
200
-
201
- if ( isset($_GET["paper"]) )
202
- $paper = rawurldecode($_GET["paper"]);
203
- else
204
- $paper = DOMPDF_DEFAULT_PAPER_SIZE;
205
-
206
- if ( isset($_GET["orientation"]) )
207
- $orientation = rawurldecode($_GET["orientation"]);
208
- else
209
- $orientation = "portrait";
210
-
211
- if ( isset($_GET["base_path"]) ) {
212
- $base_path = rawurldecode($_GET["base_path"]);
213
- $file = $base_path . $file; # Set the input file
214
- }
215
-
216
- if ( isset($_GET["options"]) ) {
217
- $options = $_GET["options"];
218
- }
219
-
220
- $file_parts = explode_url($file);
221
-
222
- /* Check to see if the input file is local and, if so, that the base path falls within that specified by DOMDPF_CHROOT */
223
- if(($file_parts['protocol'] == '' || $file_parts['protocol'] === 'file://')) {
224
- $file = realpath($file);
225
- if ( strpos($file, DOMPDF_CHROOT) !== 0 ) {
226
- throw new DOMPDF_Exception("Permission denied on $file. The file could not be found under the directory specified by DOMPDF_CHROOT.");
227
- }
228
- }
229
-
230
- if($file_parts['protocol'] === 'php://') {
231
- throw new DOMPDF_Exception("Permission denied on $file. This script does not allow PHP streams.");
232
- }
233
-
234
- $outfile = "dompdf_out.pdf"; # Don't allow them to set the output file
235
- $save_file = false; # Don't save the file
236
-
237
- break;
238
- }
239
-
240
- $dompdf = new DOMPDF();
241
-
242
- if ( $file === "-" ) {
243
- $str = "";
244
- while ( !feof(STDIN) )
245
- $str .= fread(STDIN, 4096);
246
-
247
- $dompdf->load_html($str);
248
-
249
- } else
250
- $dompdf->load_html_file($file);
251
-
252
- if ( isset($base_path) ) {
253
- $dompdf->set_base_path($base_path);
254
- }
255
-
256
- $dompdf->set_paper($paper, $orientation);
257
-
258
- $dompdf->render();
259
-
260
- if ( $_dompdf_show_warnings ) {
261
- global $_dompdf_warnings;
262
- foreach ($_dompdf_warnings as $msg)
263
- echo $msg . "\n";
264
- echo $dompdf->get_canvas()->get_cpdf()->messages;
265
- flush();
266
- }
267
-
268
- if ( $save_file ) {
269
- // if ( !is_writable($outfile) )
270
- // throw new DOMPDF_Exception("'$outfile' is not writable.");
271
- if ( strtolower(DOMPDF_PDF_BACKEND) === "gd" )
272
- $outfile = str_replace(".pdf", ".png", $outfile);
273
-
274
- list($proto, $host, $path, $file) = explode_url($outfile);
275
- if ( $proto != "" ) // i.e. not file://
276
- $outfile = $file; // just save it locally, FIXME? could save it like wget: ./host/basepath/file
277
-
278
- $outfile = realpath(dirname($outfile)) . DIRECTORY_SEPARATOR . basename($outfile);
279
-
280
- if ( strpos($outfile, DOMPDF_CHROOT) !== 0 )
281
- throw new DOMPDF_Exception("Permission denied.");
282
-
283
- file_put_contents($outfile, $dompdf->output( array("compress" => 0) ));
284
- exit(0);
285
- }
286
-
287
- if ( !headers_sent() ) {
288
- $dompdf->stream($outfile, $options);
289
- }
1
+ <?php
2
+ /**
3
+ * Command line utility to use dompdf.
4
+ * Can also be used with HTTP GET parameters
5
+ *
6
+ * @package dompdf
7
+ * @link http://dompdf.github.com/
8
+ * @author Benj Carson <benjcarson@digitaljunkies.ca>
9
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
10
+ */
11
+
12
+ /**
13
+ * Display command line usage
14
+ */
15
+ function dompdf_usage() {
16
+ $default_paper_size = DOMPDF_DEFAULT_PAPER_SIZE;
17
+
18
+ echo <<<EOD
19
+
20
+ Usage: {$_SERVER["argv"][0]} [options] html_file
21
+
22
+ html_file can be a filename, a url if fopen_wrappers are enabled, or the '-' character to read from standard input.
23
+
24
+ Options:
25
+ -h Show this message
26
+ -l List available paper sizes
27
+ -p size Paper size; something like 'letter', 'A4', 'legal', etc.
28
+ The default is '$default_paper_size'
29
+ -o orientation Either 'portrait' or 'landscape'. Default is 'portrait'
30
+ -b path Set the 'document root' of the html_file.
31
+ Relative urls (for stylesheets) are resolved using this directory.
32
+ Default is the directory of html_file.
33
+ -f file The output filename. Default is the input [html_file].pdf
34
+ -v Verbose: display html parsing warnings and file not found errors.
35
+ -d Very verbose: display oodles of debugging output: every frame
36
+ in the tree printed to stdout.
37
+ -t Comma separated list of debugging types (page-break,reflow,split)
38
+
39
+ EOD;
40
+ exit;
41
+ }
42
+
43
+ /**
44
+ * Parses command line options
45
+ *
46
+ * @return array The command line options
47
+ */
48
+ function getoptions() {
49
+
50
+ $opts = array();
51
+
52
+ if ( $_SERVER["argc"] == 1 )
53
+ return $opts;
54
+
55
+ $i = 1;
56
+ while ($i < $_SERVER["argc"]) {
57
+
58
+ switch ($_SERVER["argv"][$i]) {
59
+
60
+ case "--help":
61
+ case "-h":
62
+ $opts["h"] = true;
63
+ $i++;
64
+ break;
65
+
66
+ case "-l":
67
+ $opts["l"] = true;
68
+ $i++;
69
+ break;
70
+
71
+ case "-p":
72
+ if ( !isset($_SERVER["argv"][$i+1]) )
73
+ die("-p switch requires a size parameter\n");
74
+ $opts["p"] = $_SERVER["argv"][$i+1];
75
+ $i += 2;
76
+ break;
77
+
78
+ case "-o":
79
+ if ( !isset($_SERVER["argv"][$i+1]) )
80
+ die("-o switch requires an orientation parameter\n");
81
+ $opts["o"] = $_SERVER["argv"][$i+1];
82
+ $i += 2;
83
+ break;
84
+
85
+ case "-b":
86
+ if ( !isset($_SERVER["argv"][$i+1]) )
87
+ die("-b switch requires a path parameter\n");
88
+ $opts["b"] = $_SERVER["argv"][$i+1];
89
+ $i += 2;
90
+ break;
91
+
92
+ case "-f":
93
+ if ( !isset($_SERVER["argv"][$i+1]) )
94
+ die("-f switch requires a filename parameter\n");
95
+ $opts["f"] = $_SERVER["argv"][$i+1];
96
+ $i += 2;
97
+ break;
98
+
99
+ case "-v":
100
+ $opts["v"] = true;
101
+ $i++;
102
+ break;
103
+
104
+ case "-d":
105
+ $opts["d"] = true;
106
+ $i++;
107
+ break;
108
+
109
+ case "-t":
110
+ if ( !isset($_SERVER['argv'][$i + 1]) )
111
+ die("-t switch requires a comma separated list of types\n");
112
+ $opts["t"] = $_SERVER['argv'][$i+1];
113
+ $i += 2;
114
+ break;
115
+
116
+ default:
117
+ $opts["filename"] = $_SERVER["argv"][$i];
118
+ $i++;
119
+ break;
120
+ }
121
+
122
+ }
123
+ return $opts;
124
+ }
125
+
126
+ require_once("dompdf_config.inc.php");
127
+ global $_dompdf_show_warnings, $_dompdf_debug, $_DOMPDF_DEBUG_TYPES;
128
+
129
+ $sapi = php_sapi_name();
130
+ $options = array();
131
+
132
+ switch ( $sapi ) {
133
+
134
+ case "cli":
135
+
136
+ $opts = getoptions();
137
+
138
+ if ( isset($opts["h"]) || (!isset($opts["filename"]) && !isset($opts["l"])) ) {
139
+ dompdf_usage();
140
+ exit;
141
+ }
142
+
143
+ if ( isset($opts["l"]) ) {
144
+ echo "\nUnderstood paper sizes:\n";
145
+
146
+ foreach (array_keys(CPDF_Adapter::$PAPER_SIZES) as $size)
147
+ echo " " . mb_strtoupper($size) . "\n";
148
+ exit;
149
+ }
150
+ $file = $opts["filename"];
151
+
152
+ if ( isset($opts["p"]) )
153
+ $paper = $opts["p"];
154
+ else
155
+ $paper = DOMPDF_DEFAULT_PAPER_SIZE;
156
+
157
+ if ( isset($opts["o"]) )
158
+ $orientation = $opts["o"];
159
+ else
160
+ $orientation = "portrait";
161
+
162
+ if ( isset($opts["b"]) )
163
+ $base_path = $opts["b"];
164
+
165
+ if ( isset($opts["f"]) )
166
+ $outfile = $opts["f"];
167
+ else {
168
+ if ( $file === "-" )
169
+ $outfile = "dompdf_out.pdf";
170
+ else
171
+ $outfile = str_ireplace(array(".html", ".htm", ".php"), "", $file) . ".pdf";
172
+ }
173
+
174
+ if ( isset($opts["v"]) )
175
+ $_dompdf_show_warnings = true;
176
+
177
+ if ( isset($opts["d"]) ) {
178
+ $_dompdf_show_warnings = true;
179
+ $_dompdf_debug = true;
180
+ }
181
+
182
+ if ( isset($opts['t']) ) {
183
+ $arr = explode(',',$opts['t']);
184
+ $types = array();
185
+ foreach ($arr as $type)
186
+ $types[ trim($type) ] = 1;
187
+ $_DOMPDF_DEBUG_TYPES = $types;
188
+ }
189
+
190
+ $save_file = true;
191
+
192
+ break;
193
+
194
+ default:
195
+
196
+ if ( isset($_GET["input_file"]) )
197
+ $file = rawurldecode($_GET["input_file"]);
198
+ else
199
+ throw new DOMPDF_Exception("An input file is required (i.e. input_file _GET variable).");
200
+
201
+ if ( isset($_GET["paper"]) )
202
+ $paper = rawurldecode($_GET["paper"]);
203
+ else
204
+ $paper = DOMPDF_DEFAULT_PAPER_SIZE;
205
+
206
+ if ( isset($_GET["orientation"]) )
207
+ $orientation = rawurldecode($_GET["orientation"]);
208
+ else
209
+ $orientation = "portrait";
210
+
211
+ if ( isset($_GET["base_path"]) ) {
212
+ $base_path = rawurldecode($_GET["base_path"]);
213
+ $file = $base_path . $file; # Set the input file
214
+ }
215
+
216
+ if ( isset($_GET["options"]) ) {
217
+ $options = $_GET["options"];
218
+ }
219
+
220
+ $file_parts = explode_url($file);
221
+
222
+ /* Check to see if the input file is local and, if so, that the base path falls within that specified by DOMDPF_CHROOT */
223
+ if(($file_parts['protocol'] == '' || $file_parts['protocol'] === 'file://')) {
224
+ $file = realpath($file);
225
+ if ( strpos($file, DOMPDF_CHROOT) !== 0 ) {
226
+ throw new DOMPDF_Exception("Permission denied on $file. The file could not be found under the directory specified by DOMPDF_CHROOT.");
227
+ }
228
+ }
229
+
230
+ if($file_parts['protocol'] === 'php://') {
231
+ throw new DOMPDF_Exception("Permission denied on $file. This script does not allow PHP streams.");
232
+ }
233
+
234
+ $outfile = "dompdf_out.pdf"; # Don't allow them to set the output file
235
+ $save_file = false; # Don't save the file
236
+
237
+ break;
238
+ }
239
+
240
+ $dompdf = new DOMPDF();
241
+
242
+ if ( $file === "-" ) {
243
+ $str = "";
244
+ while ( !feof(STDIN) )
245
+ $str .= fread(STDIN, 4096);
246
+
247
+ $dompdf->load_html($str);
248
+
249
+ } else
250
+ $dompdf->load_html_file($file);
251
+
252
+ if ( isset($base_path) ) {
253
+ $dompdf->set_base_path($base_path);
254
+ }
255
+
256
+ $dompdf->set_paper($paper, $orientation);
257
+
258
+ $dompdf->render();
259
+
260
+ if ( $_dompdf_show_warnings ) {
261
+ global $_dompdf_warnings;
262
+ foreach ($_dompdf_warnings as $msg)
263
+ echo $msg . "\n";
264
+ echo $dompdf->get_canvas()->get_cpdf()->messages;
265
+ flush();
266
+ }
267
+
268
+ if ( $save_file ) {
269
+ // if ( !is_writable($outfile) )
270
+ // throw new DOMPDF_Exception("'$outfile' is not writable.");
271
+ if ( strtolower(DOMPDF_PDF_BACKEND) === "gd" )
272
+ $outfile = str_replace(".pdf", ".png", $outfile);
273
+
274
+ list($proto, $host, $path, $file) = explode_url($outfile);
275
+ if ( $proto != "" ) // i.e. not file://
276
+ $outfile = $file; // just save it locally, FIXME? could save it like wget: ./host/basepath/file
277
+
278
+ $outfile = realpath(dirname($outfile)) . DIRECTORY_SEPARATOR . basename($outfile);
279
+
280
+ if ( strpos($outfile, DOMPDF_CHROOT) !== 0 )
281
+ throw new DOMPDF_Exception("Permission denied.");
282
+
283
+ file_put_contents($outfile, $dompdf->output( array("compress" => 0) ));
284
+ exit(0);
285
+ }
286
+
287
+ if ( !headers_sent() ) {
288
+ $dompdf->stream($outfile, $options);
289
+ }
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: pomegranate
3
  Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice, packing slip, export, email, bulk, automatic
4
  Requires at least: 3.5
5
- Tested up to: 4.5
6
- Stable tag: 1.5.36
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -235,6 +235,14 @@ This usually only happens on batch actions. PDF creation is a memory intensive j
235
 
236
  == Changelog ==
237
 
 
 
 
 
 
 
 
 
238
  = 1.5.36 =
239
  * Translations: Fixed Romanian (incorrect "Factură Proforma" translation for "Invoice")
240
 
2
  Contributors: pomegranate
3
  Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice, packing slip, export, email, bulk, automatic
4
  Requires at least: 3.5
5
+ Tested up to: 4.6
6
+ Stable tag: 1.5.37
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
235
 
236
  == Changelog ==
237
 
238
+ = 1.5.37 =
239
+ * Feature: Added support for third party invoice numbers
240
+ * Feature: Enable pre-invoice number click-to-edit
241
+ * Fix: Review link for custom admins
242
+ * Fix: PHP7 compatibility
243
+ * Fix: Invoice date hour/minute pattern
244
+ * Tweak: Multisite WooCommerce check optimization
245
+
246
  = 1.5.36 =
247
  * Translations: Fixed Romanian (incorrect "Factură Proforma" translation for "Invoice")
248
 
woocommerce-pdf-invoices-packingslips.php CHANGED
@@ -3,7 +3,7 @@
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: 1.5.36
7
  * Author: Ewout Fernhout
8
  * Author URI: http://www.wpovernight.com
9
  * License: GPLv2 or later
@@ -33,7 +33,7 @@ if ( !class_exists( 'WooCommerce_PDF_Invoices' ) ) {
33
  self::$plugin_basename = plugin_basename(__FILE__);
34
  self::$plugin_url = plugin_dir_url(self::$plugin_basename);
35
  self::$plugin_path = trailingslashit(dirname(__FILE__));
36
- self::$version = '1.5.36';
37
 
38
  // load the localisation & classes
39
  add_action( 'plugins_loaded', array( $this, 'translations' ) ); // or use init?
@@ -104,7 +104,7 @@ if ( !class_exists( 'WooCommerce_PDF_Invoices' ) ) {
104
  */
105
  public function is_woocommerce_activated() {
106
  $blog_plugins = get_option( 'active_plugins', array() );
107
- $site_plugins = get_site_option( 'active_sitewide_plugins', array() );
108
 
109
  if ( in_array( 'woocommerce/woocommerce.php', $blog_plugins ) || isset( $site_plugins['woocommerce/woocommerce.php'] ) ) {
110
  return 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: 1.5.37
7
  * Author: Ewout Fernhout
8
  * Author URI: http://www.wpovernight.com
9
  * License: GPLv2 or later
33
  self::$plugin_basename = plugin_basename(__FILE__);
34
  self::$plugin_url = plugin_dir_url(self::$plugin_basename);
35
  self::$plugin_path = trailingslashit(dirname(__FILE__));
36
+ self::$version = '1.5.37';
37
 
38
  // load the localisation & classes
39
  add_action( 'plugins_loaded', array( $this, 'translations' ) ); // or use init?
104
  */
105
  public function is_woocommerce_activated() {
106
  $blog_plugins = get_option( 'active_plugins', array() );
107
+ $site_plugins = is_multisite() ? (array) maybe_unserialize( get_site_option('active_sitewide_plugins' ) ) : array();
108
 
109
  if ( in_array( 'woocommerce/woocommerce.php', $blog_plugins ) || isset( $site_plugins['woocommerce/woocommerce.php'] ) ) {
110
  return true;