Version Description
- Fix: Minor XSS issue on settings screens by escaping and sanitizing 'tab' & 'section' GET variables. Discovered by Detectify.
- Fix: Pakistani Rupee Symbol
- Feature: Automatically enable extended currency symbol support for currencies not supported by Open Sans
- Dev: added
wpo_wcpdf_document_number_settings
filter
Download this release
Release Info
Developer | pomegranate |
Plugin | ![]() |
Version | 2.0.13 |
Comparing to | |
See all releases |
Code changes from version 2.0.12 to 2.0.13
- includes/class-wcpdf-install.php +48 -1
- includes/class-wcpdf-main.php +3 -3
- includes/class-wcpdf-settings.php +254 -254
- includes/documents/abstract-wcpdf-order-document.php +676 -676
- includes/views/wcpdf-settings-page.php +51 -50
- readme.txt +8 -2
- vendor/dompdf/dompdf/lib/fonts/currencies.ttf +0 -0
- woocommerce-pdf-invoices-packingslips.php +2 -2
includes/class-wcpdf-install.php
CHANGED
@@ -80,12 +80,59 @@ class Install {
|
|
80 |
WPO_WCPDF()->main->init_tmp( $tmp_base );
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
// set default settings
|
84 |
$settings_defaults = array(
|
85 |
'wpo_wcpdf_settings_general' => array(
|
86 |
'download_display' => 'display',
|
87 |
'template_path' => WPO_WCPDF()->plugin_path() . '/templates/Simple',
|
88 |
-
|
89 |
'paper_size' => 'a4',
|
90 |
// 'header_logo' => '',
|
91 |
// 'shop_name' => array(),
|
80 |
WPO_WCPDF()->main->init_tmp( $tmp_base );
|
81 |
}
|
82 |
|
83 |
+
// Unsupported currency symbols
|
84 |
+
$unsupported_symbols = array (
|
85 |
+
'AED',
|
86 |
+
'AFN',
|
87 |
+
'BDT',
|
88 |
+
'BHD',
|
89 |
+
'BTC',
|
90 |
+
'CRC',
|
91 |
+
'DZD',
|
92 |
+
'GEL',
|
93 |
+
'GHS',
|
94 |
+
'ILS',
|
95 |
+
'INR',
|
96 |
+
'IQD',
|
97 |
+
'IRR',
|
98 |
+
'IRT',
|
99 |
+
'JOD',
|
100 |
+
'KHR',
|
101 |
+
'KPW',
|
102 |
+
'KRW',
|
103 |
+
'KWD',
|
104 |
+
'LAK',
|
105 |
+
'LBP',
|
106 |
+
'LKR',
|
107 |
+
'LYD',
|
108 |
+
'MAD',
|
109 |
+
'MNT',
|
110 |
+
'MUR',
|
111 |
+
'MVR',
|
112 |
+
'NPR',
|
113 |
+
'OMR',
|
114 |
+
'PHP',
|
115 |
+
'PKR',
|
116 |
+
'PYG',
|
117 |
+
'QAR',
|
118 |
+
'RUB',
|
119 |
+
'SAR',
|
120 |
+
'SCR',
|
121 |
+
'SDG',
|
122 |
+
'SYP',
|
123 |
+
'THB',
|
124 |
+
'TND',
|
125 |
+
'TRY',
|
126 |
+
'UAH',
|
127 |
+
'YER',
|
128 |
+
);
|
129 |
+
|
130 |
// set default settings
|
131 |
$settings_defaults = array(
|
132 |
'wpo_wcpdf_settings_general' => array(
|
133 |
'download_display' => 'display',
|
134 |
'template_path' => WPO_WCPDF()->plugin_path() . '/templates/Simple',
|
135 |
+
'currency_font' => ( in_array( get_woocommerce_currency(), $unsupported_symbols ) ) ? 1 : '',
|
136 |
'paper_size' => 'a4',
|
137 |
// 'header_logo' => '',
|
138 |
// 'shop_name' => array(),
|
includes/class-wcpdf-main.php
CHANGED
@@ -161,11 +161,11 @@ class Main {
|
|
161 |
}
|
162 |
|
163 |
// Generate the output
|
164 |
-
$document_type = $_GET['document_type'];
|
165 |
|
166 |
-
$order_ids = (array) explode('x'
|
167 |
// Process oldest first: reverse $order_ids array
|
168 |
-
$order_ids = array_reverse($order_ids);
|
169 |
|
170 |
// set default is allowed
|
171 |
$allowed = true;
|
161 |
}
|
162 |
|
163 |
// Generate the output
|
164 |
+
$document_type = sanitize_text_field( $_GET['document_type'] );
|
165 |
|
166 |
+
$order_ids = (array) array_map( 'absint', explode( 'x', $_GET['order_ids'] ) );
|
167 |
// Process oldest first: reverse $order_ids array
|
168 |
+
$order_ids = array_reverse( $order_ids );
|
169 |
|
170 |
// set default is allowed
|
171 |
$allowed = true;
|
includes/class-wcpdf-settings.php
CHANGED
@@ -1,255 +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 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();
|
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' ] ) ? sanitize_text_field( $_GET[ 'tab' ] ) : 'general';
|
104 |
+
$active_section = isset( $_GET[ 'section' ] ) ? sanitize_text_field( $_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/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 apply_filters( 'wpo_wcpdf_document_number_settings', $number_settings, $this );
|
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/views/wcpdf-settings-page.php
CHANGED
@@ -1,50 +1,51 @@
|
|
1 |
-
<script type="text/javascript">
|
2 |
-
jQuery( function( $ ) {
|
3 |
-
$("#footer-thankyou").html("If you like <strong>WooCommerce PDF Invoices & Packing Slips</strong> please leave us a <a href='https://wordpress.org/support/view/plugin-reviews/woocommerce-pdf-invoices-packing-slips?rate=5#postform'>★★★★★</a> rating. A huge thank you in advance!");
|
4 |
-
});
|
5 |
-
</script>
|
6 |
-
<div class="wrap">
|
7 |
-
<div class="icon32" id="icon-options-general"><br /></div>
|
8 |
-
<h2><?php _e( 'WooCommerce PDF Invoices', 'woocommerce-pdf-invoices-packing-slips' ); ?></h2>
|
9 |
-
<h2 class="nav-tab-wrapper">
|
10 |
-
<?php
|
11 |
-
foreach ($settings_tabs as $tab_slug => $tab_title ) {
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
|
1 |
+
<script type="text/javascript">
|
2 |
+
jQuery( function( $ ) {
|
3 |
+
$("#footer-thankyou").html("If you like <strong>WooCommerce PDF Invoices & Packing Slips</strong> please leave us a <a href='https://wordpress.org/support/view/plugin-reviews/woocommerce-pdf-invoices-packing-slips?rate=5#postform'>★★★★★</a> rating. A huge thank you in advance!");
|
4 |
+
});
|
5 |
+
</script>
|
6 |
+
<div class="wrap">
|
7 |
+
<div class="icon32" id="icon-options-general"><br /></div>
|
8 |
+
<h2><?php _e( 'WooCommerce PDF Invoices', 'woocommerce-pdf-invoices-packing-slips' ); ?></h2>
|
9 |
+
<h2 class="nav-tab-wrapper">
|
10 |
+
<?php
|
11 |
+
foreach ($settings_tabs as $tab_slug => $tab_title ) {
|
12 |
+
$tab_link = esc_url("?page=wpo_wcpdf_options_page&tab={$tab_slug}");
|
13 |
+
printf('<a href="%1$s" class="nav-tab nav-tab-%2$s %3$s">%4$s</a>', $tab_link, $tab_slug, (($active_tab == $tab_slug) ? 'nav-tab-active' : ''), $tab_title);
|
14 |
+
}
|
15 |
+
?>
|
16 |
+
</h2>
|
17 |
+
|
18 |
+
<?php
|
19 |
+
do_action( 'wpo_wcpdf_before_settings_page', $active_tab, $active_section );
|
20 |
+
|
21 |
+
// save or check option to hide extensions ad
|
22 |
+
if ( isset( $_GET['wpo_wcpdf_hide_extensions_ad'] ) ) {
|
23 |
+
update_option( 'wpo_wcpdf_hide_extensions_ad', true );
|
24 |
+
$hide_ad = true;
|
25 |
+
} else {
|
26 |
+
$hide_ad = get_option( 'wpo_wcpdf_hide_extensions_ad' );
|
27 |
+
}
|
28 |
+
|
29 |
+
if ( !$hide_ad && !( class_exists('WooCommerce_PDF_IPS_Pro') && class_exists('WooCommerce_PDF_IPS_Dropbox') && class_exists('WooCommerce_PDF_IPS_Templates') && class_exists('WooCommerce_Ext_PrintOrders') ) ) {
|
30 |
+
include('wcpdf-extensions.php');
|
31 |
+
}
|
32 |
+
|
33 |
+
?>
|
34 |
+
<form method="post" action="options.php" id="wpo-wcpdf-settings" class="<?php echo "{$active_tab} {$active_section}"; ?>">
|
35 |
+
<?php
|
36 |
+
do_action( 'wpo_wcpdf_before_settings', $active_tab, $active_section );
|
37 |
+
if ( has_action( 'wpo_wcpdf_settings_output_'.$active_tab ) ) {
|
38 |
+
do_action( 'wpo_wcpdf_settings_output_'.$active_tab, $active_section );
|
39 |
+
} else {
|
40 |
+
// legacy settings
|
41 |
+
settings_fields( "wpo_wcpdf_{$active_tab}_settings" );
|
42 |
+
do_settings_sections( "wpo_wcpdf_{$active_tab}_settings" );
|
43 |
+
|
44 |
+
submit_button();
|
45 |
+
}
|
46 |
+
do_action( 'wpo_wcpdf_after_settings', $active_tab, $active_section );
|
47 |
+
?>
|
48 |
+
|
49 |
+
</form>
|
50 |
+
<?php do_action( 'wpo_wcpdf_after_settings_page', $active_tab, $active_section ); ?>
|
51 |
+
</div>
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-
|
|
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 |
|
@@ -104,6 +104,12 @@ There's a setting on the Status tab of the settings page that allows you to togg
|
|
104 |
|
105 |
**2.0 is a BIG update! Make a full site backup before upgrading**
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
= 2.0.12 =
|
108 |
* Option: Use different HTML parser (debug settings)
|
109 |
|
@@ -192,5 +198,5 @@ There's a setting on the Status tab of the settings page that allows you to togg
|
|
192 |
|
193 |
== Upgrade Notice ==
|
194 |
|
195 |
-
= 2.0.
|
196 |
**2.0 is a BIG update! Make a full site backup before upgrading!**
|
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.13
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
104 |
|
105 |
**2.0 is a BIG update! Make a full site backup before upgrading**
|
106 |
|
107 |
+
= 2.0.13 =
|
108 |
+
* Fix: Minor XSS issue on settings screens by escaping and sanitizing 'tab' & 'section' GET variables. Discovered by Detectify.
|
109 |
+
* Fix: Pakistani Rupee Symbol
|
110 |
+
* Feature: Automatically enable extended currency symbol support for currencies not supported by Open Sans
|
111 |
+
* Dev: added `wpo_wcpdf_document_number_settings` filter
|
112 |
+
|
113 |
= 2.0.12 =
|
114 |
* Option: Use different HTML parser (debug settings)
|
115 |
|
198 |
|
199 |
== Upgrade Notice ==
|
200 |
|
201 |
+
= 2.0.13 =
|
202 |
**2.0 is a BIG update! Make a full site backup before upgrading!**
|
vendor/dompdf/dompdf/lib/fonts/currencies.ttf
CHANGED
Binary file
|
woocommerce-pdf-invoices-packingslips.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
* Plugin URI: http://www.wpovernight.com
|
5 |
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
-
* Version: 2.0.
|
7 |
* Author: Ewout Fernhout
|
8 |
* Author URI: http://www.wpovernight.com
|
9 |
* License: GPLv2 or later
|
@@ -19,7 +19,7 @@ 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 |
|
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.13
|
7 |
* Author: Ewout Fernhout
|
8 |
* Author URI: http://www.wpovernight.com
|
9 |
* License: GPLv2 or later
|
19 |
|
20 |
class WPO_WCPDF {
|
21 |
|
22 |
+
public $version = '2.0.13';
|
23 |
public $plugin_basename;
|
24 |
public $legacy_mode;
|
25 |
|