Version Description
- Feature: Add support for Bedrock / alternative folder structures
- Dev: Filter for merged documents
- Fix: Better attributes fallback for product variations
Download this release
Release Info
Developer | pomegranate |
Plugin | WooCommerce PDF Invoices & Packing Slips |
Version | 2.0.8 |
Comparing to | |
See all releases |
Code changes from version 2.0.7 to 2.0.8
- assets/js/admin-script.js +4 -0
- includes/class-wcpdf-admin.php +48 -0
- includes/class-wcpdf-main.php +2 -2
- includes/class-wcpdf-pdf-maker.php +57 -57
- includes/class-wcpdf-settings-callbacks.php +503 -503
- includes/class-wcpdf-settings-debug.php +184 -184
- includes/class-wcpdf-settings-general.php +274 -269
- includes/class-wcpdf-settings.php +254 -248
- includes/compatibility/mb-string-compatibility.php +127 -127
- includes/documents/abstract-wcpdf-order-document-methods.php +17 -17
- includes/documents/abstract-wcpdf-order-document.php +676 -676
- includes/documents/class-wcpdf-bulk-document.php +124 -119
- includes/documents/class-wcpdf-invoice.php +352 -352
- includes/documents/class-wcpdf-sequential-number-store.php +165 -165
- readme.txt +613 -608
- woocommerce-pdf-invoices-packingslips.php +355 -355
assets/js/admin-script.js
CHANGED
@@ -28,4 +28,8 @@ jQuery( function( $ ) {
|
|
28 |
Â
}
|
29 |
Â
});
|
30 |
Â
});
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
31 |
Â
});
|
28 |
Â
}
|
29 |
Â
});
|
30 |
Â
});
|
31 |
+
$( '.wpo-wcpdf-review-notice' ).on( 'click', '.notice-dismiss', function( event ) {
|
32 |
+
event.preventDefault();
|
33 |
+
window.location.href = $( '.wpo-wcpdf-dismiss' ).attr('href');
|
34 |
+
});
|
35 |
Â
});
|
includes/class-wcpdf-admin.php
CHANGED
@@ -23,6 +23,54 @@ class Admin {
|
|
23 |
Â
|
24 |
Â
add_action( 'save_post', array( $this,'save_invoice_number_date' ) );
|
25 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
26 |
Â
}
|
27 |
Â
|
28 |
Â
/**
|
23 |
Â
|
24 |
Â
add_action( 'save_post', array( $this,'save_invoice_number_date' ) );
|
25 |
Â
|
26 |
+
add_action( 'admin_notices', array( $this, 'review_plugin_notice' ) );
|
27 |
+
// add_action( 'wpo_wcpdf_after_pdf', array( $this,'update_pdf_counter' ), 10, 2 );
|
28 |
+
}
|
29 |
+
|
30 |
+
// display review admin notice after 100 pdf downloads
|
31 |
+
public function review_plugin_notice() {
|
32 |
+
if ( $this->is_order_page() === false && !( isset( $_GET['page'] ) && $_GET['page'] == 'wpo_wcpdf_options_page' ) ) {
|
33 |
+
return;
|
34 |
+
}
|
35 |
+
|
36 |
+
if ( get_option( 'wpo_wcpdf_review_notice_dismissed' ) !== false ) {
|
37 |
+
return;
|
38 |
+
} else {
|
39 |
+
if ( isset( $_GET['wpo_wcpdf_dismis_review'] ) ) {
|
40 |
+
update_option( 'wpo_wcpdf_review_notice_dismissed', true );
|
41 |
+
return;
|
42 |
+
}
|
43 |
+
|
44 |
+
$invoice_count = $this->get_invoice_count();
|
45 |
+
if ( $invoice_count > 100 ) {
|
46 |
+
?>
|
47 |
+
<div class="notice notice-info is-dismissible wpo-wcpdf-review-notice">
|
48 |
+
<h3><?php _e( 'Wow, you have created more than 100 invoices with our plugin!', 'woocommerce-pdf-invoices-packing-slips' ); ?></h3>
|
49 |
+
<p><?php _e( 'It would mean a lot to us if you would quickly give our plugin a 5-star rating. Help us spread the word and boost our motivation!', 'woocommerce-pdf-invoices-packing-slips' ); ?></p>
|
50 |
+
<ul>
|
51 |
+
<li><a href="https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips/reviews/?rate=5#new-post" class="button"><?php _e( 'Yes you deserve it!', 'woocommerce-pdf-invoices-packing-slips' ); ?></span></a></li>
|
52 |
+
<li><a href="<?php echo esc_url( add_query_arg( 'wpo_wcpdf_dismis_review', true ) ); ?>" class="wpo-wcpdf-dismiss"><?php _e( 'Already did!', 'woocommerce-pdf-invoices-packing-slips' ); ?></a></li>
|
53 |
+
<li><a href="mailto:support@wpovernight.com?Subject=Here%20is%20how%20I%20think%20you%20can%20do%20better"><?php _e( 'Actually, I have a complaint...', 'woocommerce-pdf-invoices-packing-slips' ); ?></a></li>
|
54 |
+
</ul>
|
55 |
+
</div>
|
56 |
+
<!-- Hide extensions ad if this is shown -->
|
57 |
+
<style>.wcpdf-extensions-ad { display: none; }</style>
|
58 |
+
<?php
|
59 |
+
}
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
public function get_invoice_count() {
|
64 |
+
global $wpdb;
|
65 |
+
$invoice_count = $wpdb->get_var("SELECT count(*) FROM `wp_postmeta` WHERE `meta_key` = '_wcpdf_invoice_number'");
|
66 |
+
return (int) $invoice_count;
|
67 |
+
}
|
68 |
+
|
69 |
+
public function update_pdf_counter( $document_type, $document ) {
|
70 |
+
if ( in_array( $document_type, array('invoice','packing-slip') ) ) {
|
71 |
+
$pdf_count = (int) get_option( 'wpo_wcpdf_count_'.$document_type, 0 );
|
72 |
+
update_option( 'wpo_wcpdf_count_'.$document_type, $pdf_count + 1 );
|
73 |
+
}
|
74 |
Â
}
|
75 |
Â
|
76 |
Â
/**
|
includes/class-wcpdf-main.php
CHANGED
@@ -374,7 +374,7 @@ class Main {
|
|
374 |
Â
* Adds spans around placeholders to be able to make replacement (page count) and css (page number)
|
375 |
Â
*/
|
376 |
Â
public function format_page_number_placeholders ( $html, $document ) {
|
377 |
-
$html = str_replace('{{PAGE_COUNT}}', '<span class="pagecount"
|
378 |
Â
$html = str_replace('{{PAGE_NUM}}', '<span class="pagenum"></span>', $html );
|
379 |
Â
return $html;
|
380 |
Â
}
|
@@ -383,7 +383,7 @@ class Main {
|
|
383 |
Â
* Replace {{PAGE_COUNT}} placeholder with total page count
|
384 |
Â
*/
|
385 |
Â
public function page_number_replacements ( $dompdf, $html ) {
|
386 |
-
$placeholder = '
|
387 |
Â
// create placeholder version with ASCII 0 spaces (dompdf 0.8)
|
388 |
Â
$placeholder_0 = '';
|
389 |
Â
$placeholder_chars = str_split($placeholder);
|
374 |
Â
* Adds spans around placeholders to be able to make replacement (page count) and css (page number)
|
375 |
Â
*/
|
376 |
Â
public function format_page_number_placeholders ( $html, $document ) {
|
377 |
+
$html = str_replace('{{PAGE_COUNT}}', '<span class="pagecount">^C^</span>', $html);
|
378 |
Â
$html = str_replace('{{PAGE_NUM}}', '<span class="pagenum"></span>', $html );
|
379 |
Â
return $html;
|
380 |
Â
}
|
383 |
Â
* Replace {{PAGE_COUNT}} placeholder with total page count
|
384 |
Â
*/
|
385 |
Â
public function page_number_replacements ( $dompdf, $html ) {
|
386 |
+
$placeholder = '^C^';
|
387 |
Â
// create placeholder version with ASCII 0 spaces (dompdf 0.8)
|
388 |
Â
$placeholder_0 = '';
|
389 |
Â
$placeholder_chars = str_split($placeholder);
|
includes/class-wcpdf-pdf-maker.php
CHANGED
@@ -1,57 +1,57 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices;
|
3 |
-
|
4 |
-
use Dompdf\Dompdf;
|
5 |
-
use Dompdf\Options;
|
6 |
-
|
7 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
-
exit; // Exit if accessed directly
|
9 |
-
}
|
10 |
-
|
11 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\PDF_Maker' ) ) :
|
12 |
-
|
13 |
-
class PDF_Maker {
|
14 |
-
public $html;
|
15 |
-
public $settings;
|
16 |
-
|
17 |
-
public function __construct( $html, $settings = array() ) {
|
18 |
-
$this->html = $html;
|
19 |
-
|
20 |
-
$default_settings = array(
|
21 |
-
'paper_size' => 'A4',
|
22 |
-
'paper_orientation' => 'portrait',
|
23 |
-
'font_subsetting' => false,
|
24 |
-
);
|
25 |
-
$this->settings = $settings + $default_settings;
|
26 |
-
}
|
27 |
-
|
28 |
-
public function output() {
|
29 |
-
if ( empty( $this->html ) ) {
|
30 |
-
return;
|
31 |
-
}
|
32 |
-
|
33 |
-
require WPO_WCPDF()->plugin_path() . '/vendor/autoload.php';
|
34 |
-
|
35 |
-
// set options
|
36 |
-
$options = new Options();
|
37 |
-
$options->setdefaultFont( 'dejavu sans');
|
38 |
-
$options->setTempDir( WPO_WCPDF()->main->get_tmp_path('dompdf') );
|
39 |
-
$options->setLogOutputFile( WPO_WCPDF()->main->get_tmp_path('dompdf') . "/log.htm");
|
40 |
-
$options->setFontDir( WPO_WCPDF()->main->get_tmp_path('fonts') );
|
41 |
-
$options->setFontCache( WPO_WCPDF()->main->get_tmp_path('fonts') );
|
42 |
-
$options->setIsRemoteEnabled( true );
|
43 |
-
$options->setIsFontSubsettingEnabled( $this->settings['font_subsetting'] );
|
44 |
-
|
45 |
-
// instantiate and use the dompdf class
|
46 |
-
$dompdf = new Dompdf( $options );
|
47 |
-
$dompdf->loadHtml( $this->html );
|
48 |
-
$dompdf->setPaper( $this->settings['paper_size'], $this->settings['paper_orientation'] );
|
49 |
-
$dompdf = apply_filters( 'wpo_wcpdf_before_dompdf_render', $dompdf, $this->html );
|
50 |
-
$dompdf->render();
|
51 |
-
$dompdf = apply_filters( 'wpo_wcpdf_after_dompdf_render', $dompdf, $this->html );
|
52 |
-
|
53 |
-
return $dompdf->output();
|
54 |
-
}
|
55 |
-
}
|
56 |
-
|
57 |
-
endif; // class_exists
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices;
|
3 |
+
|
4 |
+
use Dompdf\Dompdf;
|
5 |
+
use Dompdf\Options;
|
6 |
+
|
7 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
+
exit; // Exit if accessed directly
|
9 |
+
}
|
10 |
+
|
11 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\PDF_Maker' ) ) :
|
12 |
+
|
13 |
+
class PDF_Maker {
|
14 |
+
public $html;
|
15 |
+
public $settings;
|
16 |
+
|
17 |
+
public function __construct( $html, $settings = array() ) {
|
18 |
+
$this->html = $html;
|
19 |
+
|
20 |
+
$default_settings = array(
|
21 |
+
'paper_size' => 'A4',
|
22 |
+
'paper_orientation' => 'portrait',
|
23 |
+
'font_subsetting' => false,
|
24 |
+
);
|
25 |
+
$this->settings = $settings + $default_settings;
|
26 |
+
}
|
27 |
+
|
28 |
+
public function output() {
|
29 |
+
if ( empty( $this->html ) ) {
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
|
33 |
+
require WPO_WCPDF()->plugin_path() . '/vendor/autoload.php';
|
34 |
+
|
35 |
+
// set options
|
36 |
+
$options = new Options();
|
37 |
+
$options->setdefaultFont( 'dejavu sans');
|
38 |
+
$options->setTempDir( WPO_WCPDF()->main->get_tmp_path('dompdf') );
|
39 |
+
$options->setLogOutputFile( WPO_WCPDF()->main->get_tmp_path('dompdf') . "/log.htm");
|
40 |
+
$options->setFontDir( WPO_WCPDF()->main->get_tmp_path('fonts') );
|
41 |
+
$options->setFontCache( WPO_WCPDF()->main->get_tmp_path('fonts') );
|
42 |
+
$options->setIsRemoteEnabled( true );
|
43 |
+
$options->setIsFontSubsettingEnabled( $this->settings['font_subsetting'] );
|
44 |
+
|
45 |
+
// instantiate and use the dompdf class
|
46 |
+
$dompdf = new Dompdf( $options );
|
47 |
+
$dompdf->loadHtml( $this->html );
|
48 |
+
$dompdf->setPaper( $this->settings['paper_size'], $this->settings['paper_orientation'] );
|
49 |
+
$dompdf = apply_filters( 'wpo_wcpdf_before_dompdf_render', $dompdf, $this->html );
|
50 |
+
$dompdf->render();
|
51 |
+
$dompdf = apply_filters( 'wpo_wcpdf_after_dompdf_render', $dompdf, $this->html );
|
52 |
+
|
53 |
+
return $dompdf->output();
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
endif; // class_exists
|
includes/class-wcpdf-settings-callbacks.php
CHANGED
@@ -1,504 +1,504 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices;
|
3 |
-
|
4 |
-
use WPO\WC\PDF_Invoices\Documents\Sequential_Number_Store;
|
5 |
-
|
6 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
7 |
-
exit; // Exit if accessed directly
|
8 |
-
}
|
9 |
-
|
10 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings_Callbacks' ) ) :
|
11 |
-
|
12 |
-
class Settings_Callbacks {
|
13 |
-
/**
|
14 |
-
* Section null callback.
|
15 |
-
*
|
16 |
-
* @return void.
|
17 |
-
*/
|
18 |
-
public function section() {
|
19 |
-
}
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Debug section callback.
|
23 |
-
*
|
24 |
-
* @return void.
|
25 |
-
*/
|
26 |
-
public function debug_section() {
|
27 |
-
_e( '<b>Warning!</b> The settings below are meant for debugging/development only. Do not use them on a live website!' , 'woocommerce-pdf-invoices-packing-slips' );
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Custom fields section callback.
|
32 |
-
*
|
33 |
-
* @return void.
|
34 |
-
*/
|
35 |
-
public function custom_fields_section() {
|
36 |
-
_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' , 'woocommerce-pdf-invoices-packing-slips' );
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Checkbox callback.
|
41 |
-
*
|
42 |
-
* args:
|
43 |
-
* option_name - name of the main option
|
44 |
-
* id - key of the setting
|
45 |
-
* value - value if not 1 (optional)
|
46 |
-
* default - default setting (optional)
|
47 |
-
* description - description (optional)
|
48 |
-
*
|
49 |
-
* @return void.
|
50 |
-
*/
|
51 |
-
public function checkbox( $args ) {
|
52 |
-
extract( $this->normalize_settings_args( $args ) );
|
53 |
-
|
54 |
-
// output checkbox
|
55 |
-
printf( '<input type="checkbox" id="%1$s" name="%2$s" value="%3$s"%4$s />', $id, $setting_name, $value, checked( $value, $current, false ) );
|
56 |
-
|
57 |
-
// output description.
|
58 |
-
if ( isset( $description ) ) {
|
59 |
-
printf( '<p class="description">%s</p>', $description );
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Text input callback.
|
65 |
-
*
|
66 |
-
* args:
|
67 |
-
* option_name - name of the main option
|
68 |
-
* id - key of the setting
|
69 |
-
* size - size of the text input (em)
|
70 |
-
* default - default setting (optional)
|
71 |
-
* description - description (optional)
|
72 |
-
* type - type (optional)
|
73 |
-
*
|
74 |
-
* @return void.
|
75 |
-
*/
|
76 |
-
public function text_input( $args ) {
|
77 |
-
extract( $this->normalize_settings_args( $args ) );
|
78 |
-
|
79 |
-
if (empty($type)) {
|
80 |
-
$type = 'text';
|
81 |
-
}
|
82 |
-
|
83 |
-
printf( '<input type="%1$s" id="%2$s" name="%3$s" value="%4$s" size="%5$s" placeholder="%6$s"/>', $type, $id, $setting_name, esc_attr( $current ), $size, $placeholder );
|
84 |
-
|
85 |
-
// output description.
|
86 |
-
if ( isset( $description ) ) {
|
87 |
-
printf( '<p class="description">%s</p>', $description );
|
88 |
-
}
|
89 |
-
}
|
90 |
-
|
91 |
-
// Single text option (not part of any settings array)
|
92 |
-
public function singular_text_element( $args ) {
|
93 |
-
$option_name = $args['option_name'];
|
94 |
-
$id = $args['id'];
|
95 |
-
$size = isset( $args['size'] ) ? $args['size'] : '25';
|
96 |
-
$class = isset( $args['translatable'] ) && $args['translatable'] === true ? 'translatable' : '';
|
97 |
-
|
98 |
-
$option = get_option( $option_name );
|
99 |
-
|
100 |
-
if ( isset( $option ) ) {
|
101 |
-
$current = $option;
|
102 |
-
} else {
|
103 |
-
$current = isset( $args['default'] ) ? $args['default'] : '';
|
104 |
-
}
|
105 |
-
|
106 |
-
$html = sprintf( '<input type="text" id="%1$s" name="%2$s" value="%3$s" size="%4$s" class="%5$s"/>', $id, $option_name, $current, $size, $class );
|
107 |
-
|
108 |
-
// Displays option description.
|
109 |
-
if ( isset( $args['description'] ) ) {
|
110 |
-
$html .= sprintf( '<p class="description">%s</p>', $args['description'] );
|
111 |
-
}
|
112 |
-
|
113 |
-
echo $html;
|
114 |
-
}
|
115 |
-
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Textarea callback.
|
119 |
-
*
|
120 |
-
* args:
|
121 |
-
* option_name - name of the main option
|
122 |
-
* id - key of the setting
|
123 |
-
* width - width of the text input (em)
|
124 |
-
* height - height of the text input (lines)
|
125 |
-
* default - default setting (optional)
|
126 |
-
* description - description (optional)
|
127 |
-
*
|
128 |
-
* @return void.
|
129 |
-
*/
|
130 |
-
public function textarea( $args ) {
|
131 |
-
extract( $this->normalize_settings_args( $args ) );
|
132 |
-
|
133 |
-
printf( '<textarea id="%1$s" name="%2$s" cols="%4$s" rows="%5$s" placeholder="%6$s"/>%3$s</textarea>', $id, $setting_name, esc_textarea( $current ), $width, $height, $placeholder );
|
134 |
-
|
135 |
-
// output description.
|
136 |
-
if ( isset( $description ) ) {
|
137 |
-
printf( '<p class="description">%s</p>', $description );
|
138 |
-
}
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Select element callback.
|
143 |
-
*
|
144 |
-
* @param array $args Field arguments.
|
145 |
-
*
|
146 |
-
* @return string Select field.
|
147 |
-
*/
|
148 |
-
public function select( $args ) {
|
149 |
-
extract( $this->normalize_settings_args( $args ) );
|
150 |
-
|
151 |
-
printf( '<select id="%1$s" name="%2$s">', $id, $setting_name );
|
152 |
-
|
153 |
-
foreach ( $options as $key => $label ) {
|
154 |
-
printf( '<option value="%s"%s>%s</option>', $key, selected( $current, $key, false ), $label );
|
155 |
-
}
|
156 |
-
|
157 |
-
echo '</select>';
|
158 |
-
|
159 |
-
if (isset($custom)) {
|
160 |
-
printf( '<div class="%1$s_custom custom">', $id );
|
161 |
-
|
162 |
-
if (is_callable( array( $this, $custom['type'] ) ) ) {
|
163 |
-
$this->{$custom['type']}( $custom['args'] );
|
164 |
-
}
|
165 |
-
echo '</div>';
|
166 |
-
?>
|
167 |
-
<script type="text/javascript">
|
168 |
-
jQuery(document).ready(function($) {
|
169 |
-
function check_<?php echo $id; ?>_custom() {
|
170 |
-
var custom = $('#<?php echo $id; ?>').val();
|
171 |
-
console.log(custom);
|
172 |
-
if (custom == 'custom') {
|
173 |
-
$( '.<?php echo $id; ?>_custom').show();
|
174 |
-
} else {
|
175 |
-
$( '.<?php echo $id; ?>_custom').hide();
|
176 |
-
}
|
177 |
-
}
|
178 |
-
|
179 |
-
check_<?php echo $id; ?>_custom();
|
180 |
-
|
181 |
-
$( '#<?php echo $id; ?>' ).change(function() {
|
182 |
-
check_<?php echo $id; ?>_custom();
|
183 |
-
});
|
184 |
-
|
185 |
-
});
|
186 |
-
</script>
|
187 |
-
<?php
|
188 |
-
}
|
189 |
-
|
190 |
-
// Displays option description.
|
191 |
-
if ( isset( $args['description'] ) ) {
|
192 |
-
printf( '<p class="description">%s</p>', $args['description'] );
|
193 |
-
}
|
194 |
-
|
195 |
-
}
|
196 |
-
|
197 |
-
public function radio_button( $args ) {
|
198 |
-
extract( $this->normalize_settings_args( $args ) );
|
199 |
-
|
200 |
-
foreach ( $options as $key => $label ) {
|
201 |
-
printf( '<input type="radio" class="radio" id="%1$s[%3$s]" name="%2$s" value="%3$s"%4$s />', $id, $setting_name, $key, checked( $current, $key, false ) );
|
202 |
-
printf( '<label for="%1$s[%3$s]"> %4$s</label><br>', $id, $setting_name, $key, $label);
|
203 |
-
}
|
204 |
-
|
205 |
-
|
206 |
-
// Displays option description.
|
207 |
-
if ( isset( $args['description'] ) ) {
|
208 |
-
printf( '<p class="description">%s</p>', $args['description'] );
|
209 |
-
}
|
210 |
-
|
211 |
-
}
|
212 |
-
|
213 |
-
/**
|
214 |
-
* Multiple text element callback.
|
215 |
-
* @param array $args Field arguments.
|
216 |
-
* @return string Text input field.
|
217 |
-
*/
|
218 |
-
public function multiple_text_input( $args ) {
|
219 |
-
extract( $this->normalize_settings_args( $args ) );
|
220 |
-
|
221 |
-
if (!empty($header)) {
|
222 |
-
echo "<p><strong>{$header}</strong>:</p>";
|
223 |
-
}
|
224 |
-
|
225 |
-
printf('<p class="%s multiple-text-input">', $id);
|
226 |
-
foreach ($fields as $name => $field) {
|
227 |
-
$size = $field['size'];
|
228 |
-
$placeholder = isset( $field['placeholder'] ) ? $field['placeholder'] : '';
|
229 |
-
|
230 |
-
if (isset($field['label_width'])) {
|
231 |
-
$style = sprintf( 'style="display:inline-block; width:%1$s;"', $field['label_width'] );
|
232 |
-
} else {
|
233 |
-
$style = '';
|
234 |
-
}
|
235 |
-
|
236 |
-
$description = isset( $field['description'] ) ? '<span style="font-style:italic;">'.$field['description'].'</span>' : '';
|
237 |
-
|
238 |
-
// output field label
|
239 |
-
if (isset($field['label'])) {
|
240 |
-
printf( '<label for="%1$s_%2$s" %3$s>%4$s:</label>', $id, $name, $style, $field['label'] );
|
241 |
-
}
|
242 |
-
|
243 |
-
// output field
|
244 |
-
$field_current = isset($current[$name]) ? $current[$name] : '';
|
245 |
-
$type = isset( $field['type'] ) ? $field['type'] : 'text';
|
246 |
-
printf( '<input type="%1$s" id="%2$s_%4$s" name="%3$s[%4$s]" value="%5$s" size="%6$s" placeholder="%7$s"/> %8$s<br/>', $type, $id, $setting_name, $name, esc_attr( $field_current ), $size, $placeholder, $description );
|
247 |
-
}
|
248 |
-
echo "</p>";
|
249 |
-
|
250 |
-
// Displays option description.
|
251 |
-
if ( isset( $args['description'] ) ) {
|
252 |
-
printf( '<p class="description">%s</p>', $args['description'] );
|
253 |
-
}
|
254 |
-
}
|
255 |
-
|
256 |
-
/**
|
257 |
-
* Multiple text element callback.
|
258 |
-
* @param array $args Field arguments.
|
259 |
-
* @return string Text input field.
|
260 |
-
*/
|
261 |
-
public function multiple_checkboxes( $args ) {
|
262 |
-
extract( $this->normalize_settings_args( $args ) );
|
263 |
-
|
264 |
-
foreach ($fields as $name => $label) {
|
265 |
-
// $label = $field['label'];
|
266 |
-
|
267 |
-
// output checkbox
|
268 |
-
$field_current = isset($current[$name]) ? $current[$name] : '';
|
269 |
-
printf( '<input type="checkbox" id="%1$s_%3$s" name="%2$s[%3$s]" value="%4$s"%5$s />', $id, $setting_name, $name, $value, checked( $value, $field_current, false ) );
|
270 |
-
|
271 |
-
// output field label
|
272 |
-
printf( '<label for="%1$s_%2$s">%3$s</label><br>', $id, $name, $label );
|
273 |
-
|
274 |
-
}
|
275 |
-
|
276 |
-
// Displays option description.
|
277 |
-
if ( isset( $args['description'] ) ) {
|
278 |
-
printf( '<p class="description">%s</p>', $args['description'] );
|
279 |
-
}
|
280 |
-
}
|
281 |
-
|
282 |
-
/**
|
283 |
-
* Media upload callback.
|
284 |
-
*
|
285 |
-
* @param array $args Field arguments.
|
286 |
-
*
|
287 |
-
* @return string Media upload button & preview.
|
288 |
-
*/
|
289 |
-
public function media_upload( $args ) {
|
290 |
-
extract( $this->normalize_settings_args( $args ) );
|
291 |
-
|
292 |
-
if( !empty($current) ) {
|
293 |
-
$attachment = wp_get_attachment_image_src( $current, 'thumbnail', false );
|
294 |
-
|
295 |
-
$attachment_src = $attachment[0];
|
296 |
-
$attachment_width = $attachment[1];
|
297 |
-
$attachment_height = $attachment[2];
|
298 |
-
$attachment_resolution = round($attachment_height/(3/2.54));
|
299 |
-
|
300 |
-
printf('<img src="%1$s" style="display:block" id="img-%4$s"/>', $attachment_src, $attachment_width, $attachment_height, $id );
|
301 |
-
printf('<div class="attachment-resolution"><p class="description">%s: %sdpi (default height = 3cm)</p></div>', __('Image resolution'), $attachment_resolution );
|
302 |
-
printf('<span class="button wpo_remove_image_button" data-input_id="%1$s">%2$s</span>', $id, $remove_button_text );
|
303 |
-
}
|
304 |
-
|
305 |
-
printf( '<input id="%1$s" name="%2$s" type="hidden" value="%3$s" />', $id, $setting_name, $current );
|
306 |
-
|
307 |
-
printf( '<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 );
|
308 |
-
|
309 |
-
// Displays option description.
|
310 |
-
if ( isset( $description ) ) {
|
311 |
-
printf( '<p class="description">%s</p>', $description );
|
312 |
-
}
|
313 |
-
}
|
314 |
-
|
315 |
-
/**
|
316 |
-
* Next document number edit callback.
|
317 |
-
*
|
318 |
-
* @param array $args Field arguments.
|
319 |
-
*/
|
320 |
-
public function next_number_edit( $args ) {
|
321 |
-
extract( $args );
|
322 |
-
$number_store_method = WPO_WCPDF()->settings->get_sequential_number_store_method();
|
323 |
-
$number_store = new Sequential_Number_Store( $store, $number_store_method );
|
324 |
-
$next_number = $number_store->get_next();
|
325 |
-
$nonce = wp_create_nonce( "wpo_wcpdf_next_{$store}" );
|
326 |
-
printf( '<input id="next_%1$s" class="next-number-input" type="text" size="%2$s" value="%3$s" disabled="disabled" data-store="%1$s" data-nonce="%4$s"/> <span class="edit-next-number dashicons dashicons-edit"></span><span class="save-next-number button secondary" style="display:none;">%5$s</span>', $store, $size, $next_number, $nonce, __( 'Save', 'woocommerce-pdf-invoices-packing-slips' ) );
|
327 |
-
// Displays option description.
|
328 |
-
if ( isset( $description ) ) {
|
329 |
-
printf( '<p class="description">%s</p>', $description );
|
330 |
-
}
|
331 |
-
}
|
332 |
-
|
333 |
-
/**
|
334 |
-
* Wrapper function to create tabs for settings in different languages
|
335 |
-
* @param [type] $args [description]
|
336 |
-
* @param [type] $callback [description]
|
337 |
-
* @return [type] [description]
|
338 |
-
*/
|
339 |
-
public function i18n_wrap ( $args ) {
|
340 |
-
extract( $this->normalize_settings_args( $args ) );
|
341 |
-
|
342 |
-
if ( $languages = $this->get_languages() ) {
|
343 |
-
printf( '<div id="%s-%s-translations" class="translations">', $option_name, $id)
|
344 |
-
?>
|
345 |
-
<ul>
|
346 |
-
<?php foreach ( $languages as $lang_code => $language_name ) {
|
347 |
-
$translation_id = "{$option_name}_{$id}_{$lang_code}";
|
348 |
-
printf('<li><a href="#%s">%s</a></li>', $translation_id, $language_name );
|
349 |
-
}
|
350 |
-
?>
|
351 |
-
</ul>
|
352 |
-
<?php foreach ( $languages as $lang_code => $language_name ) {
|
353 |
-
$translation_id = "{$option_name}_{$id}_{$lang_code}";
|
354 |
-
printf( '<div id="%s">', $translation_id );
|
355 |
-
$args['lang'] = $lang_code;
|
356 |
-
// don't use internationalized placeholders since they're not translated,
|
357 |
-
// to avoid confusion (user thinking they're all the same)
|
358 |
-
if ( $callback == 'multiple_text_input' ) {
|
359 |
-
foreach ($fields as $key => $field_args) {
|
360 |
-
if (!empty($field_args['placeholder']) && isset($field_args['i18n_placeholder'])) {
|
361 |
-
$args['fields'][$key]['placeholder'] = '';
|
362 |
-
}
|
363 |
-
}
|
364 |
-
} else {
|
365 |
-
if (!empty($args['placeholder']) && isset($args['i18n_placeholder'])) {
|
366 |
-
$args['placeholder'] = '';
|
367 |
-
}
|
368 |
-
}
|
369 |
-
// specific description for internationalized fields (to compensate for missing placeholder)
|
370 |
-
if (!empty($args['i18n_description'])) {
|
371 |
-
$args['description'] = $args['i18n_description'];
|
372 |
-
}
|
373 |
-
call_user_func( array( $this, $callback ), $args );
|
374 |
-
echo '</div>';
|
375 |
-
}
|
376 |
-
?>
|
377 |
-
|
378 |
-
</div>
|
379 |
-
<?php
|
380 |
-
} else {
|
381 |
-
$args['lang'] = 'default';
|
382 |
-
call_user_func( array( $this, $callback ), $args );
|
383 |
-
}
|
384 |
-
}
|
385 |
-
|
386 |
-
public function get_languages () {
|
387 |
-
$multilingual = function_exists('icl_get_languages');
|
388 |
-
// $multilingual = true; // for development
|
389 |
-
|
390 |
-
if ($multilingual) {
|
391 |
-
// use this instead of function call for development outside of WPML
|
392 |
-
// $icl_get_languages = 'a:3:{s:2:"en";a:8:{s:2:"id";s:1:"1";s:6:"active";s:1:"1";s:11:"native_name";s:7:"English";s:7:"missing";s:1:"0";s:15:"translated_name";s:7:"English";s:13:"language_code";s:2:"en";s:16:"country_flag_url";s:43:"http://yourdomain/wpmlpath/res/flags/en.png";s:3:"url";s:23:"http://yourdomain/about";}s:2:"fr";a:8:{s:2:"id";s:1:"4";s:6:"active";s:1:"0";s:11:"native_name";s:9:"Français";s:7:"missing";s:1:"0";s:15:"translated_name";s:6:"French";s:13:"language_code";s:2:"fr";s:16:"country_flag_url";s:43:"http://yourdomain/wpmlpath/res/flags/fr.png";s:3:"url";s:29:"http://yourdomain/fr/a-propos";}s:2:"it";a:8:{s:2:"id";s:2:"27";s:6:"active";s:1:"0";s:11:"native_name";s:8:"Italiano";s:7:"missing";s:1:"0";s:15:"translated_name";s:7:"Italian";s:13:"language_code";s:2:"it";s:16:"country_flag_url";s:43:"http://yourdomain/wpmlpath/res/flags/it.png";s:3:"url";s:26:"http://yourdomain/it/circa";}}';
|
393 |
-
// $icl_get_languages = unserialize($icl_get_languages);
|
394 |
-
|
395 |
-
$icl_get_languages = icl_get_languages('skip_missing=0');
|
396 |
-
$languages = array();
|
397 |
-
foreach ($icl_get_languages as $lang => $data) {
|
398 |
-
$languages[$data['language_code']] = $data['native_name'];
|
399 |
-
}
|
400 |
-
} else {
|
401 |
-
return false;
|
402 |
-
}
|
403 |
-
|
404 |
-
return $languages;
|
405 |
-
}
|
406 |
-
|
407 |
-
public function normalize_settings_args ( $args ) {
|
408 |
-
$args['value'] = isset( $args['value'] ) ? $args['value'] : 1;
|
409 |
-
|
410 |
-
$args['placeholder'] = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
|
411 |
-
|
412 |
-
// get main settings array
|
413 |
-
$option = get_option( $args['option_name'] );
|
414 |
-
|
415 |
-
$args['setting_name'] = "{$args['option_name']}[{$args['id']}]";
|
416 |
-
|
417 |
-
if ( !isset($args['lang']) && !empty($args['translatable']) ) {
|
418 |
-
$args['lang'] = 'default';
|
419 |
-
}
|
420 |
-
|
421 |
-
if (isset($args['lang'])) {
|
422 |
-
// i18n settings name
|
423 |
-
$args['setting_name'] = "{$args['setting_name']}[{$args['lang']}]";
|
424 |
-
// copy current option value if set
|
425 |
-
|
426 |
-
if ( $args['lang'] == 'default' && !empty($option[$args['id']]) && !isset( $option[$args['id']]['default'] ) ) {
|
427 |
-
// we're switching back from WPML to normal
|
428 |
-
// try english first
|
429 |
-
if ( isset( $option[$args['id']]['en'] ) ) {
|
430 |
-
$args['current'] = $option[$args['id']]['en'];
|
431 |
-
} elseif ( is_array( $option[$args['id']] ) ) {
|
432 |
-
// fallback to the first language if english not found
|
433 |
-
$first = array_shift($option[$args['id']]);
|
434 |
-
if (!empty($first)) {
|
435 |
-
$args['current'] = $first;
|
436 |
-
}
|
437 |
-
} elseif ( is_string( $option[$args['id']] ) ) {
|
438 |
-
$args['current'] = $option[$args['id']];
|
439 |
-
} else {
|
440 |
-
// nothing, really?
|
441 |
-
$args['current'] = '';
|
442 |
-
}
|
443 |
-
} else {
|
444 |
-
if ( isset( $option[$args['id']][$args['lang']] ) ) {
|
445 |
-
$args['current'] = $option[$args['id']][$args['lang']];
|
446 |
-
} elseif (isset( $option[$args['id']]['default'] )) {
|
447 |
-
$args['current'] = $option[$args['id']]['default'];
|
448 |
-
}
|
449 |
-
}
|
450 |
-
} else {
|
451 |
-
// copy current option value if set
|
452 |
-
if ( isset( $option[$args['id']] ) ) {
|
453 |
-
$args['current'] = $option[$args['id']];
|
454 |
-
}
|
455 |
-
}
|
456 |
-
|
457 |
-
// falback to default or empty if no value in option
|
458 |
-
if ( !isset($args['current']) ) {
|
459 |
-
$args['current'] = isset( $args['default'] ) ? $args['default'] : '';
|
460 |
-
}
|
461 |
-
|
462 |
-
return $args;
|
463 |
-
}
|
464 |
-
|
465 |
-
/**
|
466 |
-
* Validate options.
|
467 |
-
*
|
468 |
-
* @param array $input options to valid.
|
469 |
-
*
|
470 |
-
* @return array validated options.
|
471 |
-
*/
|
472 |
-
public function validate( $input ) {
|
473 |
-
// echo '<pre>';var_dump($input);die('</pre>');
|
474 |
-
// Create our array for storing the validated options.
|
475 |
-
$output = array();
|
476 |
-
|
477 |
-
if (empty($input) || !is_array($input)) {
|
478 |
-
return $input;
|
479 |
-
}
|
480 |
-
|
481 |
-
// Loop through each of the incoming options.
|
482 |
-
foreach ( $input as $key => $value ) {
|
483 |
-
|
484 |
-
// Check to see if the current option has a value. If so, process it.
|
485 |
-
if ( isset( $input[$key] ) ) {
|
486 |
-
if ( is_array( $input[$key] ) ) {
|
487 |
-
foreach ( $input[$key] as $sub_key => $sub_value ) {
|
488 |
-
$output[$key][$sub_key] = $input[$key][$sub_key];
|
489 |
-
}
|
490 |
-
} else {
|
491 |
-
$output[$key] = $input[$key];
|
492 |
-
}
|
493 |
-
}
|
494 |
-
}
|
495 |
-
|
496 |
-
// Return the array processing any additional functions filtered by this action.
|
497 |
-
return apply_filters( 'wpo_wcpdf_validate_input', $output, $input );
|
498 |
-
}
|
499 |
-
}
|
500 |
-
|
501 |
-
|
502 |
-
endif; // class_exists
|
503 |
-
|
504 |
Â
return new Settings_Callbacks();
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices;
|
3 |
+
|
4 |
+
use WPO\WC\PDF_Invoices\Documents\Sequential_Number_Store;
|
5 |
+
|
6 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
7 |
+
exit; // Exit if accessed directly
|
8 |
+
}
|
9 |
+
|
10 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings_Callbacks' ) ) :
|
11 |
+
|
12 |
+
class Settings_Callbacks {
|
13 |
+
/**
|
14 |
+
* Section null callback.
|
15 |
+
*
|
16 |
+
* @return void.
|
17 |
+
*/
|
18 |
+
public function section() {
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Debug section callback.
|
23 |
+
*
|
24 |
+
* @return void.
|
25 |
+
*/
|
26 |
+
public function debug_section() {
|
27 |
+
_e( '<b>Warning!</b> The settings below are meant for debugging/development only. Do not use them on a live website!' , 'woocommerce-pdf-invoices-packing-slips' );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Custom fields section callback.
|
32 |
+
*
|
33 |
+
* @return void.
|
34 |
+
*/
|
35 |
+
public function custom_fields_section() {
|
36 |
+
_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' , 'woocommerce-pdf-invoices-packing-slips' );
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Checkbox callback.
|
41 |
+
*
|
42 |
+
* args:
|
43 |
+
* option_name - name of the main option
|
44 |
+
* id - key of the setting
|
45 |
+
* value - value if not 1 (optional)
|
46 |
+
* default - default setting (optional)
|
47 |
+
* description - description (optional)
|
48 |
+
*
|
49 |
+
* @return void.
|
50 |
+
*/
|
51 |
+
public function checkbox( $args ) {
|
52 |
+
extract( $this->normalize_settings_args( $args ) );
|
53 |
+
|
54 |
+
// output checkbox
|
55 |
+
printf( '<input type="checkbox" id="%1$s" name="%2$s" value="%3$s"%4$s />', $id, $setting_name, $value, checked( $value, $current, false ) );
|
56 |
+
|
57 |
+
// output description.
|
58 |
+
if ( isset( $description ) ) {
|
59 |
+
printf( '<p class="description">%s</p>', $description );
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Text input callback.
|
65 |
+
*
|
66 |
+
* args:
|
67 |
+
* option_name - name of the main option
|
68 |
+
* id - key of the setting
|
69 |
+
* size - size of the text input (em)
|
70 |
+
* default - default setting (optional)
|
71 |
+
* description - description (optional)
|
72 |
+
* type - type (optional)
|
73 |
+
*
|
74 |
+
* @return void.
|
75 |
+
*/
|
76 |
+
public function text_input( $args ) {
|
77 |
+
extract( $this->normalize_settings_args( $args ) );
|
78 |
+
|
79 |
+
if (empty($type)) {
|
80 |
+
$type = 'text';
|
81 |
+
}
|
82 |
+
|
83 |
+
printf( '<input type="%1$s" id="%2$s" name="%3$s" value="%4$s" size="%5$s" placeholder="%6$s"/>', $type, $id, $setting_name, esc_attr( $current ), $size, $placeholder );
|
84 |
+
|
85 |
+
// output description.
|
86 |
+
if ( isset( $description ) ) {
|
87 |
+
printf( '<p class="description">%s</p>', $description );
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
// Single text option (not part of any settings array)
|
92 |
+
public function singular_text_element( $args ) {
|
93 |
+
$option_name = $args['option_name'];
|
94 |
+
$id = $args['id'];
|
95 |
+
$size = isset( $args['size'] ) ? $args['size'] : '25';
|
96 |
+
$class = isset( $args['translatable'] ) && $args['translatable'] === true ? 'translatable' : '';
|
97 |
+
|
98 |
+
$option = get_option( $option_name );
|
99 |
+
|
100 |
+
if ( isset( $option ) ) {
|
101 |
+
$current = $option;
|
102 |
+
} else {
|
103 |
+
$current = isset( $args['default'] ) ? $args['default'] : '';
|
104 |
+
}
|
105 |
+
|
106 |
+
$html = sprintf( '<input type="text" id="%1$s" name="%2$s" value="%3$s" size="%4$s" class="%5$s"/>', $id, $option_name, $current, $size, $class );
|
107 |
+
|
108 |
+
// Displays option description.
|
109 |
+
if ( isset( $args['description'] ) ) {
|
110 |
+
$html .= sprintf( '<p class="description">%s</p>', $args['description'] );
|
111 |
+
}
|
112 |
+
|
113 |
+
echo $html;
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Textarea callback.
|
119 |
+
*
|
120 |
+
* args:
|
121 |
+
* option_name - name of the main option
|
122 |
+
* id - key of the setting
|
123 |
+
* width - width of the text input (em)
|
124 |
+
* height - height of the text input (lines)
|
125 |
+
* default - default setting (optional)
|
126 |
+
* description - description (optional)
|
127 |
+
*
|
128 |
+
* @return void.
|
129 |
+
*/
|
130 |
+
public function textarea( $args ) {
|
131 |
+
extract( $this->normalize_settings_args( $args ) );
|
132 |
+
|
133 |
+
printf( '<textarea id="%1$s" name="%2$s" cols="%4$s" rows="%5$s" placeholder="%6$s"/>%3$s</textarea>', $id, $setting_name, esc_textarea( $current ), $width, $height, $placeholder );
|
134 |
+
|
135 |
+
// output description.
|
136 |
+
if ( isset( $description ) ) {
|
137 |
+
printf( '<p class="description">%s</p>', $description );
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Select element callback.
|
143 |
+
*
|
144 |
+
* @param array $args Field arguments.
|
145 |
+
*
|
146 |
+
* @return string Select field.
|
147 |
+
*/
|
148 |
+
public function select( $args ) {
|
149 |
+
extract( $this->normalize_settings_args( $args ) );
|
150 |
+
|
151 |
+
printf( '<select id="%1$s" name="%2$s">', $id, $setting_name );
|
152 |
+
|
153 |
+
foreach ( $options as $key => $label ) {
|
154 |
+
printf( '<option value="%s"%s>%s</option>', $key, selected( $current, $key, false ), $label );
|
155 |
+
}
|
156 |
+
|
157 |
+
echo '</select>';
|
158 |
+
|
159 |
+
if (isset($custom)) {
|
160 |
+
printf( '<div class="%1$s_custom custom">', $id );
|
161 |
+
|
162 |
+
if (is_callable( array( $this, $custom['type'] ) ) ) {
|
163 |
+
$this->{$custom['type']}( $custom['args'] );
|
164 |
+
}
|
165 |
+
echo '</div>';
|
166 |
+
?>
|
167 |
+
<script type="text/javascript">
|
168 |
+
jQuery(document).ready(function($) {
|
169 |
+
function check_<?php echo $id; ?>_custom() {
|
170 |
+
var custom = $('#<?php echo $id; ?>').val();
|
171 |
+
console.log(custom);
|
172 |
+
if (custom == 'custom') {
|
173 |
+
$( '.<?php echo $id; ?>_custom').show();
|
174 |
+
} else {
|
175 |
+
$( '.<?php echo $id; ?>_custom').hide();
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
check_<?php echo $id; ?>_custom();
|
180 |
+
|
181 |
+
$( '#<?php echo $id; ?>' ).change(function() {
|
182 |
+
check_<?php echo $id; ?>_custom();
|
183 |
+
});
|
184 |
+
|
185 |
+
});
|
186 |
+
</script>
|
187 |
+
<?php
|
188 |
+
}
|
189 |
+
|
190 |
+
// Displays option description.
|
191 |
+
if ( isset( $args['description'] ) ) {
|
192 |
+
printf( '<p class="description">%s</p>', $args['description'] );
|
193 |
+
}
|
194 |
+
|
195 |
+
}
|
196 |
+
|
197 |
+
public function radio_button( $args ) {
|
198 |
+
extract( $this->normalize_settings_args( $args ) );
|
199 |
+
|
200 |
+
foreach ( $options as $key => $label ) {
|
201 |
+
printf( '<input type="radio" class="radio" id="%1$s[%3$s]" name="%2$s" value="%3$s"%4$s />', $id, $setting_name, $key, checked( $current, $key, false ) );
|
202 |
+
printf( '<label for="%1$s[%3$s]"> %4$s</label><br>', $id, $setting_name, $key, $label);
|
203 |
+
}
|
204 |
+
|
205 |
+
|
206 |
+
// Displays option description.
|
207 |
+
if ( isset( $args['description'] ) ) {
|
208 |
+
printf( '<p class="description">%s</p>', $args['description'] );
|
209 |
+
}
|
210 |
+
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Multiple text element callback.
|
215 |
+
* @param array $args Field arguments.
|
216 |
+
* @return string Text input field.
|
217 |
+
*/
|
218 |
+
public function multiple_text_input( $args ) {
|
219 |
+
extract( $this->normalize_settings_args( $args ) );
|
220 |
+
|
221 |
+
if (!empty($header)) {
|
222 |
+
echo "<p><strong>{$header}</strong>:</p>";
|
223 |
+
}
|
224 |
+
|
225 |
+
printf('<p class="%s multiple-text-input">', $id);
|
226 |
+
foreach ($fields as $name => $field) {
|
227 |
+
$size = $field['size'];
|
228 |
+
$placeholder = isset( $field['placeholder'] ) ? $field['placeholder'] : '';
|
229 |
+
|
230 |
+
if (isset($field['label_width'])) {
|
231 |
+
$style = sprintf( 'style="display:inline-block; width:%1$s;"', $field['label_width'] );
|
232 |
+
} else {
|
233 |
+
$style = '';
|
234 |
+
}
|
235 |
+
|
236 |
+
$description = isset( $field['description'] ) ? '<span style="font-style:italic;">'.$field['description'].'</span>' : '';
|
237 |
+
|
238 |
+
// output field label
|
239 |
+
if (isset($field['label'])) {
|
240 |
+
printf( '<label for="%1$s_%2$s" %3$s>%4$s:</label>', $id, $name, $style, $field['label'] );
|
241 |
+
}
|
242 |
+
|
243 |
+
// output field
|
244 |
+
$field_current = isset($current[$name]) ? $current[$name] : '';
|
245 |
+
$type = isset( $field['type'] ) ? $field['type'] : 'text';
|
246 |
+
printf( '<input type="%1$s" id="%2$s_%4$s" name="%3$s[%4$s]" value="%5$s" size="%6$s" placeholder="%7$s"/> %8$s<br/>', $type, $id, $setting_name, $name, esc_attr( $field_current ), $size, $placeholder, $description );
|
247 |
+
}
|
248 |
+
echo "</p>";
|
249 |
+
|
250 |
+
// Displays option description.
|
251 |
+
if ( isset( $args['description'] ) ) {
|
252 |
+
printf( '<p class="description">%s</p>', $args['description'] );
|
253 |
+
}
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Multiple text element callback.
|
258 |
+
* @param array $args Field arguments.
|
259 |
+
* @return string Text input field.
|
260 |
+
*/
|
261 |
+
public function multiple_checkboxes( $args ) {
|
262 |
+
extract( $this->normalize_settings_args( $args ) );
|
263 |
+
|
264 |
+
foreach ($fields as $name => $label) {
|
265 |
+
// $label = $field['label'];
|
266 |
+
|
267 |
+
// output checkbox
|
268 |
+
$field_current = isset($current[$name]) ? $current[$name] : '';
|
269 |
+
printf( '<input type="checkbox" id="%1$s_%3$s" name="%2$s[%3$s]" value="%4$s"%5$s />', $id, $setting_name, $name, $value, checked( $value, $field_current, false ) );
|
270 |
+
|
271 |
+
// output field label
|
272 |
+
printf( '<label for="%1$s_%2$s">%3$s</label><br>', $id, $name, $label );
|
273 |
+
|
274 |
+
}
|
275 |
+
|
276 |
+
// Displays option description.
|
277 |
+
if ( isset( $args['description'] ) ) {
|
278 |
+
printf( '<p class="description">%s</p>', $args['description'] );
|
279 |
+
}
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* Media upload callback.
|
284 |
+
*
|
285 |
+
* @param array $args Field arguments.
|
286 |
+
*
|
287 |
+
* @return string Media upload button & preview.
|
288 |
+
*/
|
289 |
+
public function media_upload( $args ) {
|
290 |
+
extract( $this->normalize_settings_args( $args ) );
|
291 |
+
|
292 |
+
if( !empty($current) ) {
|
293 |
+
$attachment = wp_get_attachment_image_src( $current, 'thumbnail', false );
|
294 |
+
|
295 |
+
$attachment_src = $attachment[0];
|
296 |
+
$attachment_width = $attachment[1];
|
297 |
+
$attachment_height = $attachment[2];
|
298 |
+
$attachment_resolution = round($attachment_height/(3/2.54));
|
299 |
+
|
300 |
+
printf('<img src="%1$s" style="display:block" id="img-%4$s"/>', $attachment_src, $attachment_width, $attachment_height, $id );
|
301 |
+
printf('<div class="attachment-resolution"><p class="description">%s: %sdpi (default height = 3cm)</p></div>', __('Image resolution'), $attachment_resolution );
|
302 |
+
printf('<span class="button wpo_remove_image_button" data-input_id="%1$s">%2$s</span>', $id, $remove_button_text );
|
303 |
+
}
|
304 |
+
|
305 |
+
printf( '<input id="%1$s" name="%2$s" type="hidden" value="%3$s" />', $id, $setting_name, $current );
|
306 |
+
|
307 |
+
printf( '<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 );
|
308 |
+
|
309 |
+
// Displays option description.
|
310 |
+
if ( isset( $description ) ) {
|
311 |
+
printf( '<p class="description">%s</p>', $description );
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Next document number edit callback.
|
317 |
+
*
|
318 |
+
* @param array $args Field arguments.
|
319 |
+
*/
|
320 |
+
public function next_number_edit( $args ) {
|
321 |
+
extract( $args );
|
322 |
+
$number_store_method = WPO_WCPDF()->settings->get_sequential_number_store_method();
|
323 |
+
$number_store = new Sequential_Number_Store( $store, $number_store_method );
|
324 |
+
$next_number = $number_store->get_next();
|
325 |
+
$nonce = wp_create_nonce( "wpo_wcpdf_next_{$store}" );
|
326 |
+
printf( '<input id="next_%1$s" class="next-number-input" type="text" size="%2$s" value="%3$s" disabled="disabled" data-store="%1$s" data-nonce="%4$s"/> <span class="edit-next-number dashicons dashicons-edit"></span><span class="save-next-number button secondary" style="display:none;">%5$s</span>', $store, $size, $next_number, $nonce, __( 'Save', 'woocommerce-pdf-invoices-packing-slips' ) );
|
327 |
+
// Displays option description.
|
328 |
+
if ( isset( $description ) ) {
|
329 |
+
printf( '<p class="description">%s</p>', $description );
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Wrapper function to create tabs for settings in different languages
|
335 |
+
* @param [type] $args [description]
|
336 |
+
* @param [type] $callback [description]
|
337 |
+
* @return [type] [description]
|
338 |
+
*/
|
339 |
+
public function i18n_wrap ( $args ) {
|
340 |
+
extract( $this->normalize_settings_args( $args ) );
|
341 |
+
|
342 |
+
if ( $languages = $this->get_languages() ) {
|
343 |
+
printf( '<div id="%s-%s-translations" class="translations">', $option_name, $id)
|
344 |
+
?>
|
345 |
+
<ul>
|
346 |
+
<?php foreach ( $languages as $lang_code => $language_name ) {
|
347 |
+
$translation_id = "{$option_name}_{$id}_{$lang_code}";
|
348 |
+
printf('<li><a href="#%s">%s</a></li>', $translation_id, $language_name );
|
349 |
+
}
|
350 |
+
?>
|
351 |
+
</ul>
|
352 |
+
<?php foreach ( $languages as $lang_code => $language_name ) {
|
353 |
+
$translation_id = "{$option_name}_{$id}_{$lang_code}";
|
354 |
+
printf( '<div id="%s">', $translation_id );
|
355 |
+
$args['lang'] = $lang_code;
|
356 |
+
// don't use internationalized placeholders since they're not translated,
|
357 |
+
// to avoid confusion (user thinking they're all the same)
|
358 |
+
if ( $callback == 'multiple_text_input' ) {
|
359 |
+
foreach ($fields as $key => $field_args) {
|
360 |
+
if (!empty($field_args['placeholder']) && isset($field_args['i18n_placeholder'])) {
|
361 |
+
$args['fields'][$key]['placeholder'] = '';
|
362 |
+
}
|
363 |
+
}
|
364 |
+
} else {
|
365 |
+
if (!empty($args['placeholder']) && isset($args['i18n_placeholder'])) {
|
366 |
+
$args['placeholder'] = '';
|
367 |
+
}
|
368 |
+
}
|
369 |
+
// specific description for internationalized fields (to compensate for missing placeholder)
|
370 |
+
if (!empty($args['i18n_description'])) {
|
371 |
+
$args['description'] = $args['i18n_description'];
|
372 |
+
}
|
373 |
+
call_user_func( array( $this, $callback ), $args );
|
374 |
+
echo '</div>';
|
375 |
+
}
|
376 |
+
?>
|
377 |
+
|
378 |
+
</div>
|
379 |
+
<?php
|
380 |
+
} else {
|
381 |
+
$args['lang'] = 'default';
|
382 |
+
call_user_func( array( $this, $callback ), $args );
|
383 |
+
}
|
384 |
+
}
|
385 |
+
|
386 |
+
public function get_languages () {
|
387 |
+
$multilingual = function_exists('icl_get_languages');
|
388 |
+
// $multilingual = true; // for development
|
389 |
+
|
390 |
+
if ($multilingual) {
|
391 |
+
// use this instead of function call for development outside of WPML
|
392 |
+
// $icl_get_languages = 'a:3:{s:2:"en";a:8:{s:2:"id";s:1:"1";s:6:"active";s:1:"1";s:11:"native_name";s:7:"English";s:7:"missing";s:1:"0";s:15:"translated_name";s:7:"English";s:13:"language_code";s:2:"en";s:16:"country_flag_url";s:43:"http://yourdomain/wpmlpath/res/flags/en.png";s:3:"url";s:23:"http://yourdomain/about";}s:2:"fr";a:8:{s:2:"id";s:1:"4";s:6:"active";s:1:"0";s:11:"native_name";s:9:"Français";s:7:"missing";s:1:"0";s:15:"translated_name";s:6:"French";s:13:"language_code";s:2:"fr";s:16:"country_flag_url";s:43:"http://yourdomain/wpmlpath/res/flags/fr.png";s:3:"url";s:29:"http://yourdomain/fr/a-propos";}s:2:"it";a:8:{s:2:"id";s:2:"27";s:6:"active";s:1:"0";s:11:"native_name";s:8:"Italiano";s:7:"missing";s:1:"0";s:15:"translated_name";s:7:"Italian";s:13:"language_code";s:2:"it";s:16:"country_flag_url";s:43:"http://yourdomain/wpmlpath/res/flags/it.png";s:3:"url";s:26:"http://yourdomain/it/circa";}}';
|
393 |
+
// $icl_get_languages = unserialize($icl_get_languages);
|
394 |
+
|
395 |
+
$icl_get_languages = icl_get_languages('skip_missing=0');
|
396 |
+
$languages = array();
|
397 |
+
foreach ($icl_get_languages as $lang => $data) {
|
398 |
+
$languages[$data['language_code']] = $data['native_name'];
|
399 |
+
}
|
400 |
+
} else {
|
401 |
+
return false;
|
402 |
+
}
|
403 |
+
|
404 |
+
return $languages;
|
405 |
+
}
|
406 |
+
|
407 |
+
public function normalize_settings_args ( $args ) {
|
408 |
+
$args['value'] = isset( $args['value'] ) ? $args['value'] : 1;
|
409 |
+
|
410 |
+
$args['placeholder'] = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
|
411 |
+
|
412 |
+
// get main settings array
|
413 |
+
$option = get_option( $args['option_name'] );
|
414 |
+
|
415 |
+
$args['setting_name'] = "{$args['option_name']}[{$args['id']}]";
|
416 |
+
|
417 |
+
if ( !isset($args['lang']) && !empty($args['translatable']) ) {
|
418 |
+
$args['lang'] = 'default';
|
419 |
+
}
|
420 |
+
|
421 |
+
if (isset($args['lang'])) {
|
422 |
+
// i18n settings name
|
423 |
+
$args['setting_name'] = "{$args['setting_name']}[{$args['lang']}]";
|
424 |
+
// copy current option value if set
|
425 |
+
|
426 |
+
if ( $args['lang'] == 'default' && !empty($option[$args['id']]) && !isset( $option[$args['id']]['default'] ) ) {
|
427 |
+
// we're switching back from WPML to normal
|
428 |
+
// try english first
|
429 |
+
if ( isset( $option[$args['id']]['en'] ) ) {
|
430 |
+
$args['current'] = $option[$args['id']]['en'];
|
431 |
+
} elseif ( is_array( $option[$args['id']] ) ) {
|
432 |
+
// fallback to the first language if english not found
|
433 |
+
$first = array_shift($option[$args['id']]);
|
434 |
+
if (!empty($first)) {
|
435 |
+
$args['current'] = $first;
|
436 |
+
}
|
437 |
+
} elseif ( is_string( $option[$args['id']] ) ) {
|
438 |
+
$args['current'] = $option[$args['id']];
|
439 |
+
} else {
|
440 |
+
// nothing, really?
|
441 |
+
$args['current'] = '';
|
442 |
+
}
|
443 |
+
} else {
|
444 |
+
if ( isset( $option[$args['id']][$args['lang']] ) ) {
|
445 |
+
$args['current'] = $option[$args['id']][$args['lang']];
|
446 |
+
} elseif (isset( $option[$args['id']]['default'] )) {
|
447 |
+
$args['current'] = $option[$args['id']]['default'];
|
448 |
+
}
|
449 |
+
}
|
450 |
+
} else {
|
451 |
+
// copy current option value if set
|
452 |
+
if ( isset( $option[$args['id']] ) ) {
|
453 |
+
$args['current'] = $option[$args['id']];
|
454 |
+
}
|
455 |
+
}
|
456 |
+
|
457 |
+
// falback to default or empty if no value in option
|
458 |
+
if ( !isset($args['current']) ) {
|
459 |
+
$args['current'] = isset( $args['default'] ) ? $args['default'] : '';
|
460 |
+
}
|
461 |
+
|
462 |
+
return $args;
|
463 |
+
}
|
464 |
+
|
465 |
+
/**
|
466 |
+
* Validate options.
|
467 |
+
*
|
468 |
+
* @param array $input options to valid.
|
469 |
+
*
|
470 |
+
* @return array validated options.
|
471 |
+
*/
|
472 |
+
public function validate( $input ) {
|
473 |
+
// echo '<pre>';var_dump($input);die('</pre>');
|
474 |
+
// Create our array for storing the validated options.
|
475 |
+
$output = array();
|
476 |
+
|
477 |
+
if (empty($input) || !is_array($input)) {
|
478 |
+
return $input;
|
479 |
+
}
|
480 |
+
|
481 |
+
// Loop through each of the incoming options.
|
482 |
+
foreach ( $input as $key => $value ) {
|
483 |
+
|
484 |
+
// Check to see if the current option has a value. If so, process it.
|
485 |
+
if ( isset( $input[$key] ) ) {
|
486 |
+
if ( is_array( $input[$key] ) ) {
|
487 |
+
foreach ( $input[$key] as $sub_key => $sub_value ) {
|
488 |
+
$output[$key][$sub_key] = $input[$key][$sub_key];
|
489 |
+
}
|
490 |
+
} else {
|
491 |
+
$output[$key] = $input[$key];
|
492 |
+
}
|
493 |
+
}
|
494 |
+
}
|
495 |
+
|
496 |
+
// Return the array processing any additional functions filtered by this action.
|
497 |
+
return apply_filters( 'wpo_wcpdf_validate_input', $output, $input );
|
498 |
+
}
|
499 |
+
}
|
500 |
+
|
501 |
+
|
502 |
+
endif; // class_exists
|
503 |
+
|
504 |
Â
return new Settings_Callbacks();
|
includes/class-wcpdf-settings-debug.php
CHANGED
@@ -1,185 +1,185 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices;
|
3 |
-
|
4 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
-
exit; // Exit if accessed directly
|
6 |
-
}
|
7 |
-
|
8 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings_Debug' ) ) :
|
9 |
-
|
10 |
-
class Settings_Debug {
|
11 |
-
|
12 |
-
function __construct() {
|
13 |
-
add_action( 'admin_init', array( $this, 'init_settings' ) );
|
14 |
-
add_action( 'wpo_wcpdf_settings_output_debug', array( $this, 'output' ), 10, 1 );
|
15 |
-
add_action( 'wpo_wcpdf_after_settings_page', array( $this, 'debug_tools' ), 10, 2 );
|
16 |
-
}
|
17 |
-
|
18 |
-
public function output( $section ) {
|
19 |
-
settings_fields( "wpo_wcpdf_settings_debug" );
|
20 |
-
do_settings_sections( "wpo_wcpdf_settings_debug" );
|
21 |
-
|
22 |
-
submit_button();
|
23 |
-
}
|
24 |
-
|
25 |
-
public function debug_tools( $tab, $section ) {
|
26 |
-
if ($tab !== 'debug') {
|
27 |
-
return;
|
28 |
-
}
|
29 |
-
?>
|
30 |
-
<form method="post">
|
31 |
-
<input type="hidden" name="wpo_wcpdf_debug_tools_action" value="install_fonts">
|
32 |
-
<input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Reinstall fonts', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
|
33 |
-
<?php
|
34 |
-
if (isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'install_fonts') {
|
35 |
-
$font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
|
36 |
-
|
37 |
-
// clear folder first
|
38 |
-
if ( function_exists("glob") && $files = glob( $font_path.'/*.*' ) ) {
|
39 |
-
$exclude_files = array( 'index.php', '.htaccess' );
|
40 |
-
foreach($files as $file) {
|
41 |
-
if( is_file($file) && !in_array( basename($file), $exclude_files ) ) {
|
42 |
-
unlink($file);
|
43 |
-
}
|
44 |
-
}
|
45 |
-
}
|
46 |
-
|
47 |
-
WPO_WCPDF()->main->copy_fonts( $font_path );
|
48 |
-
printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Fonts reinstalled!', 'woocommerce-pdf-invoices-packing-slips' ) );
|
49 |
-
}
|
50 |
-
?>
|
51 |
-
</form>
|
52 |
-
<form method="post">
|
53 |
-
<input type="hidden" name="wpo_wcpdf_debug_tools_action" value="clear_tmp">
|
54 |
-
<input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Remove temporary files', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
|
55 |
-
<?php
|
56 |
-
if (isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'clear_tmp') {
|
57 |
-
$tmp_path = WPO_WCPDF()->main->get_tmp_path('attachments');
|
58 |
-
|
59 |
-
if ( !function_exists("glob") ) {
|
60 |
-
// glob is disabled
|
61 |
-
printf('<div class="notice notice-error"><p>%s<br><code>%s</code></p></div>', __( "Unable to read temporary folder contents!", 'woocommerce-pdf-invoices-packing-slips' ), $tmp_path);
|
62 |
-
} else {
|
63 |
-
$success = 0;
|
64 |
-
$error = 0;
|
65 |
-
if ( $files = glob($tmp_path.'*.pdf') ) { // get all pdf files
|
66 |
-
foreach($files as $file) {
|
67 |
-
if(is_file($file)) {
|
68 |
-
// delete file
|
69 |
-
if ( unlink($file) === true ) {
|
70 |
-
$success++;
|
71 |
-
} else {
|
72 |
-
$error++;
|
73 |
-
}
|
74 |
-
}
|
75 |
-
}
|
76 |
-
|
77 |
-
if ($error > 0) {
|
78 |
-
$message = sprintf( __( 'Unable to delete %d files! (deleted %d)', 'woocommerce-pdf-invoices-packing-slips' ), $error, $success);
|
79 |
-
printf('<div class="notice notice-error"><p>%s</p></div>', $message);
|
80 |
-
} else {
|
81 |
-
$message = sprintf( __( 'Successfully deleted %d files!', 'woocommerce-pdf-invoices-packing-slips' ), $success );
|
82 |
-
printf('<div class="notice notice-success"><p>%s</p></div>', $message);
|
83 |
-
}
|
84 |
-
} else {
|
85 |
-
printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Nothing to delete!', 'woocommerce-pdf-invoices-packing-slips' ) );
|
86 |
-
}
|
87 |
-
}
|
88 |
-
}
|
89 |
-
?>
|
90 |
-
</form>
|
91 |
-
<form method="post">
|
92 |
-
<input type="hidden" name="wpo_wcpdf_debug_tools_action" value="delete_legacy_settings">
|
93 |
-
<input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Delete legacy (1.X) settings', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
|
94 |
-
<?php
|
95 |
-
if (isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'delete_legacy_settings') {
|
96 |
-
// delete options
|
97 |
-
delete_option( 'wpo_wcpdf_general_settings' );
|
98 |
-
delete_option( 'wpo_wcpdf_template_settings' );
|
99 |
-
delete_option( 'wpo_wcpdf_debug_settings' );
|
100 |
-
// and delete cache of these options, just in case...
|
101 |
-
wp_cache_delete( 'wpo_wcpdf_general_settings','options' );
|
102 |
-
wp_cache_delete( 'wpo_wcpdf_template_settings','options' );
|
103 |
-
wp_cache_delete( 'wpo_wcpdf_debug_settings','options' );
|
104 |
-
|
105 |
-
printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Legacy settings deleted!', 'woocommerce-pdf-invoices-packing-slips' ) );
|
106 |
-
}
|
107 |
-
?>
|
108 |
-
</form>
|
109 |
-
<?php
|
110 |
-
include( WPO_WCPDF()->plugin_path() . '/includes/views/dompdf-status.php' );
|
111 |
-
}
|
112 |
-
|
113 |
-
public function init_settings() {
|
114 |
-
// Register settings.
|
115 |
-
$page = $option_group = $option_name = 'wpo_wcpdf_settings_debug';
|
116 |
-
|
117 |
-
$settings_fields = array(
|
118 |
-
array(
|
119 |
-
'type' => 'section',
|
120 |
-
'id' => 'debug_settings',
|
121 |
-
'title' => __( 'Debug settings', 'woocommerce-pdf-invoices-packing-slips' ),
|
122 |
-
'callback' => 'section',
|
123 |
-
),
|
124 |
-
array(
|
125 |
-
'type' => 'setting',
|
126 |
-
'id' => 'legacy_mode',
|
127 |
-
'title' => __( 'Legacy mode', 'woocommerce-pdf-invoices-packing-slips' ),
|
128 |
-
'callback' => 'checkbox',
|
129 |
-
'section' => 'debug_settings',
|
130 |
-
'args' => array(
|
131 |
-
'option_name' => $option_name,
|
132 |
-
'id' => 'legacy_mode',
|
133 |
-
'description' => __( "Legacy mode ensures compatibility with templates and filters from previous versions.", 'woocommerce-pdf-invoices-packing-slips' ),
|
134 |
-
)
|
135 |
-
),
|
136 |
-
array(
|
137 |
-
'type' => 'setting',
|
138 |
-
'id' => 'calculate_document_numbers',
|
139 |
-
'title' => __( 'Calculate document numbers (slow)', 'woocommerce-pdf-invoices-packing-slips' ),
|
140 |
-
'callback' => 'checkbox',
|
141 |
-
'section' => 'debug_settings',
|
142 |
-
'args' => array(
|
143 |
-
'option_name' => $option_name,
|
144 |
-
'id' => 'calculate_document_numbers',
|
145 |
-
'description' => __( "Document numbers (such as invoice numbers) are generated using AUTO_INCREMENT by default. Use this setting if your database auto increments with more than 1.", 'woocommerce-pdf-invoices-packing-slips' ),
|
146 |
-
)
|
147 |
-
),
|
148 |
-
array(
|
149 |
-
'type' => 'setting',
|
150 |
-
'id' => 'enable_debug',
|
151 |
-
'title' => __( 'Enable debug output', 'woocommerce-pdf-invoices-packing-slips' ),
|
152 |
-
'callback' => 'checkbox',
|
153 |
-
'section' => 'debug_settings',
|
154 |
-
'args' => array(
|
155 |
-
'option_name' => $option_name,
|
156 |
-
'id' => 'enable_debug',
|
157 |
-
'description' => __( "Enable this option to output plugin errors if you're getting a blank page or other PDF generation issues", 'woocommerce-pdf-invoices-packing-slips' ) . '<br>' .
|
158 |
-
__( '<b>Caution!</b> This setting may reveal errors (from other plugins) in other places on your site too, therefor this is not recommended to leave it enabled on live sites.', 'woocommerce-pdf-invoices-packing-slips' ),
|
159 |
-
)
|
160 |
-
),
|
161 |
-
array(
|
162 |
-
'type' => 'setting',
|
163 |
-
'id' => 'html_output',
|
164 |
-
'title' => __( 'Output to HTML', 'woocommerce-pdf-invoices-packing-slips' ),
|
165 |
-
'callback' => 'checkbox',
|
166 |
-
'section' => 'debug_settings',
|
167 |
-
'args' => array(
|
168 |
-
'option_name' => $option_name,
|
169 |
-
'id' => 'html_output',
|
170 |
-
'description' => __( 'Send the template output as HTML to the browser instead of creating a PDF.', 'woocommerce-pdf-invoices-packing-slips' ),
|
171 |
-
)
|
172 |
-
),
|
173 |
-
);
|
174 |
-
|
175 |
-
// allow plugins to alter settings fields
|
176 |
-
$settings_fields = apply_filters( 'wpo_wcpdf_settings_fields_debug', $settings_fields, $page, $option_group, $option_name );
|
177 |
-
WPO_WCPDF()->settings->add_settings_fields( $settings_fields, $page, $option_group, $option_name );
|
178 |
-
return;
|
179 |
-
}
|
180 |
-
|
181 |
-
}
|
182 |
-
|
183 |
-
endif; // class_exists
|
184 |
-
|
185 |
Â
return new Settings_Debug();
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices;
|
3 |
+
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit; // Exit if accessed directly
|
6 |
+
}
|
7 |
+
|
8 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings_Debug' ) ) :
|
9 |
+
|
10 |
+
class Settings_Debug {
|
11 |
+
|
12 |
+
function __construct() {
|
13 |
+
add_action( 'admin_init', array( $this, 'init_settings' ) );
|
14 |
+
add_action( 'wpo_wcpdf_settings_output_debug', array( $this, 'output' ), 10, 1 );
|
15 |
+
add_action( 'wpo_wcpdf_after_settings_page', array( $this, 'debug_tools' ), 10, 2 );
|
16 |
+
}
|
17 |
+
|
18 |
+
public function output( $section ) {
|
19 |
+
settings_fields( "wpo_wcpdf_settings_debug" );
|
20 |
+
do_settings_sections( "wpo_wcpdf_settings_debug" );
|
21 |
+
|
22 |
+
submit_button();
|
23 |
+
}
|
24 |
+
|
25 |
+
public function debug_tools( $tab, $section ) {
|
26 |
+
if ($tab !== 'debug') {
|
27 |
+
return;
|
28 |
+
}
|
29 |
+
?>
|
30 |
+
<form method="post">
|
31 |
+
<input type="hidden" name="wpo_wcpdf_debug_tools_action" value="install_fonts">
|
32 |
+
<input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Reinstall fonts', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
|
33 |
+
<?php
|
34 |
+
if (isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'install_fonts') {
|
35 |
+
$font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' );
|
36 |
+
|
37 |
+
// clear folder first
|
38 |
+
if ( function_exists("glob") && $files = glob( $font_path.'/*.*' ) ) {
|
39 |
+
$exclude_files = array( 'index.php', '.htaccess' );
|
40 |
+
foreach($files as $file) {
|
41 |
+
if( is_file($file) && !in_array( basename($file), $exclude_files ) ) {
|
42 |
+
unlink($file);
|
43 |
+
}
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
WPO_WCPDF()->main->copy_fonts( $font_path );
|
48 |
+
printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Fonts reinstalled!', 'woocommerce-pdf-invoices-packing-slips' ) );
|
49 |
+
}
|
50 |
+
?>
|
51 |
+
</form>
|
52 |
+
<form method="post">
|
53 |
+
<input type="hidden" name="wpo_wcpdf_debug_tools_action" value="clear_tmp">
|
54 |
+
<input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Remove temporary files', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
|
55 |
+
<?php
|
56 |
+
if (isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'clear_tmp') {
|
57 |
+
$tmp_path = WPO_WCPDF()->main->get_tmp_path('attachments');
|
58 |
+
|
59 |
+
if ( !function_exists("glob") ) {
|
60 |
+
// glob is disabled
|
61 |
+
printf('<div class="notice notice-error"><p>%s<br><code>%s</code></p></div>', __( "Unable to read temporary folder contents!", 'woocommerce-pdf-invoices-packing-slips' ), $tmp_path);
|
62 |
+
} else {
|
63 |
+
$success = 0;
|
64 |
+
$error = 0;
|
65 |
+
if ( $files = glob($tmp_path.'*.pdf') ) { // get all pdf files
|
66 |
+
foreach($files as $file) {
|
67 |
+
if(is_file($file)) {
|
68 |
+
// delete file
|
69 |
+
if ( unlink($file) === true ) {
|
70 |
+
$success++;
|
71 |
+
} else {
|
72 |
+
$error++;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
if ($error > 0) {
|
78 |
+
$message = sprintf( __( 'Unable to delete %d files! (deleted %d)', 'woocommerce-pdf-invoices-packing-slips' ), $error, $success);
|
79 |
+
printf('<div class="notice notice-error"><p>%s</p></div>', $message);
|
80 |
+
} else {
|
81 |
+
$message = sprintf( __( 'Successfully deleted %d files!', 'woocommerce-pdf-invoices-packing-slips' ), $success );
|
82 |
+
printf('<div class="notice notice-success"><p>%s</p></div>', $message);
|
83 |
+
}
|
84 |
+
} else {
|
85 |
+
printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Nothing to delete!', 'woocommerce-pdf-invoices-packing-slips' ) );
|
86 |
+
}
|
87 |
+
}
|
88 |
+
}
|
89 |
+
?>
|
90 |
+
</form>
|
91 |
+
<form method="post">
|
92 |
+
<input type="hidden" name="wpo_wcpdf_debug_tools_action" value="delete_legacy_settings">
|
93 |
+
<input type="submit" name="submit" id="submit" class="button" value="<?php _e( 'Delete legacy (1.X) settings', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
|
94 |
+
<?php
|
95 |
+
if (isset($_POST['wpo_wcpdf_debug_tools_action']) && $_POST['wpo_wcpdf_debug_tools_action'] == 'delete_legacy_settings') {
|
96 |
+
// delete options
|
97 |
+
delete_option( 'wpo_wcpdf_general_settings' );
|
98 |
+
delete_option( 'wpo_wcpdf_template_settings' );
|
99 |
+
delete_option( 'wpo_wcpdf_debug_settings' );
|
100 |
+
// and delete cache of these options, just in case...
|
101 |
+
wp_cache_delete( 'wpo_wcpdf_general_settings','options' );
|
102 |
+
wp_cache_delete( 'wpo_wcpdf_template_settings','options' );
|
103 |
+
wp_cache_delete( 'wpo_wcpdf_debug_settings','options' );
|
104 |
+
|
105 |
+
printf('<div class="notice notice-success"><p>%s</p></div>', __( 'Legacy settings deleted!', 'woocommerce-pdf-invoices-packing-slips' ) );
|
106 |
+
}
|
107 |
+
?>
|
108 |
+
</form>
|
109 |
+
<?php
|
110 |
+
include( WPO_WCPDF()->plugin_path() . '/includes/views/dompdf-status.php' );
|
111 |
+
}
|
112 |
+
|
113 |
+
public function init_settings() {
|
114 |
+
// Register settings.
|
115 |
+
$page = $option_group = $option_name = 'wpo_wcpdf_settings_debug';
|
116 |
+
|
117 |
+
$settings_fields = array(
|
118 |
+
array(
|
119 |
+
'type' => 'section',
|
120 |
+
'id' => 'debug_settings',
|
121 |
+
'title' => __( 'Debug settings', 'woocommerce-pdf-invoices-packing-slips' ),
|
122 |
+
'callback' => 'section',
|
123 |
+
),
|
124 |
+
array(
|
125 |
+
'type' => 'setting',
|
126 |
+
'id' => 'legacy_mode',
|
127 |
+
'title' => __( 'Legacy mode', 'woocommerce-pdf-invoices-packing-slips' ),
|
128 |
+
'callback' => 'checkbox',
|
129 |
+
'section' => 'debug_settings',
|
130 |
+
'args' => array(
|
131 |
+
'option_name' => $option_name,
|
132 |
+
'id' => 'legacy_mode',
|
133 |
+
'description' => __( "Legacy mode ensures compatibility with templates and filters from previous versions.", 'woocommerce-pdf-invoices-packing-slips' ),
|
134 |
+
)
|
135 |
+
),
|
136 |
+
array(
|
137 |
+
'type' => 'setting',
|
138 |
+
'id' => 'calculate_document_numbers',
|
139 |
+
'title' => __( 'Calculate document numbers (slow)', 'woocommerce-pdf-invoices-packing-slips' ),
|
140 |
+
'callback' => 'checkbox',
|
141 |
+
'section' => 'debug_settings',
|
142 |
+
'args' => array(
|
143 |
+
'option_name' => $option_name,
|
144 |
+
'id' => 'calculate_document_numbers',
|
145 |
+
'description' => __( "Document numbers (such as invoice numbers) are generated using AUTO_INCREMENT by default. Use this setting if your database auto increments with more than 1.", 'woocommerce-pdf-invoices-packing-slips' ),
|
146 |
+
)
|
147 |
+
),
|
148 |
+
array(
|
149 |
+
'type' => 'setting',
|
150 |
+
'id' => 'enable_debug',
|
151 |
+
'title' => __( 'Enable debug output', 'woocommerce-pdf-invoices-packing-slips' ),
|
152 |
+
'callback' => 'checkbox',
|
153 |
+
'section' => 'debug_settings',
|
154 |
+
'args' => array(
|
155 |
+
'option_name' => $option_name,
|
156 |
+
'id' => 'enable_debug',
|
157 |
+
'description' => __( "Enable this option to output plugin errors if you're getting a blank page or other PDF generation issues", 'woocommerce-pdf-invoices-packing-slips' ) . '<br>' .
|
158 |
+
__( '<b>Caution!</b> This setting may reveal errors (from other plugins) in other places on your site too, therefor this is not recommended to leave it enabled on live sites.', 'woocommerce-pdf-invoices-packing-slips' ),
|
159 |
+
)
|
160 |
+
),
|
161 |
+
array(
|
162 |
+
'type' => 'setting',
|
163 |
+
'id' => 'html_output',
|
164 |
+
'title' => __( 'Output to HTML', 'woocommerce-pdf-invoices-packing-slips' ),
|
165 |
+
'callback' => 'checkbox',
|
166 |
+
'section' => 'debug_settings',
|
167 |
+
'args' => array(
|
168 |
+
'option_name' => $option_name,
|
169 |
+
'id' => 'html_output',
|
170 |
+
'description' => __( 'Send the template output as HTML to the browser instead of creating a PDF.', 'woocommerce-pdf-invoices-packing-slips' ),
|
171 |
+
)
|
172 |
+
),
|
173 |
+
);
|
174 |
+
|
175 |
+
// allow plugins to alter settings fields
|
176 |
+
$settings_fields = apply_filters( 'wpo_wcpdf_settings_fields_debug', $settings_fields, $page, $option_group, $option_name );
|
177 |
+
WPO_WCPDF()->settings->add_settings_fields( $settings_fields, $page, $option_group, $option_name );
|
178 |
+
return;
|
179 |
+
}
|
180 |
+
|
181 |
+
}
|
182 |
+
|
183 |
+
endif; // class_exists
|
184 |
+
|
185 |
Â
return new Settings_Debug();
|
includes/class-wcpdf-settings-general.php
CHANGED
@@ -1,270 +1,275 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices;
|
3 |
-
|
4 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
-
exit; // Exit if accessed directly
|
6 |
-
}
|
7 |
-
|
8 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings_General' ) ) :
|
9 |
-
|
10 |
-
class Settings_General {
|
11 |
-
|
12 |
-
function __construct() {
|
13 |
-
add_action( 'admin_init', array( $this, 'init_settings' ) );
|
14 |
-
add_action( 'wpo_wcpdf_settings_output_general', array( $this, 'output' ), 10, 1 );
|
15 |
-
}
|
16 |
-
|
17 |
-
public function output( $section ) {
|
18 |
-
settings_fields( "wpo_wcpdf_settings_general" );
|
19 |
-
do_settings_sections( "wpo_wcpdf_settings_general" );
|
20 |
-
|
21 |
-
submit_button();
|
22 |
-
}
|
23 |
-
|
24 |
-
public function init_settings() {
|
25 |
-
$page = $option_group = $option_name = 'wpo_wcpdf_settings_general';
|
26 |
-
|
27 |
-
$template_base_path = ( defined( 'WC_TEMPLATE_PATH' ) ? WC_TEMPLATE_PATH : $GLOBALS['woocommerce']->template_url );
|
28 |
-
$theme_template_path = get_stylesheet_directory() . '/' . $template_base_path;
|
29 |
-
$wp_content_dir = str_replace( ABSPATH, '', WP_CONTENT_DIR );
|
30 |
-
$theme_template_path = substr($theme_template_path, strpos($theme_template_path, $wp_content_dir)) . 'pdf/yourtemplate';
|
31 |
-
$plugin_template_path = "{$wp_content_dir}/plugins/woocommerce-pdf-invoices-packing-slips/templates/Simple";
|
32 |
-
|
33 |
-
$settings_fields = array(
|
34 |
-
array(
|
35 |
-
'type' => 'section',
|
36 |
-
'id' => 'general_settings',
|
37 |
-
'title' => __( 'General settings', 'woocommerce-pdf-invoices-packing-slips' ),
|
38 |
-
'callback' => 'section',
|
39 |
-
),
|
40 |
-
array(
|
41 |
-
'type' => 'setting',
|
42 |
-
'id' => 'download_display',
|
43 |
-
'title' => __( 'How do you want to view the PDF?', 'woocommerce-pdf-invoices-packing-slips' ),
|
44 |
-
'callback' => 'select',
|
45 |
-
'section' => 'general_settings',
|
46 |
-
'args' => array(
|
47 |
-
'option_name' => $option_name,
|
48 |
-
'id' => 'download_display',
|
49 |
-
'options' => array(
|
50 |
-
'download' => __( 'Download the PDF' , 'woocommerce-pdf-invoices-packing-slips' ),
|
51 |
-
'display' => __( 'Open the PDF in a new browser tab/window' , 'woocommerce-pdf-invoices-packing-slips' ),
|
52 |
-
),
|
53 |
-
)
|
54 |
-
),
|
55 |
-
array(
|
56 |
-
'type' => 'setting',
|
57 |
-
'id' => 'template_path',
|
58 |
-
'title' => __( 'Choose a template', 'woocommerce-pdf-invoices-packing-slips' ),
|
59 |
-
'callback' => 'select',
|
60 |
-
'section' => 'general_settings',
|
61 |
-
'args' => array(
|
62 |
-
'option_name' => $option_name,
|
63 |
-
'id' => 'template_path',
|
64 |
-
'options' => $this->find_templates(),
|
65 |
-
'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' , 'woocommerce-pdf-invoices-packing-slips' ), $plugin_template_path, $theme_template_path),
|
66 |
-
)
|
67 |
-
),
|
68 |
-
array(
|
69 |
-
'type' => 'setting',
|
70 |
-
'id' => 'paper_size',
|
71 |
-
'title' => __( 'Paper size', 'woocommerce-pdf-invoices-packing-slips' ),
|
72 |
-
'callback' => 'select',
|
73 |
-
'section' => 'general_settings',
|
74 |
-
'args' => array(
|
75 |
-
'option_name' => $option_name,
|
76 |
-
'id' => 'paper_size',
|
77 |
-
'options' => apply_filters( 'wpo_wcpdf_template_settings_paper_size', array(
|
78 |
-
'a4' => __( 'A4' , 'woocommerce-pdf-invoices-packing-slips' ),
|
79 |
-
'letter' => __( 'Letter' , 'woocommerce-pdf-invoices-packing-slips' ),
|
80 |
-
) ),
|
81 |
-
)
|
82 |
-
),
|
83 |
-
array(
|
84 |
-
'type' => 'setting',
|
85 |
-
'id' => 'currency_font',
|
86 |
-
'title' => __( 'Extended currency symbol support', 'woocommerce-pdf-invoices-packing-slips' ),
|
87 |
-
'callback' => 'checkbox',
|
88 |
-
'section' => 'general_settings',
|
89 |
-
'args' => array(
|
90 |
-
'option_name' => $option_name,
|
91 |
-
'id' => 'currency_font',
|
92 |
-
'description' => __( 'Enable this if your currency symbol is not displaying properly' , 'woocommerce-pdf-invoices-packing-slips' ),
|
93 |
-
)
|
94 |
-
),
|
95 |
-
array(
|
96 |
-
'type' => 'setting',
|
97 |
-
'id' => 'font_subsetting',
|
98 |
-
'title' => __( 'Enable font subsetting', 'woocommerce-pdf-invoices-packing-slips' ),
|
99 |
-
'callback' => 'checkbox',
|
100 |
-
'section' => 'general_settings',
|
101 |
-
'args' => array(
|
102 |
-
'option_name' => $option_name,
|
103 |
-
'id' => 'font_subsetting',
|
104 |
-
'description' => __( "Font subsetting can reduce file size by only including the characters that are used in the PDF, but limits the ability to edit PDF files later. Recommended if you're using an Asian font." , 'woocommerce-pdf-invoices-packing-slips' ),
|
105 |
-
)
|
106 |
-
),
|
107 |
-
array(
|
108 |
-
'type' => 'setting',
|
109 |
-
'id' => 'header_logo',
|
110 |
-
'title' => __( 'Shop header/logo', 'woocommerce-pdf-invoices-packing-slips' ),
|
111 |
-
'callback' => 'media_upload',
|
112 |
-
'section' => 'general_settings',
|
113 |
-
'args' => array(
|
114 |
-
'option_name' => $option_name,
|
115 |
-
'id' => 'header_logo',
|
116 |
-
'uploader_title' => __( 'Select or upload your invoice header/logo', 'woocommerce-pdf-invoices-packing-slips' ),
|
117 |
-
'uploader_button_text' => __( 'Set image', 'woocommerce-pdf-invoices-packing-slips' ),
|
118 |
-
'remove_button_text' => __( 'Remove image', 'woocommerce-pdf-invoices-packing-slips' ),
|
119 |
-
//'description' => __( '...', 'woocommerce-pdf-invoices-packing-slips' ),
|
120 |
-
)
|
121 |
-
),
|
122 |
-
array(
|
123 |
-
'type' => 'setting',
|
124 |
-
'id' => 'shop_name',
|
125 |
-
'title' => __( 'Shop Name', 'woocommerce-pdf-invoices-packing-slips' ),
|
126 |
-
'callback' => 'text_input',
|
127 |
-
'section' => 'general_settings',
|
128 |
-
'args' => array(
|
129 |
-
'option_name' => $option_name,
|
130 |
-
'id' => 'shop_name',
|
131 |
-
'size' => '72',
|
132 |
-
'translatable' => true,
|
133 |
-
)
|
134 |
-
),
|
135 |
-
array(
|
136 |
-
'type' => 'setting',
|
137 |
-
'id' => 'shop_address',
|
138 |
-
'title' => __( 'Shop Address', 'woocommerce-pdf-invoices-packing-slips' ),
|
139 |
-
'callback' => 'textarea',
|
140 |
-
'section' => 'general_settings',
|
141 |
-
'args' => array(
|
142 |
-
'option_name' => $option_name,
|
143 |
-
'id' => 'shop_address',
|
144 |
-
'width' => '72',
|
145 |
-
'height' => '8',
|
146 |
-
'translatable' => true,
|
147 |
-
//'description' => __( '...', 'woocommerce-pdf-invoices-packing-slips' ),
|
148 |
-
)
|
149 |
-
),
|
150 |
-
array(
|
151 |
-
'type' => 'setting',
|
152 |
-
'id' => 'footer',
|
153 |
-
'title' => __( 'Footer: terms & conditions, policies, etc.', 'woocommerce-pdf-invoices-packing-slips' ),
|
154 |
-
'callback' => 'textarea',
|
155 |
-
'section' => 'general_settings',
|
156 |
-
'args' => array(
|
157 |
-
'option_name' => $option_name,
|
158 |
-
'id' => 'footer',
|
159 |
-
'width' => '72',
|
160 |
-
'height' => '4',
|
161 |
-
'translatable' => true,
|
162 |
-
//'description' => __( '...', 'woocommerce-pdf-invoices-packing-slips' ),
|
163 |
-
)
|
164 |
-
),
|
165 |
-
array(
|
166 |
-
'type' => 'section',
|
167 |
-
'id' => 'extra_template_fields',
|
168 |
-
'title' => __( 'Extra template fields', 'woocommerce-pdf-invoices-packing-slips' ),
|
169 |
-
'callback' => 'custom_fields_section',
|
170 |
-
),
|
171 |
-
array(
|
172 |
-
'type' => 'setting',
|
173 |
-
'id' => 'extra_1',
|
174 |
-
'title' => __( 'Extra field 1', 'woocommerce-pdf-invoices-packing-slips' ),
|
175 |
-
'callback' => 'textarea',
|
176 |
-
'section' => 'extra_template_fields',
|
177 |
-
'args' => array(
|
178 |
-
'option_name' => $option_name,
|
179 |
-
'id' => 'extra_1',
|
180 |
-
'width' => '72',
|
181 |
-
'height' => '8',
|
182 |
-
'description' => __( 'This is footer column 1 in the <i>Modern (Premium)</i> template', 'woocommerce-pdf-invoices-packing-slips' ),
|
183 |
-
'translatable' => true,
|
184 |
-
)
|
185 |
-
),
|
186 |
-
array(
|
187 |
-
'type' => 'setting',
|
188 |
-
'id' => 'extra_2',
|
189 |
-
'title' => __( 'Extra field 2', 'woocommerce-pdf-invoices-packing-slips' ),
|
190 |
-
'callback' => 'textarea',
|
191 |
-
'section' => 'extra_template_fields',
|
192 |
-
'args' => array(
|
193 |
-
'option_name' => $option_name,
|
194 |
-
'id' => 'extra_2',
|
195 |
-
'width' => '72',
|
196 |
-
'height' => '8',
|
197 |
-
'description' => __( 'This is footer column 2 in the <i>Modern (Premium)</i> template', 'woocommerce-pdf-invoices-packing-slips' ),
|
198 |
-
'translatable' => true,
|
199 |
-
)
|
200 |
-
),
|
201 |
-
array(
|
202 |
-
'type' => 'setting',
|
203 |
-
'id' => 'extra_3',
|
204 |
-
'title' => __( 'Extra field 3', 'woocommerce-pdf-invoices-packing-slips' ),
|
205 |
-
'callback' => 'textarea',
|
206 |
-
'section' => 'extra_template_fields',
|
207 |
-
'args' => array(
|
208 |
-
'option_name' => $option_name,
|
209 |
-
'id' => 'extra_3',
|
210 |
-
'width' => '72',
|
211 |
-
'height' => '8',
|
212 |
-
'description' => __( 'This is footer column 3 in the <i>Modern (Premium)</i> template', 'woocommerce-pdf-invoices-packing-slips' ),
|
213 |
-
'translatable' => true,
|
214 |
-
)
|
215 |
-
),
|
216 |
-
);
|
217 |
-
|
218 |
-
// allow plugins to alter settings fields
|
219 |
-
$settings_fields = apply_filters( 'wpo_wcpdf_settings_fields_general', $settings_fields, $page, $option_group, $option_name );
|
220 |
-
WPO_WCPDF()->settings->add_settings_fields( $settings_fields, $page, $option_group, $option_name );
|
221 |
-
return;
|
222 |
-
}
|
223 |
-
|
224 |
-
/**
|
225 |
-
* List templates in plugin folder, theme folder & child theme folder
|
226 |
-
* @return array template path => template name
|
227 |
-
*/
|
228 |
-
public function find_templates() {
|
229 |
-
$installed_templates = array();
|
230 |
-
|
231 |
-
// get base paths
|
232 |
-
$template_base_path = ( defined( 'WC_TEMPLATE_PATH' ) ? WC_TEMPLATE_PATH : $GLOBALS['woocommerce']->template_url );
|
233 |
-
$template_base_path = untrailingslashit( $template_base_path );
|
234 |
-
$template_paths = array (
|
235 |
-
// note the order: child-theme before theme, so that array_unique filters out parent doubles
|
236 |
-
'default' => WPO_WCPDF()->plugin_path() . '/templates/',
|
237 |
-
'child-theme' => get_stylesheet_directory() . "/{$template_base_path}/pdf/",
|
238 |
-
'theme' => get_template_directory() . "/{$template_base_path}/pdf/",
|
239 |
-
);
|
240 |
-
|
241 |
-
$template_paths = apply_filters( 'wpo_wcpdf_template_paths', $template_paths );
|
242 |
-
|
243 |
-
|
244 |
-
$
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
}
|
267 |
-
|
268 |
-
|
269 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
270 |
Â
return new Settings_General();
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices;
|
3 |
+
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit; // Exit if accessed directly
|
6 |
+
}
|
7 |
+
|
8 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings_General' ) ) :
|
9 |
+
|
10 |
+
class Settings_General {
|
11 |
+
|
12 |
+
function __construct() {
|
13 |
+
add_action( 'admin_init', array( $this, 'init_settings' ) );
|
14 |
+
add_action( 'wpo_wcpdf_settings_output_general', array( $this, 'output' ), 10, 1 );
|
15 |
+
}
|
16 |
+
|
17 |
+
public function output( $section ) {
|
18 |
+
settings_fields( "wpo_wcpdf_settings_general" );
|
19 |
+
do_settings_sections( "wpo_wcpdf_settings_general" );
|
20 |
+
|
21 |
+
submit_button();
|
22 |
+
}
|
23 |
+
|
24 |
+
public function init_settings() {
|
25 |
+
$page = $option_group = $option_name = 'wpo_wcpdf_settings_general';
|
26 |
+
|
27 |
+
$template_base_path = ( defined( 'WC_TEMPLATE_PATH' ) ? WC_TEMPLATE_PATH : $GLOBALS['woocommerce']->template_url );
|
28 |
+
$theme_template_path = get_stylesheet_directory() . '/' . $template_base_path;
|
29 |
+
$wp_content_dir = str_replace( ABSPATH, '', WP_CONTENT_DIR );
|
30 |
+
$theme_template_path = substr($theme_template_path, strpos($theme_template_path, $wp_content_dir)) . 'pdf/yourtemplate';
|
31 |
+
$plugin_template_path = "{$wp_content_dir}/plugins/woocommerce-pdf-invoices-packing-slips/templates/Simple";
|
32 |
+
|
33 |
+
$settings_fields = array(
|
34 |
+
array(
|
35 |
+
'type' => 'section',
|
36 |
+
'id' => 'general_settings',
|
37 |
+
'title' => __( 'General settings', 'woocommerce-pdf-invoices-packing-slips' ),
|
38 |
+
'callback' => 'section',
|
39 |
+
),
|
40 |
+
array(
|
41 |
+
'type' => 'setting',
|
42 |
+
'id' => 'download_display',
|
43 |
+
'title' => __( 'How do you want to view the PDF?', 'woocommerce-pdf-invoices-packing-slips' ),
|
44 |
+
'callback' => 'select',
|
45 |
+
'section' => 'general_settings',
|
46 |
+
'args' => array(
|
47 |
+
'option_name' => $option_name,
|
48 |
+
'id' => 'download_display',
|
49 |
+
'options' => array(
|
50 |
+
'download' => __( 'Download the PDF' , 'woocommerce-pdf-invoices-packing-slips' ),
|
51 |
+
'display' => __( 'Open the PDF in a new browser tab/window' , 'woocommerce-pdf-invoices-packing-slips' ),
|
52 |
+
),
|
53 |
+
)
|
54 |
+
),
|
55 |
+
array(
|
56 |
+
'type' => 'setting',
|
57 |
+
'id' => 'template_path',
|
58 |
+
'title' => __( 'Choose a template', 'woocommerce-pdf-invoices-packing-slips' ),
|
59 |
+
'callback' => 'select',
|
60 |
+
'section' => 'general_settings',
|
61 |
+
'args' => array(
|
62 |
+
'option_name' => $option_name,
|
63 |
+
'id' => 'template_path',
|
64 |
+
'options' => $this->find_templates(),
|
65 |
+
'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' , 'woocommerce-pdf-invoices-packing-slips' ), $plugin_template_path, $theme_template_path),
|
66 |
+
)
|
67 |
+
),
|
68 |
+
array(
|
69 |
+
'type' => 'setting',
|
70 |
+
'id' => 'paper_size',
|
71 |
+
'title' => __( 'Paper size', 'woocommerce-pdf-invoices-packing-slips' ),
|
72 |
+
'callback' => 'select',
|
73 |
+
'section' => 'general_settings',
|
74 |
+
'args' => array(
|
75 |
+
'option_name' => $option_name,
|
76 |
+
'id' => 'paper_size',
|
77 |
+
'options' => apply_filters( 'wpo_wcpdf_template_settings_paper_size', array(
|
78 |
+
'a4' => __( 'A4' , 'woocommerce-pdf-invoices-packing-slips' ),
|
79 |
+
'letter' => __( 'Letter' , 'woocommerce-pdf-invoices-packing-slips' ),
|
80 |
+
) ),
|
81 |
+
)
|
82 |
+
),
|
83 |
+
array(
|
84 |
+
'type' => 'setting',
|
85 |
+
'id' => 'currency_font',
|
86 |
+
'title' => __( 'Extended currency symbol support', 'woocommerce-pdf-invoices-packing-slips' ),
|
87 |
+
'callback' => 'checkbox',
|
88 |
+
'section' => 'general_settings',
|
89 |
+
'args' => array(
|
90 |
+
'option_name' => $option_name,
|
91 |
+
'id' => 'currency_font',
|
92 |
+
'description' => __( 'Enable this if your currency symbol is not displaying properly' , 'woocommerce-pdf-invoices-packing-slips' ),
|
93 |
+
)
|
94 |
+
),
|
95 |
+
array(
|
96 |
+
'type' => 'setting',
|
97 |
+
'id' => 'font_subsetting',
|
98 |
+
'title' => __( 'Enable font subsetting', 'woocommerce-pdf-invoices-packing-slips' ),
|
99 |
+
'callback' => 'checkbox',
|
100 |
+
'section' => 'general_settings',
|
101 |
+
'args' => array(
|
102 |
+
'option_name' => $option_name,
|
103 |
+
'id' => 'font_subsetting',
|
104 |
+
'description' => __( "Font subsetting can reduce file size by only including the characters that are used in the PDF, but limits the ability to edit PDF files later. Recommended if you're using an Asian font." , 'woocommerce-pdf-invoices-packing-slips' ),
|
105 |
+
)
|
106 |
+
),
|
107 |
+
array(
|
108 |
+
'type' => 'setting',
|
109 |
+
'id' => 'header_logo',
|
110 |
+
'title' => __( 'Shop header/logo', 'woocommerce-pdf-invoices-packing-slips' ),
|
111 |
+
'callback' => 'media_upload',
|
112 |
+
'section' => 'general_settings',
|
113 |
+
'args' => array(
|
114 |
+
'option_name' => $option_name,
|
115 |
+
'id' => 'header_logo',
|
116 |
+
'uploader_title' => __( 'Select or upload your invoice header/logo', 'woocommerce-pdf-invoices-packing-slips' ),
|
117 |
+
'uploader_button_text' => __( 'Set image', 'woocommerce-pdf-invoices-packing-slips' ),
|
118 |
+
'remove_button_text' => __( 'Remove image', 'woocommerce-pdf-invoices-packing-slips' ),
|
119 |
+
//'description' => __( '...', 'woocommerce-pdf-invoices-packing-slips' ),
|
120 |
+
)
|
121 |
+
),
|
122 |
+
array(
|
123 |
+
'type' => 'setting',
|
124 |
+
'id' => 'shop_name',
|
125 |
+
'title' => __( 'Shop Name', 'woocommerce-pdf-invoices-packing-slips' ),
|
126 |
+
'callback' => 'text_input',
|
127 |
+
'section' => 'general_settings',
|
128 |
+
'args' => array(
|
129 |
+
'option_name' => $option_name,
|
130 |
+
'id' => 'shop_name',
|
131 |
+
'size' => '72',
|
132 |
+
'translatable' => true,
|
133 |
+
)
|
134 |
+
),
|
135 |
+
array(
|
136 |
+
'type' => 'setting',
|
137 |
+
'id' => 'shop_address',
|
138 |
+
'title' => __( 'Shop Address', 'woocommerce-pdf-invoices-packing-slips' ),
|
139 |
+
'callback' => 'textarea',
|
140 |
+
'section' => 'general_settings',
|
141 |
+
'args' => array(
|
142 |
+
'option_name' => $option_name,
|
143 |
+
'id' => 'shop_address',
|
144 |
+
'width' => '72',
|
145 |
+
'height' => '8',
|
146 |
+
'translatable' => true,
|
147 |
+
//'description' => __( '...', 'woocommerce-pdf-invoices-packing-slips' ),
|
148 |
+
)
|
149 |
+
),
|
150 |
+
array(
|
151 |
+
'type' => 'setting',
|
152 |
+
'id' => 'footer',
|
153 |
+
'title' => __( 'Footer: terms & conditions, policies, etc.', 'woocommerce-pdf-invoices-packing-slips' ),
|
154 |
+
'callback' => 'textarea',
|
155 |
+
'section' => 'general_settings',
|
156 |
+
'args' => array(
|
157 |
+
'option_name' => $option_name,
|
158 |
+
'id' => 'footer',
|
159 |
+
'width' => '72',
|
160 |
+
'height' => '4',
|
161 |
+
'translatable' => true,
|
162 |
+
//'description' => __( '...', 'woocommerce-pdf-invoices-packing-slips' ),
|
163 |
+
)
|
164 |
+
),
|
165 |
+
array(
|
166 |
+
'type' => 'section',
|
167 |
+
'id' => 'extra_template_fields',
|
168 |
+
'title' => __( 'Extra template fields', 'woocommerce-pdf-invoices-packing-slips' ),
|
169 |
+
'callback' => 'custom_fields_section',
|
170 |
+
),
|
171 |
+
array(
|
172 |
+
'type' => 'setting',
|
173 |
+
'id' => 'extra_1',
|
174 |
+
'title' => __( 'Extra field 1', 'woocommerce-pdf-invoices-packing-slips' ),
|
175 |
+
'callback' => 'textarea',
|
176 |
+
'section' => 'extra_template_fields',
|
177 |
+
'args' => array(
|
178 |
+
'option_name' => $option_name,
|
179 |
+
'id' => 'extra_1',
|
180 |
+
'width' => '72',
|
181 |
+
'height' => '8',
|
182 |
+
'description' => __( 'This is footer column 1 in the <i>Modern (Premium)</i> template', 'woocommerce-pdf-invoices-packing-slips' ),
|
183 |
+
'translatable' => true,
|
184 |
+
)
|
185 |
+
),
|
186 |
+
array(
|
187 |
+
'type' => 'setting',
|
188 |
+
'id' => 'extra_2',
|
189 |
+
'title' => __( 'Extra field 2', 'woocommerce-pdf-invoices-packing-slips' ),
|
190 |
+
'callback' => 'textarea',
|
191 |
+
'section' => 'extra_template_fields',
|
192 |
+
'args' => array(
|
193 |
+
'option_name' => $option_name,
|
194 |
+
'id' => 'extra_2',
|
195 |
+
'width' => '72',
|
196 |
+
'height' => '8',
|
197 |
+
'description' => __( 'This is footer column 2 in the <i>Modern (Premium)</i> template', 'woocommerce-pdf-invoices-packing-slips' ),
|
198 |
+
'translatable' => true,
|
199 |
+
)
|
200 |
+
),
|
201 |
+
array(
|
202 |
+
'type' => 'setting',
|
203 |
+
'id' => 'extra_3',
|
204 |
+
'title' => __( 'Extra field 3', 'woocommerce-pdf-invoices-packing-slips' ),
|
205 |
+
'callback' => 'textarea',
|
206 |
+
'section' => 'extra_template_fields',
|
207 |
+
'args' => array(
|
208 |
+
'option_name' => $option_name,
|
209 |
+
'id' => 'extra_3',
|
210 |
+
'width' => '72',
|
211 |
+
'height' => '8',
|
212 |
+
'description' => __( 'This is footer column 3 in the <i>Modern (Premium)</i> template', 'woocommerce-pdf-invoices-packing-slips' ),
|
213 |
+
'translatable' => true,
|
214 |
+
)
|
215 |
+
),
|
216 |
+
);
|
217 |
+
|
218 |
+
// allow plugins to alter settings fields
|
219 |
+
$settings_fields = apply_filters( 'wpo_wcpdf_settings_fields_general', $settings_fields, $page, $option_group, $option_name );
|
220 |
+
WPO_WCPDF()->settings->add_settings_fields( $settings_fields, $page, $option_group, $option_name );
|
221 |
+
return;
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* List templates in plugin folder, theme folder & child theme folder
|
226 |
+
* @return array template path => template name
|
227 |
+
*/
|
228 |
+
public function find_templates() {
|
229 |
+
$installed_templates = array();
|
230 |
+
|
231 |
+
// get base paths
|
232 |
+
$template_base_path = ( defined( 'WC_TEMPLATE_PATH' ) ? WC_TEMPLATE_PATH : $GLOBALS['woocommerce']->template_url );
|
233 |
+
$template_base_path = untrailingslashit( $template_base_path );
|
234 |
+
$template_paths = array (
|
235 |
+
// note the order: child-theme before theme, so that array_unique filters out parent doubles
|
236 |
+
'default' => WPO_WCPDF()->plugin_path() . '/templates/',
|
237 |
+
'child-theme' => get_stylesheet_directory() . "/{$template_base_path}/pdf/",
|
238 |
+
'theme' => get_template_directory() . "/{$template_base_path}/pdf/",
|
239 |
+
);
|
240 |
+
|
241 |
+
$template_paths = apply_filters( 'wpo_wcpdf_template_paths', $template_paths );
|
242 |
+
|
243 |
+
if ( defined('WP_CONTENT_DIR') && strpos( WP_CONTENT_DIR, ABSPATH ) !== false ) {
|
244 |
+
$forwardslash_basepath = str_replace('\\','/', ABSPATH);
|
245 |
+
} else {
|
246 |
+
$forwardslash_basepath = str_replace('\\','/', WP_CONTENT_DIR);
|
247 |
+
}
|
248 |
+
|
249 |
+
foreach ($template_paths as $template_source => $template_path) {
|
250 |
+
$dirs = (array) glob( $template_path . '*' , GLOB_ONLYDIR);
|
251 |
+
|
252 |
+
foreach ($dirs as $dir) {
|
253 |
+
// we're stripping abspath to make the plugin settings more portable
|
254 |
+
$forwardslash_dir = str_replace('\\','/', $dir);
|
255 |
+
$installed_templates[ str_replace( $forwardslash_basepath, '', $forwardslash_dir ) ] = basename($dir);
|
256 |
+
}
|
257 |
+
}
|
258 |
+
|
259 |
+
// remove parent doubles
|
260 |
+
$installed_templates = array_unique($installed_templates);
|
261 |
+
|
262 |
+
if (empty($installed_templates)) {
|
263 |
+
// fallback to Simple template for servers with glob() disabled
|
264 |
+
$simple_template_path = str_replace( ABSPATH, '', $template_paths['default'] . 'Simple' );
|
265 |
+
$installed_templates[$simple_template_path] = 'Simple';
|
266 |
+
}
|
267 |
+
|
268 |
+
return apply_filters( 'wpo_wcpdf_templates', $installed_templates );
|
269 |
+
}
|
270 |
+
|
271 |
+
}
|
272 |
+
|
273 |
+
endif; // class_exists
|
274 |
+
|
275 |
Â
return new Settings_General();
|
includes/class-wcpdf-settings.php
CHANGED
@@ -1,249 +1,255 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices;
|
3 |
-
|
4 |
-
use WPO\WC\PDF_Invoices\Documents\Sequential_Number_Store;
|
5 |
-
|
6 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
7 |
-
exit; // Exit if accessed directly
|
8 |
-
}
|
9 |
-
|
10 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings' ) ) :
|
11 |
-
|
12 |
-
class Settings {
|
13 |
-
public $options_page_hook;
|
14 |
-
|
15 |
-
function __construct() {
|
16 |
-
$this->callbacks = include( 'class-wcpdf-settings-callbacks.php' );
|
17 |
-
|
18 |
-
// include settings classes
|
19 |
-
$this->general = include( 'class-wcpdf-settings-general.php' );
|
20 |
-
$this->documents = include( 'class-wcpdf-settings-documents.php' );
|
21 |
-
$this->debug = include( 'class-wcpdf-settings-debug.php' );
|
22 |
-
|
23 |
-
|
24 |
-
// Settings menu item
|
25 |
-
add_action( 'admin_menu', array( $this, 'menu' ) ); // Add menu.
|
26 |
-
// Links on plugin page
|
27 |
-
add_filter( 'plugin_action_links_'.WPO_WCPDF()->plugin_basename, array( $this, 'add_settings_link' ) );
|
28 |
-
add_filter( 'plugin_row_meta', array( $this, 'add_support_links' ), 10, 2 );
|
29 |
-
|
30 |
-
// settings capabilities
|
31 |
-
add_filter( 'option_page_capability_wpo_wcpdf_general_settings', array( $this, 'settings_capabilities' ) );
|
32 |
-
|
33 |
-
$this->general_settings = get_option('wpo_wcpdf_settings_general');
|
34 |
-
$this->debug_settings = get_option('wpo_wcpdf_settings_debug');
|
35 |
-
|
36 |
-
// admin notice for auto_increment_increment
|
37 |
-
// add_action( 'admin_notices', array( $this, 'check_auto_increment_increment') );
|
38 |
-
|
39 |
-
// AJAX set number store
|
40 |
-
add_action( 'wp_ajax_wpo_wcpdf_set_next_number', array($this, 'set_number_store' ));
|
41 |
-
}
|
42 |
-
|
43 |
-
public function menu() {
|
44 |
-
$parent_slug = 'woocommerce';
|
45 |
-
|
46 |
-
$this->options_page_hook = add_submenu_page(
|
47 |
-
$parent_slug,
|
48 |
-
__( 'PDF Invoices', 'woocommerce-pdf-invoices-packing-slips' ),
|
49 |
-
__( 'PDF Invoices', 'woocommerce-pdf-invoices-packing-slips' ),
|
50 |
-
'manage_woocommerce',
|
51 |
-
'wpo_wcpdf_options_page',
|
52 |
-
array( $this, 'settings_page' )
|
53 |
-
);
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Add settings link to plugins page
|
58 |
-
*/
|
59 |
-
public function add_settings_link( $links ) {
|
60 |
-
$action_links = array(
|
61 |
-
'settings' => '<a href="admin.php?page=wpo_wcpdf_options_page">'. __( 'Settings', 'woocommerce' ) . '</a>',
|
62 |
-
);
|
63 |
-
|
64 |
-
return array_merge( $action_links, $links );
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Add various support links to plugin page
|
69 |
-
* after meta (version, authors, site)
|
70 |
-
*/
|
71 |
-
public function add_support_links( $links, $file ) {
|
72 |
-
if ( $file == WPO_WCPDF()->plugin_basename ) {
|
73 |
-
$row_meta = array(
|
74 |
-
'docs' => '<a href="http://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/" target="_blank" title="' . __( 'Documentation', 'woocommerce-pdf-invoices-packing-slips' ) . '">' . __( 'Documentation', 'woocommerce-pdf-invoices-packing-slips' ) . '</a>',
|
75 |
-
'support' => '<a href="https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips" target="_blank" title="' . __( 'Support Forum', 'woocommerce-pdf-invoices-packing-slips' ) . '">' . __( 'Support Forum', 'woocommerce-pdf-invoices-packing-slips' ) . '</a>',
|
76 |
-
);
|
77 |
-
|
78 |
-
return array_merge( $links, $row_meta );
|
79 |
-
}
|
80 |
-
return (array) $links;
|
81 |
-
}
|
82 |
-
|
83 |
-
function check_auto_increment_increment() {
|
84 |
-
global $wpdb;
|
85 |
-
$row = $wpdb->get_row("SHOW VARIABLES LIKE 'auto_increment_increment'");
|
86 |
-
if ( !empty($row) && !empty($row->Value) && $row->Value != 1 ) {
|
87 |
-
$error = sprintf( __( "<strong>Warning!</strong> Your database has an AUTO_INCREMENT step size of %s, your invoice numbers may not be sequential. Enable the 'Calculate document numbers (slow)' setting in the Status tab to use an alternate method." , 'woocommerce-pdf-invoices-packing-slips' ), $row->Value );
|
88 |
-
printf( '<div class="error"><p>%s</p></div>', $error );
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
|
93 |
-
public function settings_page() {
|
94 |
-
$settings_tabs = apply_filters( 'wpo_wcpdf_settings_tabs', array (
|
95 |
-
'general' => __('General', 'woocommerce-pdf-invoices-packing-slips' ),
|
96 |
-
'documents' => __('Documents', 'woocommerce-pdf-invoices-packing-slips' ),
|
97 |
-
)
|
98 |
-
);
|
99 |
-
|
100 |
-
// add status tab last in row
|
101 |
-
$settings_tabs['debug'] = __('Status', 'woocommerce-pdf-invoices-packing-slips' );
|
102 |
-
|
103 |
-
$active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'general';
|
104 |
-
$active_section = isset( $_GET[ 'section' ] ) ? $_GET[ 'section' ] : '';
|
105 |
-
|
106 |
-
include('views/wcpdf-settings-page.php');
|
107 |
-
}
|
108 |
-
|
109 |
-
public function add_settings_fields( $settings_fields, $page, $option_group, $option_name ) {
|
110 |
-
foreach ( $settings_fields as $settings_field ) {
|
111 |
-
if (!isset($settings_field['callback'])) {
|
112 |
-
continue;
|
113 |
-
} elseif ( is_callable( array( $this->callbacks, $settings_field['callback'] ) ) ) {
|
114 |
-
$callback = array( $this->callbacks, $settings_field['callback'] );
|
115 |
-
} elseif ( is_callable( $settings_field['callback'] ) ) {
|
116 |
-
$callback = $settings_field['callback'];
|
117 |
-
} else {
|
118 |
-
continue;
|
119 |
-
}
|
120 |
-
|
121 |
-
if ( $settings_field['type'] == 'section' ) {
|
122 |
-
add_settings_section(
|
123 |
-
$settings_field['id'],
|
124 |
-
$settings_field['title'],
|
125 |
-
$callback,
|
126 |
-
$page
|
127 |
-
);
|
128 |
-
} else {
|
129 |
-
add_settings_field(
|
130 |
-
$settings_field['id'],
|
131 |
-
$settings_field['title'],
|
132 |
-
$callback,
|
133 |
-
$page,
|
134 |
-
$settings_field['section'],
|
135 |
-
$settings_field['args']
|
136 |
-
);
|
137 |
-
// register option separately for singular options
|
138 |
-
if (is_string($settings_field['callback']) && $settings_field['callback'] == 'singular_text_element') {
|
139 |
-
register_setting( $option_group, $settings_field['args']['option_name'], array( $this->callbacks, 'validate' ) );
|
140 |
-
}
|
141 |
-
}
|
142 |
-
}
|
143 |
-
// $page, $option_group & $option_name are all the same...
|
144 |
-
register_setting( $option_group, $option_name, array( $this->callbacks, 'validate' ) );
|
145 |
-
add_filter( 'option_page_capability_'.$page, array( $this, 'settings_capabilities' ) );
|
146 |
-
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Set capability for settings page
|
151 |
-
*/
|
152 |
-
public function settings_capabilities() {
|
153 |
-
return 'manage_woocommerce';
|
154 |
-
}
|
155 |
-
|
156 |
-
public function get_common_document_settings() {
|
157 |
-
$common_settings = array(
|
158 |
-
'paper_size' => isset( $this->general_settings['paper_size'] ) ? $this->general_settings['paper_size'] : '',
|
159 |
-
'font_subsetting' => isset( $this->general_settings['font_subsetting'] ) || ( defined("DOMPDF_ENABLE_FONTSUBSETTING") && DOMPDF_ENABLE_FONTSUBSETTING === true ) ? true : false,
|
160 |
-
'header_logo' => isset( $this->general_settings['header_logo'] ) ? $this->general_settings['header_logo'] : '',
|
161 |
-
'shop_name' => isset( $this->general_settings['shop_name'] ) ? $this->general_settings['shop_name'] : '',
|
162 |
-
'shop_address' => isset( $this->general_settings['shop_address'] ) ? $this->general_settings['shop_address'] : '',
|
163 |
-
'footer' => isset( $this->general_settings['footer'] ) ? $this->general_settings['footer'] : '',
|
164 |
-
'extra_1' => isset( $this->general_settings['extra_1'] ) ? $this->general_settings['extra_1'] : '',
|
165 |
-
'extra_2' => isset( $this->general_settings['extra_2'] ) ? $this->general_settings['extra_2'] : '',
|
166 |
-
'extra_3' => isset( $this->general_settings['extra_3'] ) ? $this->general_settings['extra_3'] : '',
|
167 |
-
);
|
168 |
-
return $common_settings;
|
169 |
-
}
|
170 |
-
|
171 |
-
public function get_document_settings( $document_type ) {
|
172 |
-
$documents = WPO_WCPDF()->documents->get_documents('all');
|
173 |
-
foreach ($documents as $document) {
|
174 |
-
if ( $document->get_type() == $document_type ) {
|
175 |
-
return $document->settings;
|
176 |
-
}
|
177 |
-
}
|
178 |
-
return false;
|
179 |
-
}
|
180 |
-
|
181 |
-
public function get_output_format() {
|
182 |
-
if ( isset( $this->debug_settings['html_output'] ) ) {
|
183 |
-
$output_format = 'html';
|
184 |
-
} else {
|
185 |
-
$output_format = 'pdf';
|
186 |
-
}
|
187 |
-
return $output_format;
|
188 |
-
}
|
189 |
-
|
190 |
-
public function get_output_mode() {
|
191 |
-
if ( isset( WPO_WCPDF()->settings->general_settings['download_display'] ) ) {
|
192 |
-
switch ( WPO_WCPDF()->settings->general_settings['download_display'] ) {
|
193 |
-
case 'display':
|
194 |
-
$output_mode = 'inline';
|
195 |
-
break;
|
196 |
-
case 'download':
|
197 |
-
default:
|
198 |
-
$output_mode = 'download';
|
199 |
-
break;
|
200 |
-
}
|
201 |
-
} else {
|
202 |
-
$output_mode = 'download';
|
203 |
-
}
|
204 |
-
return $output_mode;
|
205 |
-
}
|
206 |
-
|
207 |
-
public function get_template_path( $document_type = NULL ) {
|
208 |
-
$template_path = isset( $this->general_settings['template_path'] )?$this->general_settings['template_path']:'';
|
209 |
-
// forward slash for consistency
|
210 |
-
$template_path = str_replace('\\','/', $template_path);
|
211 |
-
|
212 |
-
// add
|
213 |
-
|
214 |
-
if ( strpos(
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
249 |
Â
return new Settings();
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices;
|
3 |
+
|
4 |
+
use WPO\WC\PDF_Invoices\Documents\Sequential_Number_Store;
|
5 |
+
|
6 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
7 |
+
exit; // Exit if accessed directly
|
8 |
+
}
|
9 |
+
|
10 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings' ) ) :
|
11 |
+
|
12 |
+
class Settings {
|
13 |
+
public $options_page_hook;
|
14 |
+
|
15 |
+
function __construct() {
|
16 |
+
$this->callbacks = include( 'class-wcpdf-settings-callbacks.php' );
|
17 |
+
|
18 |
+
// include settings classes
|
19 |
+
$this->general = include( 'class-wcpdf-settings-general.php' );
|
20 |
+
$this->documents = include( 'class-wcpdf-settings-documents.php' );
|
21 |
+
$this->debug = include( 'class-wcpdf-settings-debug.php' );
|
22 |
+
|
23 |
+
|
24 |
+
// Settings menu item
|
25 |
+
add_action( 'admin_menu', array( $this, 'menu' ) ); // Add menu.
|
26 |
+
// Links on plugin page
|
27 |
+
add_filter( 'plugin_action_links_'.WPO_WCPDF()->plugin_basename, array( $this, 'add_settings_link' ) );
|
28 |
+
add_filter( 'plugin_row_meta', array( $this, 'add_support_links' ), 10, 2 );
|
29 |
+
|
30 |
+
// settings capabilities
|
31 |
+
add_filter( 'option_page_capability_wpo_wcpdf_general_settings', array( $this, 'settings_capabilities' ) );
|
32 |
+
|
33 |
+
$this->general_settings = get_option('wpo_wcpdf_settings_general');
|
34 |
+
$this->debug_settings = get_option('wpo_wcpdf_settings_debug');
|
35 |
+
|
36 |
+
// admin notice for auto_increment_increment
|
37 |
+
// add_action( 'admin_notices', array( $this, 'check_auto_increment_increment') );
|
38 |
+
|
39 |
+
// AJAX set number store
|
40 |
+
add_action( 'wp_ajax_wpo_wcpdf_set_next_number', array($this, 'set_number_store' ));
|
41 |
+
}
|
42 |
+
|
43 |
+
public function menu() {
|
44 |
+
$parent_slug = 'woocommerce';
|
45 |
+
|
46 |
+
$this->options_page_hook = add_submenu_page(
|
47 |
+
$parent_slug,
|
48 |
+
__( 'PDF Invoices', 'woocommerce-pdf-invoices-packing-slips' ),
|
49 |
+
__( 'PDF Invoices', 'woocommerce-pdf-invoices-packing-slips' ),
|
50 |
+
'manage_woocommerce',
|
51 |
+
'wpo_wcpdf_options_page',
|
52 |
+
array( $this, 'settings_page' )
|
53 |
+
);
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Add settings link to plugins page
|
58 |
+
*/
|
59 |
+
public function add_settings_link( $links ) {
|
60 |
+
$action_links = array(
|
61 |
+
'settings' => '<a href="admin.php?page=wpo_wcpdf_options_page">'. __( 'Settings', 'woocommerce' ) . '</a>',
|
62 |
+
);
|
63 |
+
|
64 |
+
return array_merge( $action_links, $links );
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Add various support links to plugin page
|
69 |
+
* after meta (version, authors, site)
|
70 |
+
*/
|
71 |
+
public function add_support_links( $links, $file ) {
|
72 |
+
if ( $file == WPO_WCPDF()->plugin_basename ) {
|
73 |
+
$row_meta = array(
|
74 |
+
'docs' => '<a href="http://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/" target="_blank" title="' . __( 'Documentation', 'woocommerce-pdf-invoices-packing-slips' ) . '">' . __( 'Documentation', 'woocommerce-pdf-invoices-packing-slips' ) . '</a>',
|
75 |
+
'support' => '<a href="https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips" target="_blank" title="' . __( 'Support Forum', 'woocommerce-pdf-invoices-packing-slips' ) . '">' . __( 'Support Forum', 'woocommerce-pdf-invoices-packing-slips' ) . '</a>',
|
76 |
+
);
|
77 |
+
|
78 |
+
return array_merge( $links, $row_meta );
|
79 |
+
}
|
80 |
+
return (array) $links;
|
81 |
+
}
|
82 |
+
|
83 |
+
function check_auto_increment_increment() {
|
84 |
+
global $wpdb;
|
85 |
+
$row = $wpdb->get_row("SHOW VARIABLES LIKE 'auto_increment_increment'");
|
86 |
+
if ( !empty($row) && !empty($row->Value) && $row->Value != 1 ) {
|
87 |
+
$error = sprintf( __( "<strong>Warning!</strong> Your database has an AUTO_INCREMENT step size of %s, your invoice numbers may not be sequential. Enable the 'Calculate document numbers (slow)' setting in the Status tab to use an alternate method." , 'woocommerce-pdf-invoices-packing-slips' ), $row->Value );
|
88 |
+
printf( '<div class="error"><p>%s</p></div>', $error );
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
public function settings_page() {
|
94 |
+
$settings_tabs = apply_filters( 'wpo_wcpdf_settings_tabs', array (
|
95 |
+
'general' => __('General', 'woocommerce-pdf-invoices-packing-slips' ),
|
96 |
+
'documents' => __('Documents', 'woocommerce-pdf-invoices-packing-slips' ),
|
97 |
+
)
|
98 |
+
);
|
99 |
+
|
100 |
+
// add status tab last in row
|
101 |
+
$settings_tabs['debug'] = __('Status', 'woocommerce-pdf-invoices-packing-slips' );
|
102 |
+
|
103 |
+
$active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'general';
|
104 |
+
$active_section = isset( $_GET[ 'section' ] ) ? $_GET[ 'section' ] : '';
|
105 |
+
|
106 |
+
include('views/wcpdf-settings-page.php');
|
107 |
+
}
|
108 |
+
|
109 |
+
public function add_settings_fields( $settings_fields, $page, $option_group, $option_name ) {
|
110 |
+
foreach ( $settings_fields as $settings_field ) {
|
111 |
+
if (!isset($settings_field['callback'])) {
|
112 |
+
continue;
|
113 |
+
} elseif ( is_callable( array( $this->callbacks, $settings_field['callback'] ) ) ) {
|
114 |
+
$callback = array( $this->callbacks, $settings_field['callback'] );
|
115 |
+
} elseif ( is_callable( $settings_field['callback'] ) ) {
|
116 |
+
$callback = $settings_field['callback'];
|
117 |
+
} else {
|
118 |
+
continue;
|
119 |
+
}
|
120 |
+
|
121 |
+
if ( $settings_field['type'] == 'section' ) {
|
122 |
+
add_settings_section(
|
123 |
+
$settings_field['id'],
|
124 |
+
$settings_field['title'],
|
125 |
+
$callback,
|
126 |
+
$page
|
127 |
+
);
|
128 |
+
} else {
|
129 |
+
add_settings_field(
|
130 |
+
$settings_field['id'],
|
131 |
+
$settings_field['title'],
|
132 |
+
$callback,
|
133 |
+
$page,
|
134 |
+
$settings_field['section'],
|
135 |
+
$settings_field['args']
|
136 |
+
);
|
137 |
+
// register option separately for singular options
|
138 |
+
if (is_string($settings_field['callback']) && $settings_field['callback'] == 'singular_text_element') {
|
139 |
+
register_setting( $option_group, $settings_field['args']['option_name'], array( $this->callbacks, 'validate' ) );
|
140 |
+
}
|
141 |
+
}
|
142 |
+
}
|
143 |
+
// $page, $option_group & $option_name are all the same...
|
144 |
+
register_setting( $option_group, $option_name, array( $this->callbacks, 'validate' ) );
|
145 |
+
add_filter( 'option_page_capability_'.$page, array( $this, 'settings_capabilities' ) );
|
146 |
+
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Set capability for settings page
|
151 |
+
*/
|
152 |
+
public function settings_capabilities() {
|
153 |
+
return 'manage_woocommerce';
|
154 |
+
}
|
155 |
+
|
156 |
+
public function get_common_document_settings() {
|
157 |
+
$common_settings = array(
|
158 |
+
'paper_size' => isset( $this->general_settings['paper_size'] ) ? $this->general_settings['paper_size'] : '',
|
159 |
+
'font_subsetting' => isset( $this->general_settings['font_subsetting'] ) || ( defined("DOMPDF_ENABLE_FONTSUBSETTING") && DOMPDF_ENABLE_FONTSUBSETTING === true ) ? true : false,
|
160 |
+
'header_logo' => isset( $this->general_settings['header_logo'] ) ? $this->general_settings['header_logo'] : '',
|
161 |
+
'shop_name' => isset( $this->general_settings['shop_name'] ) ? $this->general_settings['shop_name'] : '',
|
162 |
+
'shop_address' => isset( $this->general_settings['shop_address'] ) ? $this->general_settings['shop_address'] : '',
|
163 |
+
'footer' => isset( $this->general_settings['footer'] ) ? $this->general_settings['footer'] : '',
|
164 |
+
'extra_1' => isset( $this->general_settings['extra_1'] ) ? $this->general_settings['extra_1'] : '',
|
165 |
+
'extra_2' => isset( $this->general_settings['extra_2'] ) ? $this->general_settings['extra_2'] : '',
|
166 |
+
'extra_3' => isset( $this->general_settings['extra_3'] ) ? $this->general_settings['extra_3'] : '',
|
167 |
+
);
|
168 |
+
return $common_settings;
|
169 |
+
}
|
170 |
+
|
171 |
+
public function get_document_settings( $document_type ) {
|
172 |
+
$documents = WPO_WCPDF()->documents->get_documents('all');
|
173 |
+
foreach ($documents as $document) {
|
174 |
+
if ( $document->get_type() == $document_type ) {
|
175 |
+
return $document->settings;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
return false;
|
179 |
+
}
|
180 |
+
|
181 |
+
public function get_output_format() {
|
182 |
+
if ( isset( $this->debug_settings['html_output'] ) ) {
|
183 |
+
$output_format = 'html';
|
184 |
+
} else {
|
185 |
+
$output_format = 'pdf';
|
186 |
+
}
|
187 |
+
return $output_format;
|
188 |
+
}
|
189 |
+
|
190 |
+
public function get_output_mode() {
|
191 |
+
if ( isset( WPO_WCPDF()->settings->general_settings['download_display'] ) ) {
|
192 |
+
switch ( WPO_WCPDF()->settings->general_settings['download_display'] ) {
|
193 |
+
case 'display':
|
194 |
+
$output_mode = 'inline';
|
195 |
+
break;
|
196 |
+
case 'download':
|
197 |
+
default:
|
198 |
+
$output_mode = 'download';
|
199 |
+
break;
|
200 |
+
}
|
201 |
+
} else {
|
202 |
+
$output_mode = 'download';
|
203 |
+
}
|
204 |
+
return $output_mode;
|
205 |
+
}
|
206 |
+
|
207 |
+
public function get_template_path( $document_type = NULL ) {
|
208 |
+
$template_path = isset( $this->general_settings['template_path'] )?$this->general_settings['template_path']:'';
|
209 |
+
// forward slash for consistency
|
210 |
+
$template_path = str_replace('\\','/', $template_path);
|
211 |
+
|
212 |
+
// add base path, checking if it's not already there
|
213 |
+
// alternative setups like Bedrock have WP_CONTENT_DIR & ABSPATH separated
|
214 |
+
if ( defined('WP_CONTENT_DIR') && strpos( WP_CONTENT_DIR, ABSPATH ) !== false ) {
|
215 |
+
$forwardslash_basepath = str_replace('\\','/', ABSPATH);
|
216 |
+
} else {
|
217 |
+
// bedrock e.a
|
218 |
+
$forwardslash_basepath = str_replace('\\','/', WP_CONTENT_DIR);
|
219 |
+
}
|
220 |
+
|
221 |
+
if ( strpos( $template_path, $forwardslash_basepath ) === false ) {
|
222 |
+
$template_path = $forwardslash_basepath . $template_path;
|
223 |
+
}
|
224 |
+
|
225 |
+
return $template_path;
|
226 |
+
}
|
227 |
+
|
228 |
+
public function set_number_store() {
|
229 |
+
check_ajax_referer( "wpo_wcpdf_next_{$_POST['store']}", 'security' );
|
230 |
+
$number = isset( $_POST['number'] ) ? (int) $_POST['number'] : 0;
|
231 |
+
$number_store_method = $this->get_sequential_number_store_method();
|
232 |
+
$number_store = new Sequential_Number_Store( $_POST['store'], $number_store_method );
|
233 |
+
$number_store->set_next( $number );
|
234 |
+
echo "next number ({$_POST['store']}) set to {$number}";
|
235 |
+
die();
|
236 |
+
}
|
237 |
+
|
238 |
+
public function get_sequential_number_store_method() {
|
239 |
+
global $wpdb;
|
240 |
+
$method = isset( $this->debug_settings['calculate_document_numbers'] ) ? 'calculate' : 'auto_increment';
|
241 |
+
|
242 |
+
// safety first - always use calculate when auto_increment_increment is not 1
|
243 |
+
$row = $wpdb->get_row("SHOW VARIABLES LIKE 'auto_increment_increment'");
|
244 |
+
if ( !empty($row) && !empty($row->Value) && $row->Value != 1 ) {
|
245 |
+
$method = 'calculate';
|
246 |
+
}
|
247 |
+
|
248 |
+
return $method;
|
249 |
+
}
|
250 |
+
|
251 |
+
}
|
252 |
+
|
253 |
+
endif; // class_exists
|
254 |
+
|
255 |
Â
return new Settings();
|
includes/compatibility/mb-string-compatibility.php
CHANGED
@@ -1,127 +1,127 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* mb_string compatibility - something's better than nothing!
|
4 |
-
* Taken from dompdf 0.6
|
5 |
-
*/
|
6 |
-
if (!extension_loaded('mbstring')) {
|
7 |
-
if ( ! defined( 'MB_OVERLOAD_MAIL' ) ) define('MB_OVERLOAD_MAIL', 1);
|
8 |
-
if ( ! defined( 'MB_OVERLOAD_STRING' ) ) define('MB_OVERLOAD_STRING', 2);
|
9 |
-
if ( ! defined( 'MB_OVERLOAD_REGEX' ) ) define('MB_OVERLOAD_REGEX', 4);
|
10 |
-
if ( ! defined( 'MB_CASE_UPPER' ) ) define('MB_CASE_UPPER', 0);
|
11 |
-
if ( ! defined( 'MB_CASE_LOWER' ) ) define('MB_CASE_LOWER', 1);
|
12 |
-
if ( ! defined( 'MB_CASE_TITLE' ) ) define('MB_CASE_TITLE', 2);
|
13 |
-
|
14 |
-
if (!function_exists('mb_convert_encoding')) {
|
15 |
-
function mb_convert_encoding($data, $to_encoding, $from_encoding = 'UTF-8') {
|
16 |
-
if (str_replace('-', '', strtolower($to_encoding)) === 'utf8') {
|
17 |
-
return utf8_encode($data);
|
18 |
-
}
|
19 |
-
|
20 |
-
return utf8_decode($data);
|
21 |
-
}
|
22 |
-
}
|
23 |
-
|
24 |
-
if (!function_exists('mb_detect_encoding')) {
|
25 |
-
function mb_detect_encoding($data, $encoding_list = array('iso-8859-1'), $strict = false) {
|
26 |
-
return 'iso-8859-1';
|
27 |
-
}
|
28 |
-
}
|
29 |
-
|
30 |
-
if (!function_exists('mb_detect_order')) {
|
31 |
-
function mb_detect_order($encoding_list = array('iso-8859-1')) {
|
32 |
-
return 'iso-8859-1';
|
33 |
-
}
|
34 |
-
}
|
35 |
-
|
36 |
-
if (!function_exists('mb_internal_encoding')) {
|
37 |
-
function mb_internal_encoding($encoding = null) {
|
38 |
-
if (isset($encoding)) {
|
39 |
-
return true;
|
40 |
-
}
|
41 |
-
|
42 |
-
return 'iso-8859-1';
|
43 |
-
}
|
44 |
-
}
|
45 |
-
if (!function_exists('mb_strlen')) {
|
46 |
-
function mb_strlen($str, $encoding = 'iso-8859-1') {
|
47 |
-
switch (str_replace('-', '', strtolower($encoding))) {
|
48 |
-
case "utf8": return strlen(utf8_encode($str));
|
49 |
-
case "8bit": return strlen($str);
|
50 |
-
default: return strlen(utf8_decode($str));
|
51 |
-
}
|
52 |
-
}
|
53 |
-
}
|
54 |
-
|
55 |
-
if (!function_exists('mb_strpos')) {
|
56 |
-
function mb_strpos($haystack, $needle, $offset = 0) {
|
57 |
-
return strpos($haystack, $needle, $offset);
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
if (!function_exists('mb_stripos')) {
|
62 |
-
function mb_stripos($haystack, $needle, $offset = 0) {
|
63 |
-
return stripos($haystack, $needle, $offset);
|
64 |
-
}
|
65 |
-
}
|
66 |
-
|
67 |
-
if (!function_exists('mb_strrpos')) {
|
68 |
-
function mb_strrpos($haystack, $needle, $offset = 0) {
|
69 |
-
return strrpos($haystack, $needle, $offset);
|
70 |
-
}
|
71 |
-
}
|
72 |
-
|
73 |
-
if (!function_exists('mb_strtolower')) {
|
74 |
-
function mb_strtolower( $str ) {
|
75 |
-
return strtolower($str);
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
if (!function_exists('mb_strtoupper')) {
|
80 |
-
function mb_strtoupper( $str ) {
|
81 |
-
return strtoupper($str);
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
if (!function_exists('mb_substr')) {
|
86 |
-
function mb_substr($string, $start, $length = null, $encoding = 'iso-8859-1') {
|
87 |
-
if ( is_null($length) ) {
|
88 |
-
return substr($string, $start);
|
89 |
-
}
|
90 |
-
|
91 |
-
return substr($string, $start, $length);
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
if (!function_exists('mb_substr_count')) {
|
96 |
-
function mb_substr_count($haystack, $needle, $encoding = 'iso-8859-1') {
|
97 |
-
return substr_count($haystack, $needle);
|
98 |
-
}
|
99 |
-
}
|
100 |
-
|
101 |
-
if (!function_exists('mb_encode_numericentity')) {
|
102 |
-
function mb_encode_numericentity($str, $convmap, $encoding) {
|
103 |
-
return htmlspecialchars($str);
|
104 |
-
}
|
105 |
-
}
|
106 |
-
|
107 |
-
if (!function_exists('mb_convert_case')) {
|
108 |
-
function mb_convert_case($str, $mode = MB_CASE_UPPER, $encoding = array()) {
|
109 |
-
switch($mode) {
|
110 |
-
case MB_CASE_UPPER: return mb_strtoupper($str);
|
111 |
-
case MB_CASE_LOWER: return mb_strtolower($str);
|
112 |
-
case MB_CASE_TITLE: return ucwords(mb_strtolower($str));
|
113 |
-
default: return $str;
|
114 |
-
}
|
115 |
-
}
|
116 |
-
}
|
117 |
-
|
118 |
-
if (!function_exists('mb_list_encodings')) {
|
119 |
-
function mb_list_encodings() {
|
120 |
-
return array(
|
121 |
-
"ISO-8859-1",
|
122 |
-
"UTF-8",
|
123 |
-
"8bit",
|
124 |
-
);
|
125 |
-
}
|
126 |
-
}
|
127 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* mb_string compatibility - something's better than nothing!
|
4 |
+
* Taken from dompdf 0.6
|
5 |
+
*/
|
6 |
+
if (!extension_loaded('mbstring')) {
|
7 |
+
if ( ! defined( 'MB_OVERLOAD_MAIL' ) ) define('MB_OVERLOAD_MAIL', 1);
|
8 |
+
if ( ! defined( 'MB_OVERLOAD_STRING' ) ) define('MB_OVERLOAD_STRING', 2);
|
9 |
+
if ( ! defined( 'MB_OVERLOAD_REGEX' ) ) define('MB_OVERLOAD_REGEX', 4);
|
10 |
+
if ( ! defined( 'MB_CASE_UPPER' ) ) define('MB_CASE_UPPER', 0);
|
11 |
+
if ( ! defined( 'MB_CASE_LOWER' ) ) define('MB_CASE_LOWER', 1);
|
12 |
+
if ( ! defined( 'MB_CASE_TITLE' ) ) define('MB_CASE_TITLE', 2);
|
13 |
+
|
14 |
+
if (!function_exists('mb_convert_encoding')) {
|
15 |
+
function mb_convert_encoding($data, $to_encoding, $from_encoding = 'UTF-8') {
|
16 |
+
if (str_replace('-', '', strtolower($to_encoding)) === 'utf8') {
|
17 |
+
return utf8_encode($data);
|
18 |
+
}
|
19 |
+
|
20 |
+
return utf8_decode($data);
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
if (!function_exists('mb_detect_encoding')) {
|
25 |
+
function mb_detect_encoding($data, $encoding_list = array('iso-8859-1'), $strict = false) {
|
26 |
+
return 'iso-8859-1';
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
if (!function_exists('mb_detect_order')) {
|
31 |
+
function mb_detect_order($encoding_list = array('iso-8859-1')) {
|
32 |
+
return 'iso-8859-1';
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
if (!function_exists('mb_internal_encoding')) {
|
37 |
+
function mb_internal_encoding($encoding = null) {
|
38 |
+
if (isset($encoding)) {
|
39 |
+
return true;
|
40 |
+
}
|
41 |
+
|
42 |
+
return 'iso-8859-1';
|
43 |
+
}
|
44 |
+
}
|
45 |
+
if (!function_exists('mb_strlen')) {
|
46 |
+
function mb_strlen($str, $encoding = 'iso-8859-1') {
|
47 |
+
switch (str_replace('-', '', strtolower($encoding))) {
|
48 |
+
case "utf8": return strlen(utf8_encode($str));
|
49 |
+
case "8bit": return strlen($str);
|
50 |
+
default: return strlen(utf8_decode($str));
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
if (!function_exists('mb_strpos')) {
|
56 |
+
function mb_strpos($haystack, $needle, $offset = 0) {
|
57 |
+
return strpos($haystack, $needle, $offset);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
if (!function_exists('mb_stripos')) {
|
62 |
+
function mb_stripos($haystack, $needle, $offset = 0) {
|
63 |
+
return stripos($haystack, $needle, $offset);
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
if (!function_exists('mb_strrpos')) {
|
68 |
+
function mb_strrpos($haystack, $needle, $offset = 0) {
|
69 |
+
return strrpos($haystack, $needle, $offset);
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
if (!function_exists('mb_strtolower')) {
|
74 |
+
function mb_strtolower( $str ) {
|
75 |
+
return strtolower($str);
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
if (!function_exists('mb_strtoupper')) {
|
80 |
+
function mb_strtoupper( $str ) {
|
81 |
+
return strtoupper($str);
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
if (!function_exists('mb_substr')) {
|
86 |
+
function mb_substr($string, $start, $length = null, $encoding = 'iso-8859-1') {
|
87 |
+
if ( is_null($length) ) {
|
88 |
+
return substr($string, $start);
|
89 |
+
}
|
90 |
+
|
91 |
+
return substr($string, $start, $length);
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
if (!function_exists('mb_substr_count')) {
|
96 |
+
function mb_substr_count($haystack, $needle, $encoding = 'iso-8859-1') {
|
97 |
+
return substr_count($haystack, $needle);
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
if (!function_exists('mb_encode_numericentity')) {
|
102 |
+
function mb_encode_numericentity($str, $convmap, $encoding) {
|
103 |
+
return htmlspecialchars($str);
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
if (!function_exists('mb_convert_case')) {
|
108 |
+
function mb_convert_case($str, $mode = MB_CASE_UPPER, $encoding = array()) {
|
109 |
+
switch($mode) {
|
110 |
+
case MB_CASE_UPPER: return mb_strtoupper($str);
|
111 |
+
case MB_CASE_LOWER: return mb_strtolower($str);
|
112 |
+
case MB_CASE_TITLE: return ucwords(mb_strtolower($str));
|
113 |
+
default: return $str;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
if (!function_exists('mb_list_encodings')) {
|
119 |
+
function mb_list_encodings() {
|
120 |
+
return array(
|
121 |
+
"ISO-8859-1",
|
122 |
+
"UTF-8",
|
123 |
+
"8bit",
|
124 |
+
);
|
125 |
+
}
|
126 |
+
}
|
127 |
+
}
|
includes/documents/abstract-wcpdf-order-document-methods.php
CHANGED
@@ -223,33 +223,33 @@ abstract class Order_Document_Methods extends Order_Document {
|
|
223 |
Â
* Return/show product attribute
|
224 |
Â
*/
|
225 |
Â
public function get_product_attribute( $attribute_name, $product ) {
|
226 |
-
// WC3.0+ use parent product for variations
|
227 |
-
if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) && $product->is_type( 'variation' ) ) {
|
228 |
-
$product = wc_get_product( $product->get_parent_id() );
|
229 |
-
}
|
230 |
Â
// first, check the text attributes
|
231 |
Â
$attributes = $product->get_attributes();
|
232 |
Â
$attribute_key = @wc_attribute_taxonomy_name( $attribute_name );
|
233 |
Â
if (array_key_exists( sanitize_title( $attribute_name ), $attributes) ) {
|
234 |
Â
$attribute = $product->get_attribute ( $attribute_name );
|
235 |
-
return $attribute;
|
236 |
Â
} elseif (array_key_exists( sanitize_title( $attribute_key ), $attributes) ) {
|
237 |
Â
$attribute = $product->get_attribute ( $attribute_key );
|
238 |
-
return $attribute;
|
239 |
Â
}
|
240 |
Â
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
// no attribute under this name
|
251 |
-
return false;
|
252 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
253 |
Â
}
|
254 |
Â
public function product_attribute( $attribute_name, $product ) {
|
255 |
Â
echo $this->get_product_attribute( $attribute_name, $product );
|
223 |
Â
* Return/show product attribute
|
224 |
Â
*/
|
225 |
Â
public function get_product_attribute( $attribute_name, $product ) {
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
226 |
Â
// first, check the text attributes
|
227 |
Â
$attributes = $product->get_attributes();
|
228 |
Â
$attribute_key = @wc_attribute_taxonomy_name( $attribute_name );
|
229 |
Â
if (array_key_exists( sanitize_title( $attribute_name ), $attributes) ) {
|
230 |
Â
$attribute = $product->get_attribute ( $attribute_name );
|
Â
|
|
231 |
Â
} elseif (array_key_exists( sanitize_title( $attribute_key ), $attributes) ) {
|
232 |
Â
$attribute = $product->get_attribute ( $attribute_key );
|
Â
|
|
233 |
Â
}
|
234 |
Â
|
235 |
+
if (empty($attribute)) {
|
236 |
+
// not a text attribute, try attribute taxonomy
|
237 |
+
$attribute_key = @wc_attribute_taxonomy_name( $attribute_name );
|
238 |
+
$product_id = WCX_Product::get_prop($product, 'id');
|
239 |
+
$product_terms = @wc_get_product_terms( $product_id, $attribute_key, array( 'fields' => 'names' ) );
|
240 |
+
// check if not empty, then display
|
241 |
+
if ( !empty($product_terms) ) {
|
242 |
+
$attribute = array_shift( $product_terms );
|
243 |
+
}
|
Â
|
|
Â
|
|
244 |
Â
}
|
245 |
+
|
246 |
+
// WC3.0+ fallback parent product for variations
|
247 |
+
if ( empty($attribute) && version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) && $product->is_type( 'variation' ) ) {
|
248 |
+
$product = wc_get_product( $product->get_parent_id() );
|
249 |
+
$attribute = $this->get_product_attribute( $attribute_name, $product );
|
250 |
+
}
|
251 |
+
|
252 |
+
return isset($attribute) ? $attribute : false;
|
253 |
Â
}
|
254 |
Â
public function product_attribute( $attribute_name, $product ) {
|
255 |
Â
echo $this->get_product_attribute( $attribute_name, $product );
|
includes/documents/abstract-wcpdf-order-document.php
CHANGED
@@ -1,676 +1,676 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices\Documents;
|
3 |
-
|
4 |
-
use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
|
5 |
-
use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
|
6 |
-
use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
|
7 |
-
use WPO\WC\PDF_Invoices\Compatibility\WC_DateTime;
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit; // Exit if accessed directly
|
11 |
-
}
|
12 |
-
|
13 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Order_Document' ) ) :
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Abstract Document
|
17 |
-
*
|
18 |
-
* Handles generic pdf document & order data and database interaction
|
19 |
-
* which is extended by both Invoices & Packing Slips
|
20 |
-
*
|
21 |
-
* @class \WPO\WC\PDF_Invoices\Documents\Order_Document
|
22 |
-
* @version 2.0
|
23 |
-
* @category Class
|
24 |
-
* @author Ewout Fernhout
|
25 |
-
*/
|
26 |
-
|
27 |
-
abstract class Order_Document {
|
28 |
-
/**
|
29 |
-
* Document type.
|
30 |
-
* @var String
|
31 |
-
*/
|
32 |
-
public $type;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Document slug.
|
36 |
-
* @var String
|
37 |
-
*/
|
38 |
-
public $slug;
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Document title.
|
42 |
-
* @var string
|
43 |
-
*/
|
44 |
-
public $title;
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Document icon.
|
48 |
-
* @var string
|
49 |
-
*/
|
50 |
-
public $icon;
|
51 |
-
|
52 |
-
/**
|
53 |
-
* WC Order object
|
54 |
-
* @var object
|
55 |
-
*/
|
56 |
-
public $order;
|
57 |
-
|
58 |
-
/**
|
59 |
-
* WC Order ID
|
60 |
-
* @var object
|
61 |
-
*/
|
62 |
-
public $order_id;
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Document settings.
|
66 |
-
* @var array
|
67 |
-
*/
|
68 |
-
public $settings;
|
69 |
-
|
70 |
-
/**
|
71 |
-
* TRUE if document is enabled.
|
72 |
-
* @var bool
|
73 |
-
*/
|
74 |
-
public $enabled;
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Linked documents, used for data retrieval
|
78 |
-
* @var array
|
79 |
-
*/
|
80 |
-
protected $linked_documents = array();
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Core data for this object. Name value pairs (name + default value).
|
84 |
-
* @var array
|
85 |
-
*/
|
86 |
-
protected $data = array();
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Init/load the order object.
|
90 |
-
*
|
91 |
-
* @param int|object|WC_Order $order Order to init.
|
92 |
-
*/
|
93 |
-
public function __construct( $order = 0 ) {
|
94 |
-
if ( is_numeric( $order ) && $order > 0 ) {
|
95 |
-
$this->order_id = $order;
|
96 |
-
$this->order = WCX::get_order( $order_id );
|
97 |
-
} elseif ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) {
|
98 |
-
$this->order_id = WCX_Order::get_id( $order );
|
99 |
-
$this->order = $order;
|
100 |
-
}
|
101 |
-
|
102 |
-
// set properties
|
103 |
-
$this->slug = str_replace('-', '_', $this->type);
|
104 |
-
|
105 |
-
// load settings
|
106 |
-
$this->settings = $this->get_settings();
|
107 |
-
$this->enabled = $this->get_setting( 'enabled', false );
|
108 |
-
|
109 |
-
// load data
|
110 |
-
if ( $this->order ) {
|
111 |
-
$this->read_data( $this->order );
|
112 |
-
if ( WPO_WCPDF()->legacy_mode_enabled() ) {
|
113 |
-
global $wpo_wcpdf;
|
114 |
-
$wpo_wcpdf->export->order = $this->order;
|
115 |
-
$wpo_wcpdf->export->document = $this;
|
116 |
-
$wpo_wcpdf->export->order_id = $this->order_id;
|
117 |
-
$wpo_wcpdf->export->template_type = $this->type;
|
118 |
-
}
|
119 |
-
}
|
120 |
-
|
121 |
-
}
|
122 |
-
|
123 |
-
public function init_settings() {
|
124 |
-
return ;
|
125 |
-
}
|
126 |
-
|
127 |
-
public function get_settings() {
|
128 |
-
$common_settings = WPO_WCPDF()->settings->get_common_document_settings();
|
129 |
-
$document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
|
130 |
-
return (array) $document_settings + (array) $common_settings;
|
131 |
-
}
|
132 |
-
|
133 |
-
public function get_setting( $key, $default = '' ) {
|
134 |
-
$setting = isset( $this->settings[$key] ) ? $this->settings[$key] : $default;
|
135 |
-
return $setting;
|
136 |
-
}
|
137 |
-
|
138 |
-
public function get_attach_to_email_ids() {
|
139 |
-
$email_ids = isset( $this->settings['attach_to_email_ids'] ) ? array_keys( $this->settings['attach_to_email_ids'] ) : array();
|
140 |
-
return $email_ids;
|
141 |
-
}
|
142 |
-
|
143 |
-
public function get_type() {
|
144 |
-
return $this->type;
|
145 |
-
}
|
146 |
-
|
147 |
-
public function is_enabled() {
|
148 |
-
return apply_filters( 'wpo_wcpdf_document_is_enabled', $this->enabled, $this->type );
|
149 |
-
}
|
150 |
-
|
151 |
-
public function get_hook_prefix() {
|
152 |
-
return 'wpo_wcpdf_' . $this->slug . '_get_';
|
153 |
-
}
|
154 |
-
|
155 |
-
public function read_data( $order ) {
|
156 |
-
$number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number_data", true );
|
157 |
-
// fallback to legacy data for number
|
158 |
-
if ( empty( $number ) ) {
|
159 |
-
$number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number", true );
|
160 |
-
$formatted_number = WCX_Order::get_meta( $order, "_wcpdf_formatted_{$this->slug}_number", true );
|
161 |
-
if (!empty($formatted_number)) {
|
162 |
-
$number = compact( 'number', 'formatted_number' );
|
163 |
-
}
|
164 |
-
}
|
165 |
-
|
166 |
-
// pass data to setter functions
|
167 |
-
$this->set_data( array(
|
168 |
-
// always load date before number, because date is used in number formatting
|
169 |
-
'date' => WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_date", true ),
|
170 |
-
'number' => $number,
|
171 |
-
), $order );
|
172 |
-
|
173 |
-
return;
|
174 |
-
}
|
175 |
-
|
176 |
-
public function init() {
|
177 |
-
$this->set_date( current_time( 'timestamp', true ) );
|
178 |
-
}
|
179 |
-
|
180 |
-
public function save( $order = null ) {
|
181 |
-
$order = empty( $order ) ? $this->order : $order;
|
182 |
-
if ( empty( $order ) ) {
|
183 |
-
return; // nowhere to save to...
|
184 |
-
}
|
185 |
-
|
186 |
-
foreach ($this->data as $key => $value) {
|
187 |
-
if ( empty( $value ) ) {
|
188 |
-
WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}" );
|
189 |
-
if ( $key == 'date' ) {
|
190 |
-
WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted" );
|
191 |
-
} elseif ( $key == 'number' ) {
|
192 |
-
WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data" );
|
193 |
-
}
|
194 |
-
} else {
|
195 |
-
if ( $key == 'date' ) {
|
196 |
-
// store dates as timestamp and formatted as mysql time
|
197 |
-
WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->getTimestamp() );
|
198 |
-
WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted", $value->date( 'Y-m-d H:i:s' ) );
|
199 |
-
} elseif ( $key == 'number' ) {
|
200 |
-
// store both formatted number and number data
|
201 |
-
WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->formatted_number );
|
202 |
-
WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data", $value->to_array() );
|
203 |
-
}
|
204 |
-
}
|
205 |
-
}
|
206 |
-
}
|
207 |
-
|
208 |
-
public function exists() {
|
209 |
-
return !empty( $this->data['number'] );
|
210 |
-
}
|
211 |
-
|
212 |
-
/*
|
213 |
-
|--------------------------------------------------------------------------
|
214 |
-
| Data getters
|
215 |
-
|--------------------------------------------------------------------------
|
216 |
-
*/
|
217 |
-
|
218 |
-
public function get_data( $key, $document_type = '', $order = null, $context = 'view' ) {
|
219 |
-
$document_type = empty( $document_type ) ? $this->type : $document_type;
|
220 |
-
$order = empty( $order ) ? $this->order : $order;
|
221 |
-
|
222 |
-
// redirect get_data call for linked documents
|
223 |
-
if ( $document_type != $this->type ) {
|
224 |
-
if ( !isset( $this->linked_documents[ $document_type ] ) ) {
|
225 |
-
// always assume parent for documents linked to credit notes
|
226 |
-
if ($this->type == 'credit-note') {
|
227 |
-
$order = $this->get_refund_parent( $order );
|
228 |
-
}
|
229 |
-
// order is not loaded to avoid overhead - we pass this by reference directly to the read_data method instead
|
230 |
-
$this->linked_documents[ $document_type ] = wcpdf_get_document( $document_type, null );
|
231 |
-
$this->linked_documents[ $document_type ]->read_data( $order );
|
232 |
-
}
|
233 |
-
return $this->linked_documents[ $document_type ]->get_data( $key, $document_type );
|
234 |
-
}
|
235 |
-
|
236 |
-
$value = null;
|
237 |
-
|
238 |
-
if ( array_key_exists( $key, $this->data ) ) {
|
239 |
-
$value = $this->data[ $key ];
|
240 |
-
|
241 |
-
if ( 'view' === $context ) {
|
242 |
-
$value = apply_filters( $this->get_hook_prefix() . $key, $value, $this );
|
243 |
-
}
|
244 |
-
}
|
245 |
-
|
246 |
-
return $value;
|
247 |
-
}
|
248 |
-
|
249 |
-
public function get_number( $document_type = '', $order = null, $context = 'view' ) {
|
250 |
-
return $this->get_data( 'number', $document_type, $order, $context );
|
251 |
-
}
|
252 |
-
|
253 |
-
public function get_date( $document_type = '', $order = null, $context = 'view' ) {
|
254 |
-
return $this->get_data( 'date', $document_type, $order, $context );
|
255 |
-
}
|
256 |
-
|
257 |
-
public function get_title() {
|
258 |
-
return apply_filters( "wpo_wcpdf_{$this->slug}_title", $this->title );
|
259 |
-
}
|
260 |
-
|
261 |
-
/*
|
262 |
-
|--------------------------------------------------------------------------
|
263 |
-
| Data setters
|
264 |
-
|--------------------------------------------------------------------------
|
265 |
-
|
|
266 |
-
| Functions for setting order data. These should not update anything in the
|
267 |
-
| order itself and should only change what is stored in the class
|
268 |
-
| object.
|
269 |
-
*/
|
270 |
-
|
271 |
-
public function set_data( $data, $order ) {
|
272 |
-
$order = empty( $order ) ? $this->order : $order;
|
273 |
-
foreach ($data as $key => $value) {
|
274 |
-
$setter = "set_$key";
|
275 |
-
if ( is_callable( array( $this, $setter ) ) ) {
|
276 |
-
$this->$setter( $value, $order );
|
277 |
-
} else {
|
278 |
-
$this->data[ $key ] = $value;
|
279 |
-
}
|
280 |
-
}
|
281 |
-
}
|
282 |
-
|
283 |
-
public function set_date( $value, $order = null ) {
|
284 |
-
$order = empty( $order ) ? $this->order : $order;
|
285 |
-
try {
|
286 |
-
if ( empty( $value ) ) {
|
287 |
-
$this->data[ 'date' ] = null;
|
288 |
-
return;
|
289 |
-
}
|
290 |
-
|
291 |
-
if ( is_a( $value, 'WC_DateTime' ) ) {
|
292 |
-
$datetime = $value;
|
293 |
-
} elseif ( is_numeric( $value ) ) {
|
294 |
-
// Timestamps are handled as UTC timestamps in all cases.
|
295 |
-
$datetime = new WC_DateTime( "@{$value}", new \DateTimeZone( 'UTC' ) );
|
296 |
-
} else {
|
297 |
-
// Strings are defined in local WP timezone. Convert to UTC.
|
298 |
-
if ( 1 === preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|((-|\+)\d{2}:\d{2}))$/', $value, $date_bits ) ) {
|
299 |
-
$offset = ! empty( $date_bits[7] ) ? iso8601_timezone_to_offset( $date_bits[7] ) : wc_timezone_offset();
|
300 |
-
$timestamp = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] ) - $offset;
|
301 |
-
} else {
|
302 |
-
$timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $value ) ) ) );
|
303 |
-
}
|
304 |
-
$datetime = new WC_DateTime( "@{$timestamp}", new \DateTimeZone( 'UTC' ) );
|
305 |
-
}
|
306 |
-
|
307 |
-
// Set local timezone or offset.
|
308 |
-
if ( get_option( 'timezone_string' ) ) {
|
309 |
-
$datetime->setTimezone( new \DateTimeZone( wc_timezone_string() ) );
|
310 |
-
} else {
|
311 |
-
$datetime->set_utc_offset( wc_timezone_offset() );
|
312 |
-
}
|
313 |
-
|
314 |
-
$this->data[ 'date' ] = $datetime;
|
315 |
-
} catch ( Exception $e ) {}
|
316 |
-
|
317 |
-
|
318 |
-
}
|
319 |
-
|
320 |
-
public function set_number( $value, $order = null ) {
|
321 |
-
$order = empty( $order ) ? $this->order : $order;
|
322 |
-
|
323 |
-
if ( is_array( $value ) ) {
|
324 |
-
$filtered_value = array_filter( $value );
|
325 |
-
}
|
326 |
-
|
327 |
-
if ( empty( $value ) || ( is_array( $value ) && empty( $filtered_value ) ) ) {
|
328 |
-
$document_number = null;
|
329 |
-
} elseif ( $value instanceof Document_Number ) {
|
330 |
-
// WCPDF 2.0 number data
|
331 |
-
$document_number = $value;
|
332 |
-
} elseif ( is_array( $value ) ) {
|
333 |
-
// WCPDF 2.0 number data as array
|
334 |
-
$document_number = new Document_Number( $value, $this->get_number_settings(), $this, $order );
|
335 |
-
} else {
|
336 |
-
// plain number
|
337 |
-
$document_number = new Document_Number( $value, $this->get_number_settings(), $this, $order );
|
338 |
-
}
|
339 |
-
|
340 |
-
$this->data[ 'number' ] = $document_number;
|
341 |
-
}
|
342 |
-
|
343 |
-
/*
|
344 |
-
|--------------------------------------------------------------------------
|
345 |
-
| Settings getters / outputters
|
346 |
-
|--------------------------------------------------------------------------
|
347 |
-
*/
|
348 |
-
|
349 |
-
public function get_number_settings() {
|
350 |
-
$number_settings = isset($this->settings['number_format'])?$this->settings['number_format']:array();
|
351 |
-
return $number_settings;
|
352 |
-
}
|
353 |
-
|
354 |
-
/**
|
355 |
-
* Output template styles
|
356 |
-
*/
|
357 |
-
public function template_styles() {
|
358 |
-
$css = apply_filters( 'wpo_wcpdf_template_styles_file', $this->locate_template_file( "style.css" ) );
|
359 |
-
|
360 |
-
ob_start();
|
361 |
-
if (file_exists($css)) {
|
362 |
-
include($css);
|
363 |
-
}
|
364 |
-
$css = ob_get_clean();
|
365 |
-
$css = apply_filters( 'wpo_wcpdf_template_styles', $css, $this );
|
366 |
-
|
367 |
-
echo $css;
|
368 |
-
}
|
369 |
-
|
370 |
-
public function has_header_logo() {
|
371 |
-
return !empty( $this->settings['header_logo'] );
|
372 |
-
}
|
373 |
-
|
374 |
-
/**
|
375 |
-
* Return logo id
|
376 |
-
*/
|
377 |
-
public function get_header_logo_id() {
|
378 |
-
if ( !empty( $this->settings['header_logo'] ) ) {
|
379 |
-
return apply_filters( 'wpo_wcpdf_header_logo_id', $this->settings['header_logo'], $this );
|
380 |
-
}
|
381 |
-
}
|
382 |
-
|
383 |
-
/**
|
384 |
-
* Show logo html
|
385 |
-
*/
|
386 |
-
public function header_logo() {
|
387 |
-
if ($this->get_header_logo_id()) {
|
388 |
-
$attachment_id = $this->get_header_logo_id();
|
389 |
-
$company = $this->get_shop_name();
|
390 |
-
if( $attachment_id ) {
|
391 |
-
$attachment = wp_get_attachment_image_src( $attachment_id, 'full', false );
|
392 |
-
|
393 |
-
$attachment_src = $attachment[0];
|
394 |
-
$attachment_width = $attachment[1];
|
395 |
-
$attachment_height = $attachment[2];
|
396 |
-
|
397 |
-
$attachment_path = get_attached_file( $attachment_id );
|
398 |
-
|
399 |
-
if ( apply_filters('wpo_wcpdf_use_path', true) && file_exists($attachment_path) ) {
|
400 |
-
$src = $attachment_path;
|
401 |
-
} else {
|
402 |
-
$src = $attachment_src;
|
403 |
-
}
|
404 |
-
|
405 |
-
printf('<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s" />', $src, $attachment_width, $attachment_height, esc_attr( $company ) );
|
406 |
-
}
|
407 |
-
}
|
408 |
-
}
|
409 |
-
|
410 |
-
public function get_settings_text( $settings_key, $default = false, $autop = true ) {
|
411 |
-
if ( !empty( $this->settings[$settings_key]['default'] ) ) {
|
412 |
-
$text = wptexturize( trim( $this->settings[$settings_key]['default'] ) );
|
413 |
-
if ($autop === true) {
|
414 |
-
$text = wpautop( $text );
|
415 |
-
}
|
416 |
-
} else {
|
417 |
-
$text = $default;
|
418 |
-
}
|
419 |
-
return apply_filters( "wpo_wcpdf_{$settings_key}", $text, $this );
|
420 |
-
}
|
421 |
-
|
422 |
-
/**
|
423 |
-
* Return/Show custom company name or default to blog name
|
424 |
-
*/
|
425 |
-
public function get_shop_name() {
|
426 |
-
$default = get_bloginfo( 'name' );
|
427 |
-
return $this->get_settings_text( 'shop_name', $default, false );
|
428 |
-
}
|
429 |
-
public function shop_name() {
|
430 |
-
echo $this->get_shop_name();
|
431 |
-
}
|
432 |
-
|
433 |
-
/**
|
434 |
-
* Return/Show shop/company address if provided
|
435 |
-
*/
|
436 |
-
public function get_shop_address() {
|
437 |
-
return $this->get_settings_text( 'shop_address' );
|
438 |
-
}
|
439 |
-
public function shop_address() {
|
440 |
-
echo $this->get_shop_address();
|
441 |
-
}
|
442 |
-
|
443 |
-
/**
|
444 |
-
* Return/Show shop/company footer imprint, copyright etc.
|
445 |
-
*/
|
446 |
-
public function get_footer() {
|
447 |
-
return $this->get_settings_text( 'footer' );
|
448 |
-
}
|
449 |
-
public function footer() {
|
450 |
-
echo $this->get_footer();
|
451 |
-
}
|
452 |
-
|
453 |
-
/**
|
454 |
-
* Return/Show Extra field 1
|
455 |
-
*/
|
456 |
-
public function get_extra_1() {
|
457 |
-
return $this->get_settings_text( 'extra_1' );
|
458 |
-
|
459 |
-
}
|
460 |
-
public function extra_1() {
|
461 |
-
echo $this->get_extra_1();
|
462 |
-
}
|
463 |
-
|
464 |
-
/**
|
465 |
-
* Return/Show Extra field 2
|
466 |
-
*/
|
467 |
-
public function get_extra_2() {
|
468 |
-
return $this->get_settings_text( 'extra_2' );
|
469 |
-
}
|
470 |
-
public function extra_2() {
|
471 |
-
echo $this->get_extra_2();
|
472 |
-
}
|
473 |
-
|
474 |
-
/**
|
475 |
-
* Return/Show Extra field 3
|
476 |
-
*/
|
477 |
-
public function get_extra_3() {
|
478 |
-
return $this->get_settings_text( 'extra_3' );
|
479 |
-
}
|
480 |
-
public function extra_3() {
|
481 |
-
echo $this->get_extra_3();
|
482 |
-
}
|
483 |
-
|
484 |
-
/*
|
485 |
-
|--------------------------------------------------------------------------
|
486 |
-
| Output functions
|
487 |
-
|--------------------------------------------------------------------------
|
488 |
-
*/
|
489 |
-
|
490 |
-
public function get_pdf() {
|
491 |
-
do_action( 'wpo_wcpdf_before_pdf', $this->get_type(), $this );
|
492 |
-
|
493 |
-
$pdf_settings = array(
|
494 |
-
'paper_size' => apply_filters( 'wpo_wcpdf_paper_format', $this->get_setting( 'paper_size', 'A4' ), $this->get_type() ),
|
495 |
-
'paper_orientation' => apply_filters( 'wpo_wcpdf_paper_orientation', 'portrait', $this->get_type() ),
|
496 |
-
'font_subsetting' => $this->get_setting( 'font_subsetting', false ),
|
497 |
-
);
|
498 |
-
$pdf_maker = wcpdf_get_pdf_maker( $this->get_html(), $pdf_settings );
|
499 |
-
$pdf = $pdf_maker->output();
|
500 |
-
|
501 |
-
do_action( 'wpo_wcpdf_after_pdf', $this->get_type(), $this );
|
502 |
-
do_action( 'wpo_wcpdf_pdf_created', $pdf, $this );
|
503 |
-
|
504 |
-
return $pdf;
|
505 |
-
}
|
506 |
-
|
507 |
-
public function get_html( $args = array() ) {
|
508 |
-
do_action( 'wpo_wcpdf_before_html', $this->get_type(), $this );
|
509 |
-
$default_args = array (
|
510 |
-
'wrap_html_content' => true,
|
511 |
-
);
|
512 |
-
$args = $args + $default_args;
|
513 |
-
|
514 |
-
$html = $this->render_template( $this->locate_template_file( "{$this->type}.php" ) );
|
515 |
-
if ($args['wrap_html_content']) {
|
516 |
-
$html = $this->wrap_html_content( $html );
|
517 |
-
}
|
518 |
-
|
519 |
-
// clean up special characters
|
520 |
-
if ( function_exists('utf8_decode') && function_exists('mb_convert_encoding') ) {
|
521 |
-
$html = utf8_decode(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
|
522 |
-
}
|
523 |
-
|
524 |
-
do_action( 'wpo_wcpdf_after_html', $this->get_type(), $this );
|
525 |
-
|
526 |
-
return apply_filters( 'wpo_wcpdf_get_html', $html, $this );
|
527 |
-
}
|
528 |
-
|
529 |
-
public function output_pdf( $output_mode = 'download' ) {
|
530 |
-
$pdf = $this->get_pdf();
|
531 |
-
wcpdf_pdf_headers( $this->get_filename(), $output_mode, $pdf );
|
532 |
-
echo $pdf;
|
533 |
-
die();
|
534 |
-
}
|
535 |
-
|
536 |
-
public function output_html() {
|
537 |
-
echo $this->get_html();
|
538 |
-
die();
|
539 |
-
}
|
540 |
-
|
541 |
-
public function wrap_html_content( $content ) {
|
542 |
-
if ( WPO_WCPDF()->legacy_mode_enabled() ) {
|
543 |
-
$GLOBALS['wpo_wcpdf']->export->output_body = $content;
|
544 |
-
}
|
545 |
-
|
546 |
-
$html = $this->render_template( $this->locate_template_file( "html-document-wrapper.php" ), array(
|
547 |
-
'content' => $content,
|
548 |
-
)
|
549 |
-
);
|
550 |
-
return $html;
|
551 |
-
}
|
552 |
-
|
553 |
-
public function get_filename( $context = 'download', $args = array() ) {
|
554 |
-
$order_count = isset($args['order_ids']) ? count($args['order_ids']) : 1;
|
555 |
-
|
556 |
-
$name = $this->get_type();
|
557 |
-
if ( get_post_type( $this->order_id ) == 'shop_order_refund' ) {
|
558 |
-
$number = $this->order_id;
|
559 |
-
} else {
|
560 |
-
$number = method_exists( $this->order, 'get_order_number' ) ? $this->order->get_order_number() : '';
|
561 |
-
}
|
562 |
-
|
563 |
-
if ( $order_count == 1 ) {
|
564 |
-
$suffix = $number;
|
565 |
-
} else {
|
566 |
-
$suffix = date('Y-m-d'); // 2020-11-11
|
567 |
-
}
|
568 |
-
|
569 |
-
$filename = $name . '-' . $suffix . '.pdf';
|
570 |
-
|
571 |
-
// Filter filename
|
572 |
-
$order_ids = isset($args['order_ids']) ? $args['order_ids'] : array( $this->order_id );
|
573 |
-
$filename = apply_filters( 'wpo_wcpdf_filename', $filename, $this->get_type(), $order_ids, $context );
|
574 |
-
|
575 |
-
// sanitize filename (after filters to prevent human errors)!
|
576 |
-
return sanitize_file_name( $filename );
|
577 |
-
}
|
578 |
-
|
579 |
-
public function get_template_path() {
|
580 |
-
return WPO_WCPDF()->settings->get_template_path();
|
581 |
-
}
|
582 |
-
|
583 |
-
public function locate_template_file( $file ) {
|
584 |
-
if (empty($file)) {
|
585 |
-
$file = $this->type.'.php';
|
586 |
-
}
|
587 |
-
$path = WPO_WCPDF()->settings->get_template_path( $file );
|
588 |
-
$file_path = "{$path}/{$file}";
|
589 |
-
|
590 |
-
$fallback_file_path = WPO_WCPDF()->plugin_path() . '/templates/Simple/' . $file;
|
591 |
-
if ( !file_exists( $file_path ) && file_exists( $fallback_file_path ) ) {
|
592 |
-
$file_path = $fallback_file_path;
|
593 |
-
}
|
594 |
-
|
595 |
-
$file_path = apply_filters( 'wpo_wcpdf_template_file', $file_path, $this->type, $this->order );
|
596 |
-
|
597 |
-
return $file_path;
|
598 |
-
}
|
599 |
-
|
600 |
-
public function render_template( $file, $args = array() ) {
|
601 |
-
do_action( 'wpo_wcpdf_process_template', $this->get_type(), $this );
|
602 |
-
|
603 |
-
if ( ! empty( $args ) && is_array( $args ) ) {
|
604 |
-
extract( $args );
|
605 |
-
}
|
606 |
-
ob_start();
|
607 |
-
if (file_exists($file)) {
|
608 |
-
include($file);
|
609 |
-
}
|
610 |
-
return ob_get_clean();
|
611 |
-
}
|
612 |
-
|
613 |
-
/*
|
614 |
-
|--------------------------------------------------------------------------
|
615 |
-
| Settings helper functions
|
616 |
-
|--------------------------------------------------------------------------
|
617 |
-
*/
|
618 |
-
|
619 |
-
/**
|
620 |
-
* get all emails registered in WooCommerce
|
621 |
-
* @param boolean $remove_defaults switch to remove default woocommerce emails
|
622 |
-
* @return array $emails list of all email ids/slugs and names
|
623 |
-
*/
|
624 |
-
public function get_wc_emails() {
|
625 |
-
// get emails from WooCommerce
|
626 |
-
global $woocommerce;
|
627 |
-
$mailer = $woocommerce->mailer();
|
628 |
-
$wc_emails = $mailer->get_emails();
|
629 |
-
|
630 |
-
$non_order_emails = array(
|
631 |
-
'customer_note',
|
632 |
-
'customer_reset_password',
|
633 |
-
'customer_new_account'
|
634 |
-
);
|
635 |
-
|
636 |
-
$emails = array();
|
637 |
-
foreach ($wc_emails as $class => $email) {
|
638 |
-
if ( !in_array( $email->id, $non_order_emails ) ) {
|
639 |
-
switch ($email->id) {
|
640 |
-
case 'new_order':
|
641 |
-
$emails[$email->id] = sprintf('%s (%s)', $email->title, __( 'Admin email', 'woocommerce-pdf-invoices-packing-slips' ) );
|
642 |
-
break;
|
643 |
-
case 'customer_invoice':
|
644 |
-
$emails[$email->id] = sprintf('%s (%s)', $email->title, __( 'Manual email', 'woocommerce-pdf-invoices-packing-slips' ) );
|
645 |
-
break;
|
646 |
-
default:
|
647 |
-
$emails[$email->id] = $email->title;
|
648 |
-
break;
|
649 |
-
}
|
650 |
-
}
|
651 |
-
}
|
652 |
-
|
653 |
-
return apply_filters( 'wpo_wcpdf_wc_emails', $emails );
|
654 |
-
}
|
655 |
-
|
656 |
-
// get list of WooCommerce statuses
|
657 |
-
public function get_wc_order_status_list() {
|
658 |
-
if ( version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
|
659 |
-
$statuses = (array) get_terms( 'shop_order_status', array( 'hide_empty' => 0, 'orderby' => 'id' ) );
|
660 |
-
foreach ( $statuses as $status ) {
|
661 |
-
$order_statuses[esc_attr( $status->slug )] = esc_html__( $status->name, 'woocommerce' );
|
662 |
-
}
|
663 |
-
} else {
|
664 |
-
$statuses = wc_get_order_statuses();
|
665 |
-
foreach ( $statuses as $status_slug => $status ) {
|
666 |
-
$status_slug = 'wc-' === substr( $status_slug, 0, 3 ) ? substr( $status_slug, 3 ) : $status_slug;
|
667 |
-
$order_statuses[$status_slug] = $status;
|
668 |
-
}
|
669 |
-
}
|
670 |
-
return $order_statuses;
|
671 |
-
}
|
672 |
-
|
673 |
-
|
674 |
-
}
|
675 |
-
|
676 |
-
endif; // class_exists
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices\Documents;
|
3 |
+
|
4 |
+
use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
|
5 |
+
use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
|
6 |
+
use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
|
7 |
+
use WPO\WC\PDF_Invoices\Compatibility\WC_DateTime;
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit; // Exit if accessed directly
|
11 |
+
}
|
12 |
+
|
13 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Order_Document' ) ) :
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Abstract Document
|
17 |
+
*
|
18 |
+
* Handles generic pdf document & order data and database interaction
|
19 |
+
* which is extended by both Invoices & Packing Slips
|
20 |
+
*
|
21 |
+
* @class \WPO\WC\PDF_Invoices\Documents\Order_Document
|
22 |
+
* @version 2.0
|
23 |
+
* @category Class
|
24 |
+
* @author Ewout Fernhout
|
25 |
+
*/
|
26 |
+
|
27 |
+
abstract class Order_Document {
|
28 |
+
/**
|
29 |
+
* Document type.
|
30 |
+
* @var String
|
31 |
+
*/
|
32 |
+
public $type;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Document slug.
|
36 |
+
* @var String
|
37 |
+
*/
|
38 |
+
public $slug;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Document title.
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
public $title;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Document icon.
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
public $icon;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* WC Order object
|
54 |
+
* @var object
|
55 |
+
*/
|
56 |
+
public $order;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* WC Order ID
|
60 |
+
* @var object
|
61 |
+
*/
|
62 |
+
public $order_id;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Document settings.
|
66 |
+
* @var array
|
67 |
+
*/
|
68 |
+
public $settings;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* TRUE if document is enabled.
|
72 |
+
* @var bool
|
73 |
+
*/
|
74 |
+
public $enabled;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Linked documents, used for data retrieval
|
78 |
+
* @var array
|
79 |
+
*/
|
80 |
+
protected $linked_documents = array();
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Core data for this object. Name value pairs (name + default value).
|
84 |
+
* @var array
|
85 |
+
*/
|
86 |
+
protected $data = array();
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Init/load the order object.
|
90 |
+
*
|
91 |
+
* @param int|object|WC_Order $order Order to init.
|
92 |
+
*/
|
93 |
+
public function __construct( $order = 0 ) {
|
94 |
+
if ( is_numeric( $order ) && $order > 0 ) {
|
95 |
+
$this->order_id = $order;
|
96 |
+
$this->order = WCX::get_order( $order_id );
|
97 |
+
} elseif ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) {
|
98 |
+
$this->order_id = WCX_Order::get_id( $order );
|
99 |
+
$this->order = $order;
|
100 |
+
}
|
101 |
+
|
102 |
+
// set properties
|
103 |
+
$this->slug = str_replace('-', '_', $this->type);
|
104 |
+
|
105 |
+
// load settings
|
106 |
+
$this->settings = $this->get_settings();
|
107 |
+
$this->enabled = $this->get_setting( 'enabled', false );
|
108 |
+
|
109 |
+
// load data
|
110 |
+
if ( $this->order ) {
|
111 |
+
$this->read_data( $this->order );
|
112 |
+
if ( WPO_WCPDF()->legacy_mode_enabled() ) {
|
113 |
+
global $wpo_wcpdf;
|
114 |
+
$wpo_wcpdf->export->order = $this->order;
|
115 |
+
$wpo_wcpdf->export->document = $this;
|
116 |
+
$wpo_wcpdf->export->order_id = $this->order_id;
|
117 |
+
$wpo_wcpdf->export->template_type = $this->type;
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
}
|
122 |
+
|
123 |
+
public function init_settings() {
|
124 |
+
return ;
|
125 |
+
}
|
126 |
+
|
127 |
+
public function get_settings() {
|
128 |
+
$common_settings = WPO_WCPDF()->settings->get_common_document_settings();
|
129 |
+
$document_settings = get_option( 'wpo_wcpdf_documents_settings_'.$this->get_type() );
|
130 |
+
return (array) $document_settings + (array) $common_settings;
|
131 |
+
}
|
132 |
+
|
133 |
+
public function get_setting( $key, $default = '' ) {
|
134 |
+
$setting = isset( $this->settings[$key] ) ? $this->settings[$key] : $default;
|
135 |
+
return $setting;
|
136 |
+
}
|
137 |
+
|
138 |
+
public function get_attach_to_email_ids() {
|
139 |
+
$email_ids = isset( $this->settings['attach_to_email_ids'] ) ? array_keys( $this->settings['attach_to_email_ids'] ) : array();
|
140 |
+
return $email_ids;
|
141 |
+
}
|
142 |
+
|
143 |
+
public function get_type() {
|
144 |
+
return $this->type;
|
145 |
+
}
|
146 |
+
|
147 |
+
public function is_enabled() {
|
148 |
+
return apply_filters( 'wpo_wcpdf_document_is_enabled', $this->enabled, $this->type );
|
149 |
+
}
|
150 |
+
|
151 |
+
public function get_hook_prefix() {
|
152 |
+
return 'wpo_wcpdf_' . $this->slug . '_get_';
|
153 |
+
}
|
154 |
+
|
155 |
+
public function read_data( $order ) {
|
156 |
+
$number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number_data", true );
|
157 |
+
// fallback to legacy data for number
|
158 |
+
if ( empty( $number ) ) {
|
159 |
+
$number = WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_number", true );
|
160 |
+
$formatted_number = WCX_Order::get_meta( $order, "_wcpdf_formatted_{$this->slug}_number", true );
|
161 |
+
if (!empty($formatted_number)) {
|
162 |
+
$number = compact( 'number', 'formatted_number' );
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
// pass data to setter functions
|
167 |
+
$this->set_data( array(
|
168 |
+
// always load date before number, because date is used in number formatting
|
169 |
+
'date' => WCX_Order::get_meta( $order, "_wcpdf_{$this->slug}_date", true ),
|
170 |
+
'number' => $number,
|
171 |
+
), $order );
|
172 |
+
|
173 |
+
return;
|
174 |
+
}
|
175 |
+
|
176 |
+
public function init() {
|
177 |
+
$this->set_date( current_time( 'timestamp', true ) );
|
178 |
+
}
|
179 |
+
|
180 |
+
public function save( $order = null ) {
|
181 |
+
$order = empty( $order ) ? $this->order : $order;
|
182 |
+
if ( empty( $order ) ) {
|
183 |
+
return; // nowhere to save to...
|
184 |
+
}
|
185 |
+
|
186 |
+
foreach ($this->data as $key => $value) {
|
187 |
+
if ( empty( $value ) ) {
|
188 |
+
WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}" );
|
189 |
+
if ( $key == 'date' ) {
|
190 |
+
WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted" );
|
191 |
+
} elseif ( $key == 'number' ) {
|
192 |
+
WCX_Order::delete_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data" );
|
193 |
+
}
|
194 |
+
} else {
|
195 |
+
if ( $key == 'date' ) {
|
196 |
+
// store dates as timestamp and formatted as mysql time
|
197 |
+
WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->getTimestamp() );
|
198 |
+
WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_formatted", $value->date( 'Y-m-d H:i:s' ) );
|
199 |
+
} elseif ( $key == 'number' ) {
|
200 |
+
// store both formatted number and number data
|
201 |
+
WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}", $value->formatted_number );
|
202 |
+
WCX_Order::update_meta_data( $order, "_wcpdf_{$this->slug}_{$key}_data", $value->to_array() );
|
203 |
+
}
|
204 |
+
}
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
public function exists() {
|
209 |
+
return !empty( $this->data['number'] );
|
210 |
+
}
|
211 |
+
|
212 |
+
/*
|
213 |
+
|--------------------------------------------------------------------------
|
214 |
+
| Data getters
|
215 |
+
|--------------------------------------------------------------------------
|
216 |
+
*/
|
217 |
+
|
218 |
+
public function get_data( $key, $document_type = '', $order = null, $context = 'view' ) {
|
219 |
+
$document_type = empty( $document_type ) ? $this->type : $document_type;
|
220 |
+
$order = empty( $order ) ? $this->order : $order;
|
221 |
+
|
222 |
+
// redirect get_data call for linked documents
|
223 |
+
if ( $document_type != $this->type ) {
|
224 |
+
if ( !isset( $this->linked_documents[ $document_type ] ) ) {
|
225 |
+
// always assume parent for documents linked to credit notes
|
226 |
+
if ($this->type == 'credit-note') {
|
227 |
+
$order = $this->get_refund_parent( $order );
|
228 |
+
}
|
229 |
+
// order is not loaded to avoid overhead - we pass this by reference directly to the read_data method instead
|
230 |
+
$this->linked_documents[ $document_type ] = wcpdf_get_document( $document_type, null );
|
231 |
+
$this->linked_documents[ $document_type ]->read_data( $order );
|
232 |
+
}
|
233 |
+
return $this->linked_documents[ $document_type ]->get_data( $key, $document_type );
|
234 |
+
}
|
235 |
+
|
236 |
+
$value = null;
|
237 |
+
|
238 |
+
if ( array_key_exists( $key, $this->data ) ) {
|
239 |
+
$value = $this->data[ $key ];
|
240 |
+
|
241 |
+
if ( 'view' === $context ) {
|
242 |
+
$value = apply_filters( $this->get_hook_prefix() . $key, $value, $this );
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
return $value;
|
247 |
+
}
|
248 |
+
|
249 |
+
public function get_number( $document_type = '', $order = null, $context = 'view' ) {
|
250 |
+
return $this->get_data( 'number', $document_type, $order, $context );
|
251 |
+
}
|
252 |
+
|
253 |
+
public function get_date( $document_type = '', $order = null, $context = 'view' ) {
|
254 |
+
return $this->get_data( 'date', $document_type, $order, $context );
|
255 |
+
}
|
256 |
+
|
257 |
+
public function get_title() {
|
258 |
+
return apply_filters( "wpo_wcpdf_{$this->slug}_title", $this->title );
|
259 |
+
}
|
260 |
+
|
261 |
+
/*
|
262 |
+
|--------------------------------------------------------------------------
|
263 |
+
| Data setters
|
264 |
+
|--------------------------------------------------------------------------
|
265 |
+
|
|
266 |
+
| Functions for setting order data. These should not update anything in the
|
267 |
+
| order itself and should only change what is stored in the class
|
268 |
+
| object.
|
269 |
+
*/
|
270 |
+
|
271 |
+
public function set_data( $data, $order ) {
|
272 |
+
$order = empty( $order ) ? $this->order : $order;
|
273 |
+
foreach ($data as $key => $value) {
|
274 |
+
$setter = "set_$key";
|
275 |
+
if ( is_callable( array( $this, $setter ) ) ) {
|
276 |
+
$this->$setter( $value, $order );
|
277 |
+
} else {
|
278 |
+
$this->data[ $key ] = $value;
|
279 |
+
}
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
public function set_date( $value, $order = null ) {
|
284 |
+
$order = empty( $order ) ? $this->order : $order;
|
285 |
+
try {
|
286 |
+
if ( empty( $value ) ) {
|
287 |
+
$this->data[ 'date' ] = null;
|
288 |
+
return;
|
289 |
+
}
|
290 |
+
|
291 |
+
if ( is_a( $value, 'WC_DateTime' ) ) {
|
292 |
+
$datetime = $value;
|
293 |
+
} elseif ( is_numeric( $value ) ) {
|
294 |
+
// Timestamps are handled as UTC timestamps in all cases.
|
295 |
+
$datetime = new WC_DateTime( "@{$value}", new \DateTimeZone( 'UTC' ) );
|
296 |
+
} else {
|
297 |
+
// Strings are defined in local WP timezone. Convert to UTC.
|
298 |
+
if ( 1 === preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|((-|\+)\d{2}:\d{2}))$/', $value, $date_bits ) ) {
|
299 |
+
$offset = ! empty( $date_bits[7] ) ? iso8601_timezone_to_offset( $date_bits[7] ) : wc_timezone_offset();
|
300 |
+
$timestamp = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] ) - $offset;
|
301 |
+
} else {
|
302 |
+
$timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $value ) ) ) );
|
303 |
+
}
|
304 |
+
$datetime = new WC_DateTime( "@{$timestamp}", new \DateTimeZone( 'UTC' ) );
|
305 |
+
}
|
306 |
+
|
307 |
+
// Set local timezone or offset.
|
308 |
+
if ( get_option( 'timezone_string' ) ) {
|
309 |
+
$datetime->setTimezone( new \DateTimeZone( wc_timezone_string() ) );
|
310 |
+
} else {
|
311 |
+
$datetime->set_utc_offset( wc_timezone_offset() );
|
312 |
+
}
|
313 |
+
|
314 |
+
$this->data[ 'date' ] = $datetime;
|
315 |
+
} catch ( Exception $e ) {}
|
316 |
+
|
317 |
+
|
318 |
+
}
|
319 |
+
|
320 |
+
public function set_number( $value, $order = null ) {
|
321 |
+
$order = empty( $order ) ? $this->order : $order;
|
322 |
+
|
323 |
+
if ( is_array( $value ) ) {
|
324 |
+
$filtered_value = array_filter( $value );
|
325 |
+
}
|
326 |
+
|
327 |
+
if ( empty( $value ) || ( is_array( $value ) && empty( $filtered_value ) ) ) {
|
328 |
+
$document_number = null;
|
329 |
+
} elseif ( $value instanceof Document_Number ) {
|
330 |
+
// WCPDF 2.0 number data
|
331 |
+
$document_number = $value;
|
332 |
+
} elseif ( is_array( $value ) ) {
|
333 |
+
// WCPDF 2.0 number data as array
|
334 |
+
$document_number = new Document_Number( $value, $this->get_number_settings(), $this, $order );
|
335 |
+
} else {
|
336 |
+
// plain number
|
337 |
+
$document_number = new Document_Number( $value, $this->get_number_settings(), $this, $order );
|
338 |
+
}
|
339 |
+
|
340 |
+
$this->data[ 'number' ] = $document_number;
|
341 |
+
}
|
342 |
+
|
343 |
+
/*
|
344 |
+
|--------------------------------------------------------------------------
|
345 |
+
| Settings getters / outputters
|
346 |
+
|--------------------------------------------------------------------------
|
347 |
+
*/
|
348 |
+
|
349 |
+
public function get_number_settings() {
|
350 |
+
$number_settings = isset($this->settings['number_format'])?$this->settings['number_format']:array();
|
351 |
+
return $number_settings;
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Output template styles
|
356 |
+
*/
|
357 |
+
public function template_styles() {
|
358 |
+
$css = apply_filters( 'wpo_wcpdf_template_styles_file', $this->locate_template_file( "style.css" ) );
|
359 |
+
|
360 |
+
ob_start();
|
361 |
+
if (file_exists($css)) {
|
362 |
+
include($css);
|
363 |
+
}
|
364 |
+
$css = ob_get_clean();
|
365 |
+
$css = apply_filters( 'wpo_wcpdf_template_styles', $css, $this );
|
366 |
+
|
367 |
+
echo $css;
|
368 |
+
}
|
369 |
+
|
370 |
+
public function has_header_logo() {
|
371 |
+
return !empty( $this->settings['header_logo'] );
|
372 |
+
}
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Return logo id
|
376 |
+
*/
|
377 |
+
public function get_header_logo_id() {
|
378 |
+
if ( !empty( $this->settings['header_logo'] ) ) {
|
379 |
+
return apply_filters( 'wpo_wcpdf_header_logo_id', $this->settings['header_logo'], $this );
|
380 |
+
}
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Show logo html
|
385 |
+
*/
|
386 |
+
public function header_logo() {
|
387 |
+
if ($this->get_header_logo_id()) {
|
388 |
+
$attachment_id = $this->get_header_logo_id();
|
389 |
+
$company = $this->get_shop_name();
|
390 |
+
if( $attachment_id ) {
|
391 |
+
$attachment = wp_get_attachment_image_src( $attachment_id, 'full', false );
|
392 |
+
|
393 |
+
$attachment_src = $attachment[0];
|
394 |
+
$attachment_width = $attachment[1];
|
395 |
+
$attachment_height = $attachment[2];
|
396 |
+
|
397 |
+
$attachment_path = get_attached_file( $attachment_id );
|
398 |
+
|
399 |
+
if ( apply_filters('wpo_wcpdf_use_path', true) && file_exists($attachment_path) ) {
|
400 |
+
$src = $attachment_path;
|
401 |
+
} else {
|
402 |
+
$src = $attachment_src;
|
403 |
+
}
|
404 |
+
|
405 |
+
printf('<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s" />', $src, $attachment_width, $attachment_height, esc_attr( $company ) );
|
406 |
+
}
|
407 |
+
}
|
408 |
+
}
|
409 |
+
|
410 |
+
public function get_settings_text( $settings_key, $default = false, $autop = true ) {
|
411 |
+
if ( !empty( $this->settings[$settings_key]['default'] ) ) {
|
412 |
+
$text = wptexturize( trim( $this->settings[$settings_key]['default'] ) );
|
413 |
+
if ($autop === true) {
|
414 |
+
$text = wpautop( $text );
|
415 |
+
}
|
416 |
+
} else {
|
417 |
+
$text = $default;
|
418 |
+
}
|
419 |
+
return apply_filters( "wpo_wcpdf_{$settings_key}", $text, $this );
|
420 |
+
}
|
421 |
+
|
422 |
+
/**
|
423 |
+
* Return/Show custom company name or default to blog name
|
424 |
+
*/
|
425 |
+
public function get_shop_name() {
|
426 |
+
$default = get_bloginfo( 'name' );
|
427 |
+
return $this->get_settings_text( 'shop_name', $default, false );
|
428 |
+
}
|
429 |
+
public function shop_name() {
|
430 |
+
echo $this->get_shop_name();
|
431 |
+
}
|
432 |
+
|
433 |
+
/**
|
434 |
+
* Return/Show shop/company address if provided
|
435 |
+
*/
|
436 |
+
public function get_shop_address() {
|
437 |
+
return $this->get_settings_text( 'shop_address' );
|
438 |
+
}
|
439 |
+
public function shop_address() {
|
440 |
+
echo $this->get_shop_address();
|
441 |
+
}
|
442 |
+
|
443 |
+
/**
|
444 |
+
* Return/Show shop/company footer imprint, copyright etc.
|
445 |
+
*/
|
446 |
+
public function get_footer() {
|
447 |
+
return $this->get_settings_text( 'footer' );
|
448 |
+
}
|
449 |
+
public function footer() {
|
450 |
+
echo $this->get_footer();
|
451 |
+
}
|
452 |
+
|
453 |
+
/**
|
454 |
+
* Return/Show Extra field 1
|
455 |
+
*/
|
456 |
+
public function get_extra_1() {
|
457 |
+
return $this->get_settings_text( 'extra_1' );
|
458 |
+
|
459 |
+
}
|
460 |
+
public function extra_1() {
|
461 |
+
echo $this->get_extra_1();
|
462 |
+
}
|
463 |
+
|
464 |
+
/**
|
465 |
+
* Return/Show Extra field 2
|
466 |
+
*/
|
467 |
+
public function get_extra_2() {
|
468 |
+
return $this->get_settings_text( 'extra_2' );
|
469 |
+
}
|
470 |
+
public function extra_2() {
|
471 |
+
echo $this->get_extra_2();
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Return/Show Extra field 3
|
476 |
+
*/
|
477 |
+
public function get_extra_3() {
|
478 |
+
return $this->get_settings_text( 'extra_3' );
|
479 |
+
}
|
480 |
+
public function extra_3() {
|
481 |
+
echo $this->get_extra_3();
|
482 |
+
}
|
483 |
+
|
484 |
+
/*
|
485 |
+
|--------------------------------------------------------------------------
|
486 |
+
| Output functions
|
487 |
+
|--------------------------------------------------------------------------
|
488 |
+
*/
|
489 |
+
|
490 |
+
public function get_pdf() {
|
491 |
+
do_action( 'wpo_wcpdf_before_pdf', $this->get_type(), $this );
|
492 |
+
|
493 |
+
$pdf_settings = array(
|
494 |
+
'paper_size' => apply_filters( 'wpo_wcpdf_paper_format', $this->get_setting( 'paper_size', 'A4' ), $this->get_type() ),
|
495 |
+
'paper_orientation' => apply_filters( 'wpo_wcpdf_paper_orientation', 'portrait', $this->get_type() ),
|
496 |
+
'font_subsetting' => $this->get_setting( 'font_subsetting', false ),
|
497 |
+
);
|
498 |
+
$pdf_maker = wcpdf_get_pdf_maker( $this->get_html(), $pdf_settings );
|
499 |
+
$pdf = $pdf_maker->output();
|
500 |
+
|
501 |
+
do_action( 'wpo_wcpdf_after_pdf', $this->get_type(), $this );
|
502 |
+
do_action( 'wpo_wcpdf_pdf_created', $pdf, $this );
|
503 |
+
|
504 |
+
return $pdf;
|
505 |
+
}
|
506 |
+
|
507 |
+
public function get_html( $args = array() ) {
|
508 |
+
do_action( 'wpo_wcpdf_before_html', $this->get_type(), $this );
|
509 |
+
$default_args = array (
|
510 |
+
'wrap_html_content' => true,
|
511 |
+
);
|
512 |
+
$args = $args + $default_args;
|
513 |
+
|
514 |
+
$html = $this->render_template( $this->locate_template_file( "{$this->type}.php" ) );
|
515 |
+
if ($args['wrap_html_content']) {
|
516 |
+
$html = $this->wrap_html_content( $html );
|
517 |
+
}
|
518 |
+
|
519 |
+
// clean up special characters
|
520 |
+
if ( function_exists('utf8_decode') && function_exists('mb_convert_encoding') ) {
|
521 |
+
$html = utf8_decode(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
|
522 |
+
}
|
523 |
+
|
524 |
+
do_action( 'wpo_wcpdf_after_html', $this->get_type(), $this );
|
525 |
+
|
526 |
+
return apply_filters( 'wpo_wcpdf_get_html', $html, $this );
|
527 |
+
}
|
528 |
+
|
529 |
+
public function output_pdf( $output_mode = 'download' ) {
|
530 |
+
$pdf = $this->get_pdf();
|
531 |
+
wcpdf_pdf_headers( $this->get_filename(), $output_mode, $pdf );
|
532 |
+
echo $pdf;
|
533 |
+
die();
|
534 |
+
}
|
535 |
+
|
536 |
+
public function output_html() {
|
537 |
+
echo $this->get_html();
|
538 |
+
die();
|
539 |
+
}
|
540 |
+
|
541 |
+
public function wrap_html_content( $content ) {
|
542 |
+
if ( WPO_WCPDF()->legacy_mode_enabled() ) {
|
543 |
+
$GLOBALS['wpo_wcpdf']->export->output_body = $content;
|
544 |
+
}
|
545 |
+
|
546 |
+
$html = $this->render_template( $this->locate_template_file( "html-document-wrapper.php" ), array(
|
547 |
+
'content' => $content,
|
548 |
+
)
|
549 |
+
);
|
550 |
+
return $html;
|
551 |
+
}
|
552 |
+
|
553 |
+
public function get_filename( $context = 'download', $args = array() ) {
|
554 |
+
$order_count = isset($args['order_ids']) ? count($args['order_ids']) : 1;
|
555 |
+
|
556 |
+
$name = $this->get_type();
|
557 |
+
if ( get_post_type( $this->order_id ) == 'shop_order_refund' ) {
|
558 |
+
$number = $this->order_id;
|
559 |
+
} else {
|
560 |
+
$number = method_exists( $this->order, 'get_order_number' ) ? $this->order->get_order_number() : '';
|
561 |
+
}
|
562 |
+
|
563 |
+
if ( $order_count == 1 ) {
|
564 |
+
$suffix = $number;
|
565 |
+
} else {
|
566 |
+
$suffix = date('Y-m-d'); // 2020-11-11
|
567 |
+
}
|
568 |
+
|
569 |
+
$filename = $name . '-' . $suffix . '.pdf';
|
570 |
+
|
571 |
+
// Filter filename
|
572 |
+
$order_ids = isset($args['order_ids']) ? $args['order_ids'] : array( $this->order_id );
|
573 |
+
$filename = apply_filters( 'wpo_wcpdf_filename', $filename, $this->get_type(), $order_ids, $context );
|
574 |
+
|
575 |
+
// sanitize filename (after filters to prevent human errors)!
|
576 |
+
return sanitize_file_name( $filename );
|
577 |
+
}
|
578 |
+
|
579 |
+
public function get_template_path() {
|
580 |
+
return WPO_WCPDF()->settings->get_template_path();
|
581 |
+
}
|
582 |
+
|
583 |
+
public function locate_template_file( $file ) {
|
584 |
+
if (empty($file)) {
|
585 |
+
$file = $this->type.'.php';
|
586 |
+
}
|
587 |
+
$path = WPO_WCPDF()->settings->get_template_path( $file );
|
588 |
+
$file_path = "{$path}/{$file}";
|
589 |
+
|
590 |
+
$fallback_file_path = WPO_WCPDF()->plugin_path() . '/templates/Simple/' . $file;
|
591 |
+
if ( !file_exists( $file_path ) && file_exists( $fallback_file_path ) ) {
|
592 |
+
$file_path = $fallback_file_path;
|
593 |
+
}
|
594 |
+
|
595 |
+
$file_path = apply_filters( 'wpo_wcpdf_template_file', $file_path, $this->type, $this->order );
|
596 |
+
|
597 |
+
return $file_path;
|
598 |
+
}
|
599 |
+
|
600 |
+
public function render_template( $file, $args = array() ) {
|
601 |
+
do_action( 'wpo_wcpdf_process_template', $this->get_type(), $this );
|
602 |
+
|
603 |
+
if ( ! empty( $args ) && is_array( $args ) ) {
|
604 |
+
extract( $args );
|
605 |
+
}
|
606 |
+
ob_start();
|
607 |
+
if (file_exists($file)) {
|
608 |
+
include($file);
|
609 |
+
}
|
610 |
+
return ob_get_clean();
|
611 |
+
}
|
612 |
+
|
613 |
+
/*
|
614 |
+
|--------------------------------------------------------------------------
|
615 |
+
| Settings helper functions
|
616 |
+
|--------------------------------------------------------------------------
|
617 |
+
*/
|
618 |
+
|
619 |
+
/**
|
620 |
+
* get all emails registered in WooCommerce
|
621 |
+
* @param boolean $remove_defaults switch to remove default woocommerce emails
|
622 |
+
* @return array $emails list of all email ids/slugs and names
|
623 |
+
*/
|
624 |
+
public function get_wc_emails() {
|
625 |
+
// get emails from WooCommerce
|
626 |
+
global $woocommerce;
|
627 |
+
$mailer = $woocommerce->mailer();
|
628 |
+
$wc_emails = $mailer->get_emails();
|
629 |
+
|
630 |
+
$non_order_emails = array(
|
631 |
+
'customer_note',
|
632 |
+
'customer_reset_password',
|
633 |
+
'customer_new_account'
|
634 |
+
);
|
635 |
+
|
636 |
+
$emails = array();
|
637 |
+
foreach ($wc_emails as $class => $email) {
|
638 |
+
if ( !in_array( $email->id, $non_order_emails ) ) {
|
639 |
+
switch ($email->id) {
|
640 |
+
case 'new_order':
|
641 |
+
$emails[$email->id] = sprintf('%s (%s)', $email->title, __( 'Admin email', 'woocommerce-pdf-invoices-packing-slips' ) );
|
642 |
+
break;
|
643 |
+
case 'customer_invoice':
|
644 |
+
$emails[$email->id] = sprintf('%s (%s)', $email->title, __( 'Manual email', 'woocommerce-pdf-invoices-packing-slips' ) );
|
645 |
+
break;
|
646 |
+
default:
|
647 |
+
$emails[$email->id] = $email->title;
|
648 |
+
break;
|
649 |
+
}
|
650 |
+
}
|
651 |
+
}
|
652 |
+
|
653 |
+
return apply_filters( 'wpo_wcpdf_wc_emails', $emails );
|
654 |
+
}
|
655 |
+
|
656 |
+
// get list of WooCommerce statuses
|
657 |
+
public function get_wc_order_status_list() {
|
658 |
+
if ( version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
|
659 |
+
$statuses = (array) get_terms( 'shop_order_status', array( 'hide_empty' => 0, 'orderby' => 'id' ) );
|
660 |
+
foreach ( $statuses as $status ) {
|
661 |
+
$order_statuses[esc_attr( $status->slug )] = esc_html__( $status->name, 'woocommerce' );
|
662 |
+
}
|
663 |
+
} else {
|
664 |
+
$statuses = wc_get_order_statuses();
|
665 |
+
foreach ( $statuses as $status_slug => $status ) {
|
666 |
+
$status_slug = 'wc-' === substr( $status_slug, 0, 3 ) ? substr( $status_slug, 3 ) : $status_slug;
|
667 |
+
$order_statuses[$status_slug] = $status;
|
668 |
+
}
|
669 |
+
}
|
670 |
+
return $order_statuses;
|
671 |
+
}
|
672 |
+
|
673 |
+
|
674 |
+
}
|
675 |
+
|
676 |
+
endif; // class_exists
|
includes/documents/class-wcpdf-bulk-document.php
CHANGED
@@ -1,119 +1,124 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices\Documents;
|
3 |
-
|
4 |
-
use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
|
5 |
-
use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
|
6 |
-
use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
|
7 |
-
|
8 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
9 |
-
exit; // Exit if accessed directly
|
10 |
-
}
|
11 |
-
|
12 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Bulk_Document' ) ) :
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Bulk Document
|
16 |
-
*
|
17 |
-
* Wraps single documents in a bulk document
|
18 |
-
*
|
19 |
-
* @class \WPO\WC\PDF_Invoices\Documents\Bulk_Document
|
20 |
-
* @version 2.0
|
21 |
-
* @category Class
|
22 |
-
* @author Ewout Fernhout
|
23 |
-
*/
|
24 |
-
|
25 |
-
class Bulk_Document {
|
26 |
-
/**
|
27 |
-
* Document type.
|
28 |
-
* @var String
|
29 |
-
*/
|
30 |
-
public $type;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Wrapper document - used for filename etc.
|
34 |
-
* @var String
|
35 |
-
*/
|
36 |
-
public $wrapper_document;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Order IDs.
|
40 |
-
* @var array
|
41 |
-
*/
|
42 |
-
public $order_ids;
|
43 |
-
|
44 |
-
public function __construct( $document_type, $order_ids = array() ) {
|
45 |
-
$this->type = $document_type;
|
46 |
-
$this->order_ids = $order_ids;
|
47 |
-
}
|
48 |
-
|
49 |
-
public function get_type() {
|
50 |
-
return $this->type;
|
51 |
-
}
|
52 |
-
|
53 |
-
public function get_pdf() {
|
54 |
-
do_action( 'wpo_wcpdf_before_pdf', $this->get_type(), $this );
|
55 |
-
|
56 |
-
$html = $this->get_html();
|
57 |
-
$pdf_settings = array(
|
58 |
-
'paper_size' => apply_filters( 'wpo_wcpdf_paper_format', $this->wrapper_document->get_setting( 'paper_size', 'A4' ), $this->get_type() ),
|
59 |
-
'paper_orientation' => apply_filters( 'wpo_wcpdf_paper_orientation', 'portrait', $this->get_type() ),
|
60 |
-
'font_subsetting' => $this->wrapper_document->get_setting( 'font_subsetting', false ),
|
61 |
-
);
|
62 |
-
$pdf_maker = wcpdf_get_pdf_maker( $html, $pdf_settings );
|
63 |
-
$pdf = $pdf_maker->output();
|
64 |
-
|
65 |
-
do_action( 'wpo_wcpdf_after_pdf', $this->get_type(), $this );
|
66 |
-
|
67 |
-
return $pdf;
|
68 |
-
}
|
69 |
-
|
70 |
-
public function get_html() {
|
71 |
-
do_action( 'wpo_wcpdf_before_html', $this->get_type(), $this );
|
72 |
-
$html_content = array();
|
73 |
-
foreach ( $this->order_ids as $key => $order_id ) {
|
74 |
-
do_action( 'wpo_wcpdf_process_template_order', $this->get_type(), $order_id );
|
75 |
-
|
76 |
-
$order = WCX::get_order( $order_id );
|
77 |
-
|
78 |
-
$document = wcpdf_get_document( $this->get_type(), $order, true );
|
79 |
-
$html_content[ $key ] = $document->get_html( array( 'wrap_html_content' => false ) );
|
80 |
-
}
|
81 |
-
|
82 |
-
// get wrapper document
|
83 |
-
$this->wrapper_document = wcpdf_get_document( $this->get_type(), null );
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
$html
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
$
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
echo $
|
102 |
-
die();
|
103 |
-
}
|
104 |
-
|
105 |
-
public function
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
)
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices\Documents;
|
3 |
+
|
4 |
+
use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
|
5 |
+
use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
|
6 |
+
use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
|
7 |
+
|
8 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
9 |
+
exit; // Exit if accessed directly
|
10 |
+
}
|
11 |
+
|
12 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Bulk_Document' ) ) :
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Bulk Document
|
16 |
+
*
|
17 |
+
* Wraps single documents in a bulk document
|
18 |
+
*
|
19 |
+
* @class \WPO\WC\PDF_Invoices\Documents\Bulk_Document
|
20 |
+
* @version 2.0
|
21 |
+
* @category Class
|
22 |
+
* @author Ewout Fernhout
|
23 |
+
*/
|
24 |
+
|
25 |
+
class Bulk_Document {
|
26 |
+
/**
|
27 |
+
* Document type.
|
28 |
+
* @var String
|
29 |
+
*/
|
30 |
+
public $type;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Wrapper document - used for filename etc.
|
34 |
+
* @var String
|
35 |
+
*/
|
36 |
+
public $wrapper_document;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Order IDs.
|
40 |
+
* @var array
|
41 |
+
*/
|
42 |
+
public $order_ids;
|
43 |
+
|
44 |
+
public function __construct( $document_type, $order_ids = array() ) {
|
45 |
+
$this->type = $document_type;
|
46 |
+
$this->order_ids = $order_ids;
|
47 |
+
}
|
48 |
+
|
49 |
+
public function get_type() {
|
50 |
+
return $this->type;
|
51 |
+
}
|
52 |
+
|
53 |
+
public function get_pdf() {
|
54 |
+
do_action( 'wpo_wcpdf_before_pdf', $this->get_type(), $this );
|
55 |
+
|
56 |
+
$html = $this->get_html();
|
57 |
+
$pdf_settings = array(
|
58 |
+
'paper_size' => apply_filters( 'wpo_wcpdf_paper_format', $this->wrapper_document->get_setting( 'paper_size', 'A4' ), $this->get_type() ),
|
59 |
+
'paper_orientation' => apply_filters( 'wpo_wcpdf_paper_orientation', 'portrait', $this->get_type() ),
|
60 |
+
'font_subsetting' => $this->wrapper_document->get_setting( 'font_subsetting', false ),
|
61 |
+
);
|
62 |
+
$pdf_maker = wcpdf_get_pdf_maker( $html, $pdf_settings );
|
63 |
+
$pdf = $pdf_maker->output();
|
64 |
+
|
65 |
+
do_action( 'wpo_wcpdf_after_pdf', $this->get_type(), $this );
|
66 |
+
|
67 |
+
return $pdf;
|
68 |
+
}
|
69 |
+
|
70 |
+
public function get_html() {
|
71 |
+
do_action( 'wpo_wcpdf_before_html', $this->get_type(), $this );
|
72 |
+
$html_content = array();
|
73 |
+
foreach ( $this->order_ids as $key => $order_id ) {
|
74 |
+
do_action( 'wpo_wcpdf_process_template_order', $this->get_type(), $order_id );
|
75 |
+
|
76 |
+
$order = WCX::get_order( $order_id );
|
77 |
+
|
78 |
+
$document = wcpdf_get_document( $this->get_type(), $order, true );
|
79 |
+
$html_content[ $key ] = $document->get_html( array( 'wrap_html_content' => false ) );
|
80 |
+
}
|
81 |
+
|
82 |
+
// get wrapper document & insert body content
|
83 |
+
$this->wrapper_document = wcpdf_get_document( $this->get_type(), null );
|
84 |
+
$html = $this->wrapper_document->wrap_html_content( $this->merge_documents( $html_content ) );
|
85 |
+
do_action( 'wpo_wcpdf_after_html', $this->get_type(), $this );
|
86 |
+
|
87 |
+
return $html;
|
88 |
+
}
|
89 |
+
|
90 |
+
|
91 |
+
public function merge_documents( $html_content ) {
|
92 |
+
// insert page breaks merge
|
93 |
+
$page_break = "\n<div style=\"page-break-before: always;\"></div>\n";
|
94 |
+
$html = implode( $page_break, $html_content );
|
95 |
+
return apply_filters( 'wpo_wcpdf_merged_bulk_document_content', $html, $html_content, $this );
|
96 |
+
}
|
97 |
+
|
98 |
+
public function output_pdf( $output_mode = 'download' ) {
|
99 |
+
$pdf = $this->get_pdf();
|
100 |
+
wcpdf_pdf_headers( $this->get_filename(), $output_mode, $pdf );
|
101 |
+
echo $pdf;
|
102 |
+
die();
|
103 |
+
}
|
104 |
+
|
105 |
+
public function output_html() {
|
106 |
+
echo $this->get_html();
|
107 |
+
die();
|
108 |
+
}
|
109 |
+
|
110 |
+
public function get_filename( $context = 'download', $args = array() ) {
|
111 |
+
if ( empty( $this->wrapper_document ) ) {
|
112 |
+
$this->wrapper_document = wcpdf_get_document( $this->get_type(), null );
|
113 |
+
}
|
114 |
+
$default_args = array(
|
115 |
+
'order_ids' => $this->order_ids,
|
116 |
+
);
|
117 |
+
$args = $args + $default_args;
|
118 |
+
$filename = $this->wrapper_document->get_filename( $context, $args );
|
119 |
+
return $filename;
|
120 |
+
}
|
121 |
+
|
122 |
+
}
|
123 |
+
|
124 |
+
endif; // class_exists
|
includes/documents/class-wcpdf-invoice.php
CHANGED
@@ -1,353 +1,353 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices\Documents;
|
3 |
-
|
4 |
-
use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
|
5 |
-
use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
|
6 |
-
use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
|
7 |
-
|
8 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
9 |
-
exit; // Exit if accessed directly
|
10 |
-
}
|
11 |
-
|
12 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Invoice' ) ) :
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Invoice Document
|
16 |
-
*
|
17 |
-
* @class \WPO\WC\PDF_Invoices\Documents\Invoice
|
18 |
-
* @version 2.0
|
19 |
-
* @category Class
|
20 |
-
* @author Ewout Fernhout
|
21 |
-
*/
|
22 |
-
|
23 |
-
class Invoice extends Order_Document_Methods {
|
24 |
-
/**
|
25 |
-
* Init/load the order object.
|
26 |
-
*
|
27 |
-
* @param int|object|WC_Order $order Order to init.
|
28 |
-
*/
|
29 |
-
public function __construct( $order = 0 ) {
|
30 |
-
// set properties
|
31 |
-
$this->type = 'invoice';
|
32 |
-
$this->title = __( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' );
|
33 |
-
$this->icon = WPO_WCPDF()->plugin_url() . "/assets/images/invoice.png";
|
34 |
-
|
35 |
-
// Call parent constructor
|
36 |
-
parent::__construct( $order );
|
37 |
-
}
|
38 |
-
|
39 |
-
public function get_title() {
|
40 |
-
// override/not using $this->title to allow for language switching!
|
41 |
-
return apply_filters( "wpo_wcpdf_{$this->slug}_title", __( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' ) );
|
42 |
-
}
|
43 |
-
|
44 |
-
public function init() {
|
45 |
-
$this->set_date( current_time( 'timestamp', true ) );
|
46 |
-
$this->init_number();
|
47 |
-
}
|
48 |
-
|
49 |
-
public function init_number() {
|
50 |
-
global $wpdb;
|
51 |
-
// If a third-party plugin claims to generate invoice numbers, trigger this instead
|
52 |
-
if ( apply_filters( 'woocommerce_invoice_number_by_plugin', false ) || apply_filters( 'wpo_wcpdf_external_invoice_number_enabled', false, $this ) ) {
|
53 |
-
$invoice_number = apply_filters( 'woocommerce_generate_invoice_number', null, $this->order );
|
54 |
-
$invoice_number = apply_filters( 'wpo_wcpdf_external_invoice_number', $invoice_number, $this );
|
55 |
-
if ( is_numeric($invoice_number) || $invoice_number instanceof Document_Number ) {
|
56 |
-
$this->set_number( $invoice_number );
|
57 |
-
} else {
|
58 |
-
// invoice number is not numeric, treat as formatted
|
59 |
-
// try to extract meaningful number data
|
60 |
-
$formatted_number = $invoice_number;
|
61 |
-
$number = (int) preg_replace('/\D/', '', $invoice_number);
|
62 |
-
$invoice_number = compact( 'number', 'formatted_number' );
|
63 |
-
$this->set_number( $invoice_number );
|
64 |
-
}
|
65 |
-
return $invoice_number;
|
66 |
-
}
|
67 |
-
|
68 |
-
$number_store_method = WPO_WCPDF()->settings->get_sequential_number_store_method();
|
69 |
-
$number_store = new Sequential_Number_Store( 'invoice_number', $number_store_method );
|
70 |
-
// reset invoice number yearly
|
71 |
-
if ( isset( $this->settings['reset_number_yearly'] ) ) {
|
72 |
-
$current_year = date("Y");
|
73 |
-
$last_number_year = $number_store->get_last_date('Y');
|
74 |
-
// check if we need to reset
|
75 |
-
if ( $current_year != $last_number_year ) {
|
76 |
-
$number_store->set_next( 1 );
|
77 |
-
}
|
78 |
-
}
|
79 |
-
|
80 |
-
$invoice_date = $this->get_date();
|
81 |
-
$invoice_number = $number_store->increment( $this->order_id, $invoice_date->date_i18n( 'Y-m-d H:i:s' ) );
|
82 |
-
|
83 |
-
$this->set_number( $invoice_number );
|
84 |
-
|
85 |
-
return $invoice_number;
|
86 |
-
}
|
87 |
-
|
88 |
-
public function get_settings() {
|
89 |
-
$common_settings = WPO_WCPDF()->settings->get_common_document_settings();
|
90 |
-
$document_settings = get_option( 'wpo_wcpdf_documents_settings_invoice' );
|
91 |
-
return (array) $document_settings + (array) $common_settings;
|
92 |
-
}
|
93 |
-
|
94 |
-
public function get_filename( $context = 'download', $args = array() ) {
|
95 |
-
$order_count = isset($args['order_ids']) ? count($args['order_ids']) : 1;
|
96 |
-
|
97 |
-
$name = _n( 'invoice', 'invoices', $order_count, 'woocommerce-pdf-invoices-packing-slips' );
|
98 |
-
|
99 |
-
if ( $order_count == 1 ) {
|
100 |
-
if ( isset( $this->settings['display_number'] ) ) {
|
101 |
-
$suffix = (string) $this->get_number();
|
102 |
-
} else {
|
103 |
-
if ( empty( $this->order ) ) {
|
104 |
-
$order = WCX::get_order ( $order_ids[0] );
|
105 |
-
$suffix = method_exists( $order, 'get_order_number' ) ? $order->get_order_number() : '';
|
106 |
-
} else {
|
107 |
-
$suffix = method_exists( $this->order, 'get_order_number' ) ? $this->order->get_order_number() : '';
|
108 |
-
}
|
109 |
-
}
|
110 |
-
} else {
|
111 |
-
$suffix = date('Y-m-d'); // 2020-11-11
|
112 |
-
}
|
113 |
-
|
114 |
-
$filename = $name . '-' . $suffix . '.pdf';
|
115 |
-
|
116 |
-
// Filter filename
|
117 |
-
$order_ids = isset($args['order_ids']) ? $args['order_ids'] : array( $this->order_id );
|
118 |
-
$filename = apply_filters( 'wpo_wcpdf_filename', $filename, $this->get_type(), $order_ids, $context );
|
119 |
-
|
120 |
-
// sanitize filename (after filters to prevent human errors)!
|
121 |
-
return sanitize_file_name( $filename );
|
122 |
-
}
|
123 |
-
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Initialise settings
|
127 |
-
*/
|
128 |
-
public function init_settings() {
|
129 |
-
// Register settings.
|
130 |
-
$page = $option_group = $option_name = 'wpo_wcpdf_documents_settings_invoice';
|
131 |
-
|
132 |
-
$settings_fields = array(
|
133 |
-
array(
|
134 |
-
'type' => 'section',
|
135 |
-
'id' => 'invoice',
|
136 |
-
'title' => '',
|
137 |
-
'callback' => 'section',
|
138 |
-
),
|
139 |
-
array(
|
140 |
-
'type' => 'setting',
|
141 |
-
'id' => 'enabled',
|
142 |
-
'title' => __( 'Enable', 'woocommerce-pdf-invoices-packing-slips' ),
|
143 |
-
'callback' => 'checkbox',
|
144 |
-
'section' => 'invoice',
|
145 |
-
'args' => array(
|
146 |
-
'option_name' => $option_name,
|
147 |
-
'id' => 'enabled',
|
148 |
-
)
|
149 |
-
),
|
150 |
-
array(
|
151 |
-
'type' => 'setting',
|
152 |
-
'id' => 'attach_to_email_ids',
|
153 |
-
'title' => __( 'Attach to:', 'woocommerce-pdf-invoices-packing-slips' ),
|
154 |
-
'callback' => 'multiple_checkboxes',
|
155 |
-
'section' => 'invoice',
|
156 |
-
'args' => array(
|
157 |
-
'option_name' => $option_name,
|
158 |
-
'id' => 'attach_to_email_ids',
|
159 |
-
'fields' => $this->get_wc_emails(),
|
160 |
-
'description' => !is_writable( WPO_WCPDF()->main->get_tmp_path( 'attachments' ) ) ? '<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.', 'woocommerce-pdf-invoices-packing-slips' ), WPO_WCPDF()->main->get_tmp_path( 'attachments' ) ).'</span>':'',
|
161 |
-
)
|
162 |
-
),
|
163 |
-
array(
|
164 |
-
'type' => 'setting',
|
165 |
-
'id' => 'display_shipping_address',
|
166 |
-
'title' => __( 'Display shipping address', 'woocommerce-pdf-invoices-packing-slips' ),
|
167 |
-
'callback' => 'checkbox',
|
168 |
-
'section' => 'invoice',
|
169 |
-
'args' => array(
|
170 |
-
'option_name' => $option_name,
|
171 |
-
'id' => 'display_shipping_address',
|
172 |
-
'description' => __( 'Display shipping address (in addition to the default billing address) if different from billing address', 'woocommerce-pdf-invoices-packing-slips' ),
|
173 |
-
)
|
174 |
-
),
|
175 |
-
array(
|
176 |
-
'type' => 'setting',
|
177 |
-
'id' => 'display_email',
|
178 |
-
'title' => __( 'Display email address', 'woocommerce-pdf-invoices-packing-slips' ),
|
179 |
-
'callback' => 'checkbox',
|
180 |
-
'section' => 'invoice',
|
181 |
-
'args' => array(
|
182 |
-
'option_name' => $option_name,
|
183 |
-
'id' => 'display_email',
|
184 |
-
)
|
185 |
-
),
|
186 |
-
array(
|
187 |
-
'type' => 'setting',
|
188 |
-
'id' => 'display_phone',
|
189 |
-
'title' => __( 'Display phone number', 'woocommerce-pdf-invoices-packing-slips' ),
|
190 |
-
'callback' => 'checkbox',
|
191 |
-
'section' => 'invoice',
|
192 |
-
'args' => array(
|
193 |
-
'option_name' => $option_name,
|
194 |
-
'id' => 'display_phone',
|
195 |
-
)
|
196 |
-
),
|
197 |
-
array(
|
198 |
-
'type' => 'setting',
|
199 |
-
'id' => 'display_date',
|
200 |
-
'title' => __( 'Display invoice date', 'woocommerce-pdf-invoices-packing-slips' ),
|
201 |
-
'callback' => 'checkbox',
|
202 |
-
'section' => 'invoice',
|
203 |
-
'args' => array(
|
204 |
-
'option_name' => $option_name,
|
205 |
-
'id' => 'display_date',
|
206 |
-
'value' => 'invoice_date',
|
207 |
-
)
|
208 |
-
),
|
209 |
-
array(
|
210 |
-
'type' => 'setting',
|
211 |
-
'id' => 'display_number',
|
212 |
-
'title' => __( 'Display invoice number', 'woocommerce-pdf-invoices-packing-slips' ),
|
213 |
-
'callback' => 'checkbox',
|
214 |
-
'section' => 'invoice',
|
215 |
-
'args' => array(
|
216 |
-
'option_name' => $option_name,
|
217 |
-
'id' => 'display_number',
|
218 |
-
'value' => 'invoice_number',
|
219 |
-
)
|
220 |
-
),
|
221 |
-
array(
|
222 |
-
'type' => 'setting',
|
223 |
-
'id' => 'next_invoice_number',
|
224 |
-
'title' => __( 'Next invoice number (without prefix/suffix etc.)', 'woocommerce-pdf-invoices-packing-slips' ),
|
225 |
-
'callback' => 'next_number_edit',
|
226 |
-
'section' => 'invoice',
|
227 |
-
'args' => array(
|
228 |
-
'store' => 'invoice_number',
|
229 |
-
'size' => '10',
|
230 |
-
'description' => __( 'This is the number that will be used for the next document. By default, numbering starts from 1 and increases for every new document. Note that if you override this and set it lower than the current/highest number, this could create duplicate numbers!', 'woocommerce-pdf-invoices-packing-slips' ),
|
231 |
-
)
|
232 |
-
),
|
233 |
-
array(
|
234 |
-
'type' => 'setting',
|
235 |
-
'id' => 'number_format',
|
236 |
-
'title' => __( 'Number format', 'woocommerce-pdf-invoices-packing-slips' ),
|
237 |
-
'callback' => 'multiple_text_input',
|
238 |
-
'section' => 'invoice',
|
239 |
-
'args' => array(
|
240 |
-
'option_name' => $option_name,
|
241 |
-
'id' => 'number_format',
|
242 |
-
'fields' => array(
|
243 |
-
'prefix' => array(
|
244 |
-
'placeholder' => __( 'Prefix' , 'woocommerce-pdf-invoices-packing-slips' ),
|
245 |
-
'size' => 20,
|
246 |
-
'description' => __( 'to use the invoice year and/or month, use [invoice_year] or [invoice_month] respectively' , 'woocommerce-pdf-invoices-packing-slips' ),
|
247 |
-
),
|
248 |
-
'suffix' => array(
|
249 |
-
'placeholder' => __( 'Suffix' , 'woocommerce-pdf-invoices-packing-slips' ),
|
250 |
-
'size' => 20,
|
251 |
-
'description' => '',
|
252 |
-
),
|
253 |
-
'padding' => array(
|
254 |
-
'placeholder' => __( 'Padding' , 'woocommerce-pdf-invoices-packing-slips' ),
|
255 |
-
'size' => 20,
|
256 |
-
'type' => 'number',
|
257 |
-
'description' => __( 'enter the number of digits here - enter "6" to display 42 as 000042' , 'woocommerce-pdf-invoices-packing-slips' ),
|
258 |
-
),
|
259 |
-
),
|
260 |
-
'description' => __( 'note: if you have already created a custom invoice number format with a filter, the above settings will be ignored' , 'woocommerce-pdf-invoices-packing-slips' ),
|
261 |
-
)
|
262 |
-
),
|
263 |
-
array(
|
264 |
-
'type' => 'setting',
|
265 |
-
'id' => 'reset_number_yearly',
|
266 |
-
'title' => __( 'Reset invoice number yearly', 'woocommerce-pdf-invoices-packing-slips' ),
|
267 |
-
'callback' => 'checkbox',
|
268 |
-
'section' => 'invoice',
|
269 |
-
'args' => array(
|
270 |
-
'option_name' => $option_name,
|
271 |
-
'id' => 'reset_number_yearly',
|
272 |
-
)
|
273 |
-
),
|
274 |
-
array(
|
275 |
-
'type' => 'setting',
|
276 |
-
'id' => 'my_account_buttons',
|
277 |
-
'title' => __( 'Allow My Account invoice download', 'woocommerce-pdf-invoices-packing-slips' ),
|
278 |
-
'callback' => 'select',
|
279 |
-
'section' => 'invoice',
|
280 |
-
'args' => array(
|
281 |
-
'option_name' => $option_name,
|
282 |
-
'id' => 'my_account_buttons',
|
283 |
-
'options' => array(
|
284 |
-
'available' => __( 'Only when an invoice is already created/emailed' , 'woocommerce-pdf-invoices-packing-slips' ),
|
285 |
-
'custom' => __( 'Only for specific order statuses (define below)' , 'woocommerce-pdf-invoices-packing-slips' ),
|
286 |
-
'always' => __( 'Always' , 'woocommerce-pdf-invoices-packing-slips' ),
|
287 |
-
'never' => __( 'Never' , 'woocommerce-pdf-invoices-packing-slips' ),
|
288 |
-
),
|
289 |
-
'custom' => array(
|
290 |
-
'type' => 'multiple_checkboxes',
|
291 |
-
'args' => array(
|
292 |
-
'option_name' => $option_name,
|
293 |
-
'id' => 'my_account_restrict',
|
294 |
-
'fields' => $this->get_wc_order_status_list(),
|
295 |
-
),
|
296 |
-
),
|
297 |
-
)
|
298 |
-
),
|
299 |
-
array(
|
300 |
-
'type' => 'setting',
|
301 |
-
'id' => 'invoice_number_column',
|
302 |
-
'title' => __( 'Enable invoice number column in the orders list', 'woocommerce-pdf-invoices-packing-slips' ),
|
303 |
-
'callback' => 'checkbox',
|
304 |
-
'section' => 'invoice',
|
305 |
-
'args' => array(
|
306 |
-
'option_name' => $option_name,
|
307 |
-
'id' => 'invoice_number_column',
|
308 |
-
)
|
309 |
-
),
|
310 |
-
array(
|
311 |
-
'type' => 'setting',
|
312 |
-
'id' => 'disable_free',
|
313 |
-
'title' => __( 'Disable for free products', 'woocommerce-pdf-invoices-packing-slips' ),
|
314 |
-
'callback' => 'checkbox',
|
315 |
-
'section' => 'invoice',
|
316 |
-
'args' => array(
|
317 |
-
'option_name' => $option_name,
|
318 |
-
'id' => 'disable_free',
|
319 |
-
'description' => __( "Disable automatic creation/attachment when only free products are ordered", 'woocommerce-pdf-invoices-packing-slips' ),
|
320 |
-
)
|
321 |
-
),
|
322 |
-
);
|
323 |
-
|
324 |
-
|
325 |
-
// remove/rename some fields when invoice number is controlled externally
|
326 |
-
if( apply_filters('woocommerce_invoice_number_by_plugin', false) ) {
|
327 |
-
$remove_settings = array( 'next_invoice_number', 'number_format', 'reset_number_yearly' );
|
328 |
-
foreach ($settings_fields as $key => $settings_field) {
|
329 |
-
if (in_array($settings_field['id'], $remove_settings)) {
|
330 |
-
unset($settings_fields[$key]);
|
331 |
-
} elseif ( $settings_field['id'] == 'display_number' ) {
|
332 |
-
// alternate description for invoice number
|
333 |
-
$invoice_number_desc = __( 'Invoice numbers are created by a third-party extension.', 'woocommerce-pdf-invoices-packing-slips' );
|
334 |
-
if ( esc_attr( apply_filters( 'woocommerce_invoice_number_configuration_link', null ) ) ) {
|
335 |
-
$invoice_number_desc .= ' '.sprintf(__( 'Configure it <a href="%s">here</a>.', 'woocommerce-pdf-invoices-packing-slips' ), $config_link);
|
336 |
-
}
|
337 |
-
$settings_fields[$key]['args']['description'] = '<i>'.$invoice_number_desc.'</i>';
|
338 |
-
}
|
339 |
-
}
|
340 |
-
}
|
341 |
-
|
342 |
-
// allow plugins to alter settings fields
|
343 |
-
$settings_fields = apply_filters( 'wpo_wcpdf_settings_fields_documents_invoice', $settings_fields, $page, $option_group, $option_name );
|
344 |
-
WPO_WCPDF()->settings->add_settings_fields( $settings_fields, $page, $option_group, $option_name );
|
345 |
-
return;
|
346 |
-
|
347 |
-
}
|
348 |
-
|
349 |
-
}
|
350 |
-
|
351 |
-
endif; // class_exists
|
352 |
-
|
353 |
Â
return new Invoice();
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices\Documents;
|
3 |
+
|
4 |
+
use WPO\WC\PDF_Invoices\Compatibility\WC_Core as WCX;
|
5 |
+
use WPO\WC\PDF_Invoices\Compatibility\Order as WCX_Order;
|
6 |
+
use WPO\WC\PDF_Invoices\Compatibility\Product as WCX_Product;
|
7 |
+
|
8 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
9 |
+
exit; // Exit if accessed directly
|
10 |
+
}
|
11 |
+
|
12 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Invoice' ) ) :
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Invoice Document
|
16 |
+
*
|
17 |
+
* @class \WPO\WC\PDF_Invoices\Documents\Invoice
|
18 |
+
* @version 2.0
|
19 |
+
* @category Class
|
20 |
+
* @author Ewout Fernhout
|
21 |
+
*/
|
22 |
+
|
23 |
+
class Invoice extends Order_Document_Methods {
|
24 |
+
/**
|
25 |
+
* Init/load the order object.
|
26 |
+
*
|
27 |
+
* @param int|object|WC_Order $order Order to init.
|
28 |
+
*/
|
29 |
+
public function __construct( $order = 0 ) {
|
30 |
+
// set properties
|
31 |
+
$this->type = 'invoice';
|
32 |
+
$this->title = __( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' );
|
33 |
+
$this->icon = WPO_WCPDF()->plugin_url() . "/assets/images/invoice.png";
|
34 |
+
|
35 |
+
// Call parent constructor
|
36 |
+
parent::__construct( $order );
|
37 |
+
}
|
38 |
+
|
39 |
+
public function get_title() {
|
40 |
+
// override/not using $this->title to allow for language switching!
|
41 |
+
return apply_filters( "wpo_wcpdf_{$this->slug}_title", __( 'Invoice', 'woocommerce-pdf-invoices-packing-slips' ) );
|
42 |
+
}
|
43 |
+
|
44 |
+
public function init() {
|
45 |
+
$this->set_date( current_time( 'timestamp', true ) );
|
46 |
+
$this->init_number();
|
47 |
+
}
|
48 |
+
|
49 |
+
public function init_number() {
|
50 |
+
global $wpdb;
|
51 |
+
// If a third-party plugin claims to generate invoice numbers, trigger this instead
|
52 |
+
if ( apply_filters( 'woocommerce_invoice_number_by_plugin', false ) || apply_filters( 'wpo_wcpdf_external_invoice_number_enabled', false, $this ) ) {
|
53 |
+
$invoice_number = apply_filters( 'woocommerce_generate_invoice_number', null, $this->order );
|
54 |
+
$invoice_number = apply_filters( 'wpo_wcpdf_external_invoice_number', $invoice_number, $this );
|
55 |
+
if ( is_numeric($invoice_number) || $invoice_number instanceof Document_Number ) {
|
56 |
+
$this->set_number( $invoice_number );
|
57 |
+
} else {
|
58 |
+
// invoice number is not numeric, treat as formatted
|
59 |
+
// try to extract meaningful number data
|
60 |
+
$formatted_number = $invoice_number;
|
61 |
+
$number = (int) preg_replace('/\D/', '', $invoice_number);
|
62 |
+
$invoice_number = compact( 'number', 'formatted_number' );
|
63 |
+
$this->set_number( $invoice_number );
|
64 |
+
}
|
65 |
+
return $invoice_number;
|
66 |
+
}
|
67 |
+
|
68 |
+
$number_store_method = WPO_WCPDF()->settings->get_sequential_number_store_method();
|
69 |
+
$number_store = new Sequential_Number_Store( 'invoice_number', $number_store_method );
|
70 |
+
// reset invoice number yearly
|
71 |
+
if ( isset( $this->settings['reset_number_yearly'] ) ) {
|
72 |
+
$current_year = date("Y");
|
73 |
+
$last_number_year = $number_store->get_last_date('Y');
|
74 |
+
// check if we need to reset
|
75 |
+
if ( $current_year != $last_number_year ) {
|
76 |
+
$number_store->set_next( 1 );
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
$invoice_date = $this->get_date();
|
81 |
+
$invoice_number = $number_store->increment( $this->order_id, $invoice_date->date_i18n( 'Y-m-d H:i:s' ) );
|
82 |
+
|
83 |
+
$this->set_number( $invoice_number );
|
84 |
+
|
85 |
+
return $invoice_number;
|
86 |
+
}
|
87 |
+
|
88 |
+
public function get_settings() {
|
89 |
+
$common_settings = WPO_WCPDF()->settings->get_common_document_settings();
|
90 |
+
$document_settings = get_option( 'wpo_wcpdf_documents_settings_invoice' );
|
91 |
+
return (array) $document_settings + (array) $common_settings;
|
92 |
+
}
|
93 |
+
|
94 |
+
public function get_filename( $context = 'download', $args = array() ) {
|
95 |
+
$order_count = isset($args['order_ids']) ? count($args['order_ids']) : 1;
|
96 |
+
|
97 |
+
$name = _n( 'invoice', 'invoices', $order_count, 'woocommerce-pdf-invoices-packing-slips' );
|
98 |
+
|
99 |
+
if ( $order_count == 1 ) {
|
100 |
+
if ( isset( $this->settings['display_number'] ) ) {
|
101 |
+
$suffix = (string) $this->get_number();
|
102 |
+
} else {
|
103 |
+
if ( empty( $this->order ) ) {
|
104 |
+
$order = WCX::get_order ( $order_ids[0] );
|
105 |
+
$suffix = method_exists( $order, 'get_order_number' ) ? $order->get_order_number() : '';
|
106 |
+
} else {
|
107 |
+
$suffix = method_exists( $this->order, 'get_order_number' ) ? $this->order->get_order_number() : '';
|
108 |
+
}
|
109 |
+
}
|
110 |
+
} else {
|
111 |
+
$suffix = date('Y-m-d'); // 2020-11-11
|
112 |
+
}
|
113 |
+
|
114 |
+
$filename = $name . '-' . $suffix . '.pdf';
|
115 |
+
|
116 |
+
// Filter filename
|
117 |
+
$order_ids = isset($args['order_ids']) ? $args['order_ids'] : array( $this->order_id );
|
118 |
+
$filename = apply_filters( 'wpo_wcpdf_filename', $filename, $this->get_type(), $order_ids, $context );
|
119 |
+
|
120 |
+
// sanitize filename (after filters to prevent human errors)!
|
121 |
+
return sanitize_file_name( $filename );
|
122 |
+
}
|
123 |
+
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Initialise settings
|
127 |
+
*/
|
128 |
+
public function init_settings() {
|
129 |
+
// Register settings.
|
130 |
+
$page = $option_group = $option_name = 'wpo_wcpdf_documents_settings_invoice';
|
131 |
+
|
132 |
+
$settings_fields = array(
|
133 |
+
array(
|
134 |
+
'type' => 'section',
|
135 |
+
'id' => 'invoice',
|
136 |
+
'title' => '',
|
137 |
+
'callback' => 'section',
|
138 |
+
),
|
139 |
+
array(
|
140 |
+
'type' => 'setting',
|
141 |
+
'id' => 'enabled',
|
142 |
+
'title' => __( 'Enable', 'woocommerce-pdf-invoices-packing-slips' ),
|
143 |
+
'callback' => 'checkbox',
|
144 |
+
'section' => 'invoice',
|
145 |
+
'args' => array(
|
146 |
+
'option_name' => $option_name,
|
147 |
+
'id' => 'enabled',
|
148 |
+
)
|
149 |
+
),
|
150 |
+
array(
|
151 |
+
'type' => 'setting',
|
152 |
+
'id' => 'attach_to_email_ids',
|
153 |
+
'title' => __( 'Attach to:', 'woocommerce-pdf-invoices-packing-slips' ),
|
154 |
+
'callback' => 'multiple_checkboxes',
|
155 |
+
'section' => 'invoice',
|
156 |
+
'args' => array(
|
157 |
+
'option_name' => $option_name,
|
158 |
+
'id' => 'attach_to_email_ids',
|
159 |
+
'fields' => $this->get_wc_emails(),
|
160 |
+
'description' => !is_writable( WPO_WCPDF()->main->get_tmp_path( 'attachments' ) ) ? '<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.', 'woocommerce-pdf-invoices-packing-slips' ), WPO_WCPDF()->main->get_tmp_path( 'attachments' ) ).'</span>':'',
|
161 |
+
)
|
162 |
+
),
|
163 |
+
array(
|
164 |
+
'type' => 'setting',
|
165 |
+
'id' => 'display_shipping_address',
|
166 |
+
'title' => __( 'Display shipping address', 'woocommerce-pdf-invoices-packing-slips' ),
|
167 |
+
'callback' => 'checkbox',
|
168 |
+
'section' => 'invoice',
|
169 |
+
'args' => array(
|
170 |
+
'option_name' => $option_name,
|
171 |
+
'id' => 'display_shipping_address',
|
172 |
+
'description' => __( 'Display shipping address (in addition to the default billing address) if different from billing address', 'woocommerce-pdf-invoices-packing-slips' ),
|
173 |
+
)
|
174 |
+
),
|
175 |
+
array(
|
176 |
+
'type' => 'setting',
|
177 |
+
'id' => 'display_email',
|
178 |
+
'title' => __( 'Display email address', 'woocommerce-pdf-invoices-packing-slips' ),
|
179 |
+
'callback' => 'checkbox',
|
180 |
+
'section' => 'invoice',
|
181 |
+
'args' => array(
|
182 |
+
'option_name' => $option_name,
|
183 |
+
'id' => 'display_email',
|
184 |
+
)
|
185 |
+
),
|
186 |
+
array(
|
187 |
+
'type' => 'setting',
|
188 |
+
'id' => 'display_phone',
|
189 |
+
'title' => __( 'Display phone number', 'woocommerce-pdf-invoices-packing-slips' ),
|
190 |
+
'callback' => 'checkbox',
|
191 |
+
'section' => 'invoice',
|
192 |
+
'args' => array(
|
193 |
+
'option_name' => $option_name,
|
194 |
+
'id' => 'display_phone',
|
195 |
+
)
|
196 |
+
),
|
197 |
+
array(
|
198 |
+
'type' => 'setting',
|
199 |
+
'id' => 'display_date',
|
200 |
+
'title' => __( 'Display invoice date', 'woocommerce-pdf-invoices-packing-slips' ),
|
201 |
+
'callback' => 'checkbox',
|
202 |
+
'section' => 'invoice',
|
203 |
+
'args' => array(
|
204 |
+
'option_name' => $option_name,
|
205 |
+
'id' => 'display_date',
|
206 |
+
'value' => 'invoice_date',
|
207 |
+
)
|
208 |
+
),
|
209 |
+
array(
|
210 |
+
'type' => 'setting',
|
211 |
+
'id' => 'display_number',
|
212 |
+
'title' => __( 'Display invoice number', 'woocommerce-pdf-invoices-packing-slips' ),
|
213 |
+
'callback' => 'checkbox',
|
214 |
+
'section' => 'invoice',
|
215 |
+
'args' => array(
|
216 |
+
'option_name' => $option_name,
|
217 |
+
'id' => 'display_number',
|
218 |
+
'value' => 'invoice_number',
|
219 |
+
)
|
220 |
+
),
|
221 |
+
array(
|
222 |
+
'type' => 'setting',
|
223 |
+
'id' => 'next_invoice_number',
|
224 |
+
'title' => __( 'Next invoice number (without prefix/suffix etc.)', 'woocommerce-pdf-invoices-packing-slips' ),
|
225 |
+
'callback' => 'next_number_edit',
|
226 |
+
'section' => 'invoice',
|
227 |
+
'args' => array(
|
228 |
+
'store' => 'invoice_number',
|
229 |
+
'size' => '10',
|
230 |
+
'description' => __( 'This is the number that will be used for the next document. By default, numbering starts from 1 and increases for every new document. Note that if you override this and set it lower than the current/highest number, this could create duplicate numbers!', 'woocommerce-pdf-invoices-packing-slips' ),
|
231 |
+
)
|
232 |
+
),
|
233 |
+
array(
|
234 |
+
'type' => 'setting',
|
235 |
+
'id' => 'number_format',
|
236 |
+
'title' => __( 'Number format', 'woocommerce-pdf-invoices-packing-slips' ),
|
237 |
+
'callback' => 'multiple_text_input',
|
238 |
+
'section' => 'invoice',
|
239 |
+
'args' => array(
|
240 |
+
'option_name' => $option_name,
|
241 |
+
'id' => 'number_format',
|
242 |
+
'fields' => array(
|
243 |
+
'prefix' => array(
|
244 |
+
'placeholder' => __( 'Prefix' , 'woocommerce-pdf-invoices-packing-slips' ),
|
245 |
+
'size' => 20,
|
246 |
+
'description' => __( 'to use the invoice year and/or month, use [invoice_year] or [invoice_month] respectively' , 'woocommerce-pdf-invoices-packing-slips' ),
|
247 |
+
),
|
248 |
+
'suffix' => array(
|
249 |
+
'placeholder' => __( 'Suffix' , 'woocommerce-pdf-invoices-packing-slips' ),
|
250 |
+
'size' => 20,
|
251 |
+
'description' => '',
|
252 |
+
),
|
253 |
+
'padding' => array(
|
254 |
+
'placeholder' => __( 'Padding' , 'woocommerce-pdf-invoices-packing-slips' ),
|
255 |
+
'size' => 20,
|
256 |
+
'type' => 'number',
|
257 |
+
'description' => __( 'enter the number of digits here - enter "6" to display 42 as 000042' , 'woocommerce-pdf-invoices-packing-slips' ),
|
258 |
+
),
|
259 |
+
),
|
260 |
+
'description' => __( 'note: if you have already created a custom invoice number format with a filter, the above settings will be ignored' , 'woocommerce-pdf-invoices-packing-slips' ),
|
261 |
+
)
|
262 |
+
),
|
263 |
+
array(
|
264 |
+
'type' => 'setting',
|
265 |
+
'id' => 'reset_number_yearly',
|
266 |
+
'title' => __( 'Reset invoice number yearly', 'woocommerce-pdf-invoices-packing-slips' ),
|
267 |
+
'callback' => 'checkbox',
|
268 |
+
'section' => 'invoice',
|
269 |
+
'args' => array(
|
270 |
+
'option_name' => $option_name,
|
271 |
+
'id' => 'reset_number_yearly',
|
272 |
+
)
|
273 |
+
),
|
274 |
+
array(
|
275 |
+
'type' => 'setting',
|
276 |
+
'id' => 'my_account_buttons',
|
277 |
+
'title' => __( 'Allow My Account invoice download', 'woocommerce-pdf-invoices-packing-slips' ),
|
278 |
+
'callback' => 'select',
|
279 |
+
'section' => 'invoice',
|
280 |
+
'args' => array(
|
281 |
+
'option_name' => $option_name,
|
282 |
+
'id' => 'my_account_buttons',
|
283 |
+
'options' => array(
|
284 |
+
'available' => __( 'Only when an invoice is already created/emailed' , 'woocommerce-pdf-invoices-packing-slips' ),
|
285 |
+
'custom' => __( 'Only for specific order statuses (define below)' , 'woocommerce-pdf-invoices-packing-slips' ),
|
286 |
+
'always' => __( 'Always' , 'woocommerce-pdf-invoices-packing-slips' ),
|
287 |
+
'never' => __( 'Never' , 'woocommerce-pdf-invoices-packing-slips' ),
|
288 |
+
),
|
289 |
+
'custom' => array(
|
290 |
+
'type' => 'multiple_checkboxes',
|
291 |
+
'args' => array(
|
292 |
+
'option_name' => $option_name,
|
293 |
+
'id' => 'my_account_restrict',
|
294 |
+
'fields' => $this->get_wc_order_status_list(),
|
295 |
+
),
|
296 |
+
),
|
297 |
+
)
|
298 |
+
),
|
299 |
+
array(
|
300 |
+
'type' => 'setting',
|
301 |
+
'id' => 'invoice_number_column',
|
302 |
+
'title' => __( 'Enable invoice number column in the orders list', 'woocommerce-pdf-invoices-packing-slips' ),
|
303 |
+
'callback' => 'checkbox',
|
304 |
+
'section' => 'invoice',
|
305 |
+
'args' => array(
|
306 |
+
'option_name' => $option_name,
|
307 |
+
'id' => 'invoice_number_column',
|
308 |
+
)
|
309 |
+
),
|
310 |
+
array(
|
311 |
+
'type' => 'setting',
|
312 |
+
'id' => 'disable_free',
|
313 |
+
'title' => __( 'Disable for free products', 'woocommerce-pdf-invoices-packing-slips' ),
|
314 |
+
'callback' => 'checkbox',
|
315 |
+
'section' => 'invoice',
|
316 |
+
'args' => array(
|
317 |
+
'option_name' => $option_name,
|
318 |
+
'id' => 'disable_free',
|
319 |
+
'description' => __( "Disable automatic creation/attachment when only free products are ordered", 'woocommerce-pdf-invoices-packing-slips' ),
|
320 |
+
)
|
321 |
+
),
|
322 |
+
);
|
323 |
+
|
324 |
+
|
325 |
+
// remove/rename some fields when invoice number is controlled externally
|
326 |
+
if( apply_filters('woocommerce_invoice_number_by_plugin', false) ) {
|
327 |
+
$remove_settings = array( 'next_invoice_number', 'number_format', 'reset_number_yearly' );
|
328 |
+
foreach ($settings_fields as $key => $settings_field) {
|
329 |
+
if (in_array($settings_field['id'], $remove_settings)) {
|
330 |
+
unset($settings_fields[$key]);
|
331 |
+
} elseif ( $settings_field['id'] == 'display_number' ) {
|
332 |
+
// alternate description for invoice number
|
333 |
+
$invoice_number_desc = __( 'Invoice numbers are created by a third-party extension.', 'woocommerce-pdf-invoices-packing-slips' );
|
334 |
+
if ( esc_attr( apply_filters( 'woocommerce_invoice_number_configuration_link', null ) ) ) {
|
335 |
+
$invoice_number_desc .= ' '.sprintf(__( 'Configure it <a href="%s">here</a>.', 'woocommerce-pdf-invoices-packing-slips' ), $config_link);
|
336 |
+
}
|
337 |
+
$settings_fields[$key]['args']['description'] = '<i>'.$invoice_number_desc.'</i>';
|
338 |
+
}
|
339 |
+
}
|
340 |
+
}
|
341 |
+
|
342 |
+
// allow plugins to alter settings fields
|
343 |
+
$settings_fields = apply_filters( 'wpo_wcpdf_settings_fields_documents_invoice', $settings_fields, $page, $option_group, $option_name );
|
344 |
+
WPO_WCPDF()->settings->add_settings_fields( $settings_fields, $page, $option_group, $option_name );
|
345 |
+
return;
|
346 |
+
|
347 |
+
}
|
348 |
+
|
349 |
+
}
|
350 |
+
|
351 |
+
endif; // class_exists
|
352 |
+
|
353 |
Â
return new Invoice();
|
includes/documents/class-wcpdf-sequential-number-store.php
CHANGED
@@ -1,165 +1,165 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPO\WC\PDF_Invoices\Documents;
|
3 |
-
|
4 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
-
exit; // Exit if accessed directly
|
6 |
-
}
|
7 |
-
|
8 |
-
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Sequential_Number_Store' ) ) :
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Class handling database interaction for sequential numbers
|
12 |
-
*
|
13 |
-
* @class \WPO\WC\PDF_Invoices\Documents\Sequential_Number_Store
|
14 |
-
* @version 2.0
|
15 |
-
* @category Class
|
16 |
-
* @author Ewout Fernhout
|
17 |
-
*/
|
18 |
-
|
19 |
-
class Sequential_Number_Store {
|
20 |
-
/**
|
21 |
-
* Name of the table that stores the number sequence (without the wp_wcpdf_ table prefix)
|
22 |
-
* @var String
|
23 |
-
*/
|
24 |
-
public $table_name;
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Number store method, either 'auto_increment' or 'calculate'
|
28 |
-
* @var String
|
29 |
-
*/
|
30 |
-
public $method;
|
31 |
-
|
32 |
-
public function __construct( $table_name, $method = 'auto_increment' ) {
|
33 |
-
global $wpdb;
|
34 |
-
$this->table_name = "{$wpdb->prefix}wcpdf_{$table_name}"; // i.e. wp_wcpdf_invoice_number
|
35 |
-
$this->method = $method;
|
36 |
-
|
37 |
-
$this->init();
|
38 |
-
}
|
39 |
-
|
40 |
-
public function init() {
|
41 |
-
global $wpdb;
|
42 |
-
// check if table exists
|
43 |
-
if( $wpdb->get_var("SHOW TABLES LIKE '{$this->table_name}'") == $this->table_name) {
|
44 |
-
// check calculated_number column if using 'calculate' method
|
45 |
-
if ( $this->method == 'calculate' ) {
|
46 |
-
$column_exists = $wpdb->get_var("SHOW COLUMNS FROM `{$this->table_name}` LIKE 'calculated_number'");
|
47 |
-
if (empty($column_exists)) {
|
48 |
-
$wpdb->query("ALTER TABLE {$this->table_name} ADD calculated_number int (16)");
|
49 |
-
}
|
50 |
-
}
|
51 |
-
return; // no further business
|
52 |
-
}
|
53 |
-
|
54 |
-
// create table (in case of concurrent requests, this does no harm if it already exists)
|
55 |
-
$charset_collate = $wpdb->get_charset_collate();
|
56 |
-
// dbDelta is a sensitive kid, so we omit indentation
|
57 |
-
$sql = "CREATE TABLE {$this->table_name} (
|
58 |
-
id int(16) NOT NULL AUTO_INCREMENT,
|
59 |
-
order_id int(16),
|
60 |
-
date datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
61 |
-
calculated_number int (16),
|
62 |
-
PRIMARY KEY (id)
|
63 |
-
) $charset_collate;";
|
64 |
-
|
65 |
-
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
66 |
-
$result = dbDelta( $sql );
|
67 |
-
|
68 |
-
return $result;
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Consume/create the next number and return it
|
73 |
-
* @param integer $order_id WooCommerce Order ID
|
74 |
-
* @param string $date Local date, formatted as Y-m-d H:i:s
|
75 |
-
* @return int Number that was consumed/created
|
76 |
-
*/
|
77 |
-
public function increment( $order_id = 0, $date = null ) {
|
78 |
-
global $wpdb;
|
79 |
-
if ( empty( $date ) ) {
|
80 |
-
$date = get_date_from_gmt( date( 'Y-m-d H:i:s' ) );
|
81 |
-
}
|
82 |
-
|
83 |
-
$data = array(
|
84 |
-
'order_id' => (int) $order_id,
|
85 |
-
'date' => $date,
|
86 |
-
);
|
87 |
-
|
88 |
-
if ( $this->method == 'auto_increment' ) {
|
89 |
-
$wpdb->insert( $this->table_name, $data );
|
90 |
-
$number = $wpdb->insert_id;
|
91 |
-
} elseif ( $this->method == 'calculate' ) {
|
92 |
-
$number = $data['calculated_number'] = $this->get_next();
|
93 |
-
$wpdb->insert( $this->table_name, $data );
|
94 |
-
}
|
95 |
-
|
96 |
-
// return generated number
|
97 |
-
return $number;
|
98 |
-
}
|
99 |
-
|
100 |
-
/**
|
101 |
-
* Get the number that will be used on the next increment
|
102 |
-
* @return int next number
|
103 |
-
*/
|
104 |
-
public function get_next() {
|
105 |
-
global $wpdb;
|
106 |
-
if ( $this->method == 'auto_increment' ) {
|
107 |
-
// get next auto_increment value
|
108 |
-
$table_status = $wpdb->get_row("SHOW TABLE STATUS LIKE '{$this->table_name}'");
|
109 |
-
$next = $table_status->Auto_increment;
|
110 |
-
} elseif ( $this->method == 'calculate' ) {
|
111 |
-
$last_row = $wpdb->get_row( "SELECT * FROM {$this->table_name} WHERE id = ( SELECT MAX(id) from {$this->table_name} )" );
|
112 |
-
if ( empty( $last_row ) ) {
|
113 |
-
$next = 1;
|
114 |
-
} elseif ( !empty( $last_row->calculated_number ) ) {
|
115 |
-
$next = (int) $last_row->calculated_number + 1;
|
116 |
-
} else {
|
117 |
-
$next = (int) $last_row->id + 1;
|
118 |
-
}
|
119 |
-
}
|
120 |
-
return $next;
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Set the number that will be used on the next increment
|
125 |
-
*/
|
126 |
-
public function set_next( $number = 1 ) {
|
127 |
-
global $wpdb;
|
128 |
-
|
129 |
-
// delete all rows
|
130 |
-
$delete = $wpdb->query("TRUNCATE TABLE {$this->table_name}");
|
131 |
-
|
132 |
-
// set auto_increment
|
133 |
-
if ( $number > 1 ) {
|
134 |
-
// if AUTO_INCREMENT is not 1, we need to make sure we have a 'highest value' in case of server restarts
|
135 |
-
// https://serverfault.com/questions/228690/mysql-auto-increment-fields-resets-by-itself
|
136 |
-
$highest_number = (int) $number - 1;
|
137 |
-
$wpdb->query("ALTER TABLE {$this->table_name} AUTO_INCREMENT={$highest_number};");
|
138 |
-
$data = array(
|
139 |
-
'order_id' => 0,
|
140 |
-
'date' => get_date_from_gmt( date( 'Y-m-d H:i:s' ) ),
|
141 |
-
);
|
142 |
-
|
143 |
-
if ( $this->method == 'calculate' ) {
|
144 |
-
$data['calculated_number'] = $highest_number;
|
145 |
-
}
|
146 |
-
|
147 |
-
// after this insert, AUTO_INCREMENT will be equal to $number
|
148 |
-
$wpdb->insert( $this->table_name, $data );
|
149 |
-
} else {
|
150 |
-
// simple scenario, no need to insert any rows
|
151 |
-
$wpdb->query("ALTER TABLE {$this->table_name} AUTO_INCREMENT={$number};");
|
152 |
-
}
|
153 |
-
}
|
154 |
-
|
155 |
-
public function get_last_date( $format = 'Y-m-d H:i:s' ) {
|
156 |
-
global $wpdb;
|
157 |
-
$row = $wpdb->get_row( "SELECT * FROM {$this->table_name} WHERE id = ( SELECT MAX(id) from {$this->table_name} )" );
|
158 |
-
$date = isset( $row->date ) ? $row->date : 'now';
|
159 |
-
$formatted_date = date( $format, strtotime( $date ) );
|
160 |
-
|
161 |
-
return $formatted_date;
|
162 |
-
}
|
163 |
-
}
|
164 |
-
|
165 |
-
endif; // class_exists
|
1 |
+
<?php
|
2 |
+
namespace WPO\WC\PDF_Invoices\Documents;
|
3 |
+
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit; // Exit if accessed directly
|
6 |
+
}
|
7 |
+
|
8 |
+
if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Documents\\Sequential_Number_Store' ) ) :
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Class handling database interaction for sequential numbers
|
12 |
+
*
|
13 |
+
* @class \WPO\WC\PDF_Invoices\Documents\Sequential_Number_Store
|
14 |
+
* @version 2.0
|
15 |
+
* @category Class
|
16 |
+
* @author Ewout Fernhout
|
17 |
+
*/
|
18 |
+
|
19 |
+
class Sequential_Number_Store {
|
20 |
+
/**
|
21 |
+
* Name of the table that stores the number sequence (without the wp_wcpdf_ table prefix)
|
22 |
+
* @var String
|
23 |
+
*/
|
24 |
+
public $table_name;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Number store method, either 'auto_increment' or 'calculate'
|
28 |
+
* @var String
|
29 |
+
*/
|
30 |
+
public $method;
|
31 |
+
|
32 |
+
public function __construct( $table_name, $method = 'auto_increment' ) {
|
33 |
+
global $wpdb;
|
34 |
+
$this->table_name = "{$wpdb->prefix}wcpdf_{$table_name}"; // i.e. wp_wcpdf_invoice_number
|
35 |
+
$this->method = $method;
|
36 |
+
|
37 |
+
$this->init();
|
38 |
+
}
|
39 |
+
|
40 |
+
public function init() {
|
41 |
+
global $wpdb;
|
42 |
+
// check if table exists
|
43 |
+
if( $wpdb->get_var("SHOW TABLES LIKE '{$this->table_name}'") == $this->table_name) {
|
44 |
+
// check calculated_number column if using 'calculate' method
|
45 |
+
if ( $this->method == 'calculate' ) {
|
46 |
+
$column_exists = $wpdb->get_var("SHOW COLUMNS FROM `{$this->table_name}` LIKE 'calculated_number'");
|
47 |
+
if (empty($column_exists)) {
|
48 |
+
$wpdb->query("ALTER TABLE {$this->table_name} ADD calculated_number int (16)");
|
49 |
+
}
|
50 |
+
}
|
51 |
+
return; // no further business
|
52 |
+
}
|
53 |
+
|
54 |
+
// create table (in case of concurrent requests, this does no harm if it already exists)
|
55 |
+
$charset_collate = $wpdb->get_charset_collate();
|
56 |
+
// dbDelta is a sensitive kid, so we omit indentation
|
57 |
+
$sql = "CREATE TABLE {$this->table_name} (
|
58 |
+
id int(16) NOT NULL AUTO_INCREMENT,
|
59 |
+
order_id int(16),
|
60 |
+
date datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
61 |
+
calculated_number int (16),
|
62 |
+
PRIMARY KEY (id)
|
63 |
+
) $charset_collate;";
|
64 |
+
|
65 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
66 |
+
$result = dbDelta( $sql );
|
67 |
+
|
68 |
+
return $result;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Consume/create the next number and return it
|
73 |
+
* @param integer $order_id WooCommerce Order ID
|
74 |
+
* @param string $date Local date, formatted as Y-m-d H:i:s
|
75 |
+
* @return int Number that was consumed/created
|
76 |
+
*/
|
77 |
+
public function increment( $order_id = 0, $date = null ) {
|
78 |
+
global $wpdb;
|
79 |
+
if ( empty( $date ) ) {
|
80 |
+
$date = get_date_from_gmt( date( 'Y-m-d H:i:s' ) );
|
81 |
+
}
|
82 |
+
|
83 |
+
$data = array(
|
84 |
+
'order_id' => (int) $order_id,
|
85 |
+
'date' => $date,
|
86 |
+
);
|
87 |
+
|
88 |
+
if ( $this->method == 'auto_increment' ) {
|
89 |
+
$wpdb->insert( $this->table_name, $data );
|
90 |
+
$number = $wpdb->insert_id;
|
91 |
+
} elseif ( $this->method == 'calculate' ) {
|
92 |
+
$number = $data['calculated_number'] = $this->get_next();
|
93 |
+
$wpdb->insert( $this->table_name, $data );
|
94 |
+
}
|
95 |
+
|
96 |
+
// return generated number
|
97 |
+
return $number;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Get the number that will be used on the next increment
|
102 |
+
* @return int next number
|
103 |
+
*/
|
104 |
+
public function get_next() {
|
105 |
+
global $wpdb;
|
106 |
+
if ( $this->method == 'auto_increment' ) {
|
107 |
+
// get next auto_increment value
|
108 |
+
$table_status = $wpdb->get_row("SHOW TABLE STATUS LIKE '{$this->table_name}'");
|
109 |
+
$next = $table_status->Auto_increment;
|
110 |
+
} elseif ( $this->method == 'calculate' ) {
|
111 |
+
$last_row = $wpdb->get_row( "SELECT * FROM {$this->table_name} WHERE id = ( SELECT MAX(id) from {$this->table_name} )" );
|
112 |
+
if ( empty( $last_row ) ) {
|
113 |
+
$next = 1;
|
114 |
+
} elseif ( !empty( $last_row->calculated_number ) ) {
|
115 |
+
$next = (int) $last_row->calculated_number + 1;
|
116 |
+
} else {
|
117 |
+
$next = (int) $last_row->id + 1;
|
118 |
+
}
|
119 |
+
}
|
120 |
+
return $next;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Set the number that will be used on the next increment
|
125 |
+
*/
|
126 |
+
public function set_next( $number = 1 ) {
|
127 |
+
global $wpdb;
|
128 |
+
|
129 |
+
// delete all rows
|
130 |
+
$delete = $wpdb->query("TRUNCATE TABLE {$this->table_name}");
|
131 |
+
|
132 |
+
// set auto_increment
|
133 |
+
if ( $number > 1 ) {
|
134 |
+
// if AUTO_INCREMENT is not 1, we need to make sure we have a 'highest value' in case of server restarts
|
135 |
+
// https://serverfault.com/questions/228690/mysql-auto-increment-fields-resets-by-itself
|
136 |
+
$highest_number = (int) $number - 1;
|
137 |
+
$wpdb->query("ALTER TABLE {$this->table_name} AUTO_INCREMENT={$highest_number};");
|
138 |
+
$data = array(
|
139 |
+
'order_id' => 0,
|
140 |
+
'date' => get_date_from_gmt( date( 'Y-m-d H:i:s' ) ),
|
141 |
+
);
|
142 |
+
|
143 |
+
if ( $this->method == 'calculate' ) {
|
144 |
+
$data['calculated_number'] = $highest_number;
|
145 |
+
}
|
146 |
+
|
147 |
+
// after this insert, AUTO_INCREMENT will be equal to $number
|
148 |
+
$wpdb->insert( $this->table_name, $data );
|
149 |
+
} else {
|
150 |
+
// simple scenario, no need to insert any rows
|
151 |
+
$wpdb->query("ALTER TABLE {$this->table_name} AUTO_INCREMENT={$number};");
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
public function get_last_date( $format = 'Y-m-d H:i:s' ) {
|
156 |
+
global $wpdb;
|
157 |
+
$row = $wpdb->get_row( "SELECT * FROM {$this->table_name} WHERE id = ( SELECT MAX(id) from {$this->table_name} )" );
|
158 |
+
$date = isset( $row->date ) ? $row->date : 'now';
|
159 |
+
$formatted_date = date( $format, strtotime( $date ) );
|
160 |
+
|
161 |
+
return $formatted_date;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
endif; // class_exists
|
readme.txt
CHANGED
@@ -1,609 +1,614 @@
|
|
1 |
-
=== WooCommerce PDF Invoices & Packing Slips ===
|
2 |
-
Contributors: pomegranate
|
3 |
-
Donate link: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
|
4 |
-
Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice, packing slip, export, email, bulk, automatic
|
5 |
-
Requires at least: 3.5
|
6 |
-
Tested up to: 4.8
|
7 |
-
Stable tag: 2.0.
|
8 |
-
License: GPLv2 or later
|
9 |
-
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
-
|
11 |
-
Create, print & automatically email PDF invoices & packing slips for WooCommerce orders.
|
12 |
-
|
13 |
-
== Description ==
|
14 |
-
|
15 |
-
This WooCommerce extension automatically adds a PDF invoice to the order confirmation emails sent out to your customers. Includes a basic template (additional templates are available from [WP Overnight](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)) as well as the possibility to modify/create your own templates. In addition, you can choose to download or print invoices and packing slips from the WooCommerce order admin.
|
16 |
-
|
17 |
-
= Main features =
|
18 |
-
* Automatically attach invoice PDF to WooCommerce emails of your choice
|
19 |
-
* Download the PDF invoice / packing slip from the order admin page
|
20 |
-
* Generate PDF invoices / packings slips in bulk
|
21 |
-
* **Fully customizable** HTML/CSS invoice templates
|
22 |
-
* Download invoices from the My Account page
|
23 |
-
* Sequential invoice numbers - with custom formatting
|
24 |
-
* **Available in: Czech, Dutch, English, Finnish, French, German, Hungarian, Italian, Japanese (see FAQ for adding custom fonts!), Norwegian, Polish, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish & Ukrainian**
|
25 |
-
|
26 |
-
In addition to this, we offer several premium extensions:
|
27 |
-
|
28 |
-
* Create/email PDF Proforma Invoices, Credit Notes (for Refunds), email Packing Slips & more with [WooCommerce PDF Invoices & Packing Slips Professional](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
|
29 |
-
* Upload all invoices automatically to Dropbox with [WooCommerce PDF Invoices & Packing Slips to Dropbox](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-dropbox/)
|
30 |
-
* Automatically send new orders or packing slips to your printer, as soon as the customer orders! [WooCommerce Automatic Order Printing](https://www.simbahosting.co.uk/s3/product/woocommerce-automatic-order-printing/?affiliates=2) (from our partners at Simba Hosting)
|
31 |
-
* More advanced & stylish templates with [WooCommerce PDF Invoices & Packing Slips Premium Templates](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)
|
32 |
-
|
33 |
-
= Fully customizable =
|
34 |
-
In addition to a number of default settings (including a custom header/logo) and several layout fields that you can use out of the box, the plugin contains HTML/CSS based templates that allow for customization & full control over the PDF output. Copy the templates to your theme folder and you don't have to worry that your customizations will be overwritten when you update the plugin.
|
35 |
-
|
36 |
-
* Insert customer header image/logo
|
37 |
-
* Modify shop data / footer / disclaimer etc. on the invoices & packing slips
|
38 |
-
* Select paper size (Letter or A4)
|
39 |
-
* Translation ready
|
40 |
-
|
41 |
-
== Installation ==
|
42 |
-
|
43 |
-
= Minimum Requirements =
|
44 |
-
|
45 |
-
* WooCommerce 2.0 or later
|
46 |
-
* WordPress 3.5 or later
|
47 |
-
|
48 |
-
= Automatic installation =
|
49 |
-
Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't even need to leave your web browser. To do an automatic install of WooCommerce PDF Invoices & Packing Slips, log in to your WordPress admin panel, navigate to the Plugins menu and click Add New.
|
50 |
-
|
51 |
-
In the search field type "WooCommerce PDF Invoices & Packing Slips" and click Search Plugins. You can install it by simply clicking Install Now. After clicking that link you will be asked if you're sure you want to install the plugin. Click yes and WordPress will automatically complete the installation. After installation has finished, click the 'activate plugin' link.
|
52 |
-
|
53 |
-
= Manual installation via the WordPress interface =
|
54 |
-
1. Download the plugin zip file to your computer
|
55 |
-
2. Go to the WordPress admin panel menu Plugins > Add New
|
56 |
-
3. Choose upload
|
57 |
-
4. Upload the plugin zip file, the plugin will now be installed
|
58 |
-
5. After installation has finished, click the 'activate plugin' link
|
59 |
-
|
60 |
-
= Manual installation via FTP =
|
61 |
-
1. Download the plugin file to your computer and unzip it
|
62 |
-
2. Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress installation's wp-content/plugins/ directory.
|
63 |
-
3. Activate the plugin from the Plugins menu within the WordPress admin.
|
64 |
-
|
65 |
-
== Frequently Asked Questions ==
|
66 |
-
|
67 |
-
= Where can I find the documentation? =
|
68 |
-
|
69 |
-
[WooCommerce PDF Invoices & Packing Slips documentation](http://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/)
|
70 |
-
|
71 |
-
= It's not working! =
|
72 |
-
|
73 |
-
Check out our step by step diagnostic instructions here: https://wordpress.org/support/topic/read-this-first-9/
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
= Where can I find more templates? =
|
80 |
-
|
81 |
-
Go to [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/) to checkout more templates! These include templates with more tax details and product thumbnails. Need a custom templates? Contact us at support@wpovernight.com for more information.
|
82 |
-
|
83 |
-
= Can I create/send a proforma invoice or a credit note? =
|
84 |
-
This is a feature of our Professional extension, which can be found at [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
|
85 |
-
|
86 |
-
= Can I contribute to the code? =
|
87 |
-
You're more than welcome! This plugin is hosted on github, where you can post issues or make pull requests.
|
88 |
-
https://github.com/wpovernight/woocommerce-pdf-invoices-packing-slips
|
89 |
-
|
90 |
-
= How can I display the HTML/CSS source for debugging/developing templates? =
|
91 |
-
There's a setting on the Status tab of the settings page that allows you to toggle HTML output. Don't forget to turn if off after you're done testing!
|
92 |
-
|
93 |
-
|
94 |
-
== Screenshots ==
|
95 |
-
|
96 |
-
1. General settings page
|
97 |
-
2. Template settings page
|
98 |
-
3. Simple invoice PDF
|
99 |
-
4. Simple packing slip PDF
|
100 |
-
|
101 |
-
== Changelog ==
|
102 |
-
|
103 |
-
**2.0 is a BIG update! Make a full site backup before upgrading**
|
104 |
-
|
105 |
-
= 2.0.
|
106 |
-
* Feature:
|
107 |
-
*
|
108 |
-
* Fix:
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
* Feature:
|
113 |
-
* Fix:
|
114 |
-
* Fix:
|
115 |
-
|
116 |
-
|
117 |
-
*
|
118 |
-
|
119 |
-
|
120 |
-
*
|
121 |
-
* Fix:
|
122 |
-
* Tweak:
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
*
|
128 |
-
*
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
* Fix:
|
133 |
-
* Fix:
|
134 |
-
|
135 |
-
|
136 |
-
*
|
137 |
-
|
138 |
-
|
139 |
-
* Fix: order notes
|
140 |
-
*
|
141 |
-
*
|
142 |
-
|
143 |
-
|
144 |
-
* Fix:
|
145 |
-
|
146 |
-
|
147 |
-
* Fix: PHP
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
*
|
153 |
-
|
154 |
-
|
155 |
-
* New:
|
156 |
-
* New:
|
157 |
-
*
|
158 |
-
*
|
159 |
-
*
|
160 |
-
*
|
161 |
-
*
|
162 |
-
|
163 |
-
|
164 |
-
*
|
165 |
-
* Fix:
|
166 |
-
*
|
167 |
-
|
168 |
-
= 1.6.
|
169 |
-
*
|
170 |
-
* Fix:
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
* Fix:
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
* Fix:
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
* Fix:
|
194 |
-
|
195 |
-
|
196 |
-
*
|
197 |
-
|
198 |
-
|
199 |
-
*
|
200 |
-
*
|
201 |
-
*
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
*
|
206 |
-
* Fix:
|
207 |
-
*
|
208 |
-
|
209 |
-
|
210 |
-
*
|
211 |
-
|
212 |
-
|
213 |
-
*
|
214 |
-
*
|
215 |
-
*
|
216 |
-
|
217 |
-
|
218 |
-
*
|
219 |
-
|
220 |
-
|
221 |
-
*
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
*
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
* Fix:
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
*
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
*
|
248 |
-
*
|
249 |
-
|
250 |
-
= 1.5.
|
251 |
-
*
|
252 |
-
*
|
253 |
-
*
|
254 |
-
|
255 |
-
= 1.5.
|
256 |
-
*
|
257 |
-
*
|
258 |
-
*
|
259 |
-
|
260 |
-
|
261 |
-
*
|
262 |
-
|
263 |
-
|
264 |
-
*
|
265 |
-
*
|
266 |
-
*
|
267 |
-
|
268 |
-
|
269 |
-
*
|
270 |
-
*
|
271 |
-
*
|
272 |
-
*
|
273 |
-
|
274 |
-
|
275 |
-
*
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
*
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
*
|
285 |
-
*
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
*
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
*
|
294 |
-
*
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
* Fix:
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
* Feature:
|
310 |
-
* Tweak:
|
311 |
-
|
312 |
-
|
313 |
-
*
|
314 |
-
*
|
315 |
-
|
316 |
-
|
317 |
-
*
|
318 |
-
*
|
319 |
-
* Translations:
|
320 |
-
|
321 |
-
= 1.5.
|
322 |
-
*
|
323 |
-
*
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
* Tweak:
|
328 |
-
*
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
*
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
*
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
*
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
* Feature:
|
359 |
-
|
360 |
-
|
361 |
-
*
|
362 |
-
*
|
363 |
-
*
|
364 |
-
*
|
365 |
-
*
|
366 |
-
*
|
367 |
-
|
368 |
-
|
369 |
-
* Fix:
|
370 |
-
*
|
371 |
-
*
|
372 |
-
|
373 |
-
|
374 |
-
*
|
375 |
-
|
376 |
-
|
377 |
-
*
|
378 |
-
*
|
379 |
-
*
|
380 |
-
|
381 |
-
= 1.5.
|
382 |
-
*
|
383 |
-
*
|
384 |
-
*
|
385 |
-
|
386 |
-
|
387 |
-
*
|
388 |
-
|
389 |
-
|
390 |
-
*
|
391 |
-
*
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
*
|
400 |
-
|
401 |
-
|
402 |
-
*
|
403 |
-
*
|
404 |
-
*
|
405 |
-
|
406 |
-
|
407 |
-
*
|
408 |
-
* Translations: Updated
|
409 |
-
*
|
410 |
-
|
411 |
-
= 1.4.
|
412 |
-
*
|
413 |
-
* Translations:
|
414 |
-
* Translations:
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
*
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
*
|
428 |
-
*
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
*
|
433 |
-
*
|
434 |
-
*
|
435 |
-
|
436 |
-
|
437 |
-
*
|
438 |
-
|
439 |
-
|
440 |
-
*
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
*
|
446 |
-
|
447 |
-
|
448 |
-
*
|
449 |
-
*
|
450 |
-
*
|
451 |
-
*
|
452 |
-
|
453 |
-
|
454 |
-
*
|
455 |
-
*
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
*
|
460 |
-
*
|
461 |
-
|
462 |
-
= 1.4.
|
463 |
-
*
|
464 |
-
*
|
465 |
-
* Translations:
|
466 |
-
|
467 |
-
|
468 |
-
*
|
469 |
-
|
470 |
-
|
471 |
-
*
|
472 |
-
*
|
473 |
-
*
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
*
|
478 |
-
*
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
* Fix:
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
*
|
487 |
-
*
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
*
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
*
|
497 |
-
|
498 |
-
= 1.3.
|
499 |
-
*
|
500 |
-
*
|
501 |
-
* Translations: Added
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
*
|
506 |
-
*
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
*
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
*
|
522 |
-
* Fix:
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
*
|
527 |
-
* Fix:
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
*
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
*
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
*
|
540 |
-
*
|
541 |
-
|
542 |
-
|
543 |
-
*
|
544 |
-
|
545 |
-
|
546 |
-
*
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
*
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
* Feature:
|
556 |
-
*
|
557 |
-
*
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
*
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
*
|
570 |
-
*
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
*
|
575 |
-
*
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
* Fix:
|
584 |
-
|
585 |
-
= 1.1.
|
586 |
-
* Feature:
|
587 |
-
*
|
588 |
-
*
|
589 |
-
|
590 |
-
= 1.1.
|
591 |
-
* Feature:
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
* Feature:
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
*
|
601 |
-
*
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
=
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
609 |
Â
**2.0 is a BIG update! Make a full site backup before upgrading!**
|
1 |
+
=== WooCommerce PDF Invoices & Packing Slips ===
|
2 |
+
Contributors: pomegranate
|
3 |
+
Donate link: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/
|
4 |
+
Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice, packing slip, export, email, bulk, automatic
|
5 |
+
Requires at least: 3.5
|
6 |
+
Tested up to: 4.8
|
7 |
+
Stable tag: 2.0.8
|
8 |
+
License: GPLv2 or later
|
9 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
+
|
11 |
+
Create, print & automatically email PDF invoices & packing slips for WooCommerce orders.
|
12 |
+
|
13 |
+
== Description ==
|
14 |
+
|
15 |
+
This WooCommerce extension automatically adds a PDF invoice to the order confirmation emails sent out to your customers. Includes a basic template (additional templates are available from [WP Overnight](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)) as well as the possibility to modify/create your own templates. In addition, you can choose to download or print invoices and packing slips from the WooCommerce order admin.
|
16 |
+
|
17 |
+
= Main features =
|
18 |
+
* Automatically attach invoice PDF to WooCommerce emails of your choice
|
19 |
+
* Download the PDF invoice / packing slip from the order admin page
|
20 |
+
* Generate PDF invoices / packings slips in bulk
|
21 |
+
* **Fully customizable** HTML/CSS invoice templates
|
22 |
+
* Download invoices from the My Account page
|
23 |
+
* Sequential invoice numbers - with custom formatting
|
24 |
+
* **Available in: Czech, Dutch, English, Finnish, French, German, Hungarian, Italian, Japanese (see FAQ for adding custom fonts!), Norwegian, Polish, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish & Ukrainian**
|
25 |
+
|
26 |
+
In addition to this, we offer several premium extensions:
|
27 |
+
|
28 |
+
* Create/email PDF Proforma Invoices, Credit Notes (for Refunds), email Packing Slips & more with [WooCommerce PDF Invoices & Packing Slips Professional](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
|
29 |
+
* Upload all invoices automatically to Dropbox with [WooCommerce PDF Invoices & Packing Slips to Dropbox](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-dropbox/)
|
30 |
+
* Automatically send new orders or packing slips to your printer, as soon as the customer orders! [WooCommerce Automatic Order Printing](https://www.simbahosting.co.uk/s3/product/woocommerce-automatic-order-printing/?affiliates=2) (from our partners at Simba Hosting)
|
31 |
+
* More advanced & stylish templates with [WooCommerce PDF Invoices & Packing Slips Premium Templates](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/)
|
32 |
+
|
33 |
+
= Fully customizable =
|
34 |
+
In addition to a number of default settings (including a custom header/logo) and several layout fields that you can use out of the box, the plugin contains HTML/CSS based templates that allow for customization & full control over the PDF output. Copy the templates to your theme folder and you don't have to worry that your customizations will be overwritten when you update the plugin.
|
35 |
+
|
36 |
+
* Insert customer header image/logo
|
37 |
+
* Modify shop data / footer / disclaimer etc. on the invoices & packing slips
|
38 |
+
* Select paper size (Letter or A4)
|
39 |
+
* Translation ready
|
40 |
+
|
41 |
+
== Installation ==
|
42 |
+
|
43 |
+
= Minimum Requirements =
|
44 |
+
|
45 |
+
* WooCommerce 2.0 or later
|
46 |
+
* WordPress 3.5 or later
|
47 |
+
|
48 |
+
= Automatic installation =
|
49 |
+
Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't even need to leave your web browser. To do an automatic install of WooCommerce PDF Invoices & Packing Slips, log in to your WordPress admin panel, navigate to the Plugins menu and click Add New.
|
50 |
+
|
51 |
+
In the search field type "WooCommerce PDF Invoices & Packing Slips" and click Search Plugins. You can install it by simply clicking Install Now. After clicking that link you will be asked if you're sure you want to install the plugin. Click yes and WordPress will automatically complete the installation. After installation has finished, click the 'activate plugin' link.
|
52 |
+
|
53 |
+
= Manual installation via the WordPress interface =
|
54 |
+
1. Download the plugin zip file to your computer
|
55 |
+
2. Go to the WordPress admin panel menu Plugins > Add New
|
56 |
+
3. Choose upload
|
57 |
+
4. Upload the plugin zip file, the plugin will now be installed
|
58 |
+
5. After installation has finished, click the 'activate plugin' link
|
59 |
+
|
60 |
+
= Manual installation via FTP =
|
61 |
+
1. Download the plugin file to your computer and unzip it
|
62 |
+
2. Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress installation's wp-content/plugins/ directory.
|
63 |
+
3. Activate the plugin from the Plugins menu within the WordPress admin.
|
64 |
+
|
65 |
+
== Frequently Asked Questions ==
|
66 |
+
|
67 |
+
= Where can I find the documentation? =
|
68 |
+
|
69 |
+
[WooCommerce PDF Invoices & Packing Slips documentation](http://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/)
|
70 |
+
|
71 |
+
= It's not working! =
|
72 |
+
|
73 |
+
Check out our step by step diagnostic instructions here: https://wordpress.org/support/topic/read-this-first-9/
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
|
78 |
+
|
79 |
+
= Where can I find more templates? =
|
80 |
+
|
81 |
+
Go to [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/) to checkout more templates! These include templates with more tax details and product thumbnails. Need a custom templates? Contact us at support@wpovernight.com for more information.
|
82 |
+
|
83 |
+
= Can I create/send a proforma invoice or a credit note? =
|
84 |
+
This is a feature of our Professional extension, which can be found at [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/)
|
85 |
+
|
86 |
+
= Can I contribute to the code? =
|
87 |
+
You're more than welcome! This plugin is hosted on github, where you can post issues or make pull requests.
|
88 |
+
https://github.com/wpovernight/woocommerce-pdf-invoices-packing-slips
|
89 |
+
|
90 |
+
= How can I display the HTML/CSS source for debugging/developing templates? =
|
91 |
+
There's a setting on the Status tab of the settings page that allows you to toggle HTML output. Don't forget to turn if off after you're done testing!
|
92 |
+
|
93 |
+
|
94 |
+
== Screenshots ==
|
95 |
+
|
96 |
+
1. General settings page
|
97 |
+
2. Template settings page
|
98 |
+
3. Simple invoice PDF
|
99 |
+
4. Simple packing slip PDF
|
100 |
+
|
101 |
+
== Changelog ==
|
102 |
+
|
103 |
+
**2.0 is a BIG update! Make a full site backup before upgrading**
|
104 |
+
|
105 |
+
= 2.0.8 =
|
106 |
+
* Feature: Add support for Bedrock / alternative folder structures
|
107 |
+
* Dev: Filter for merged documents
|
108 |
+
* Fix: Better attributes fallback for product variations
|
109 |
+
|
110 |
+
= 2.0.7 =
|
111 |
+
* Feature: Added button to delete legacy settings
|
112 |
+
* Feature: Option to enable font subsetting
|
113 |
+
* Fix: Invoice number sequence for databases with alternative auto_increment_increment settings
|
114 |
+
* Fix: Fallback function for MB String (mb_stripos)
|
115 |
+
|
116 |
+
= 2.0.6 =
|
117 |
+
* Feature: Improved third party invoice number filters (`wpo_wcpdf_external_invoice_number_enabled` & `wpo_wcpdf_external_invoice_number`)
|
118 |
+
* Fix: Underline position for Open Sans font
|
119 |
+
* Fix: Invoice number auto_increment for servers that restarted frequently
|
120 |
+
* Fix: Dompdf log file location (preventing open base_dir notices breaking PDF header)
|
121 |
+
* Fix: 1.6.6 Settings migration duplicates merging
|
122 |
+
* Tweak: Clear fonts folder when manually reinstalling fonts
|
123 |
+
|
124 |
+
= 2.0.5 =
|
125 |
+
* Feature: Remove temporary files (Status tab)
|
126 |
+
* Fix: Page number replacement
|
127 |
+
* Tweak: Fallback functions for MB String extension
|
128 |
+
* Tweak: Improved wpo_wcpdf_check_privs usability for my account privileges
|
129 |
+
* Legacy support: added wc_price alias for format_price method in document
|
130 |
+
|
131 |
+
= 2.0.4 =
|
132 |
+
* Fix: Apply filters for custom invoice number formatting in document too
|
133 |
+
* Fix: Parent fallback for missing dates from refunds
|
134 |
+
|
135 |
+
= 2.0.3 =
|
136 |
+
* Fix: Better support for legacy invoice number filter (`wpo_wcpdf_invoice_number` - replaced by `wpo_wcpdf_formatted_document_number`)
|
137 |
+
* Fix: Document number formatting fallback to order date if no document date available
|
138 |
+
* Fix: Updated classmap: PSR loading didn't work on some installations
|
139 |
+
* Fix: Prevent order notes from all orders showing when document is not loaded properly in filter
|
140 |
+
* Tweak: Disable deprecation notices during email sending
|
141 |
+
* Tweak: ignore outdated language packs
|
142 |
+
|
143 |
+
= 2.0.2 =
|
144 |
+
* Fix: order notes using correct order_id
|
145 |
+
* Fix: WC3.0 deprecation notice for currency
|
146 |
+
* Fix: Avoid crashing on PHP5.2 and older
|
147 |
+
* Fix: Only use PHP MB String when present
|
148 |
+
* Fix: Remote images
|
149 |
+
* Fix: Download option
|
150 |
+
|
151 |
+
= 2.0.1 =
|
152 |
+
* Fix: PHP 5.4 issue
|
153 |
+
|
154 |
+
= 2.0.0 =
|
155 |
+
* New: Better structured & more advanced settings for documents
|
156 |
+
* New: Option to enable & disable Packing Slips or Invoices
|
157 |
+
* New: Invoice number sequence stored separately for improved speed & performance
|
158 |
+
* New: Completely rewritten codebase for more flexibility & better reliability
|
159 |
+
* New: Updated PDF library to DOMPDF 0.8
|
160 |
+
* New: PDF Library made pluggable (by using the `wpo_wcpdf_pdf_maker` filter)
|
161 |
+
* New: lots of new functions & filters to allow developers to hook into the plugin
|
162 |
+
* Changed: **$wpo_wcpdf variable is now deprecated** (legacy mode available & automatically enabled on update)
|
163 |
+
* Fix: Improved PHP 7 & 7.1 support
|
164 |
+
* Fix: Positive prices for refunds
|
165 |
+
* Fix: Use parent for attributes retrieved for product variations
|
166 |
+
* Fix: Set content type to PDF for download
|
167 |
+
|
168 |
+
= 1.6.6 =
|
169 |
+
* Feature: Facilitate downgrading from 2.0 (re-installing fonts & resetting version)
|
170 |
+
* Fix: Update currencies font (added Georgian Lari)
|
171 |
+
* Translations: Added Indonesian
|
172 |
+
|
173 |
+
= 1.6.5 =
|
174 |
+
* Fix: Duplicate invoice numbers when bulk completing orders (WC3.0)
|
175 |
+
* Fix: Hidden Invoice date when order refunded
|
176 |
+
|
177 |
+
= 1.6.4 =
|
178 |
+
* Fix: My account invoice button visibility
|
179 |
+
|
180 |
+
= 1.6.3 =
|
181 |
+
* Fix: Empty date handling
|
182 |
+
* Fix: Shipping notes on refunds (reason for refund)
|
183 |
+
|
184 |
+
= 1.6.2 =
|
185 |
+
* Fix: TM Extra Product Options compatibility (in WC3.0)
|
186 |
+
* Fix: Tax display in WC3.0
|
187 |
+
|
188 |
+
= 1.6.1 =
|
189 |
+
* Fix: Error with totals in credit notes
|
190 |
+
* Fix: Always set invoice date when invoice is create (even display is disabled in the settings)
|
191 |
+
|
192 |
+
= 1.6.0.2 =
|
193 |
+
* Fix: Don't crash with PHP 5.2 or older (5.3 or higher required, 5.6 or higher recommended)
|
194 |
+
|
195 |
+
= 1.6.0 =
|
196 |
+
* WooCommerce 3.0 Compatible
|
197 |
+
* **Requires PHP version 5.3 or higher**
|
198 |
+
* Fix: Invoice number display in mobile view
|
199 |
+
* Fix: Update formatted invoice number in order meta when number is altered
|
200 |
+
* Fix: global plugin object loading in wrapped cron methods
|
201 |
+
* Tweak: Avoid PHP7 scan false positives in DomPDF
|
202 |
+
|
203 |
+
= 1.5.39 =
|
204 |
+
* Feature: new template action hooks `wpo_wcpdf_before_document` & `wpo_wcpdf_after_document`
|
205 |
+
* Tweak: In totals, emphasize order total rather than last item
|
206 |
+
* Fix: User deprecation notices
|
207 |
+
* Translations: Updated Slovenian
|
208 |
+
|
209 |
+
= 1.5.38 =
|
210 |
+
* Fix: Thumbnail path fallback
|
211 |
+
* Fix: Edge/IE hour & minute pattern
|
212 |
+
* Fix: Skip over non-order objects
|
213 |
+
* Tweak: Let shop manager view My Account links
|
214 |
+
* Dev: added `wpo_wcpdf_before_attachment_creation` action
|
215 |
+
* Translations: Updated POT, Swedish, Dutch & Norwegian
|
216 |
+
|
217 |
+
= 1.5.37 =
|
218 |
+
* Feature: Added support for third party invoice numbers
|
219 |
+
* Feature: Enable pre-invoice number click-to-edit
|
220 |
+
* Fix: Review link for custom admins
|
221 |
+
* Fix: PHP7 compatibility
|
222 |
+
* Fix: Invoice date hour/minute pattern
|
223 |
+
* Tweak: Multisite WooCommerce check optimization
|
224 |
+
|
225 |
+
= 1.5.36 =
|
226 |
+
* Translations: Fixed Romanian (incorrect "Factură Proforma" translation for "Invoice")
|
227 |
+
|
228 |
+
= 1.5.35 =
|
229 |
+
* Translations: Fixed "Includes %s" string for WC2.6+
|
230 |
+
|
231 |
+
= 1.5.34 =
|
232 |
+
* Fix: Document check that was introduced in 1.5.33 for disable free setting
|
233 |
+
|
234 |
+
= 1.5.33 =
|
235 |
+
* Tweak: Don't apply 'disable free' setting to packing slip attachment
|
236 |
+
* Translations: Updated Romanian
|
237 |
+
|
238 |
+
= 1.5.32 =
|
239 |
+
* Fix: Updated currency font with Indian Rupee symbol
|
240 |
+
* Translations: added Formal German (currently a copy of informal German)
|
241 |
+
|
242 |
+
= 1.5.31 =
|
243 |
+
* Feature: [invoice_day] or [order_day] in invoice number format
|
244 |
+
* Fix: Link to hide all ads when premium extensions active
|
245 |
+
|
246 |
+
= 1.5.30 =
|
247 |
+
* Feature: Enable currency font for extended currency support
|
248 |
+
* Fix: Font sync on plugin update
|
249 |
+
|
250 |
+
= 1.5.29 =
|
251 |
+
* Translations: Added Croation (Thanks Neven/Spine ICT!), updated French (Thanks Sabra!)
|
252 |
+
* Tweak: filter shop address before checking if it's empty
|
253 |
+
* Dev: added $order to `wpo_wcpdf_template_file` filter
|
254 |
+
|
255 |
+
= 1.5.28 =
|
256 |
+
* Tweak: the 'Next invoice number' is now stored separately in the database for faster and more reliable retrieval. Circumventing any caching, this should prevent duplicate invoice numbers.
|
257 |
+
* Fix: Bulk actions plugin conflicts
|
258 |
+
* Experimental: page numbers (use {{PAGE_NUM}} / {{PAGE_COUNT}} in your template)
|
259 |
+
|
260 |
+
= 1.5.27 =
|
261 |
+
* Feature: Use [invoice_year] and [invoice_month] placeholders in invoice number prefix/suffix
|
262 |
+
* Feature: WooCommerce Order Status & Actions Manager emails compatibility
|
263 |
+
* Feature: Add invoice number to WC REST API
|
264 |
+
* Fix: Allow positive 'discounts' (price corrections)
|
265 |
+
* Fix: Discounts rounding
|
266 |
+
* Translations: Updated Finnish & Portugese & POT
|
267 |
+
|
268 |
+
= 1.5.26 =
|
269 |
+
* Feature: Automatically list all emails registered in WooCommerce
|
270 |
+
* Feature: Reset invoice number yearly
|
271 |
+
* Feature: WooCommerce Chained Products compatibility
|
272 |
+
* Feature: WooCommerce Product Bundles visibility settings taken into account in invoice
|
273 |
+
* Fix: Disable PDF creation from trashed order_ids
|
274 |
+
* Tweak: Alert when no orders selected for bulk export (Props to Dartui!)
|
275 |
+
* Tweak: PDF invoice settings always under WooCommerce menu (also for premium users)
|
276 |
+
* Tweak: extra $item_id passed in row class filter
|
277 |
+
* Translations: Updated Slovenian, Spanish, Dutch & POT file
|
278 |
+
|
279 |
+
= 1.5.24 =
|
280 |
+
* Hotfix: Subscriptions renewal filter arguments
|
281 |
+
|
282 |
+
= 1.5.23 =
|
283 |
+
* Fix: WooCommerce Subscriptons 2.0 deprecation notice.
|
284 |
+
* Tweak: better qTranslate-X support
|
285 |
+
* Tweak: filter for user privileges check (wpo_wcpdf_check_privs)
|
286 |
+
* Translations: French translations fix
|
287 |
+
|
288 |
+
= 1.5.22 =
|
289 |
+
* Fix: Workaround for bug in WPML (which cleared all settings)
|
290 |
+
* Translation: fixed Polish translation for invoice
|
291 |
+
|
292 |
+
= 1.5.21 =
|
293 |
+
* Translations: Added Estionan (thanks Tanel!)
|
294 |
+
* Tweak: WC2.4 compatibility
|
295 |
+
|
296 |
+
= 1.5.20 =
|
297 |
+
* Feature: Option to 'never' display My Account invoice link
|
298 |
+
* Fix: Order total for refunds in WC2.4
|
299 |
+
* Fix: notice when no custom statuses selected for My Account display
|
300 |
+
* Tweak: Product bundles styles
|
301 |
+
|
302 |
+
= 1.5.19 =
|
303 |
+
* Fix: Invoice number search (broke other custom searches)
|
304 |
+
|
305 |
+
= 1.5.18 =
|
306 |
+
* Fix: wpo_wcpdf_item_row_class packing slip filter arguments
|
307 |
+
|
308 |
+
= 1.5.17 =
|
309 |
+
* Feature: WooCommerce Product Bundles compatibility styles
|
310 |
+
* Tweak: wpo_wcpdf_item_row_class as filter instead of action
|
311 |
+
|
312 |
+
= 1.5.16 =
|
313 |
+
* Feature: Search orders by invoice number (note: search on formatted invoice number only works for new orders)
|
314 |
+
* Feature: Formatted invoice number stored in order
|
315 |
+
* Tweak: Function parameters added to some of the filters
|
316 |
+
* Tweak: WooCommerce 2.4 compatibility
|
317 |
+
* Dev feature: action to add class to items table row (wpo_wcpdf_item_row_class)
|
318 |
+
* Translations: Swedish updated (thanks Conney!)
|
319 |
+
* Translations: Norwegian updated
|
320 |
+
|
321 |
+
= 1.5.15 =
|
322 |
+
* Fix: invoice number padding didn't work for values lower than 3
|
323 |
+
* Tweak: WPML compatibility filter
|
324 |
+
* Translations: Updated French (Thanks Nicolas!)
|
325 |
+
|
326 |
+
= 1.5.14 =
|
327 |
+
* Tweak: Invoice number & date edit fields moved to separate box on order edit page
|
328 |
+
* Translations: Updated POT & Dutch
|
329 |
+
|
330 |
+
= 1.5.13 =
|
331 |
+
* Fix: Better address comparison to determine when to display alternate address
|
332 |
+
* Tweak: Filter N/A addresses
|
333 |
+
* Tweak: Use WooCommerce function for 2.3 discounts
|
334 |
+
* Translations: Czech Updated (Thanks Ivo!)
|
335 |
+
* Translations: French (minor fixes)
|
336 |
+
|
337 |
+
= 1.5.12 =
|
338 |
+
* Translations: added Danish, Updated POT & Italian
|
339 |
+
|
340 |
+
= 1.5.11 =
|
341 |
+
* Fix: Product text attributes (now checks key too)
|
342 |
+
* Fix: Status page upload explanation typos
|
343 |
+
|
344 |
+
= 1.5.10 =
|
345 |
+
* Fix: Double check to make sure plugin doesn't attach to user emails
|
346 |
+
|
347 |
+
= 1.5.9 =
|
348 |
+
* Feature: Shorthand function to display product attributes: `$wpo_wcpdf->get_product_attribute( $attribute_name, $product )`
|
349 |
+
|
350 |
+
= 1.5.8 =
|
351 |
+
* Feature: disable invoice for free orders
|
352 |
+
* Feature: action to insert data before & after item meta
|
353 |
+
* Tweak: Added classes to sku & weight
|
354 |
+
* Tweak: Hide payment method from totals (already shown in template)
|
355 |
+
* Translations: Updated POT & Dutch
|
356 |
+
|
357 |
+
= 1.5.7 =
|
358 |
+
* Feature: Setting to show email address & phone number on invoice or packing slip (does not work on custom templates based on previous versions!)
|
359 |
+
|
360 |
+
= 1.5.6 =
|
361 |
+
* Feature: Setting to show shipping address on invoice (does not work on custom templates based on previous versions!)
|
362 |
+
* Feature: My Account invoice download setting
|
363 |
+
* Feature: several new template actions
|
364 |
+
* Tweak: WooCommerce Bookings compatibility
|
365 |
+
* Tweak: Gerenal stylesheet cleanup
|
366 |
+
* Fix: temp path check/error on settings page
|
367 |
+
* Fix: Document titles for credit notes and proforma (Pro)
|
368 |
+
* Fix: Discount including tax
|
369 |
+
* Fix: Special characters on item meta (requires WooCommerce 2.3.6)
|
370 |
+
* Translations: Missing text domain on several strings
|
371 |
+
* Translations: Updated POT & Dutch
|
372 |
+
|
373 |
+
= 1.5.5 =
|
374 |
+
* Fix: Check for incomplete line tax data (Subscriptions compatibility)
|
375 |
+
* Fix: More precise template path instructions
|
376 |
+
* Fix: duplicate stylesheet filter
|
377 |
+
* Fix: Always prefer original order's billing address for refunds (WooCommerce EU VAT Number compatibility)
|
378 |
+
* Translations: Updated German (MwSt. instead of formal Ust.)
|
379 |
+
* Translations: Updated Dutch
|
380 |
+
|
381 |
+
= 1.5.4 =
|
382 |
+
* Tweak: include plugin version in style/script includes
|
383 |
+
* Tweak: upload code cleanup
|
384 |
+
* Fix: Parent invoice number (for Credit Notes in professional extension)
|
385 |
+
|
386 |
+
= 1.5.3 =
|
387 |
+
* Feature: add original order date value to order date filter
|
388 |
+
* Feature: Work with line_tax_data when available
|
389 |
+
* Feature: pass item_id to items
|
390 |
+
* Tweak: later check for woocommerce active
|
391 |
+
* Fix: do not try to validate empty settings (Status page settings)
|
392 |
+
* Translations: Fixed Dutch typo
|
393 |
+
|
394 |
+
= 1.5.2 =
|
395 |
+
* Fix: fatal error when trying to activate with WooCommerce not installed yet.
|
396 |
+
* Tweak: indentation fix on the Simple template
|
397 |
+
|
398 |
+
= 1.5.1 =
|
399 |
+
* Fix: prevent errors when upgrading
|
400 |
+
|
401 |
+
= 1.5.0 =
|
402 |
+
* Feature: All temporary files are now stored centrally in the WP uploads folder.
|
403 |
+
* Feature: Debug settings in status panel (output errors & output to HTML)
|
404 |
+
* Feature: Compatibility filter for WooCommerce Subscriptions (prevents duplicate invoice numbers)
|
405 |
+
* Tweak: Pass order to totals filters
|
406 |
+
* Translations: Updated POT
|
407 |
+
* Translations: Updated Italian (Thanks Astrid!)
|
408 |
+
* Translations: Updated Dutch
|
409 |
+
* FAQ: instructions for placing a link on the thank you page
|
410 |
+
|
411 |
+
= 1.4.14 =
|
412 |
+
* Fix: fatal error when user registers at checkout (applies to credit notes only)
|
413 |
+
* Translations: Updated German (Thanks Dietmar!)
|
414 |
+
* Translations: Place your custom translations in wp-content/languages/woocommerce-pdf-invoices-packing-slips/wpo_wcpdf-LOCALE.mo to protect them from being overwritten by plugin updates.
|
415 |
+
|
416 |
+
= 1.4.13 =
|
417 |
+
* Feature: use separate file for all your template specific functions (template-functions.php)
|
418 |
+
* Translations: Added Slovenian (thanks gregy1403!)
|
419 |
+
* Translations: Updated Norwegian & Dutch.
|
420 |
+
* Translations: Added Japanese - needs custom font!
|
421 |
+
* FAQ: instructions on how to use custom fonts
|
422 |
+
|
423 |
+
= 1.4.12 =
|
424 |
+
* Fix: issues with post parent objects (WC2.1 and older)
|
425 |
+
|
426 |
+
= 1.4.11 =
|
427 |
+
* Small fix: bulk actions for specific i18n configurations
|
428 |
+
* Tweak: total row key used as class in Simple template
|
429 |
+
|
430 |
+
= 1.4.10 =
|
431 |
+
* Fix: Invoice not attaching
|
432 |
+
* Translations: Updated POT file
|
433 |
+
* Translations: Updated Dutch, Norwegian, Polish, Brazilian Portugese, Romanian, Russian, Slovak, Spanish & Ukrainian (Many thanks to all the translators!)
|
434 |
+
* Templates: added action hooks for easier customizations (`wpo_wcpdf_before_order_details`, `wpo_wcpdf_after_order_details`, `wpo_wcpdf_invoice_title` & `wpo_wcpdf_packing_slip_title`)
|
435 |
+
|
436 |
+
= 1.4.9 =
|
437 |
+
* Feature: Order number and date are now displayed by default in the Simple template (invoice number and date still optional)
|
438 |
+
* Feature: Display Customer/Order notes with a simple shorthand (see FAQ)
|
439 |
+
* Translations: Added Brazilian Portugese (thanks Victor Debone!)
|
440 |
+
* Tweak: Fail more gracefully when there are errors during PDF generation
|
441 |
+
* Tweak: added template type class to template output body
|
442 |
+
* Tweak: cleaned up Simple template style.css
|
443 |
+
|
444 |
+
= 1.4.8 =
|
445 |
+
* Translations: Added Finnish (Thanks Sami Mäkelä/Contrast.fi!)
|
446 |
+
|
447 |
+
= 1.4.7 =
|
448 |
+
* Fix: check if image file exists locally, fallback to url if not (CDN compatibility)
|
449 |
+
* Fix: make deleting invoice date possible
|
450 |
+
* Fix: correct tmp folder check on status page
|
451 |
+
* Translations: updated po/mo files
|
452 |
+
* Tweak: changed settings capability requirement to `manage_woocommerce` (was: `manage_options`)
|
453 |
+
* Tweak: better email attachment function
|
454 |
+
* Tweak: prevent footer overlap (Simple template)
|
455 |
+
* Tweak: fallback if `glob()` is not allowed on the server
|
456 |
+
* Tweak: better custom template instructions (reflects path to actual (child-)theme)
|
457 |
+
|
458 |
+
= 1.4.6 =
|
459 |
+
* HOTFIX: WooCommerce 2.2 compatibility fix
|
460 |
+
* Filter for PDF temp folder (wpo_wcpdf_tmp_path)
|
461 |
+
|
462 |
+
= 1.4.5 =
|
463 |
+
* Fix: Double date conversion for order date on invoice number filter (to avoid i18n date issues)
|
464 |
+
* Fix: Template selector reset after update
|
465 |
+
* Translations: added Norwegian (Thanks Aleksander!)
|
466 |
+
|
467 |
+
= 1.4.4 =
|
468 |
+
* Feature: Editable invoice date per order/invoice.
|
469 |
+
* Feature: HTML is now allowed in footer and other settings fields.
|
470 |
+
* Translations: Updated German (Thanks Nadine!)
|
471 |
+
* Fix: template paths are now saved relative to the site base path (ABSPATH) to prevent errors when moving to another server
|
472 |
+
* Tweak: Changed bulk action hook for better theme compatibility
|
473 |
+
* Tweak: Newlines in custom checkout fields
|
474 |
+
|
475 |
+
= 1.4.3 =
|
476 |
+
* Feature: Added function to call custom fields more easily (see FAQ)
|
477 |
+
* Feature: Change the my account button text via a filter (wpo_wcpdf_myaccount_button_text)
|
478 |
+
* Translations: Added Danish (Thanks Mads!)
|
479 |
+
* Tweak: only load PDF engine if it's not already loaded by another plugin
|
480 |
+
|
481 |
+
= 1.4.2 =
|
482 |
+
* Fix: Don't create invoice number when exporting packing slips
|
483 |
+
* Fix: Division by zero for 0 quantity items
|
484 |
+
|
485 |
+
= 1.4.1 =
|
486 |
+
* Translations: Added Polish (Thanks Mike!)
|
487 |
+
* Fix: Invoice number formatting notices in debug mode
|
488 |
+
|
489 |
+
= 1.4.0 =
|
490 |
+
* Feature: Invoice numbers can now be given a prefix, suffix or padding on the settings page!
|
491 |
+
* Filter: `wpo_wcpdf_email_allowed_statuses` to attach pdf to custom order status emails
|
492 |
+
* Tweak: Sequential Order Numbers Pro compatibility
|
493 |
+
* Tweak: Filenames are now automatically sanitized to prevent issues with illegal characters
|
494 |
+
|
495 |
+
= 1.3.2 =
|
496 |
+
* Fix: error on wpo_wcpdf_email_attachment filter when $pdf_path not set
|
497 |
+
|
498 |
+
= 1.3.1 =
|
499 |
+
* Fix: invoice number was cleared when Order Actions were being used when an invoice number was not set
|
500 |
+
* Translations: Updated Slovak (Thanks Jozef!)
|
501 |
+
* Translations: Added Czech (Thanks CubiQ!)
|
502 |
+
|
503 |
+
= 1.3.0 =
|
504 |
+
* Feature: Added 'status' panel for better problem diagnosis
|
505 |
+
* Tweak: split create & get invoice number calls to prevent slow database calls from causing number skipping
|
506 |
+
* Translations: Added Romanian (Thanks Leonardo!)
|
507 |
+
* Translations: Added Slovak (Thanks Oleg!)
|
508 |
+
|
509 |
+
= 1.2.13 =
|
510 |
+
* Feature: added filter for custom email attachment condition (wpo_wcpdf_custom_email_condition)
|
511 |
+
* Fix: warning for tax implode
|
512 |
+
|
513 |
+
= 1.2.12 =
|
514 |
+
* Fix: hyperlink underline (was more like a strikethrough)
|
515 |
+
|
516 |
+
= 1.2.11 =
|
517 |
+
* Translations: Fixed German spelling error
|
518 |
+
* Translations: Updated Swedish (Thanks Fredrik!)
|
519 |
+
|
520 |
+
= 1.2.10 =
|
521 |
+
* Translations: Added Swedish (Thanks Jonathan!)
|
522 |
+
* Fix: Line-height issue (on some systems, the space between lines was very high)
|
523 |
+
|
524 |
+
= 1.2.9 =
|
525 |
+
* Fix: bug where 'standard' tax class would not display in some cases
|
526 |
+
* Fix: bug that caused the totals to jump for some font sizes
|
527 |
+
* Fix: WC2.1 deprecated totals function
|
528 |
+
* Fix: If multiple taxes were set up with the same name, only one would display (Simple template was not affected)
|
529 |
+
|
530 |
+
= 1.2.8 =
|
531 |
+
* Template: Body line-height defined to prevent character jumping with italic texts
|
532 |
+
* Fix: Open Sans now included in plugin package (fixes font issues for servers with allow_url_fopen disabled)
|
533 |
+
|
534 |
+
= 1.2.7 =
|
535 |
+
* Translations: POT, DE & NL updated
|
536 |
+
* Fix: Removed stray span tag in totals table
|
537 |
+
|
538 |
+
= 1.2.6 =
|
539 |
+
* Translations: Spanish update (thanks prepu!)
|
540 |
+
* Fix: More advanced checks to determine if a customer can download the invoice (including a status filter)
|
541 |
+
|
542 |
+
= 1.2.5 =
|
543 |
+
* Feature: Optional Invoice Number column for the orders listing
|
544 |
+
* Feature: Better support for international characters
|
545 |
+
* Translations: Added Russian & Ukrainian translation (thanks Oleg!)
|
546 |
+
* Translations: Updated Spanish (Thanks Manuel!) and Dutch translations & POT file
|
547 |
+
* Tweak: Memory limit notice
|
548 |
+
* Tweak: Filename name now includes invoice number (when configured in the settings)
|
549 |
+
|
550 |
+
= 1.2.4 =
|
551 |
+
* Feature: Set which type of emails you want to attach the invoice to
|
552 |
+
|
553 |
+
= 1.2.3 =
|
554 |
+
* Feature: Manually edit invoice number on the edit order screen
|
555 |
+
* Feature: Set the first (/next) invoice number on the settings screen
|
556 |
+
* Fix: Bug where invoice number would be generated twice due to slow database calls
|
557 |
+
* Fix: php strict warnings
|
558 |
+
|
559 |
+
= 1.2.2 =
|
560 |
+
* Feature: Simple template now uses Open Sans to include more international special characters
|
561 |
+
* Feature: Implemented filters for paper size & orientation ([read here](http://wordpress.org/support/topic/select-a5-paper-size-for-packing-slips?replies=5#post-5211129))
|
562 |
+
* Tweak: PDF engine updated (dompdf 0.6.0)
|
563 |
+
* Tweak: Download PDF link on the my account page is now only shown when an invoice is already created by the admin or automatically, to prevent unwanted invoice created (creating problems with european laws).
|
564 |
+
|
565 |
+
= 1.2.1 =
|
566 |
+
* Fix: shipping & fees functions didn't output correctly with the tax set to 'incl'
|
567 |
+
|
568 |
+
= 1.2.0 =
|
569 |
+
* Feature: Sequential invoice numbers (set upon invoice creation).
|
570 |
+
* Feature: Invoice date (set upon invoice creation).
|
571 |
+
|
572 |
+
= 1.1.6 =
|
573 |
+
* Feature: Hungarian translations added - thanks Joseph!
|
574 |
+
* Tweak: Better debug code.
|
575 |
+
* Tweak: Error reporting when templates not found.
|
576 |
+
* Fix: tax rate calculation for free items.
|
577 |
+
|
578 |
+
= 1.1.5 =
|
579 |
+
* Feature: German translations added - thanks Christian!
|
580 |
+
* Fix: dompdf 0.6.0 proved to be less stable, so switching back to beta3 for now.
|
581 |
+
|
582 |
+
= 1.1.4 =
|
583 |
+
* Fix: Template paths on windows servers were not properly saved (stripslashes), resulting in an empty output.
|
584 |
+
|
585 |
+
= 1.1.3 =
|
586 |
+
* Feature: PDF engine (dompdf) updated to 0.6.0 for better stability and utf-8 support.
|
587 |
+
* Tweak: Local server path is used for header image for better compatibility with server settings.
|
588 |
+
* Fix: several small bugs.
|
589 |
+
|
590 |
+
= 1.1.2 =
|
591 |
+
* Feature: Totals can now be called with simpler template functions
|
592 |
+
* Feature: Italian translations - thanks max66max!
|
593 |
+
* Tweak: improved memory performance
|
594 |
+
|
595 |
+
= 1.1.1 =
|
596 |
+
* Feature: French translations - thanks Guillaume!
|
597 |
+
|
598 |
+
= 1.1.0 =
|
599 |
+
* Feature: Fees can now also be called ex. VAT
|
600 |
+
* Feature: Invoices can now be downloaded from the My Account page
|
601 |
+
* Feature: Spanish translation & POT file included
|
602 |
+
* Fix: ternary statements that caused an error
|
603 |
+
|
604 |
+
= 1.0.1 =
|
605 |
+
* Tweak: Packing slip now displays shipping address instead of billing address
|
606 |
+
* Tweak: Variation data is now displayed by default
|
607 |
+
|
608 |
+
= 1.0.0 =
|
609 |
+
* First release
|
610 |
+
|
611 |
+
== Upgrade Notice ==
|
612 |
+
|
613 |
+
= 2.0.8 =
|
614 |
Â
**2.0 is a BIG update! Make a full site backup before upgrading!**
|
woocommerce-pdf-invoices-packingslips.php
CHANGED
@@ -1,355 +1,355 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
-
* Plugin URI: http://www.wpovernight.com
|
5 |
-
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
-
* Version: 2.0.
|
7 |
-
* Author: Ewout Fernhout
|
8 |
-
* Author URI: http://www.wpovernight.com
|
9 |
-
* License: GPLv2 or later
|
10 |
-
* License URI: http://www.opensource.org/licenses/gpl-license.php
|
11 |
-
* Text Domain: woocommerce-pdf-invoices-packing-slips
|
12 |
-
*/
|
13 |
-
|
14 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
-
exit; // Exit if accessed directly
|
16 |
-
}
|
17 |
-
|
18 |
-
if ( !class_exists( 'WPO_WCPDF' ) ) :
|
19 |
-
|
20 |
-
class WPO_WCPDF {
|
21 |
-
|
22 |
-
public $version = '2.0.
|
23 |
-
public $plugin_basename;
|
24 |
-
public $legacy_mode;
|
25 |
-
|
26 |
-
protected static $_instance = null;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Main Plugin Instance
|
30 |
-
*
|
31 |
-
* Ensures only one instance of plugin is loaded or can be loaded.
|
32 |
-
*/
|
33 |
-
public static function instance() {
|
34 |
-
if ( is_null( self::$_instance ) ) {
|
35 |
-
self::$_instance = new self();
|
36 |
-
}
|
37 |
-
return self::$_instance;
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Constructor
|
42 |
-
*/
|
43 |
-
public function __construct() {
|
44 |
-
$this->plugin_basename = plugin_basename(__FILE__);
|
45 |
-
|
46 |
-
$this->define( 'WPO_WCPDF_VERSION', $this->version );
|
47 |
-
|
48 |
-
// load the localisation & classes
|
49 |
-
add_action( 'plugins_loaded', array( $this, 'translations' ) );
|
50 |
-
add_filter( 'load_textdomain_mofile', array( $this, 'textdomain_fallback' ), 10, 2 );
|
51 |
-
add_action( 'plugins_loaded', array( $this, 'load_classes' ), 9 );
|
52 |
-
add_action( 'in_plugin_update_message-'.$this->plugin_basename, array( $this, 'in_plugin_update_message' ) );
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Define constant if not already set
|
57 |
-
* @param string $name
|
58 |
-
* @param string|bool $value
|
59 |
-
*/
|
60 |
-
private function define( $name, $value ) {
|
61 |
-
if ( ! defined( $name ) ) {
|
62 |
-
define( $name, $value );
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Load the translation / textdomain files
|
69 |
-
*
|
70 |
-
* Note: the first-loaded translation file overrides any following ones if the same translation is present
|
71 |
-
*/
|
72 |
-
public function translations() {
|
73 |
-
$locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce-pdf-invoices-packing-slips' );
|
74 |
-
$dir = trailingslashit( WP_LANG_DIR );
|
75 |
-
|
76 |
-
$textdomains = array( 'woocommerce-pdf-invoices-packing-slips' );
|
77 |
-
if ( $this->legacy_mode_enabled() === true ) {
|
78 |
-
$textdomains[] = 'wpo_wcpdf';
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Frontend/global Locale. Looks in:
|
83 |
-
*
|
84 |
-
* - WP_LANG_DIR/woocommerce-pdf-invoices-packing-slips/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
|
85 |
-
* - WP_LANG_DIR/plugins/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
|
86 |
-
* - woocommerce-pdf-invoices-packing-slips-pro/languages/woocommerce-pdf-invoices-packing-slips-LOCALE.mo (which if not found falls back to:)
|
87 |
-
* - WP_LANG_DIR/plugins/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
|
88 |
-
*/
|
89 |
-
foreach ($textdomains as $textdomain) {
|
90 |
-
load_textdomain( $textdomain, $dir . 'woocommerce-pdf-invoices-packing-slips/woocommerce-pdf-invoices-packing-slips-' . $locale . '.mo' );
|
91 |
-
load_textdomain( $textdomain, $dir . 'plugins/woocommerce-pdf-invoices-packing-slips-' . $locale . '.mo' );
|
92 |
-
load_plugin_textdomain( $textdomain, false, dirname( plugin_basename(__FILE__) ) . '/languages' );
|
93 |
-
}
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Maintain backwards compatibility with old translation files
|
98 |
-
* Uses old .mo file if it exists in any of the override locations
|
99 |
-
*/
|
100 |
-
public function textdomain_fallback( $mofile, $textdomain ) {
|
101 |
-
$plugin_domain = 'woocommerce-pdf-invoices-packing-slips';
|
102 |
-
$old_domain = 'wpo_wcpdf';
|
103 |
-
|
104 |
-
if ($textdomain == $old_domain) {
|
105 |
-
$textdomain = $plugin_domain;
|
106 |
-
$mofile = str_replace( "{$old_domain}-", "{$textdomain}-", $mofile ); // with trailing dash to target file and not folder
|
107 |
-
}
|
108 |
-
|
109 |
-
if ( $textdomain === $plugin_domain ) {
|
110 |
-
$old_mofile = str_replace( "{$textdomain}-", "{$old_domain}-", $mofile ); // with trailing dash to target file and not folder
|
111 |
-
if ( file_exists( $old_mofile ) ) {
|
112 |
-
// we have an old override - use it
|
113 |
-
return $old_mofile;
|
114 |
-
}
|
115 |
-
|
116 |
-
// prevent loading outdated language packs
|
117 |
-
$pofile = str_replace('.mo', '.po', $mofile);
|
118 |
-
if ( file_exists( $pofile ) ) {
|
119 |
-
// load po file
|
120 |
-
$podata = file_get_contents($pofile);
|
121 |
-
// set revision date threshold
|
122 |
-
$block_before = strtotime( '2017-05-15' );
|
123 |
-
// read revision date
|
124 |
-
preg_match('~PO-Revision-Date: (.*?)\\\n~s',$podata,$matches);
|
125 |
-
if (isset($matches[1])) {
|
126 |
-
$revision_date = $matches[1];
|
127 |
-
if ( $revision_timestamp = strtotime($revision_date) ) {
|
128 |
-
// check if revision is before threshold date
|
129 |
-
if ( $revision_timestamp < $block_before ) {
|
130 |
-
// try bundled
|
131 |
-
$bundled_file = $this->plugin_path() . '/languages/'. basename( $mofile );
|
132 |
-
if (file_exists($bundled_file)) {
|
133 |
-
return $bundled_file;
|
134 |
-
} else {
|
135 |
-
return '';
|
136 |
-
}
|
137 |
-
// delete po & mo file if possible
|
138 |
-
// @unlink($pofile);
|
139 |
-
// @unlink($mofile);
|
140 |
-
}
|
141 |
-
}
|
142 |
-
}
|
143 |
-
}
|
144 |
-
}
|
145 |
-
|
146 |
-
return $mofile;
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Load the main plugin classes and functions
|
151 |
-
*/
|
152 |
-
public function includes() {
|
153 |
-
// WooCommerce compatibility classes
|
154 |
-
include_once( $this->plugin_path() . '/includes/compatibility/abstract-wc-data-compatibility.php' );
|
155 |
-
include_once( $this->plugin_path() . '/includes/compatibility/class-wc-date-compatibility.php' );
|
156 |
-
include_once( $this->plugin_path() . '/includes/compatibility/class-wc-core-compatibility.php' );
|
157 |
-
include_once( $this->plugin_path() . '/includes/compatibility/class-wc-order-compatibility.php' );
|
158 |
-
include_once( $this->plugin_path() . '/includes/compatibility/class-wc-product-compatibility.php' );
|
159 |
-
include_once( $this->plugin_path() . '/includes/compatibility/wc-datetime-functions-compatibility.php' );
|
160 |
-
|
161 |
-
// Third party compatibility
|
162 |
-
include_once( $this->plugin_path() . '/includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php' );
|
163 |
-
|
164 |
-
// Plugin classes
|
165 |
-
include_once( $this->plugin_path() . '/includes/wcpdf-functions.php' );
|
166 |
-
$this->settings = include_once( $this->plugin_path() . '/includes/class-wcpdf-settings.php' );
|
167 |
-
$this->documents = include_once( $this->plugin_path() . '/includes/class-wcpdf-documents.php' );
|
168 |
-
$this->main = include_once( $this->plugin_path() . '/includes/class-wcpdf-main.php' );
|
169 |
-
include_once( $this->plugin_path() . '/includes/class-wcpdf-assets.php' );
|
170 |
-
include_once( $this->plugin_path() . '/includes/class-wcpdf-admin.php' );
|
171 |
-
include_once( $this->plugin_path() . '/includes/class-wcpdf-frontend.php' );
|
172 |
-
include_once( $this->plugin_path() . '/includes/class-wcpdf-install.php' );
|
173 |
-
|
174 |
-
// Backwards compatibility with self
|
175 |
-
include_once( $this->plugin_path() . '/includes/legacy/class-wcpdf-legacy.php' );
|
176 |
-
include_once( $this->plugin_path() . '/includes/legacy/class-wcpdf-legacy-deprecated-hooks.php' );
|
177 |
-
|
178 |
-
// PHP MB String fallback functions
|
179 |
-
include_once( $this->plugin_path() . '/includes/compatibility/mb-string-compatibility.php' );
|
180 |
-
}
|
181 |
-
|
182 |
-
|
183 |
-
/**
|
184 |
-
* Instantiate classes when woocommerce is activated
|
185 |
-
*/
|
186 |
-
public function load_classes() {
|
187 |
-
if ( $this->is_woocommerce_activated() === false ) {
|
188 |
-
add_action( 'admin_notices', array ( $this, 'need_woocommerce' ) );
|
189 |
-
return;
|
190 |
-
}
|
191 |
-
|
192 |
-
if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
|
193 |
-
add_action( 'admin_notices', array ( $this, 'required_php_version' ) );
|
194 |
-
return;
|
195 |
-
}
|
196 |
-
|
197 |
-
// all systems ready - GO!
|
198 |
-
$this->includes();
|
199 |
-
}
|
200 |
-
|
201 |
-
/**
|
202 |
-
* Check if legacy mode is enabled
|
203 |
-
*/
|
204 |
-
public function legacy_mode_enabled() {
|
205 |
-
if (!isset($this->legacy_mode)) {
|
206 |
-
$debug_settings = get_option( 'wpo_wcpdf_settings_debug' );
|
207 |
-
$this->legacy_mode = isset($debug_settings['legacy_mode']);
|
208 |
-
}
|
209 |
-
return $this->legacy_mode;
|
210 |
-
}
|
211 |
-
|
212 |
-
|
213 |
-
/**
|
214 |
-
* Check if woocommerce is activated
|
215 |
-
*/
|
216 |
-
public function is_woocommerce_activated() {
|
217 |
-
$blog_plugins = get_option( 'active_plugins', array() );
|
218 |
-
$site_plugins = is_multisite() ? (array) maybe_unserialize( get_site_option('active_sitewide_plugins' ) ) : array();
|
219 |
-
|
220 |
-
if ( in_array( 'woocommerce/woocommerce.php', $blog_plugins ) || isset( $site_plugins['woocommerce/woocommerce.php'] ) ) {
|
221 |
-
return true;
|
222 |
-
} else {
|
223 |
-
return false;
|
224 |
-
}
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* WooCommerce not active notice.
|
229 |
-
*
|
230 |
-
* @return string Fallack notice.
|
231 |
-
*/
|
232 |
-
|
233 |
-
public function need_woocommerce() {
|
234 |
-
$error = sprintf( __( 'WooCommerce PDF Invoices & Packing Slips requires %sWooCommerce%s to be installed & activated!' , 'woocommerce-pdf-invoices-packing-slips' ), '<a href="http://wordpress.org/extend/plugins/woocommerce/">', '</a>' );
|
235 |
-
|
236 |
-
$message = '<div class="error"><p>' . $error . '</p></div>';
|
237 |
-
|
238 |
-
echo $message;
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* PHP version requirement notice
|
243 |
-
*/
|
244 |
-
|
245 |
-
public function required_php_version() {
|
246 |
-
$error = __( 'WooCommerce PDF Invoices & Packing Slips requires PHP 5.3 or higher (5.6 or higher recommended).', 'woocommerce-pdf-invoices-packing-slips' );
|
247 |
-
$how_to_update = __( 'How to update your PHP version', 'woocommerce-pdf-invoices-packing-slips' );
|
248 |
-
$message = sprintf('<div class="error"><p>%s</p><p><a href="%s">%s</a></p></div>', $error, 'http://docs.wpovernight.com/general/how-to-update-your-php-version/', $how_to_update);
|
249 |
-
|
250 |
-
echo $message;
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* Show plugin changes. Code adapted from W3 Total Cache.
|
255 |
-
*/
|
256 |
-
public function in_plugin_update_message( $args ) {
|
257 |
-
$transient_name = 'wpo_wcpdf_upgrade_notice_' . $args['Version'];
|
258 |
-
|
259 |
-
if ( false === ( $upgrade_notice = get_transient( $transient_name ) ) ) {
|
260 |
-
$response = wp_safe_remote_get( 'https://plugins.svn.wordpress.org/woocommerce-pdf-invoices-packing-slips/trunk/readme.txt' );
|
261 |
-
|
262 |
-
if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
|
263 |
-
$upgrade_notice = self::parse_update_notice( $response['body'], $args['new_version'] );
|
264 |
-
set_transient( $transient_name, $upgrade_notice, DAY_IN_SECONDS );
|
265 |
-
}
|
266 |
-
}
|
267 |
-
|
268 |
-
echo wp_kses_post( $upgrade_notice );
|
269 |
-
}
|
270 |
-
|
271 |
-
/**
|
272 |
-
* Parse update notice from readme file.
|
273 |
-
*
|
274 |
-
* @param string $content
|
275 |
-
* @param string $new_version
|
276 |
-
* @return string
|
277 |
-
*/
|
278 |
-
private function parse_update_notice( $content, $new_version ) {
|
279 |
-
// Output Upgrade Notice.
|
280 |
-
$matches = null;
|
281 |
-
$regexp = '~==\s*Upgrade Notice\s*==\s*=\s*(.*)\s*=(.*)(=\s*' . preg_quote( $new_version ) . '\s*=|$)~Uis';
|
282 |
-
$upgrade_notice = '';
|
283 |
-
|
284 |
-
|
285 |
-
if ( preg_match( $regexp, $content, $matches ) ) {
|
286 |
-
$notices = (array) preg_split( '~[\r\n]+~', trim( $matches[2] ) );
|
287 |
-
|
288 |
-
// Convert the full version strings to minor versions.
|
289 |
-
$notice_version_parts = explode( '.', trim( $matches[1] ) );
|
290 |
-
$current_version_parts = explode( '.', $this->version );
|
291 |
-
|
292 |
-
if ( 3 !== sizeof( $notice_version_parts ) ) {
|
293 |
-
return;
|
294 |
-
}
|
295 |
-
|
296 |
-
$notice_version = $notice_version_parts[0] . '.' . $notice_version_parts[1];
|
297 |
-
$current_version = $current_version_parts[0] . '.' . $current_version_parts[1];
|
298 |
-
|
299 |
-
// Check the latest stable version and ignore trunk.
|
300 |
-
if ( version_compare( $current_version, $notice_version, '<' ) ) {
|
301 |
-
|
302 |
-
$upgrade_notice .= '</p><p class="wpo_wcpdf_upgrade_notice">';
|
303 |
-
|
304 |
-
foreach ( $notices as $index => $line ) {
|
305 |
-
$upgrade_notice .= preg_replace( '~\[([^\]]*)\]\(([^\)]*)\)~', '<a href="${2}">${1}</a>', $line );
|
306 |
-
}
|
307 |
-
}
|
308 |
-
}
|
309 |
-
|
310 |
-
return wp_kses_post( $upgrade_notice );
|
311 |
-
}
|
312 |
-
|
313 |
-
/**
|
314 |
-
* Get the plugin url.
|
315 |
-
* @return string
|
316 |
-
*/
|
317 |
-
public function plugin_url() {
|
318 |
-
return untrailingslashit( plugins_url( '/', __FILE__ ) );
|
319 |
-
}
|
320 |
-
|
321 |
-
/**
|
322 |
-
* Get the plugin path.
|
323 |
-
* @return string
|
324 |
-
*/
|
325 |
-
public function plugin_path() {
|
326 |
-
return untrailingslashit( plugin_dir_path( __FILE__ ) );
|
327 |
-
}
|
328 |
-
|
329 |
-
} // class WPO_WCPDF
|
330 |
-
|
331 |
-
endif; // class_exists
|
332 |
-
|
333 |
-
/**
|
334 |
-
* Returns the main instance of WooCommerce PDF Invoices & Packing Slips to prevent the need to use globals.
|
335 |
-
*
|
336 |
-
* @since 1.6
|
337 |
-
* @return WPO_WCPDF
|
338 |
-
*/
|
339 |
-
function WPO_WCPDF() {
|
340 |
-
return WPO_WCPDF::instance();
|
341 |
-
}
|
342 |
-
|
343 |
-
WPO_WCPDF(); // load plugin
|
344 |
-
|
345 |
-
// legacy class for plugin detecting
|
346 |
-
if ( !class_exists( 'WooCommerce_PDF_Invoices' ) ) {
|
347 |
-
class WooCommerce_PDF_Invoices{
|
348 |
-
public static $version;
|
349 |
-
|
350 |
-
public function __construct() {
|
351 |
-
self::$version = WPO_WCPDF()->version;
|
352 |
-
}
|
353 |
-
}
|
354 |
-
new WooCommerce_PDF_Invoices();
|
355 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
+
* Plugin URI: http://www.wpovernight.com
|
5 |
+
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
+
* Version: 2.0.8
|
7 |
+
* Author: Ewout Fernhout
|
8 |
+
* Author URI: http://www.wpovernight.com
|
9 |
+
* License: GPLv2 or later
|
10 |
+
* License URI: http://www.opensource.org/licenses/gpl-license.php
|
11 |
+
* Text Domain: woocommerce-pdf-invoices-packing-slips
|
12 |
+
*/
|
13 |
+
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
+
exit; // Exit if accessed directly
|
16 |
+
}
|
17 |
+
|
18 |
+
if ( !class_exists( 'WPO_WCPDF' ) ) :
|
19 |
+
|
20 |
+
class WPO_WCPDF {
|
21 |
+
|
22 |
+
public $version = '2.0.8';
|
23 |
+
public $plugin_basename;
|
24 |
+
public $legacy_mode;
|
25 |
+
|
26 |
+
protected static $_instance = null;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Main Plugin Instance
|
30 |
+
*
|
31 |
+
* Ensures only one instance of plugin is loaded or can be loaded.
|
32 |
+
*/
|
33 |
+
public static function instance() {
|
34 |
+
if ( is_null( self::$_instance ) ) {
|
35 |
+
self::$_instance = new self();
|
36 |
+
}
|
37 |
+
return self::$_instance;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Constructor
|
42 |
+
*/
|
43 |
+
public function __construct() {
|
44 |
+
$this->plugin_basename = plugin_basename(__FILE__);
|
45 |
+
|
46 |
+
$this->define( 'WPO_WCPDF_VERSION', $this->version );
|
47 |
+
|
48 |
+
// load the localisation & classes
|
49 |
+
add_action( 'plugins_loaded', array( $this, 'translations' ) );
|
50 |
+
add_filter( 'load_textdomain_mofile', array( $this, 'textdomain_fallback' ), 10, 2 );
|
51 |
+
add_action( 'plugins_loaded', array( $this, 'load_classes' ), 9 );
|
52 |
+
add_action( 'in_plugin_update_message-'.$this->plugin_basename, array( $this, 'in_plugin_update_message' ) );
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Define constant if not already set
|
57 |
+
* @param string $name
|
58 |
+
* @param string|bool $value
|
59 |
+
*/
|
60 |
+
private function define( $name, $value ) {
|
61 |
+
if ( ! defined( $name ) ) {
|
62 |
+
define( $name, $value );
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Load the translation / textdomain files
|
69 |
+
*
|
70 |
+
* Note: the first-loaded translation file overrides any following ones if the same translation is present
|
71 |
+
*/
|
72 |
+
public function translations() {
|
73 |
+
$locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce-pdf-invoices-packing-slips' );
|
74 |
+
$dir = trailingslashit( WP_LANG_DIR );
|
75 |
+
|
76 |
+
$textdomains = array( 'woocommerce-pdf-invoices-packing-slips' );
|
77 |
+
if ( $this->legacy_mode_enabled() === true ) {
|
78 |
+
$textdomains[] = 'wpo_wcpdf';
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Frontend/global Locale. Looks in:
|
83 |
+
*
|
84 |
+
* - WP_LANG_DIR/woocommerce-pdf-invoices-packing-slips/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
|
85 |
+
* - WP_LANG_DIR/plugins/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
|
86 |
+
* - woocommerce-pdf-invoices-packing-slips-pro/languages/woocommerce-pdf-invoices-packing-slips-LOCALE.mo (which if not found falls back to:)
|
87 |
+
* - WP_LANG_DIR/plugins/woocommerce-pdf-invoices-packing-slips-LOCALE.mo
|
88 |
+
*/
|
89 |
+
foreach ($textdomains as $textdomain) {
|
90 |
+
load_textdomain( $textdomain, $dir . 'woocommerce-pdf-invoices-packing-slips/woocommerce-pdf-invoices-packing-slips-' . $locale . '.mo' );
|
91 |
+
load_textdomain( $textdomain, $dir . 'plugins/woocommerce-pdf-invoices-packing-slips-' . $locale . '.mo' );
|
92 |
+
load_plugin_textdomain( $textdomain, false, dirname( plugin_basename(__FILE__) ) . '/languages' );
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Maintain backwards compatibility with old translation files
|
98 |
+
* Uses old .mo file if it exists in any of the override locations
|
99 |
+
*/
|
100 |
+
public function textdomain_fallback( $mofile, $textdomain ) {
|
101 |
+
$plugin_domain = 'woocommerce-pdf-invoices-packing-slips';
|
102 |
+
$old_domain = 'wpo_wcpdf';
|
103 |
+
|
104 |
+
if ($textdomain == $old_domain) {
|
105 |
+
$textdomain = $plugin_domain;
|
106 |
+
$mofile = str_replace( "{$old_domain}-", "{$textdomain}-", $mofile ); // with trailing dash to target file and not folder
|
107 |
+
}
|
108 |
+
|
109 |
+
if ( $textdomain === $plugin_domain ) {
|
110 |
+
$old_mofile = str_replace( "{$textdomain}-", "{$old_domain}-", $mofile ); // with trailing dash to target file and not folder
|
111 |
+
if ( file_exists( $old_mofile ) ) {
|
112 |
+
// we have an old override - use it
|
113 |
+
return $old_mofile;
|
114 |
+
}
|
115 |
+
|
116 |
+
// prevent loading outdated language packs
|
117 |
+
$pofile = str_replace('.mo', '.po', $mofile);
|
118 |
+
if ( file_exists( $pofile ) ) {
|
119 |
+
// load po file
|
120 |
+
$podata = file_get_contents($pofile);
|
121 |
+
// set revision date threshold
|
122 |
+
$block_before = strtotime( '2017-05-15' );
|
123 |
+
// read revision date
|
124 |
+
preg_match('~PO-Revision-Date: (.*?)\\\n~s',$podata,$matches);
|
125 |
+
if (isset($matches[1])) {
|
126 |
+
$revision_date = $matches[1];
|
127 |
+
if ( $revision_timestamp = strtotime($revision_date) ) {
|
128 |
+
// check if revision is before threshold date
|
129 |
+
if ( $revision_timestamp < $block_before ) {
|
130 |
+
// try bundled
|
131 |
+
$bundled_file = $this->plugin_path() . '/languages/'. basename( $mofile );
|
132 |
+
if (file_exists($bundled_file)) {
|
133 |
+
return $bundled_file;
|
134 |
+
} else {
|
135 |
+
return '';
|
136 |
+
}
|
137 |
+
// delete po & mo file if possible
|
138 |
+
// @unlink($pofile);
|
139 |
+
// @unlink($mofile);
|
140 |
+
}
|
141 |
+
}
|
142 |
+
}
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
return $mofile;
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Load the main plugin classes and functions
|
151 |
+
*/
|
152 |
+
public function includes() {
|
153 |
+
// WooCommerce compatibility classes
|
154 |
+
include_once( $this->plugin_path() . '/includes/compatibility/abstract-wc-data-compatibility.php' );
|
155 |
+
include_once( $this->plugin_path() . '/includes/compatibility/class-wc-date-compatibility.php' );
|
156 |
+
include_once( $this->plugin_path() . '/includes/compatibility/class-wc-core-compatibility.php' );
|
157 |
+
include_once( $this->plugin_path() . '/includes/compatibility/class-wc-order-compatibility.php' );
|
158 |
+
include_once( $this->plugin_path() . '/includes/compatibility/class-wc-product-compatibility.php' );
|
159 |
+
include_once( $this->plugin_path() . '/includes/compatibility/wc-datetime-functions-compatibility.php' );
|
160 |
+
|
161 |
+
// Third party compatibility
|
162 |
+
include_once( $this->plugin_path() . '/includes/compatibility/class-wcpdf-compatibility-third-party-plugins.php' );
|
163 |
+
|
164 |
+
// Plugin classes
|
165 |
+
include_once( $this->plugin_path() . '/includes/wcpdf-functions.php' );
|
166 |
+
$this->settings = include_once( $this->plugin_path() . '/includes/class-wcpdf-settings.php' );
|
167 |
+
$this->documents = include_once( $this->plugin_path() . '/includes/class-wcpdf-documents.php' );
|
168 |
+
$this->main = include_once( $this->plugin_path() . '/includes/class-wcpdf-main.php' );
|
169 |
+
include_once( $this->plugin_path() . '/includes/class-wcpdf-assets.php' );
|
170 |
+
include_once( $this->plugin_path() . '/includes/class-wcpdf-admin.php' );
|
171 |
+
include_once( $this->plugin_path() . '/includes/class-wcpdf-frontend.php' );
|
172 |
+
include_once( $this->plugin_path() . '/includes/class-wcpdf-install.php' );
|
173 |
+
|
174 |
+
// Backwards compatibility with self
|
175 |
+
include_once( $this->plugin_path() . '/includes/legacy/class-wcpdf-legacy.php' );
|
176 |
+
include_once( $this->plugin_path() . '/includes/legacy/class-wcpdf-legacy-deprecated-hooks.php' );
|
177 |
+
|
178 |
+
// PHP MB String fallback functions
|
179 |
+
include_once( $this->plugin_path() . '/includes/compatibility/mb-string-compatibility.php' );
|
180 |
+
}
|
181 |
+
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Instantiate classes when woocommerce is activated
|
185 |
+
*/
|
186 |
+
public function load_classes() {
|
187 |
+
if ( $this->is_woocommerce_activated() === false ) {
|
188 |
+
add_action( 'admin_notices', array ( $this, 'need_woocommerce' ) );
|
189 |
+
return;
|
190 |
+
}
|
191 |
+
|
192 |
+
if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
|
193 |
+
add_action( 'admin_notices', array ( $this, 'required_php_version' ) );
|
194 |
+
return;
|
195 |
+
}
|
196 |
+
|
197 |
+
// all systems ready - GO!
|
198 |
+
$this->includes();
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Check if legacy mode is enabled
|
203 |
+
*/
|
204 |
+
public function legacy_mode_enabled() {
|
205 |
+
if (!isset($this->legacy_mode)) {
|
206 |
+
$debug_settings = get_option( 'wpo_wcpdf_settings_debug' );
|
207 |
+
$this->legacy_mode = isset($debug_settings['legacy_mode']);
|
208 |
+
}
|
209 |
+
return $this->legacy_mode;
|
210 |
+
}
|
211 |
+
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Check if woocommerce is activated
|
215 |
+
*/
|
216 |
+
public function is_woocommerce_activated() {
|
217 |
+
$blog_plugins = get_option( 'active_plugins', array() );
|
218 |
+
$site_plugins = is_multisite() ? (array) maybe_unserialize( get_site_option('active_sitewide_plugins' ) ) : array();
|
219 |
+
|
220 |
+
if ( in_array( 'woocommerce/woocommerce.php', $blog_plugins ) || isset( $site_plugins['woocommerce/woocommerce.php'] ) ) {
|
221 |
+
return true;
|
222 |
+
} else {
|
223 |
+
return false;
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* WooCommerce not active notice.
|
229 |
+
*
|
230 |
+
* @return string Fallack notice.
|
231 |
+
*/
|
232 |
+
|
233 |
+
public function need_woocommerce() {
|
234 |
+
$error = sprintf( __( 'WooCommerce PDF Invoices & Packing Slips requires %sWooCommerce%s to be installed & activated!' , 'woocommerce-pdf-invoices-packing-slips' ), '<a href="http://wordpress.org/extend/plugins/woocommerce/">', '</a>' );
|
235 |
+
|
236 |
+
$message = '<div class="error"><p>' . $error . '</p></div>';
|
237 |
+
|
238 |
+
echo $message;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* PHP version requirement notice
|
243 |
+
*/
|
244 |
+
|
245 |
+
public function required_php_version() {
|
246 |
+
$error = __( 'WooCommerce PDF Invoices & Packing Slips requires PHP 5.3 or higher (5.6 or higher recommended).', 'woocommerce-pdf-invoices-packing-slips' );
|
247 |
+
$how_to_update = __( 'How to update your PHP version', 'woocommerce-pdf-invoices-packing-slips' );
|
248 |
+
$message = sprintf('<div class="error"><p>%s</p><p><a href="%s">%s</a></p></div>', $error, 'http://docs.wpovernight.com/general/how-to-update-your-php-version/', $how_to_update);
|
249 |
+
|
250 |
+
echo $message;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Show plugin changes. Code adapted from W3 Total Cache.
|
255 |
+
*/
|
256 |
+
public function in_plugin_update_message( $args ) {
|
257 |
+
$transient_name = 'wpo_wcpdf_upgrade_notice_' . $args['Version'];
|
258 |
+
|
259 |
+
if ( false === ( $upgrade_notice = get_transient( $transient_name ) ) ) {
|
260 |
+
$response = wp_safe_remote_get( 'https://plugins.svn.wordpress.org/woocommerce-pdf-invoices-packing-slips/trunk/readme.txt' );
|
261 |
+
|
262 |
+
if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
|
263 |
+
$upgrade_notice = self::parse_update_notice( $response['body'], $args['new_version'] );
|
264 |
+
set_transient( $transient_name, $upgrade_notice, DAY_IN_SECONDS );
|
265 |
+
}
|
266 |
+
}
|
267 |
+
|
268 |
+
echo wp_kses_post( $upgrade_notice );
|
269 |
+
}
|
270 |
+
|
271 |
+
/**
|
272 |
+
* Parse update notice from readme file.
|
273 |
+
*
|
274 |
+
* @param string $content
|
275 |
+
* @param string $new_version
|
276 |
+
* @return string
|
277 |
+
*/
|
278 |
+
private function parse_update_notice( $content, $new_version ) {
|
279 |
+
// Output Upgrade Notice.
|
280 |
+
$matches = null;
|
281 |
+
$regexp = '~==\s*Upgrade Notice\s*==\s*=\s*(.*)\s*=(.*)(=\s*' . preg_quote( $new_version ) . '\s*=|$)~Uis';
|
282 |
+
$upgrade_notice = '';
|
283 |
+
|
284 |
+
|
285 |
+
if ( preg_match( $regexp, $content, $matches ) ) {
|
286 |
+
$notices = (array) preg_split( '~[\r\n]+~', trim( $matches[2] ) );
|
287 |
+
|
288 |
+
// Convert the full version strings to minor versions.
|
289 |
+
$notice_version_parts = explode( '.', trim( $matches[1] ) );
|
290 |
+
$current_version_parts = explode( '.', $this->version );
|
291 |
+
|
292 |
+
if ( 3 !== sizeof( $notice_version_parts ) ) {
|
293 |
+
return;
|
294 |
+
}
|
295 |
+
|
296 |
+
$notice_version = $notice_version_parts[0] . '.' . $notice_version_parts[1];
|
297 |
+
$current_version = $current_version_parts[0] . '.' . $current_version_parts[1];
|
298 |
+
|
299 |
+
// Check the latest stable version and ignore trunk.
|
300 |
+
if ( version_compare( $current_version, $notice_version, '<' ) ) {
|
301 |
+
|
302 |
+
$upgrade_notice .= '</p><p class="wpo_wcpdf_upgrade_notice">';
|
303 |
+
|
304 |
+
foreach ( $notices as $index => $line ) {
|
305 |
+
$upgrade_notice .= preg_replace( '~\[([^\]]*)\]\(([^\)]*)\)~', '<a href="${2}">${1}</a>', $line );
|
306 |
+
}
|
307 |
+
}
|
308 |
+
}
|
309 |
+
|
310 |
+
return wp_kses_post( $upgrade_notice );
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Get the plugin url.
|
315 |
+
* @return string
|
316 |
+
*/
|
317 |
+
public function plugin_url() {
|
318 |
+
return untrailingslashit( plugins_url( '/', __FILE__ ) );
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Get the plugin path.
|
323 |
+
* @return string
|
324 |
+
*/
|
325 |
+
public function plugin_path() {
|
326 |
+
return untrailingslashit( plugin_dir_path( __FILE__ ) );
|
327 |
+
}
|
328 |
+
|
329 |
+
} // class WPO_WCPDF
|
330 |
+
|
331 |
+
endif; // class_exists
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Returns the main instance of WooCommerce PDF Invoices & Packing Slips to prevent the need to use globals.
|
335 |
+
*
|
336 |
+
* @since 1.6
|
337 |
+
* @return WPO_WCPDF
|
338 |
+
*/
|
339 |
+
function WPO_WCPDF() {
|
340 |
+
return WPO_WCPDF::instance();
|
341 |
+
}
|
342 |
+
|
343 |
+
WPO_WCPDF(); // load plugin
|
344 |
+
|
345 |
+
// legacy class for plugin detecting
|
346 |
+
if ( !class_exists( 'WooCommerce_PDF_Invoices' ) ) {
|
347 |
+
class WooCommerce_PDF_Invoices{
|
348 |
+
public static $version;
|
349 |
+
|
350 |
+
public function __construct() {
|
351 |
+
self::$version = WPO_WCPDF()->version;
|
352 |
+
}
|
353 |
+
}
|
354 |
+
new WooCommerce_PDF_Invoices();
|
355 |
+
}
|