Booster for WooCommerce - Version 2.4.5

Version Description

  • 06/04/2016 =
  • Dev - K_TCPDF_THROW_EXCEPTION_ERROR "is defined" check added to tcpdf_config.php file.
  • Dev - Default type added to WCJ_Module::create_meta_box() (works for text type).
  • Fix - Shortcodes - General - [wcj_get_left_to_free_shipping] bug fixed.
  • Dev - Shortcodes - General - [wcj_currency_select_link_list] shortcode added.
  • Dev - Shortcodes - General - [wcj_currency_select_radio_list] shortcode added.
  • Fix - Shortcodes - Orders - [wcj_order_checkout_field] - field_id string conversion added.
  • Fix - Widgets - Multicurrency Switcher - Default title value set to blank.
  • Dev - Widgets - Multicurrency Switcher - "Switcher type" options added.
  • Fix - PRICES & CURRENCIES - Prices and Currencies by Country - Wrong currency in emails bug fixed (again).
  • Fix - PRICES & CURRENCIES - Prices and Currencies by Country - Main price empty (or Call for Price) bug fixed.
  • Dev - PRODUCTS - SKU - Description tip added to "Variable Products Variations" option.
  • Fix - PRODUCTS - Product Input Fields - File type field - "Leave blank to accept all files" bug fixed.
  • Fix - PRODUCTS - Product Input Fields - File type field - Adding from archive bug fixed.
  • Dev - PRODUCTS - Product Cost Price - "Affiliate commission" optional field added (also affected WCJ_Product class).
  • Dev - PRODUCTS - Product Cost Price - Options to enable/disable fields added (also affected functions in WCJ_Module and WCJ_Product classes).
  • Dev - PRODUCTS - Product Cost Price - wcj_purchase_data_product_options and wcj_get_product_purchase_price filters added (second filter added to WCJ_Product class).
  • Dev - PRODUCTS - Product Cost Price - Variable products support added.
  • Dev - PRODUCTS - Product Cost Price - Code refactoring.
  • Dev - CART & CHECKOUT - Checkout Custom Fields - Custom fields added to user profile and to checkout page defaults.
  • Dev - CART & CHECKOUT - Checkout Files Upload - Initial module release.
  • Dev - EMAILS & MISC. - Emails - "New order (Status)" triggers added to custom emails.
Download this release

Release Info

Developer algoritmika
Plugin Icon 128x128 Booster for WooCommerce
Version 2.4.5
Comparing to
See all releases

Code changes from version 2.4.4 to 2.4.5

includes/admin/wcj-modules-cats.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Modules Array.
6
  *
7
- * @version 2.4.3
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -74,6 +74,7 @@ return array(
74
  'mini_cart',
75
  'checkout_core_fields',
76
  'checkout_custom_fields',
 
77
  'checkout_custom_info',
78
  ),
79
  ),
4
  *
5
  * The WooCommerce Modules Array.
6
  *
7
+ * @version 2.4.5
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
74
  'mini_cart',
75
  'checkout_core_fields',
76
  'checkout_custom_fields',
77
+ 'checkout_files_upload',
78
  'checkout_custom_info',
79
  ),
80
  ),
includes/class-wcj-checkout-custom-fields.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Checkout Custom Fields class.
6
  *
7
- * @version 2.4.0
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -17,7 +17,7 @@ class WCJ_Checkout_Custom_Fields extends WCJ_Module {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.3.0
21
  */
22
  function __construct() {
23
 
@@ -50,7 +50,54 @@ class WCJ_Checkout_Custom_Fields extends WCJ_Module {
50
 
51
  // add_filter( 'woocommerce_form_field_' . 'number', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
52
  add_filter( 'woocommerce_form_field_' . 'text', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
 
54
  }
55
 
56
  /**
4
  *
5
  * The WooCommerce Jetpack Checkout Custom Fields class.
6
  *
7
+ * @version 2.4.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 2.4.5
21
  */
22
  function __construct() {
23
 
50
 
51
  // add_filter( 'woocommerce_form_field_' . 'number', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
52
  add_filter( 'woocommerce_form_field_' . 'text', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
53
+
54
+ add_filter( 'woocommerce_customer_meta_fields', array( $this, 'add_checkout_custom_fields_customer_meta_fields' ) );
55
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
56
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
57
+ $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
58
+ $the_key = 'wcj_checkout_field_' . $i;
59
+ $the_name = $the_section . '_' . $the_key;
60
+ add_filter( 'default_checkout_' . $the_name, array( $this, 'add_default_checkout_custom_fields' ), PHP_INT_MAX, 2 );
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * add_checkout_custom_fields_customer_meta_fields.
68
+ *
69
+ * @version 2.4.5
70
+ * @since 2.4.5
71
+ */
72
+ function add_checkout_custom_fields_customer_meta_fields( $fields ) {
73
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
74
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
75
+ $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
76
+ $the_key = 'wcj_checkout_field_' . $i;
77
+ $the_name = $the_section . '_' . $the_key;
78
+ $fields[ $the_section ]['fields'][ $the_name ] = array(
79
+ 'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
80
+ 'description' => '',
81
+ );
82
+ }
83
+ }
84
+ return $fields;
85
+ }
86
+
87
+ /**
88
+ * add_default_checkout_custom_fields.
89
+ *
90
+ * @version 2.4.5
91
+ * @since 2.4.5
92
+ */
93
+ function add_default_checkout_custom_fields( $default_value, $field_key ) {
94
+ if ( is_user_logged_in() ) {
95
+ $current_user = wp_get_current_user();
96
+ if ( $meta = get_user_meta( $current_user->ID, $field_key, true ) ) {
97
+ return $meta;
98
+ }
99
  }
100
+ return $default_value;
101
  }
102
 
103
  /**
includes/class-wcj-checkout-files-upload.php ADDED
@@ -0,0 +1,472 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce Jetpack Checkout Files Upload
4
+ *
5
+ * The WooCommerce Jetpack Checkout Files Upload class.
6
+ *
7
+ * @version 2.4.5
8
+ * @since 2.4.5
9
+ * @author Algoritmika Ltd.
10
+ */
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) exit;
13
+
14
+ if ( ! class_exists( 'WCJ_Checkout_Files_Upload' ) ) :
15
+
16
+ class WCJ_Checkout_Files_Upload extends WCJ_Module {
17
+
18
+ /**
19
+ * Constructor.
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'checkout_files_upload';
24
+ $this->short_desc = __( 'Checkout Files Upload', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Let customers upload files on WooCommerce checkout.', 'woocommerce-jetpack' );
26
+ parent::__construct();
27
+
28
+ if ( $this->is_enabled() ) {
29
+ add_action( 'add_meta_boxes', array( $this, 'add_file_admin_order_meta_box' ) );
30
+ add_action( 'init', array( $this, 'process_checkout_files_upload' ) );
31
+ /* add_action(
32
+ get_option( 'wcj_checkout_files_upload_hook', 'woocommerce_before_checkout_form' ),
33
+ array( $this, 'add_files_upload_form_to_checkout_frontend' )
34
+ ); */
35
+ $total_number = apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
36
+ for ( $i = 1; $i <= $total_number; $i++ ) {
37
+ add_action(
38
+ get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ),
39
+ array( $this, 'add_files_upload_form_to_checkout_frontend' ),
40
+ get_option( 'wcj_checkout_files_upload_hook_priority_' . $i, 10 )
41
+ );
42
+ }
43
+ add_action( 'woocommerce_checkout_order_processed', array( $this, 'add_files_to_order' ), PHP_INT_MAX, 2 );
44
+ add_action( 'woocommerce_after_checkout_validation', array( $this, 'validate' ) );
45
+ }
46
+ }
47
+
48
+ /**
49
+ * validate.
50
+ */
51
+ function validate( $posted ) {
52
+ $total_number = apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
53
+ for ( $i = 1; $i <= $total_number; $i++ ) {
54
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_required_' . $i, 'no' ) && ! isset( $_SESSION[ 'wcj_checkout_files_upload_' . $i ] ) ) {
55
+ // Is required
56
+ wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_required_' . $i, __( 'File is required!', 'woocommerce-jetpack' ) ), 'error' );
57
+ }
58
+ if ( '' != ( $file_accept = get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) ) && isset( $_SESSION[ 'wcj_checkout_files_upload_' . $i ] ) ) {
59
+ // Validate file type
60
+ $file_accept = explode( ',', $file_accept );
61
+ if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
62
+ $file_name = $_SESSION[ 'wcj_checkout_files_upload_' . $i ]['name'];
63
+ $file_type = '.' . pathinfo( $file_name, PATHINFO_EXTENSION );
64
+ if ( ! in_array( $file_type, $file_accept ) ) {
65
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
66
+ __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $file_name ), 'error' );
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+
73
+ /**
74
+ * add_file_admin_order_meta_box.
75
+ */
76
+ function add_file_admin_order_meta_box() {
77
+ $screen = 'shop_order';
78
+ $context = 'side';
79
+ $priority = 'high';
80
+ add_meta_box(
81
+ 'wc-jetpack-' . $this->id,
82
+ __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Uploaded Files', 'woocommerce-jetpack' ),
83
+ array( $this, 'create_file_admin_order_meta_box' ),
84
+ $screen,
85
+ $context,
86
+ $priority
87
+ );
88
+ }
89
+
90
+ /**
91
+ * create_file_admin_order_meta_box.
92
+ */
93
+ function create_file_admin_order_meta_box() {
94
+ $order_id = get_the_ID();
95
+ $html = '';
96
+ $total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
97
+ for ( $i = 1; $i <= $total_files; $i++ ) {
98
+ $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
99
+ $real_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
100
+ if ( '' != $order_file_name ) {
101
+ $html .= '<p><a href="' . add_query_arg(
102
+ array(
103
+ 'wcj_download_checkout_file_admin' => $order_file_name,
104
+ 'wcj_checkout_file_number' => $i,
105
+ ) ) . '">' . $real_file_name . '</a></p>';
106
+ }
107
+ }
108
+ echo $html;
109
+ }
110
+
111
+ /**
112
+ * add_files_to_order.
113
+ */
114
+ function add_files_to_order( $order_id, $posted ) {
115
+ $upload_dir = wcj_get_wcj_uploads_dir( 'checkout_files_upload' );
116
+ if ( ! file_exists( $upload_dir ) ) {
117
+ mkdir( $upload_dir, 0755, true );
118
+ }
119
+ $total_number = apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
120
+ for ( $i = 1; $i <= $total_number; $i++ ) {
121
+ if ( isset( $_SESSION[ 'wcj_checkout_files_upload_' . $i ] ) ) {
122
+ $file_name = $_SESSION[ 'wcj_checkout_files_upload_' . $i ]['name'];
123
+ $ext = pathinfo( $file_name, PATHINFO_EXTENSION );
124
+ $download_file_name = $order_id . '_' . $i . '.' . $ext;
125
+ $file_path = $upload_dir . '/' . $download_file_name;
126
+ $tmp_file_name = $_SESSION[ 'wcj_checkout_files_upload_' . $i ]['tmp_name'];
127
+ $file_data = file_get_contents( $tmp_file_name );
128
+ file_put_contents( $file_path, $file_data );
129
+ unlink( $tmp_file_name );
130
+ unset( $_SESSION[ 'wcj_checkout_files_upload_' . $i ] );
131
+ update_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, $download_file_name );
132
+ update_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, $file_name );
133
+ }
134
+ }
135
+ update_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', $total_number );
136
+ }
137
+
138
+ /**
139
+ * process_checkout_files_upload.
140
+ */
141
+ function process_checkout_files_upload() {
142
+ if ( ! session_id() ) {
143
+ session_start();
144
+ }
145
+ // Remove file
146
+ $total_number = apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
147
+ for ( $i = 1; $i <= $total_number; $i++ ) {
148
+ if ( isset( $_POST[ 'wcj_remove_checkout_file_' . $i ] ) ) {
149
+ $file_name = 'wcj_checkout_files_upload_' . $i;
150
+ unlink( $_SESSION[ $file_name ]['tmp_name'] );
151
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
152
+ __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $_SESSION[ $file_name ]['name'] ) );
153
+ unset( $_SESSION[ $file_name ] );
154
+ }
155
+ }
156
+ // Upload file
157
+ for ( $i = 1; $i <= $total_number; $i++ ) {
158
+ if ( isset( $_POST[ 'wcj_upload_checkout_file_' . $i ] ) ) {
159
+ $file_name = 'wcj_checkout_files_upload_' . $i;
160
+ if ( isset( $_FILES[ $file_name ] ) && '' != $_FILES[ $file_name ]['tmp_name'] ) {
161
+ $_SESSION[ $file_name ] = $_FILES[ $file_name ];
162
+ $tmp_dest_file = tempnam( sys_get_temp_dir(), 'wcj' );
163
+ move_uploaded_file( $_SESSION[ $file_name ]['tmp_name'], $tmp_dest_file );
164
+ $_SESSION[ $file_name ]['tmp_name'] = $tmp_dest_file;
165
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_upload_' . $i,
166
+ __( 'File "%s" was successfully uploaded.', 'woocommerce-jetpack' ) ), $_SESSION[ $file_name ]['name'] ) );
167
+ } else {
168
+ wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_upload_no_file_' . $i,
169
+ __( 'Please select file to upload!', 'woocommerce-jetpack' ) ), 'notice' );
170
+ }
171
+ }
172
+ }
173
+ // Admin file download
174
+ if ( isset( $_GET['wcj_download_checkout_file_admin'] ) ) {
175
+ $tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $_GET['wcj_download_checkout_file_admin'];
176
+ $file_name = get_post_meta( $_GET['post'], '_' . 'wcj_checkout_files_upload_real_name_' . $_GET['wcj_checkout_file_number'], true );
177
+ if ( is_super_admin() || is_shop_manager() ) {
178
+ header( "Expires: 0" );
179
+ header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
180
+ header( "Cache-Control: private", false );
181
+ header( 'Content-disposition: attachment; filename=' . $file_name );
182
+ header( "Content-Transfer-Encoding: binary" );
183
+ header( "Content-Length: ". filesize( $tmp_file_name ) );
184
+ readfile( $tmp_file_name );
185
+ exit();
186
+ }
187
+ }
188
+ // User file download
189
+ if ( isset( $_GET['wcj_download_checkout_file'] ) ) {
190
+ $tmp_file_name = $_SESSION[ $_GET['wcj_download_checkout_file'] ]['tmp_name'];
191
+ $file_name = $_SESSION[ $_GET['wcj_download_checkout_file'] ]['name'];
192
+ header( "Expires: 0" );
193
+ header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
194
+ header( "Cache-Control: private", false );
195
+ header( 'Content-disposition: attachment; filename=' . $file_name );
196
+ header( "Content-Transfer-Encoding: binary" );
197
+ header( "Content-Length: ". filesize( $tmp_file_name ) );
198
+ readfile( $tmp_file_name );
199
+ exit();
200
+ }
201
+ /* // Upload all files
202
+ if ( isset( $_POST['wcj_checkout_files_upload_submit'] ) ) {
203
+ $total_number = apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
204
+ for ( $i = 1; $i <= $total_number; $i++ ) {
205
+ $file_name = 'wcj_checkout_files_upload_' . $i;
206
+ if ( isset( $_FILES[ $file_name ] ) && '' != $_FILES[ $file_name ]['tmp_name'] ) {
207
+ $_SESSION[ $file_name ] = $_FILES[ $file_name ];
208
+ $tmp_dest_file = tempnam( sys_get_temp_dir(), 'wcj' );
209
+ move_uploaded_file( $_SESSION[ $file_name ]['tmp_name'], $tmp_dest_file );
210
+ $_SESSION[ $file_name ]['tmp_name'] = $tmp_dest_file;
211
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_upload_' . $i,
212
+ __( 'File "%s" was successfully uploaded.', 'woocommerce-jetpack' ) ), $_SESSION[ $file_name ]['name'] ) );
213
+ }
214
+ }
215
+ } */
216
+ }
217
+
218
+ /**
219
+ * add_files_upload_form_to_checkout_frontend.
220
+ */
221
+ function add_files_upload_form_to_checkout_frontend() {
222
+ $html = '';
223
+ // $html .= '<form enctype="multipart/form-data" action="" method="POST">';
224
+ $total_number = apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
225
+ // $html .= '<table>';
226
+ $current_filter = current_filter();
227
+ // $current_filter_priority = current_filter_priority();
228
+ global $wp_filter;
229
+ $current_filter_priority = key( $wp_filter[ current_filter() ] );
230
+ for ( $i = 1; $i <= $total_number; $i++ ) {
231
+ if (
232
+ 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) &&
233
+ $current_filter === get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) &&
234
+ $current_filter_priority == get_option( 'wcj_checkout_files_upload_hook_priority_' . $i, 10 )
235
+ ) {
236
+ $html .= '<form enctype="multipart/form-data" action="" method="POST">';
237
+ $html .= '<table>';
238
+ if ( '' != ( $the_label = get_option( 'wcj_checkout_files_upload_label_' . $i, '' ) ) ) {
239
+ $html .= '<tr>';
240
+ $html .= '<td colspan="2">';
241
+ $html .= '<label for="wcj_checkout_files_upload_' . $i . '">' . $the_label . '</label>';
242
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_required_' . $i, 'no' ) ) {
243
+ $html .= '&nbsp;<abbr class="required" title="required">*</abbr>';
244
+ }
245
+ $html .= '</td>';
246
+ $html .= '</tr>';
247
+ }
248
+ if ( ! isset( $_SESSION[ 'wcj_checkout_files_upload_' . $i ] ) ) {
249
+ $html .= '<tr>';
250
+ $html .= '<td style="width:50%;">';
251
+ $html .= '<input type="file" name="wcj_checkout_files_upload_' . $i . '" id="wcj_checkout_files_upload_' . $i .
252
+ '" accept="' . get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) . '">';
253
+ $html .= '</td>';
254
+ $html .= '<td style="width:50%;">';
255
+ $html .= '<input type="submit"' .
256
+ ' class="button alt"' .
257
+ ' style="width:100%;"' .
258
+ ' name="wcj_upload_checkout_file_' . $i . '"' .
259
+ ' id="wcj_upload_checkout_file_' . $i . '"' .
260
+ ' value="' . get_option( 'wcj_checkout_files_upload_label_upload_button_' . $i, __( 'Upload', 'woocommerce-jetpack' ) ) . '"' .
261
+ ' data-value="' . get_option( 'wcj_checkout_files_upload_label_upload_button_' . $i, __( 'Upload', 'woocommerce-jetpack' ) ) . '">';
262
+ $html .= '</td>';
263
+ $html .= '</tr>';
264
+ } else {
265
+ $html .= '<tr>';
266
+ $html .= '<td style="width:50%;">';
267
+ $html .= '<a href="' . add_query_arg( 'wcj_download_checkout_file', 'wcj_checkout_files_upload_' . $i ) . '">' .
268
+ $_SESSION[ 'wcj_checkout_files_upload_' . $i ]['name'] . '</a>';
269
+ $html .= '</td>';
270
+ $html .= '<td style="width:50%;">';
271
+ $html .= '<input type="submit"' .
272
+ ' class="button"' .
273
+ ' style="width:100%;"' .
274
+ ' name="wcj_remove_checkout_file_' . $i . '"' .
275
+ ' id="wcj_remove_checkout_file_' . $i . '"' .
276
+ ' value="' . get_option( 'wcj_checkout_files_upload_label_remove_button_' . $i, __( 'Remove', 'woocommerce-jetpack' ) ) . '"' .
277
+ ' data-value="' . get_option( 'wcj_checkout_files_upload_label_remove_button_' . $i, __( 'Remove', 'woocommerce-jetpack' ) ) . '">';
278
+ $html .= '</td>';
279
+ $html .= '</tr>';
280
+ }
281
+ $html .= '</table>';
282
+ $html .= '</form>';
283
+ }
284
+ }
285
+ /* if ( $total_number > 1 ) {
286
+ $html .= '<tr>';
287
+ $html .= '<td colspan="2">';
288
+ $html .= '<input type="submit"' .
289
+ ' class="button alt"' .
290
+ ' name="wcj_checkout_files_upload_submit"' .
291
+ ' id="wcj_checkout_files_upload_submit"' .
292
+ ' value="' . __( 'Upload All', 'woocommerce-jetpack' ) . '"' .
293
+ ' data-value="' . __( 'Upload All', 'woocommerce-jetpack' ) . '"></p>';
294
+ $html .= '</td>';
295
+ $html .= '</tr>';
296
+ } */
297
+ // $html .= '</table>';
298
+ // $html .= '</form>';
299
+ echo $html;
300
+ }
301
+
302
+ /**
303
+ * get_settings.
304
+ *
305
+ * @todo styling options; options to place form on: cart, order review and my account pages.
306
+ */
307
+ function get_settings() {
308
+ $settings = array(
309
+ array(
310
+ 'title' => __( 'Options', 'woocommerce-jetpack' ),
311
+ 'type' => 'title',
312
+ 'id' => 'wcj_checkout_files_upload_options',
313
+ ),
314
+ /* array(
315
+ 'title' => __( 'Position', 'woocommerce-jetpack' ),
316
+ 'id' => 'wcj_checkout_files_upload_hook',
317
+ 'default' => 'woocommerce_before_checkout_form',
318
+ 'type' => 'select',
319
+ 'options' => array(
320
+ 'woocommerce_before_checkout_form' => __( 'Before checkout form', 'woocommerce-jetpack' ),
321
+ 'woocommerce_after_checkout_form' => __( 'After checkout form', 'woocommerce-jetpack' ),
322
+ ),
323
+ ), */
324
+ array(
325
+ 'title' => __( 'Total Files', 'woocommerce-jetpack' ),
326
+ 'id' => 'wcj_checkout_files_upload_total_number',
327
+ 'default' => 1,
328
+ 'type' => 'custom_number',
329
+ 'desc' => apply_filters( 'get_wc_jetpack_plus_message', '', 'desc' ),
330
+ 'custom_attributes' => array_merge(
331
+ is_array( apply_filters( 'get_wc_jetpack_plus_message', '', 'readonly' ) ) ?
332
+ apply_filters( 'get_wc_jetpack_plus_message', '', 'readonly' ) : array(),
333
+ array( 'step' => '1', 'min' => '1', )
334
+ ),
335
+ ),
336
+ );
337
+ $total_number = apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
338
+ for ( $i = 1; $i <= $total_number; $i++ ) {
339
+ $settings = array_merge( $settings, array(
340
+ array(
341
+ 'title' => __( 'File', 'woocommerce-jetpack' ) . ' #' . $i,
342
+ 'id' => 'wcj_checkout_files_upload_enabled_' . $i,
343
+ 'desc' => __( 'Enabled', 'woocommerce-jetpack' ),
344
+ 'type' => 'checkbox',
345
+ 'default' => 'yes',
346
+ ),
347
+ array(
348
+ 'id' => 'wcj_checkout_files_upload_required_' . $i,
349
+ 'desc' => __( 'Required', 'woocommerce-jetpack' ),
350
+ 'type' => 'checkbox',
351
+ 'default' => 'no',
352
+ ),
353
+ array(
354
+ 'id' => 'wcj_checkout_files_upload_hook_' . $i,
355
+ 'desc' => __( 'Position', 'woocommerce-jetpack' ),
356
+ 'default' => 'woocommerce_before_checkout_form',
357
+ 'type' => 'select',
358
+ 'options' => array(
359
+ 'woocommerce_before_checkout_form' => __( 'Before checkout form', 'woocommerce-jetpack' ),
360
+ 'woocommerce_after_checkout_form' => __( 'After checkout form', 'woocommerce-jetpack' ),
361
+
362
+ /* 'woocommerce_before_checkout_billing_form' => __( 'Before checkout billing form', 'woocommerce-jetpack' ),
363
+ 'woocommerce_after_checkout_billing_form' => __( 'After checkout billing form', 'woocommerce-jetpack' ),
364
+ 'woocommerce_before_checkout_registration_form' => __( 'Before checkout registration form', 'woocommerce-jetpack' ),
365
+ 'woocommerce_after_checkout_registration_form' => __( 'After checkout registration form', 'woocommerce-jetpack' ), */
366
+
367
+ /* 'woocommerce_before_checkout_shipping_form' => __( 'Before checkout shipping form', 'woocommerce-jetpack' ),
368
+ 'woocommerce_after_checkout_shipping_form' => __( 'After checkout shipping form', 'woocommerce-jetpack' ),
369
+ 'woocommerce_before_order_notes' => __( 'Before order notes', 'woocommerce-jetpack' ),
370
+ 'woocommerce_after_order_notes' => __( 'After order notes', 'woocommerce-jetpack' ), */
371
+
372
+ /* 'woocommerce_checkout_before_customer_details' => __( 'Before checkout customer details', 'woocommerce-jetpack' ),
373
+ 'woocommerce_checkout_billing' => __( 'Inside checkout billing', 'woocommerce-jetpack' ),
374
+ 'woocommerce_checkout_shipping' => __( 'Inside checkout shipping', 'woocommerce-jetpack' ),
375
+ 'woocommerce_checkout_after_customer_details' => __( 'After checkout customer details', 'woocommerce-jetpack' ),
376
+ 'woocommerce_checkout_before_order_review' => __( 'Before checkout order review', 'woocommerce-jetpack' ),
377
+ 'woocommerce_checkout_order_review' => __( 'Inside checkout order review', 'woocommerce-jetpack' ),
378
+ 'woocommerce_checkout_after_order_review' => __( 'After checkout order review', 'woocommerce-jetpack' ), */
379
+ ),
380
+ 'css' => 'width:250px;',
381
+ ),
382
+ array(
383
+ 'desc' => __( 'Position order', 'woocommerce-jetpack' ),
384
+ 'id' => 'wcj_checkout_files_upload_hook_priority_' . $i,
385
+ 'default' => 20,
386
+ 'type' => 'number',
387
+ 'custom_attributes' => array( 'min' => '0' ),
388
+ 'css' => 'width:250px;',
389
+ ),
390
+ array(
391
+ 'desc' => __( 'Label', 'woocommerce-jetpack' ),
392
+ 'desc_tip' => __( 'Leave blank to disable label', 'woocommerce-jetpack' ),
393
+ 'id' => 'wcj_checkout_files_upload_label_' . $i,
394
+ 'default' => __( 'Please select file to upload', 'woocommerce-jetpack' ),
395
+ 'type' => 'text',
396
+ 'css' => 'width:250px;',
397
+ ),
398
+ array(
399
+ 'desc' => __( 'Accepted file types', 'woocommerce-jetpack' ),
400
+ 'desc_tip' => __( 'Accepted file types. E.g.: ".jpg,.jpeg,.png". Leave blank to accept all files', 'woocommerce-jetpack' ),
401
+ 'id' => 'wcj_checkout_files_upload_file_accept_' . $i,
402
+ 'default' => '.jpg,.jpeg,.png',
403
+ 'type' => 'text',
404
+ 'css' => 'width:250px;',
405
+ ),
406
+ array(
407
+ 'desc' => __( 'Label: Upload button', 'woocommerce-jetpack' ),
408
+ 'id' => 'wcj_checkout_files_upload_label_upload_button_' . $i,
409
+ 'default' => __( 'Upload', 'woocommerce-jetpack' ),
410
+ 'type' => 'text',
411
+ 'css' => 'width:250px;',
412
+ ),
413
+ array(
414
+ 'desc' => __( 'Label: Remove button', 'woocommerce-jetpack' ),
415
+ 'id' => 'wcj_checkout_files_upload_label_remove_button_' . $i,
416
+ 'default' => __( 'Remove', 'woocommerce-jetpack' ),
417
+ 'type' => 'text',
418
+ 'css' => 'width:250px;',
419
+ ),
420
+ array(
421
+ 'desc' => __( 'Notice: Wrong file type', 'woocommerce-jetpack' ),
422
+ 'desc_tip' => __( '%s will be replaced with file name', 'woocommerce-jetpack' ),
423
+ 'id' => 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
424
+ 'default' => __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ),
425
+ 'type' => 'text',
426
+ 'css' => 'width:250px;',
427
+ ),
428
+ array(
429
+ 'desc' => __( 'Notice: File is required', 'woocommerce-jetpack' ),
430
+ 'id' => 'wcj_checkout_files_upload_notice_required_' . $i,
431
+ 'default' => __( 'File is required!', 'woocommerce-jetpack' ),
432
+ 'type' => 'text',
433
+ 'css' => 'width:250px;',
434
+ ),
435
+ array(
436
+ 'desc' => __( 'Notice: File was successfully uploaded', 'woocommerce-jetpack' ),
437
+ 'desc_tip' => __( '%s will be replaced with file name', 'woocommerce-jetpack' ),
438
+ 'id' => 'wcj_checkout_files_upload_notice_success_upload_' . $i,
439
+ 'default' => __( 'File "%s" was successfully uploaded.', 'woocommerce-jetpack' ),
440
+ 'type' => 'text',
441
+ 'css' => 'width:250px;',
442
+ ),
443
+ array(
444
+ 'desc' => __( 'Notice: No file selected', 'woocommerce-jetpack' ),
445
+ 'id' => 'wcj_checkout_files_upload_notice_upload_no_file_' . $i,
446
+ 'default' => __( 'Please select file to upload!', 'woocommerce-jetpack' ),
447
+ 'type' => 'text',
448
+ 'css' => 'width:250px;',
449
+ ),
450
+ array(
451
+ 'desc' => __( 'Notice: File was successfully removed', 'woocommerce-jetpack' ),
452
+ 'desc_tip' => __( '%s will be replaced with file name', 'woocommerce-jetpack' ),
453
+ 'id' => 'wcj_checkout_files_upload_notice_success_remove_' . $i,
454
+ 'default' => __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ),
455
+ 'type' => 'text',
456
+ 'css' => 'width:250px;',
457
+ ),
458
+ ) );
459
+ }
460
+ $settings = array_merge( $settings, array(
461
+ array(
462
+ 'type' => 'sectionend',
463
+ 'id' => 'wcj_checkout_files_upload_options',
464
+ ),
465
+ ) );
466
+ return $this->add_standard_settings( $settings );
467
+ }
468
+ }
469
+
470
+ endif;
471
+
472
+ return new WCJ_Checkout_Files_Upload();
includes/class-wcj-emails.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Emails class.
6
  *
7
- * @version 2.3.10
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -17,7 +17,7 @@ class WCJ_Emails extends WCJ_Module {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.3.9
21
  */
22
  public function __construct() {
23
 
@@ -27,6 +27,7 @@ class WCJ_Emails extends WCJ_Module {
27
  parent::__construct();
28
 
29
  if ( $this->is_enabled() ) {
 
30
  add_filter( 'woocommerce_email_classes', array( $this, 'add_custom_emails_to_wc' ) );
31
  add_filter( 'woocommerce_resend_order_emails_available', array( $this, 'add_custom_emails_to_wc_resend_order_emails' ) );
32
  if ( '' != get_option( 'wcj_emails_bcc_email' ) ) {
@@ -41,6 +42,17 @@ class WCJ_Emails extends WCJ_Module {
41
  }
42
  }
43
 
 
 
 
 
 
 
 
 
 
 
 
44
  /**
45
  * add_custom_emails_to_wc_resend_order_emails.
46
  *
4
  *
5
  * The WooCommerce Jetpack Emails class.
6
  *
7
+ * @version 2.4.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 2.4.5
21
  */
22
  public function __construct() {
23
 
27
  parent::__construct();
28
 
29
  if ( $this->is_enabled() ) {
30
+ add_filter( 'woocommerce_email_actions', array( $this, 'add_custom_woocommerce_email_actions' ) );
31
  add_filter( 'woocommerce_email_classes', array( $this, 'add_custom_emails_to_wc' ) );
32
  add_filter( 'woocommerce_resend_order_emails_available', array( $this, 'add_custom_emails_to_wc_resend_order_emails' ) );
33
  if ( '' != get_option( 'wcj_emails_bcc_email' ) ) {
42
  }
43
  }
44
 
45
+ /**
46
+ * add_custom_woocommerce_email_actions.
47
+ *
48
+ * @version 2.4.5
49
+ * @since 2.4.5
50
+ */
51
+ function add_custom_woocommerce_email_actions( $email_actions ) {
52
+ $email_actions[] = 'woocommerce_new_order';
53
+ return $email_actions;
54
+ }
55
+
56
  /**
57
  * add_custom_emails_to_wc_resend_order_emails.
58
  *
includes/class-wcj-price-by-country.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Price by Country class.
6
  *
7
- * @version 2.4.4
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -17,7 +17,7 @@ class WCJ_Price_By_Country extends WCJ_Module {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.4.4
21
  */
22
  public function __construct() {
23
 
@@ -39,6 +39,10 @@ class WCJ_Price_By_Country extends WCJ_Module {
39
  $do_load_core = false;
40
  }
41
  }
 
 
 
 
42
  if ( $do_load_core ) {
43
  // Frontend
44
  include_once( 'price-by-country/class-wcj-price-by-country-core.php' );
4
  *
5
  * The WooCommerce Jetpack Price by Country class.
6
  *
7
+ * @version 2.4.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 2.4.5
21
  */
22
  public function __construct() {
23
 
39
  $do_load_core = false;
40
  }
41
  }
42
+ if ( ! defined( 'DOING_AJAX' ) && '/wc-api/WC_Gateway_Paypal/' == $_SERVER['REQUEST_URI'] ) {
43
+ // "Wrong currency in emails" bug fix
44
+ $do_load_core = false;
45
+ }
46
  if ( $do_load_core ) {
47
  // Frontend
48
  include_once( 'price-by-country/class-wcj-price-by-country-core.php' );
includes/class-wcj-purchase-data.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Purchase Data class.
6
  *
7
- * @version 2.2.6
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -18,9 +18,9 @@ class WCJ_Purchase_Data extends WCJ_Module {
18
  /**
19
  * Constructor.
20
  *
21
- * @version 2.2.4
22
  */
23
- public function __construct() {
24
 
25
  $this->id = 'purchase_data';
26
  $this->short_desc = __( 'Product Cost Price', 'woocommerce-jetpack' );
@@ -29,10 +29,8 @@ class WCJ_Purchase_Data extends WCJ_Module {
29
 
30
  if ( $this->is_enabled() ) {
31
 
32
- add_action( 'add_meta_boxes', array( $this, 'add_purchase_price_meta_box' ) );
33
- add_action( 'save_post_product', array( $this, 'save_purchase_price_meta_box' ), PHP_INT_MAX, 2 );
34
-
35
- //add_action( 'init', array( $this, 'calculate_all_products_profit' ) );
36
 
37
  if ( 'yes' === get_option( 'wcj_purchase_data_custom_columns_profit', 'no' ) ) {
38
  add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_order_columns' ), PHP_INT_MAX );
@@ -55,25 +53,23 @@ class WCJ_Purchase_Data extends WCJ_Module {
55
  * Output custom columns for orders
56
  *
57
  * @param string $column
58
- * @version 2.2.6
59
  * @since 2.2.4
 
60
  */
61
- public function render_order_columns( $column ) {
62
-
63
  if ( 'profit' === $column ) {
64
  $total_profit = 0;
65
  $the_order = wc_get_order( get_the_ID() );
66
  if ( 'completed' === $the_order->get_status() ) {
67
  $is_forecasted = false;
68
  foreach ( $the_order->get_items() as $item_id => $item ) {
69
- // $product = $this->get_product_from_item( $item );
70
  $the_profit = 0;
71
- if ( 0 != ( $purchase_price = wc_get_product_purchase_price( $item['product_id'] ) ) ) {
 
72
  $the_profit = ( $item['line_total'] + $item['line_tax'] ) - $purchase_price * $item['qty'];
73
- // $total_profit += $the_profit;
74
- // echo $item['line_total'] . ' ~ ' . $purchase_price . ' ~ ' . $item['qty'];
75
  } else {
76
- //$the_profit = ( $item['line_total'] + $item['line_tax'] ) * 0.2;
77
  $is_forecasted = true;
78
  }
79
  $total_profit += $the_profit;
@@ -88,175 +84,145 @@ class WCJ_Purchase_Data extends WCJ_Module {
88
  }
89
 
90
  /**
91
- * get_options.
92
- */
93
- public function get_options() {
94
- return array(
95
- array(
96
- 'name' => 'wcj_purchase_price',
97
- 'default' => 0,
98
- ),
99
- array(
100
- 'name' => 'wcj_purchase_price_extra',
101
- 'default' => 0,
102
- ),
103
- /* array(
104
- 'name' => 'wcj_purchase_price_currency',
105
- 'default' => '',
106
- ), */
107
- array(
108
- 'name' => 'wcj_purchase_date',
109
- 'default' => '',
110
- ),
111
- array(
112
- 'name' => 'wcj_purchase_partner',
113
- 'default' => '',
114
- ),
115
- array(
116
- 'name' => 'wcj_purchase_info',
117
- 'default' => '',
118
- ),
119
- );
120
- }
121
-
122
- /**
123
- * save_purchase_price_meta_box.
124
  */
125
- public function save_purchase_price_meta_box( $post_id, $post ) {
126
-
127
- // Check that we are saving with purchase price metabox displayed.
128
- if ( ! isset( $_POST['woojetpack_purchase_price_save_post'] ) )
129
- return;
130
-
131
- // Save options
132
- foreach ( $this->get_options() as $option ) {
133
- $option_value = isset( $_POST[ $option['name'] ] ) ? $_POST[ $option['name'] ] : $option['default'];
134
- update_post_meta( $post_id, '_' . $option['name'], $option_value );
 
 
135
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
 
138
  /**
139
- * add_purchase_price_meta_box.
140
- */
141
- public function add_purchase_price_meta_box() {
142
- add_meta_box(
143
- 'wc-jetpack-purchase-price',
144
- __( 'WooCommerce Jetpack', 'woocommerce-jetpack' ) . ': ' . $this->short_desc,
145
- array( $this, 'create_purchase_price_meta_box' ),
146
- 'product',
147
- 'normal',
148
- 'high' );
149
- }
150
-
151
- /**
152
- * create_purchase_price_meta_box.
153
  */
154
- public function create_purchase_price_meta_box() {
155
-
156
- $current_post_id = get_the_ID();
157
-
158
- $purchase_price = 0;
159
-
160
- $html = '';
161
- $html .= '<div style="width:40%;">';
162
- $html .= '<table>';
163
- foreach ( $this->get_options() as $option ) {
164
-
165
- $option_value = get_post_meta( $current_post_id, '_' . $option['name'], true );
166
-
167
- switch ( $option['name'] ) {
168
- case 'wcj_purchase_price':
169
- $title = __( 'Product cost (purchase) price', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')';
170
- $field_html = '<input class="short wc_input_price" type="number" step="0.0001"';
171
- break;
172
- case 'wcj_purchase_price_extra':
173
- $title = __( 'Extra expenses (shipping etc.)', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')';
174
- $field_html = '<input class="short wc_input_price" type="number" step="0.0001"';
175
- break;
176
- case 'wcj_purchase_partner':
177
- $title = __( 'Seller', 'woocommerce-jetpack' );
178
- $field_html = '<input class="input-text" type="text"';
179
- break;
180
- case 'wcj_purchase_date':
181
- $title = __( '(Last) Purchase date', 'woocommerce-jetpack' );
182
- $field_html = '<input class="input-text" display="date" type="text"';
183
- break;
184
- case 'wcj_purchase_info':
185
- $title = __( 'Purchase info', 'woocommerce-jetpack' );
186
- $field_html = '<textarea id="' . $option['name'] . '" name="' . $option['name'] . '">' . $option_value . '</textarea>';
187
- break;
188
  }
189
-
190
- if ( 'wcj_purchase_info' != $option['name'] ) {
191
- $field_html .= ' id="' . $option['name'] . '" name="' . $option['name'] . '" value="' . $option_value . '">';
192
- }
193
-
194
- if ( 'wcj_purchase_price' == $option['name'] || 'wcj_purchase_price_extra' == $option['name'] ) {
195
- // Saving for later use
196
- $purchase_price += $option_value;
197
- }
198
-
199
- $html .= '<tr>';
200
- $html .= '<th>' . $title . '</th>';
201
- $html .= '<td>' . $field_html . '</td>';
202
- $html .= '</tr>';
203
  }
204
- $html .= '</table>';
205
- $html .= '<input type="hidden" name="woojetpack_purchase_price_save_post" value="woojetpack_purchase_price_save_post">';
206
- $html .= '</div>';
207
- echo $html;
208
-
209
- if ( 0 != $purchase_price ) {
210
- $the_product = wc_get_product( $current_post_id );
211
- $the_price = $the_product->get_price();
212
- if ( 0 != $the_price ) {
213
- $html = '';
214
- $html .= '<h5>' . __( 'Report', 'woocommerce-jetpack' ) . '</h5>';
215
- $html .= '<table class="widefat" style="width:300px;">';
216
-
217
- $html .= '<tr>';
218
- $html .= '<th>';
219
- $html .= __( 'Selling', 'woocommerce-jetpack' );
220
- $html .= '</th>';
221
- $html .= '<td>';
222
- $html .= wc_price( $the_price );
223
- $html .= '</td>';
224
- $html .= '</tr>';
225
-
226
- $html .= '<tr>';
227
- $html .= '<th>';
228
- $html .= __( 'Buying', 'woocommerce-jetpack' );
229
- $html .= '</th>';
230
- $html .= '<td>';
231
- $html .= wc_price( $purchase_price );
232
- $html .= '</td>';
233
- $html .= '</tr>';
234
-
235
- $the_profit = $the_price - $purchase_price;
236
- $html .= '<tr>';
237
- $html .= '<th>';
238
- $html .= __( 'Profit', 'woocommerce-jetpack' );
239
- $html .= '</th>';
240
- $html .= '<td>';
241
- $html .= wc_price( $the_profit )
242
- . sprintf( ' (%0.2f %%)', ( $the_profit / $purchase_price * 100 ) );
243
- //. sprintf( ' (%0.2f %%)', ( $the_profit / $the_price * 100 ) );
244
- $html .= '</td>';
245
- $html .= '</tr>';
246
-
247
- /* $the_min_profit = $purchase_price * 0.25;
248
- $the_min_price = $purchase_price * 1.25;
249
- $html .= '<tr>';
250
- $html .= '<th>';
251
- $html .= __( 'Min Profit', 'woocommerce-jetpack' );
252
- $html .= '</th>';
253
- $html .= '<td>';
254
- $html .= wc_price( $the_min_profit ) . ' ' . __( 'at', 'woocommerce-jetpack' ) . ' ' . wc_price( $the_min_price );
255
- $html .= '</td>';
256
- $html .= '</tr>'; */
257
-
258
- $html .= '</table>';
259
- echo $html;
260
  }
261
  }
262
  }
@@ -264,52 +230,80 @@ class WCJ_Purchase_Data extends WCJ_Module {
264
  /**
265
  * calculate_all_products_profit.
266
  *
267
- function calculate_all_products_profit() {
268
- $args = array(
269
- 'post_type' => 'product',
270
- 'post_status' => 'any',
271
- 'posts_per_page' => -1,
272
- );
273
- $loop = new WP_Query( $args );
274
- while ( $loop->have_posts() ) : $loop->the_post();
275
-
276
- $current_post_id = $loop->post->ID;
277
- $option_name = 'wcj_purchase_price';
278
- if ( ! ( $purchase_price = get_post_meta( $current_post_id, '_' . $option_name, true ) ) )
279
- $purchase_price = 0;
280
-
281
- $the_product = wc_get_product( $current_post_id );
282
- $the_price = $the_product->get_price();
283
-
284
- if ( 0 != $purchase_price ) {
285
- //echo( '<p>' );
286
- /*wcj_log(
287
- get_the_title()
288
- . ' - '
289
- . wc_price( $purchase_price )
290
- . ' - '
291
- . wc_price( $the_price )
292
- . ' - '
293
- . wc_price( $the_price - $purchase_price )
294
- );*//*
295
- //echo( '</p>' );
296
-
297
- //$the_total
298
- }
299
-
300
- endwhile;
301
-
302
- //wp_reset_query();
303
- //die();
304
- }
305
 
306
  /**
307
  * get_settings.
308
  *
309
- * @version 2.2.4
 
310
  */
311
  function get_settings() {
312
  $settings = array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  array(
314
  'title' => __( 'Orders List Custom Columns', 'woocommerce-jetpack' ),
315
  'type' => 'title',
@@ -328,7 +322,7 @@ class WCJ_Purchase_Data extends WCJ_Module {
328
  'id' => 'wcj_purchase_data_custom_columns_options',
329
  ),
330
  );
331
- return $this->add_enable_module_setting( $settings );
332
  }
333
  }
334
 
4
  *
5
  * The WooCommerce Jetpack Purchase Data class.
6
  *
7
+ * @version 2.4.5
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
18
  /**
19
  * Constructor.
20
  *
21
+ * @version 2.4.5
22
  */
23
+ function __construct() {
24
 
25
  $this->id = 'purchase_data';
26
  $this->short_desc = __( 'Product Cost Price', 'woocommerce-jetpack' );
29
 
30
  if ( $this->is_enabled() ) {
31
 
32
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
33
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
 
 
34
 
35
  if ( 'yes' === get_option( 'wcj_purchase_data_custom_columns_profit', 'no' ) ) {
36
  add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_order_columns' ), PHP_INT_MAX );
53
  * Output custom columns for orders
54
  *
55
  * @param string $column
56
+ * @version 2.4.5
57
  * @since 2.2.4
58
+ * @todo forecasted profit
59
  */
60
+ function render_order_columns( $column ) {
 
61
  if ( 'profit' === $column ) {
62
  $total_profit = 0;
63
  $the_order = wc_get_order( get_the_ID() );
64
  if ( 'completed' === $the_order->get_status() ) {
65
  $is_forecasted = false;
66
  foreach ( $the_order->get_items() as $item_id => $item ) {
 
67
  $the_profit = 0;
68
+ $product_id = ( isset( $item['variation_id'] ) && 0 != $item['variation_id'] ) ? $item['variation_id'] : $item['product_id'];
69
+ if ( 0 != ( $purchase_price = wc_get_product_purchase_price( $product_id ) ) ) {
70
  $the_profit = ( $item['line_total'] + $item['line_tax'] ) - $purchase_price * $item['qty'];
 
 
71
  } else {
72
+ // $the_profit = ( $item['line_total'] + $item['line_tax'] ) * $average_profit_margin;
73
  $is_forecasted = true;
74
  }
75
  $total_profit += $the_profit;
84
  }
85
 
86
  /**
87
+ * get_meta_box_options.
88
+ *
89
+ * @version 2.4.5
90
+ * @since 2.4.5
91
+ * @todo wcj_purchase_price_currency
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  */
93
+ function get_meta_box_options() {
94
+ $main_product_id = get_the_ID();
95
+ $_product = wc_get_product( $main_product_id );
96
+ $products = array();
97
+ if ( $_product->is_type( 'variable' ) ) {
98
+ $available_variations = $_product->get_available_variations();
99
+ foreach ( $available_variations as $variation ) {
100
+ $variation_product = wc_get_product( $variation['variation_id'] );
101
+ $products[ $variation['variation_id'] ] = ' (' . $variation_product->get_formatted_variation_attributes( true ) . ')';
102
+ }
103
+ } else {
104
+ $products[ $main_product_id ] = '';
105
  }
106
+ $options = array();
107
+ foreach ( $products as $product_id => $desc ) {
108
+ $product_options = apply_filters( 'wcj_purchase_data_product_options', array(
109
+ array(
110
+ 'name' => 'wcj_purchase_price_' . $product_id,
111
+ 'default' => 0,
112
+ 'type' => 'price',
113
+ 'title' => __( 'Product cost (purchase) price', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')',
114
+ 'desc' => $desc,
115
+ 'product_id' => $product_id,
116
+ 'meta_name' => '_' . 'wcj_purchase_price',
117
+ 'enabled' => get_option( 'wcj_purchase_price_enabled', 'yes' ),
118
+ ),
119
+ array(
120
+ 'name' => 'wcj_purchase_price_extra_' . $product_id,
121
+ 'default' => 0,
122
+ 'type' => 'price',
123
+ 'title' => __( 'Extra expenses (shipping etc.)', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')',
124
+ 'desc' => $desc,
125
+ 'product_id' => $product_id,
126
+ 'meta_name' => '_' . 'wcj_purchase_price_extra',
127
+ 'enabled' => get_option( 'wcj_purchase_price_extra_enabled', 'yes' ),
128
+ ),
129
+ array(
130
+ 'name' => 'wcj_purchase_price_affiliate_commission_' . $product_id,
131
+ 'default' => 0,
132
+ 'type' => 'price',
133
+ 'title' => __( 'Affiliate commission', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')',
134
+ 'desc' => $desc,
135
+ 'product_id' => $product_id,
136
+ 'meta_name' => '_' . 'wcj_purchase_price_affiliate_commission',
137
+ 'enabled' => get_option( 'wcj_purchase_price_affiliate_commission_enabled', 'no' ),
138
+ ),
139
+ array(
140
+ 'name' => 'wcj_purchase_date_' . $product_id,
141
+ 'default' => '',
142
+ 'type' => 'date',
143
+ 'title' => __( '(Last) Purchase date', 'woocommerce-jetpack' ),
144
+ 'desc' => $desc,
145
+ 'product_id' => $product_id,
146
+ 'meta_name' => '_' . 'wcj_purchase_date',
147
+ 'enabled' => get_option( 'wcj_purchase_date_enabled', 'yes' ),
148
+ ),
149
+ array(
150
+ 'name' => 'wcj_purchase_partner_' . $product_id,
151
+ 'default' => '',
152
+ 'type' => 'text',
153
+ 'title' => __( 'Seller', 'woocommerce-jetpack' ),
154
+ 'desc' => $desc,
155
+ 'product_id' => $product_id,
156
+ 'meta_name' => '_' . 'wcj_purchase_partner',
157
+ 'enabled' => get_option( 'wcj_purchase_partner_enabled', 'yes' ),
158
+ ),
159
+ array(
160
+ 'name' => 'wcj_purchase_info_' . $product_id,
161
+ 'default' => '',
162
+ 'type' => 'textarea',
163
+ 'title' => __( 'Purchase info', 'woocommerce-jetpack' ),
164
+ 'desc' => $desc,
165
+ 'product_id' => $product_id,
166
+ 'meta_name' => '_' . 'wcj_purchase_info',
167
+ 'enabled' => get_option( 'wcj_purchase_info_enabled', 'yes' ),
168
+ ),
169
+ ), $product_id, $desc );
170
+ $options = array_merge( $options, $product_options );
171
+ }
172
+ return $options;
173
  }
174
 
175
  /**
176
+ * create_meta_box.
177
+ *
178
+ * @version 2.4.5
179
+ * @since 2.4.5
180
+ * @todo min_profit
 
 
 
 
 
 
 
 
 
181
  */
182
+ function create_meta_box() {
183
+
184
+ parent::create_meta_box();
185
+
186
+ // Report
187
+ $main_product_id = get_the_ID();
188
+ $_product = wc_get_product( $main_product_id );
189
+ $products = array();
190
+ if ( $_product->is_type( 'variable' ) ) {
191
+ $available_variations = $_product->get_available_variations();
192
+ foreach ( $available_variations as $variation ) {
193
+ $variation_product = wc_get_product( $variation['variation_id'] );
194
+ $products[ $variation['variation_id'] ] = ' (' . $variation_product->get_formatted_variation_attributes( true ) . ')';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
196
+ } else {
197
+ $products[ $main_product_id ] = '';
 
 
 
 
 
 
 
 
 
 
 
 
198
  }
199
+ foreach ( $products as $product_id => $desc ) {
200
+ $purchase_price = wc_get_product_purchase_price( $product_id );
201
+ if ( 0 != $purchase_price ) {
202
+ $the_product = wc_get_product( $product_id );
203
+ $the_price = $the_product->get_price();
204
+ if ( 0 != $the_price ) {
205
+ $the_profit = $the_price - $purchase_price;
206
+ $table_data = array();
207
+ $table_data[] = array( __( 'Selling', 'woocommerce-jetpack' ), wc_price( $the_price ) );
208
+ $table_data[] = array( __( 'Buying', 'woocommerce-jetpack' ), wc_price( $purchase_price ) );
209
+ $table_data[] = array( __( 'Profit', 'woocommerce-jetpack' ), wc_price( $the_profit )
210
+ . sprintf( ' (%0.2f %%)', ( $the_profit / $purchase_price * 100 ) ) );
211
+ // . sprintf( ' (%0.2f %%)', ( $the_profit / $the_price * 100 ) ) );
212
+ /* $the_min_profit = $purchase_price * 0.25;
213
+ $the_min_price = $purchase_price * 1.25;
214
+ $html .= __( 'Min Profit', 'woocommerce-jetpack' );
215
+ $html .= wc_price( $the_min_profit ) . ' ' . __( 'at', 'woocommerce-jetpack' ) . ' ' . wc_price( $the_min_price ); */
216
+ $html = '';
217
+ $html .= '<h5>' . __( 'Report', 'woocommerce-jetpack' ) . $desc . '</h5>';
218
+ $html .= wcj_get_table_html( $table_data, array(
219
+ 'table_heading_type' => 'none',
220
+ 'table_class' => 'widefat striped',
221
+ 'table_style' => 'width:50%;min-width:300px;',
222
+ 'columns_styles' => array( 'width:33%;' ),
223
+ ) );
224
+ echo $html;
225
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  }
227
  }
228
  }
230
  /**
231
  * calculate_all_products_profit.
232
  *
233
+ * @todo
234
+ */
235
+ /* function calculate_all_products_profit() { } */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
  /**
238
  * get_settings.
239
  *
240
+ * @version 2.4.5
241
+ * @todo add options to set fields and column titles
242
  */
243
  function get_settings() {
244
  $settings = array(
245
+ array(
246
+ 'title' => __( 'Price Fields', 'woocommerce-jetpack' ),
247
+ 'type' => 'title',
248
+ 'desc' => __( 'This fields will be added to product\'s edit page and will be included in product\'s purchase cost calculation.', 'woocommerce-jetpack' ),
249
+ 'id' => 'wcj_purchase_data_price_fields_options',
250
+ ),
251
+ array(
252
+ 'title' => __( 'Product cost (purchase) price', 'woocommerce-jetpack' ),
253
+ 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
254
+ 'id' => 'wcj_purchase_price_enabled',
255
+ 'default' => 'yes',
256
+ 'type' => 'checkbox',
257
+ ),
258
+ array(
259
+ 'title' => __( 'Extra expenses (shipping etc.)', 'woocommerce-jetpack' ),
260
+ 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
261
+ 'id' => 'wcj_purchase_price_extra_enabled',
262
+ 'default' => 'yes',
263
+ 'type' => 'checkbox',
264
+ ),
265
+ array(
266
+ 'title' => __( 'Affiliate commission', 'woocommerce-jetpack' ),
267
+ 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
268
+ 'id' => 'wcj_purchase_price_affiliate_commission_enabled',
269
+ 'default' => 'no',
270
+ 'type' => 'checkbox',
271
+ ),
272
+ array(
273
+ 'type' => 'sectionend',
274
+ 'id' => 'wcj_purchase_data_price_fields_options',
275
+ ),
276
+ array(
277
+ 'title' => __( 'Info Fields', 'woocommerce-jetpack' ),
278
+ 'type' => 'title',
279
+ 'desc' => __( 'This fields will be added to product\'s edit page.', 'woocommerce-jetpack' ),
280
+ 'id' => 'wcj_purchase_data_info_fields_options',
281
+ ),
282
+ array(
283
+ 'title' => __( '(Last) Purchase date', 'woocommerce-jetpack' ),
284
+ 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
285
+ 'id' => 'wcj_purchase_date_enabled',
286
+ 'default' => 'yes',
287
+ 'type' => 'checkbox',
288
+ ),
289
+ array(
290
+ 'title' => __( 'Seller', 'woocommerce-jetpack' ),
291
+ 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
292
+ 'id' => 'wcj_purchase_partner_enabled',
293
+ 'default' => 'yes',
294
+ 'type' => 'checkbox',
295
+ ),
296
+ array(
297
+ 'title' => __( 'Purchase info', 'woocommerce-jetpack' ),
298
+ 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
299
+ 'id' => 'wcj_purchase_info_enabled',
300
+ 'default' => 'yes',
301
+ 'type' => 'checkbox',
302
+ ),
303
+ array(
304
+ 'type' => 'sectionend',
305
+ 'id' => 'wcj_purchase_data_info_fields_options',
306
+ ),
307
  array(
308
  'title' => __( 'Orders List Custom Columns', 'woocommerce-jetpack' ),
309
  'type' => 'title',
322
  'id' => 'wcj_purchase_data_custom_columns_options',
323
  ),
324
  );
325
+ return $this->add_standard_settings( $settings );
326
  }
327
  }
328
 
includes/class-wcj-sku.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack SKU class.
6
  *
7
- * @version 2.4.0
8
  * @author Algoritmika Ltd.
9
  * @todo add "random number" option
10
  */
@@ -200,7 +200,7 @@ class WCJ_SKU extends WCJ_Module {
200
  /**
201
  * get_settings.
202
  *
203
- * @version 2.4.0
204
  */
205
  function get_settings() {
206
 
@@ -251,6 +251,7 @@ class WCJ_SKU extends WCJ_Module {
251
 
252
  array(
253
  'title' => __( 'Variable Products Variations', 'woocommerce-jetpack' ),
 
254
  'id' => 'wcj_sku_variations_handling',
255
  'default' => 'as_variable',
256
  'type' => 'select',
4
  *
5
  * The WooCommerce Jetpack SKU class.
6
  *
7
+ * @version 2.4.5
8
  * @author Algoritmika Ltd.
9
  * @todo add "random number" option
10
  */
200
  /**
201
  * get_settings.
202
  *
203
+ * @version 2.4.5
204
  */
205
  function get_settings() {
206
 
251
 
252
  array(
253
  'title' => __( 'Variable Products Variations', 'woocommerce-jetpack' ),
254
+ 'desc_tip' => __( 'Please note, that on new variable product creation, variations will get same SKUs as parent product, and if you want variations to have different SKUs, you will need to run "Autogenerate SKUs" tool manually.' ),
255
  'id' => 'wcj_sku_variations_handling',
256
  'default' => 'as_variable',
257
  'type' => 'select',
includes/classes/class-wcj-module.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Module class.
6
  *
7
- * @version 2.4.3
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -88,17 +88,20 @@ if ( ! class_exists( 'WCJ_Module' ) ) :
88
  /**
89
  * save_meta_box.
90
  *
91
- * @since 2.4.3
92
  */
93
  function save_meta_box( $post_id, $post ) {
94
  // Check that we are saving with current metabox displayed.
95
  if ( ! isset( $_POST[ 'woojetpack_' . $this->id . '_save_post' ] ) ) return;
96
  // Save options
97
  foreach ( $this->get_meta_box_options() as $option ) {
98
- $option_value = ( isset( $_POST[ $option['name'] ] ) ) ? $_POST[ $option['name'] ] : $option['default'];
99
- $the_post_id = ( isset( $option['product_id'] ) ) ? $option['product_id'] : $post_id;
100
- $the_meta_name = ( isset( $option['meta_name'] ) ) ? $option['meta_name'] : '_' . $option['name'];
101
- update_post_meta( $the_post_id, $the_meta_name, $option_value );
 
 
 
102
  }
103
  }
104
 
@@ -125,38 +128,41 @@ if ( ! class_exists( 'WCJ_Module' ) ) :
125
  /**
126
  * create_meta_box.
127
  *
128
- * @since 2.4.3
129
  */
130
  function create_meta_box() {
131
  $current_post_id = get_the_ID();
132
  $html = '';
133
  $html .= '<table>';
134
  foreach ( $this->get_meta_box_options() as $option ) {
135
- $the_post_id = ( isset( $option['product_id'] ) ) ? $option['product_id'] : $current_post_id;
136
- $the_meta_name = ( isset( $option['meta_name'] ) ) ? $option['meta_name'] : '_' . $option['name'];
137
- $option_value = get_post_meta( $the_post_id, $the_meta_name, true );
138
- $input_ending = ' id="' . $option['name'] . '" name="' . $option['name'] . '" value="' . $option_value . '">';
139
- switch ( $option['type'] ) {
140
- case 'number':
141
- $field_html = '<input class="short" type="number"' . $input_ending;
142
- break;
143
- case 'price':
144
- $field_html = '<input class="short wc_input_price" type="number" step="0.0001"' . $input_ending;
145
- break;
146
- case 'date':
147
- $field_html = '<input class="input-text" display="date" type="text"' . $input_ending;
148
- break;
149
- case 'textarea':
150
- $field_html = '<textarea style="min-width:300px;"' . ' id="' . $option['name'] . '" name="' . $option['name'] . '">' . $option_value . '</textarea>';
151
- break;
152
- }
153
- $html .= '<tr>';
154
- $html .= '<th style="text-align:left;">' . $option['title'] . '</th>';
155
- if ( isset( $option['desc'] ) && '' != $option['desc'] ) {
156
- $html .= '<td style="font-style:italic;">' . $option['desc'] . '</td>';
 
 
 
 
 
157
  }
158
- $html .= '<td>' . $field_html . '</td>';
159
- $html .= '</tr>';
160
  }
161
  $html .= '</table>';
162
  $html .= '<input type="hidden" name="woojetpack_' . $this->id . '_save_post" value="woojetpack_' . $this->id . '_save_post">';
4
  *
5
  * The WooCommerce Jetpack Module class.
6
  *
7
+ * @version 2.4.5
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
88
  /**
89
  * save_meta_box.
90
  *
91
+ * @since 2.4.5
92
  */
93
  function save_meta_box( $post_id, $post ) {
94
  // Check that we are saving with current metabox displayed.
95
  if ( ! isset( $_POST[ 'woojetpack_' . $this->id . '_save_post' ] ) ) return;
96
  // Save options
97
  foreach ( $this->get_meta_box_options() as $option ) {
98
+ $is_enabled = ( isset( $option['enabled'] ) && 'no' === $option['enabled'] ) ? false : true;
99
+ if ( $is_enabled ) {
100
+ $option_value = ( isset( $_POST[ $option['name'] ] ) ) ? $_POST[ $option['name'] ] : $option['default'];
101
+ $the_post_id = ( isset( $option['product_id'] ) ) ? $option['product_id'] : $post_id;
102
+ $the_meta_name = ( isset( $option['meta_name'] ) ) ? $option['meta_name'] : '_' . $option['name'];
103
+ update_post_meta( $the_post_id, $the_meta_name, $option_value );
104
+ }
105
  }
106
  }
107
 
128
  /**
129
  * create_meta_box.
130
  *
131
+ * @since 2.4.5
132
  */
133
  function create_meta_box() {
134
  $current_post_id = get_the_ID();
135
  $html = '';
136
  $html .= '<table>';
137
  foreach ( $this->get_meta_box_options() as $option ) {
138
+ $is_enabled = ( isset( $option['enabled'] ) && 'no' === $option['enabled'] ) ? false : true;
139
+ if ( $is_enabled ) {
140
+ $the_post_id = ( isset( $option['product_id'] ) ) ? $option['product_id'] : $current_post_id;
141
+ $the_meta_name = ( isset( $option['meta_name'] ) ) ? $option['meta_name'] : '_' . $option['name'];
142
+ $option_value = get_post_meta( $the_post_id, $the_meta_name, true );
143
+ $input_ending = ' id="' . $option['name'] . '" name="' . $option['name'] . '" value="' . $option_value . '">';
144
+ switch ( $option['type'] ) {
145
+ case 'price':
146
+ $field_html = '<input class="short wc_input_price" type="number" step="0.0001"' . $input_ending;
147
+ break;
148
+ case 'date':
149
+ $field_html = '<input class="input-text" display="date" type="text"' . $input_ending;
150
+ break;
151
+ case 'textarea':
152
+ $field_html = '<textarea style="min-width:300px;"' . ' id="' . $option['name'] . '" name="' . $option['name'] . '">' . $option_value . '</textarea>';
153
+ break;
154
+ default:
155
+ $field_html = '<input class="short" type="' . $option['type'] . '"' . $input_ending;
156
+ break;
157
+ }
158
+ $html .= '<tr>';
159
+ $html .= '<th style="text-align:left;">' . $option['title'] . '</th>';
160
+ if ( isset( $option['desc'] ) && '' != $option['desc'] ) {
161
+ $html .= '<td style="font-style:italic;">' . $option['desc'] . '</td>';
162
+ }
163
+ $html .= '<td>' . $field_html . '</td>';
164
+ $html .= '</tr>';
165
  }
 
 
166
  }
167
  $html .= '</table>';
168
  $html .= '<input type="hidden" name="woojetpack_' . $this->id . '_save_post" value="woojetpack_' . $this->id . '_save_post">';
includes/classes/class-wcj-product.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Product class.
6
  *
7
- * @version 2.2.0
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -18,27 +18,31 @@ class WCJ_Product {
18
  public $id;
19
  public $product;
20
 
21
- /**
22
- * Constructor.
23
- */
24
- public function __construct( $product_id ) {
25
- $this->id = $product_id;
26
- //$this->product = wc_get_product( $this->id );
27
- }
28
 
29
- /**
30
- * get_purchase_price.
31
- */
 
 
32
  public function get_purchase_price() {
33
- /* $current_post_id = $this->id;//get_the_ID();
34
- $option_name = 'wcj_purchase_price';
35
- if ( ! ( $purchase_price = get_post_meta( $current_post_id, '_' . $option_name, true ) ) ) {
36
- $purchase_price = 0;
37
- } */
38
  $purchase_price = 0;
39
- $purchase_price += get_post_meta( $this->id, '_' . 'wcj_purchase_price', true );
40
- $purchase_price += get_post_meta( $this->id, '_' . 'wcj_purchase_price_extra', true );
41
- return $purchase_price;
 
 
 
 
 
 
 
42
  }
43
  }
44
 
4
  *
5
  * The WooCommerce Jetpack Product class.
6
  *
7
+ * @version 2.4.5
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
18
  public $id;
19
  public $product;
20
 
21
+ /**
22
+ * Constructor.
23
+ */
24
+ public function __construct( $product_id ) {
25
+ $this->id = $product_id;
26
+ // $this->product = wc_get_product( $this->id );
27
+ }
28
 
29
+ /**
30
+ * get_purchase_price.
31
+ *
32
+ * @version 2.4.5
33
+ */
34
  public function get_purchase_price() {
 
 
 
 
 
35
  $purchase_price = 0;
36
+ if ( 'yes' === get_option( 'wcj_purchase_price_enabled', 'yes' ) ) {
37
+ $purchase_price += get_post_meta( $this->id, '_' . 'wcj_purchase_price' , true );
38
+ }
39
+ if ( 'yes' === get_option( 'wcj_purchase_price_extra_enabled', 'yes' ) ) {
40
+ $purchase_price += get_post_meta( $this->id, '_' . 'wcj_purchase_price_extra', true );
41
+ }
42
+ if ( 'yes' === get_option( 'wcj_purchase_price_affiliate_commission_enabled', 'no' ) ) {
43
+ $purchase_price += get_post_meta( $this->id, '_' . 'wcj_purchase_price_affiliate_commission', true );
44
+ }
45
+ return apply_filters( 'wcj_get_product_purchase_price', $purchase_price, $this->id );
46
  }
47
  }
48
 
includes/emails/class-wc-email-wcj-custom.php CHANGED
@@ -11,7 +11,7 @@ if ( ! class_exists( 'WC_Email_WCJ_Custom' ) ) :
11
  *
12
  * An email sent to recipient list when selected triggers are called.
13
  *
14
- * @version 2.4.1
15
  * @since 2.3.9
16
  * @author Algoritmika Ltd.
17
  * @extends WC_Email
@@ -21,7 +21,7 @@ class WC_Email_WCJ_Custom extends WC_Email {
21
  /**
22
  * Constructor
23
  *
24
- * @version 2.4.0
25
  */
26
  function __construct( $id = 1 ) {
27
 
@@ -39,8 +39,14 @@ class WC_Email_WCJ_Custom extends WC_Email {
39
  // Triggers for this email
40
  $trigger_hooks = $this->get_option( 'trigger' );
41
  if ( ! empty( $trigger_hooks ) && is_array( $trigger_hooks ) ) {
 
42
  foreach ( $trigger_hooks as $trigger_hook ) {
43
- add_action( $trigger_hook, array( $this, 'trigger' ) );
 
 
 
 
 
44
  }
45
  }
46
 
@@ -74,7 +80,7 @@ class WC_Email_WCJ_Custom extends WC_Email {
74
  /**
75
  * Trigger.
76
  *
77
- * @version 2.4.0
78
  */
79
  function trigger( $order_id ) {
80
 
@@ -99,6 +105,23 @@ class WC_Email_WCJ_Custom extends WC_Email {
99
  if ( $order_id ) {
100
  global $post;
101
  $order = wc_get_order( $order_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  $post = $order->post;
103
  setup_postdata( $post );
104
  }
@@ -162,7 +185,7 @@ class WC_Email_WCJ_Custom extends WC_Email {
162
  /**
163
  * Initialise settings form fields
164
  *
165
- * @version 2.4.0
166
  */
167
  function init_form_fields() {
168
 
@@ -174,10 +197,12 @@ class WC_Email_WCJ_Custom extends WC_Email {
174
  $default_plain_template = ob_get_clean();
175
 
176
  $status_change_triggers = array();
 
177
  $status_triggers = array();
178
  $order_statuses = $this->get_order_statuses();
179
  foreach ( $order_statuses as $slug => $name ) {
180
- $status_triggers[ 'woocommerce_order_status_' . $slug . '_notification' ] = sprintf( __( 'Order status %s', 'woocommerce-jetpack' ), $name );
 
181
  foreach ( $order_statuses as $slug2 => $name2 ) {
182
  if ( $slug != $slug2 ) {
183
  $status_change_triggers[ 'woocommerce_order_status_' . $slug . '_to_' . $slug2 . '_notification' ] = sprintf( __( 'Order status %s to %s', 'woocommerce-jetpack' ), $name, $name2 );
@@ -197,7 +222,12 @@ class WC_Email_WCJ_Custom extends WC_Email {
197
  'type' => 'multiselect',
198
  'placeholder' => '',
199
  'default' => array(),
 
200
  'options' => array_merge(
 
 
 
 
201
  $status_triggers,
202
  array(
203
  'woocommerce_reset_password_notification' => __( 'Reset password notification', 'woocommerce-jetpack' ),
11
  *
12
  * An email sent to recipient list when selected triggers are called.
13
  *
14
+ * @version 2.4.5
15
  * @since 2.3.9
16
  * @author Algoritmika Ltd.
17
  * @extends WC_Email
21
  /**
22
  * Constructor
23
  *
24
+ * @version 2.4.5
25
  */
26
  function __construct( $id = 1 ) {
27
 
39
  // Triggers for this email
40
  $trigger_hooks = $this->get_option( 'trigger' );
41
  if ( ! empty( $trigger_hooks ) && is_array( $trigger_hooks ) ) {
42
+ $is_woocommerce_new_order_notification_added = false;
43
  foreach ( $trigger_hooks as $trigger_hook ) {
44
+ if ( false !== strpos( $trigger_hook, 'woocommerce_new_order_notification' ) && false === $is_woocommerce_new_order_notification_added ) {
45
+ add_action( 'woocommerce_new_order_notification', array( $this, 'trigger' ) );
46
+ $is_woocommerce_new_order_notification_added = true;
47
+ } else {
48
+ add_action( $trigger_hook, array( $this, 'trigger' ) );
49
+ }
50
  }
51
  }
52
 
80
  /**
81
  * Trigger.
82
  *
83
+ * @version 2.4.5
84
  */
85
  function trigger( $order_id ) {
86
 
105
  if ( $order_id ) {
106
  global $post;
107
  $order = wc_get_order( $order_id );
108
+ if ( 'woocommerce_new_order_notification' === current_filter() ) {
109
+ // Check status
110
+ $is_status_found = false;
111
+ $trigger_hooks = $this->get_option( 'trigger' );
112
+ foreach ( $trigger_hooks as $trigger_hook ) {
113
+ if ( false !== ( $pos = strpos( $trigger_hook, 'woocommerce_new_order_notification' ) ) ) {
114
+ $the_status = 'wc-' . substr( $trigger_hook, 35 );
115
+ if ( 'wc-wcj_any_status' === $the_status || $order->post_status === $the_status ) {
116
+ $is_status_found = true;
117
+ break;
118
+ }
119
+ }
120
+ }
121
+ if ( false === $is_status_found ) {
122
+ return;
123
+ }
124
+ }
125
  $post = $order->post;
126
  setup_postdata( $post );
127
  }
185
  /**
186
  * Initialise settings form fields
187
  *
188
+ * @version 2.4.5
189
  */
190
  function init_form_fields() {
191
 
197
  $default_plain_template = ob_get_clean();
198
 
199
  $status_change_triggers = array();
200
+ $new_order_triggers = array();
201
  $status_triggers = array();
202
  $order_statuses = $this->get_order_statuses();
203
  foreach ( $order_statuses as $slug => $name ) {
204
+ $new_order_triggers[ 'woocommerce_new_order_notification_' . $slug ] = sprintf( __( 'New order (%s)', 'woocommerce-jetpack' ), $name );
205
+ $status_triggers[ 'woocommerce_order_status_' . $slug . '_notification' ] = sprintf( __( 'Order status updated to %s', 'woocommerce-jetpack' ), $name );
206
  foreach ( $order_statuses as $slug2 => $name2 ) {
207
  if ( $slug != $slug2 ) {
208
  $status_change_triggers[ 'woocommerce_order_status_' . $slug . '_to_' . $slug2 . '_notification' ] = sprintf( __( 'Order status %s to %s', 'woocommerce-jetpack' ), $name, $name2 );
222
  'type' => 'multiselect',
223
  'placeholder' => '',
224
  'default' => array(),
225
+ 'desc_tip' => __( 'Please note, that all new orders in WooCommerce by default are created with Pending Payment status. If you want to change the default order status - you can use Booster\'s "Order Custom Statuses" module (in WooCommerce > Settings > Booster > Shipping & Orders > Order Custom Statuses).', 'woocommerce-jetpack' ),
226
  'options' => array_merge(
227
+ array(
228
+ 'woocommerce_new_order_notification_wcj_any_status' => __( 'New order (Any status)', 'woocommerce-jetpack' ),
229
+ ),
230
+ $new_order_triggers,
231
  $status_triggers,
232
  array(
233
  'woocommerce_reset_password_notification' => __( 'Reset password notification', 'woocommerce-jetpack' ),
includes/input-fields/class-wcj-product-input-fields-abstract.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Product Input Fields abstract class.
6
  *
7
- * @version 2.4.0
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -360,6 +360,8 @@ class WCJ_Product_Input_Fields_Abstract {
360
 
361
  /**
362
  * validate_product_input_fields_on_add_to_cart.
 
 
363
  */
364
  public function validate_product_input_fields_on_add_to_cart( $passed, $product_id ) {
365
  $total_number = apply_filters( 'wcj_get_option_filter', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $product_id, 1 ) );
@@ -393,17 +395,17 @@ class WCJ_Product_Input_Fields_Abstract {
393
  }
394
  }
395
 
396
-
397
- if ( 'file' === $type && '' != $_FILES[ $field_name ]['name'] ) {
398
  // Validate file type
399
- $file_accept = $this->get_value( 'wcj_product_input_fields_type_file_accept_' . $this->scope . '_' . $i, $product_id, '' );
400
- $file_accept = explode( ',', $file_accept );
401
- if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
402
- $file_type = '.' . pathinfo( $_FILES[ $field_name ]['name'], PATHINFO_EXTENSION );
403
- if ( ! in_array( $file_type, $file_accept ) ) {
404
- $passed = false;
405
- wc_add_notice( __( 'Wrong file type!', 'woocommerce-jetpack' ), 'error' );
406
- //wc_add_notice( $this->get_value( 'wcj_product_input_fields_wrong_file_type_msg_' . $this->scope . '_' . $i, $product_id, '' ), 'error' );
 
407
  }
408
  }
409
  }
4
  *
5
  * The WooCommerce Jetpack Product Input Fields abstract class.
6
  *
7
+ * @version 2.4.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
360
 
361
  /**
362
  * validate_product_input_fields_on_add_to_cart.
363
+ *
364
+ * @version 2.4.5
365
  */
366
  public function validate_product_input_fields_on_add_to_cart( $passed, $product_id ) {
367
  $total_number = apply_filters( 'wcj_get_option_filter', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $product_id, 1 ) );
395
  }
396
  }
397
 
398
+ if ( 'file' === $type && isset( $_FILES[ $field_name ] ) && '' != $_FILES[ $field_name ]['name'] ) {
 
399
  // Validate file type
400
+ if ( '' != ( $file_accept = $this->get_value( 'wcj_product_input_fields_type_file_accept_' . $this->scope . '_' . $i, $product_id, '' ) ) ) {
401
+ $file_accept = explode( ',', $file_accept );
402
+ if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
403
+ $file_type = '.' . pathinfo( $_FILES[ $field_name ]['name'], PATHINFO_EXTENSION );
404
+ if ( ! in_array( $file_type, $file_accept ) ) {
405
+ $passed = false;
406
+ wc_add_notice( __( 'Wrong file type!', 'woocommerce-jetpack' ), 'error' );
407
+ // wc_add_notice( $this->get_value( 'wcj_product_input_fields_wrong_file_type_msg_' . $this->scope . '_' . $i, $product_id, '' ), 'error' );
408
+ }
409
  }
410
  }
411
  }
includes/lib/tcpdf_min/config/tcpdf_config.php CHANGED
@@ -229,7 +229,10 @@ define('K_TCPDF_CALLS_IN_HTML', true);
229
  /**
230
  * If true and PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution.
231
  */
232
- define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
 
 
 
233
 
234
  //============================================================+
235
  // END OF FILE
229
  /**
230
  * If true and PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution.
231
  */
232
+ // Algoritmika - Booster version 2.4.5
233
+ if (!defined('K_TCPDF_THROW_EXCEPTION_ERROR')) {
234
+ define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
235
+ }
236
 
237
  //============================================================+
238
  // END OF FILE
includes/price-by-country/class-wcj-price-by-country-core.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Price by Country Core class.
6
  *
7
- * @version 2.4.4
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -333,7 +333,7 @@ class WCJ_Price_by_Country_Core {
333
  /**
334
  * change_price_by_country.
335
  *
336
- * @version 2.4.3
337
  */
338
  public function change_price_by_country( $price, $product ) {
339
 
@@ -391,7 +391,7 @@ class WCJ_Price_by_Country_Core {
391
  }
392
 
393
  if ( ! $is_price_modified ) {
394
- if ( 'yes' === get_option( 'wcj_price_by_country_make_empty_price_group_' . $group_id, 1 ) ) {
395
  return '';
396
  }
397
  }
4
  *
5
  * The WooCommerce Jetpack Price by Country Core class.
6
  *
7
+ * @version 2.4.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
333
  /**
334
  * change_price_by_country.
335
  *
336
+ * @version 2.4.5
337
  */
338
  public function change_price_by_country( $price, $product ) {
339
 
391
  }
392
 
393
  if ( ! $is_price_modified ) {
394
+ if ( 'yes' === get_option( 'wcj_price_by_country_make_empty_price_group_' . $group_id, 1 ) || '' === $price ) {
395
  return '';
396
  }
397
  }
includes/shortcodes/class-wcj-general-shortcodes.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack General Shortcodes class.
6
  *
7
- * @version 2.4.4
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -17,7 +17,7 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.4.4
21
  */
22
  public function __construct() {
23
 
@@ -29,6 +29,8 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
29
  'wcj_wpml_translate',
30
  'wcj_country_select_drop_down_list',
31
  'wcj_currency_select_drop_down_list',
 
 
32
  'wcj_text',
33
  'wcj_tcpdf_pagebreak',
34
  'wcj_get_left_to_free_shipping',
@@ -53,14 +55,70 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
53
 
54
  }
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  /**
57
  * wcj_get_left_to_free_shipping.
58
  *
59
- * @version 2.4.4
60
  * @since 2.4.4
61
  */
62
  function wcj_get_left_to_free_shipping( $atts, $content ) {
63
- echo wcj_get_left_to_free_shipping( $atts['content'] );
64
  }
65
 
66
  /**
@@ -74,48 +132,65 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
74
  }
75
 
76
  /**
77
- * wcj_currency_select_drop_down_list.
78
  *
79
- * @version 2.4.3
80
- * @since 2.4.3
81
  */
82
- function wcj_currency_select_drop_down_list( $atts, $content ) {
83
  // Start
84
  $html = '';
85
  $form_method = $atts['form_method'];
86
- $select_class = $atts['class'];
87
- $select_style = $atts['style'];
88
  $html .= '<form action="" method="' . $form_method . '">';
89
- $html .= '<select name="wcj-currency" id="wcj-currency" style="' . $select_style . '" class="' . $select_class . '" onchange="this.form.submit()">';
90
- // Shortcode currencies
91
- $shortcode_currencies = $atts['currencies'];
92
- if ( '' == $shortcode_currencies ) {
93
- $shortcode_currencies = array();
94
- } else {
95
- $shortcode_currencies = str_replace( ' ', '', $shortcode_currencies );
96
- $shortcode_currencies = trim( $shortcode_currencies, ',' );
97
- $shortcode_currencies = explode( ',', $shortcode_currencies );
98
- }
99
- if ( empty( $shortcode_currencies ) ) {
100
- $total_number = apply_filters( 'wcj_get_option_filter', 2, get_option( 'wcj_multicurrency_total_number', 2 ) );
101
- for ( $i = 1; $i <= $total_number; $i++ ) {
102
- $shortcode_currencies[] = get_option( 'wcj_multicurrency_currency_' . $i );
103
- }
104
  }
 
105
  // Options
106
  $currencies = wcj_get_currencies_names_and_symbols();
107
  $selected_currency = ( isset( $_SESSION['wcj-currency'] ) ) ? $_SESSION['wcj-currency'] : '';
108
  foreach ( $shortcode_currencies as $currency_code ) {
109
  if ( isset( $currencies[ $currency_code ] ) ) {
110
- $html .= '<option value="' . $currency_code . '" ' . selected( $currency_code, $selected_currency, false ) . '>' . $currencies[ $currency_code ] . '</option>';
 
 
 
 
 
 
 
111
  }
112
  }
113
  // End
114
- $html .= '</select>';
 
 
115
  $html .= '</form>';
116
  return $html;
117
  }
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  /**
120
  * wcj_country_select_drop_down_list.
121
  *
4
  *
5
  * The WooCommerce Jetpack General Shortcodes class.
6
  *
7
+ * @version 2.4.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 2.4.5
21
  */
22
  public function __construct() {
23
 
29
  'wcj_wpml_translate',
30
  'wcj_country_select_drop_down_list',
31
  'wcj_currency_select_drop_down_list',
32
+ 'wcj_currency_select_radio_list',
33
+ 'wcj_currency_select_link_list',
34
  'wcj_text',
35
  'wcj_tcpdf_pagebreak',
36
  'wcj_get_left_to_free_shipping',
55
 
56
  }
57
 
58
+ /**
59
+ * get_shortcode_currencies.
60
+ *
61
+ * @version 2.4.5
62
+ * @since 2.4.5
63
+ */
64
+ private function get_shortcode_currencies( $atts ) {
65
+ // Shortcode currencies
66
+ $shortcode_currencies = $atts['currencies'];
67
+ if ( '' == $shortcode_currencies ) {
68
+ $shortcode_currencies = array();
69
+ } else {
70
+ $shortcode_currencies = str_replace( ' ', '', $shortcode_currencies );
71
+ $shortcode_currencies = trim( $shortcode_currencies, ',' );
72
+ $shortcode_currencies = explode( ',', $shortcode_currencies );
73
+ }
74
+ if ( empty( $shortcode_currencies ) ) {
75
+ $total_number = apply_filters( 'wcj_get_option_filter', 2, get_option( 'wcj_multicurrency_total_number', 2 ) );
76
+ for ( $i = 1; $i <= $total_number; $i++ ) {
77
+ $shortcode_currencies[] = get_option( 'wcj_multicurrency_currency_' . $i );
78
+ }
79
+ }
80
+ return $shortcode_currencies;
81
+ }
82
+
83
+ /**
84
+ * wcj_currency_select_link_list.
85
+ *
86
+ * @version 2.4.5
87
+ * @since 2.4.5
88
+ */
89
+ function wcj_currency_select_link_list( $atts, $content ) {
90
+ $html = '';
91
+ $shortcode_currencies = $this->get_shortcode_currencies( $atts );
92
+ // Options
93
+ $currencies = wcj_get_currencies_names_and_symbols();
94
+ $selected_currency = ( isset( $_SESSION['wcj-currency'] ) ) ? $_SESSION['wcj-currency'] : '';
95
+ $links = array();
96
+ $first_link = '';
97
+ foreach ( $shortcode_currencies as $currency_code ) {
98
+ if ( isset( $currencies[ $currency_code ] ) ) {
99
+ $the_link = '<a href="' . add_query_arg( 'wcj-currency', $currency_code ) . '">' . $currencies[ $currency_code ] . '</a>';
100
+ if ( $currency_code != $selected_currency ) {
101
+ $links[] = $the_link;
102
+ } else {
103
+ $first_link = $the_link;
104
+ }
105
+ }
106
+ }
107
+ if ( '' != $first_link ) {
108
+ $links = array_merge( array( $first_link ), $links );
109
+ }
110
+ $html .= implode( '<br>', $links );
111
+ return $html;
112
+ }
113
+
114
  /**
115
  * wcj_get_left_to_free_shipping.
116
  *
117
+ * @version 2.4.5
118
  * @since 2.4.4
119
  */
120
  function wcj_get_left_to_free_shipping( $atts, $content ) {
121
+ return wcj_get_left_to_free_shipping( $atts['content'] );
122
  }
123
 
124
  /**
132
  }
133
 
134
  /**
135
+ * get_currency_selector.
136
  *
137
+ * @version 2.4.5
138
+ * @since 2.4.5
139
  */
140
+ private function get_currency_selector( $atts, $content, $type = 'select' ) {
141
  // Start
142
  $html = '';
143
  $form_method = $atts['form_method'];
144
+ $class = $atts['class'];
145
+ $style = $atts['style'];
146
  $html .= '<form action="" method="' . $form_method . '">';
147
+ if ( 'select' === $type ) {
148
+ $html .= '<select name="wcj-currency" id="wcj-currency-select" style="' . $style . '" class="' . $class . '" onchange="this.form.submit()">';
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
+ $shortcode_currencies = $this->get_shortcode_currencies( $atts );
151
  // Options
152
  $currencies = wcj_get_currencies_names_and_symbols();
153
  $selected_currency = ( isset( $_SESSION['wcj-currency'] ) ) ? $_SESSION['wcj-currency'] : '';
154
  foreach ( $shortcode_currencies as $currency_code ) {
155
  if ( isset( $currencies[ $currency_code ] ) ) {
156
+ if ( '' == $selected_currency ) {
157
+ $selected_currency = $currency_code;
158
+ }
159
+ if ( 'select' === $type ) {
160
+ $html .= '<option value="' . $currency_code . '" ' . selected( $currency_code, $selected_currency, false ) . '>' . $currencies[ $currency_code ] . '</option>';
161
+ } elseif ( 'radio' === $type ) {
162
+ $html .= '<input type="radio" name="wcj-currency" id="wcj-currency-radio" value="' . $currency_code . '" ' . checked( $currency_code, $selected_currency, false ) . ' onclick="this.form.submit()"> ' . $currencies[ $currency_code ] . '<br>';
163
+ }
164
  }
165
  }
166
  // End
167
+ if ( 'select' === $type ) {
168
+ $html .= '</select>';
169
+ }
170
  $html .= '</form>';
171
  return $html;
172
  }
173
 
174
+ /**
175
+ * wcj_currency_select_radio_list.
176
+ *
177
+ * @version 2.4.5
178
+ * @since 2.4.5
179
+ */
180
+ function wcj_currency_select_radio_list( $atts, $content ) {
181
+ return $this->get_currency_selector( $atts, $content, 'radio' );
182
+ }
183
+
184
+ /**
185
+ * wcj_currency_select_drop_down_list.
186
+ *
187
+ * @version 2.4.5
188
+ * @since 2.4.3
189
+ */
190
+ function wcj_currency_select_drop_down_list( $atts, $content ) {
191
+ return $this->get_currency_selector( $atts, $content, 'select' );
192
+ }
193
+
194
  /**
195
  * wcj_country_select_drop_down_list.
196
  *
includes/shortcodes/class-wcj-orders-shortcodes.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Orders Shortcodes class.
6
  *
7
- * @version 2.4.0
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -248,11 +248,17 @@ class WCJ_Orders_Shortcodes extends WCJ_Shortcodes {
248
  /**
249
  * wcj_order_checkout_field.
250
  *
251
- * @version 2.3.6
252
  */
253
  function wcj_order_checkout_field( $atts ) {
254
- if ( '' == $atts['field_id'] ) return '';
255
- $field_value = $this->the_order->$atts['field_id'];
 
 
 
 
 
 
256
  return ( is_array( $field_value ) && isset( $field_value['value'] ) ) ? $field_value['value'] : $field_value;
257
  }
258
 
4
  *
5
  * The WooCommerce Jetpack Orders Shortcodes class.
6
  *
7
+ * @version 2.4.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
248
  /**
249
  * wcj_order_checkout_field.
250
  *
251
+ * @version 2.4.5
252
  */
253
  function wcj_order_checkout_field( $atts ) {
254
+ $field_id = ( string ) $atts['field_id'];
255
+ if ( '' == $field_id ) {
256
+ return '';
257
+ }
258
+ if ( ! isset( $this->the_order->$field_id ) ) {
259
+ return '';
260
+ }
261
+ $field_value = $this->the_order->$field_id;
262
  return ( is_array( $field_value ) && isset( $field_value['value'] ) ) ? $field_value['value'] : $field_value;
263
  }
264
 
includes/widgets/class-wcj-widget-multicurrency.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Multicurrency Widget class.
6
  *
7
- * @version 2.4.3
8
  * @since 2.4.3
9
  * @author Algoritmika Ltd.
10
  */
@@ -29,6 +29,7 @@ class WCJ_Widget_Multicurrency extends WP_Widget {
29
  /**
30
  * Outputs the content of the widget
31
  *
 
32
  * @param array $args
33
  * @param array $instance
34
  */
@@ -38,36 +39,58 @@ class WCJ_Widget_Multicurrency extends WP_Widget {
38
  if ( ! empty( $instance['title'] ) ) {
39
  echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
40
  }
41
- echo do_shortcode( '[wcj_currency_select_drop_down_list]' );
 
 
 
 
 
 
 
 
 
 
42
  echo $args['after_widget'];
43
  }
44
 
45
  /**
46
  * Outputs the options form on admin
47
  *
 
48
  * @param array $instance The widget options
49
  */
50
  public function form( $instance ) {
51
  // outputs the options form on admin
52
- $title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'Currency Switcher', 'woocommerce-jetpack' );
 
53
  ?>
54
  <p>
55
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
56
  <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
57
  </p>
 
 
 
 
 
 
 
 
58
  <?php
59
  }
60
 
61
  /**
62
  * Processing widget options on save
63
  *
 
64
  * @param array $new_instance The new options
65
  * @param array $old_instance The previous options
66
  */
67
  public function update( $new_instance, $old_instance ) {
68
  // processes widget options to be saved
69
  $instance = array();
70
- $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
 
71
  return $instance;
72
  }
73
  }
4
  *
5
  * The WooCommerce Jetpack Multicurrency Widget class.
6
  *
7
+ * @version 2.4.5
8
  * @since 2.4.3
9
  * @author Algoritmika Ltd.
10
  */
29
  /**
30
  * Outputs the content of the widget
31
  *
32
+ * @version 2.4.5
33
  * @param array $args
34
  * @param array $instance
35
  */
39
  if ( ! empty( $instance['title'] ) ) {
40
  echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
41
  }
42
+ switch ( $instance['switcher_type'] ) {
43
+ case 'link_list':
44
+ echo do_shortcode( '[wcj_currency_select_link_list]' );
45
+ break;
46
+ case 'radio_list':
47
+ echo do_shortcode( '[wcj_currency_select_radio_list]' );
48
+ break;
49
+ default:
50
+ echo do_shortcode( '[wcj_currency_select_drop_down_list]' );
51
+ break;
52
+ }
53
  echo $args['after_widget'];
54
  }
55
 
56
  /**
57
  * Outputs the options form on admin
58
  *
59
+ * @version 2.4.5
60
  * @param array $instance The widget options
61
  */
62
  public function form( $instance ) {
63
  // outputs the options form on admin
64
+ $title = ! empty( $instance['title'] ) ? $instance['title'] : '';
65
+ $switcher_type = ! empty( $instance['switcher_type'] ) ? $instance['switcher_type'] : 'drop_down';
66
  ?>
67
  <p>
68
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
69
  <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
70
  </p>
71
+ <p>
72
+ <label for="<?php echo $this->get_field_id( 'switcher_type' ); ?>"><?php _e( 'Type:' ); ?></label>
73
+ <select class="widefat" id="<?php echo $this->get_field_id( 'switcher_type' ); ?>" name="<?php echo $this->get_field_name( 'switcher_type' ); ?>">
74
+ <option value="drop_down" <?php selected( $switcher_type, 'drop_down' ); ?>><?php echo __( 'Drop down', 'woocommerce-jetpack' ); ?>
75
+ <option value="radio_list" <?php selected( $switcher_type, 'radio_list' ); ?>><?php echo __( 'Radio list', 'woocommerce-jetpack' ); ?>
76
+ <option value="link_list" <?php selected( $switcher_type, 'link_list' ); ?>><?php echo __( 'Link list', 'woocommerce-jetpack' ); ?>
77
+ </select>
78
+ </p>
79
  <?php
80
  }
81
 
82
  /**
83
  * Processing widget options on save
84
  *
85
+ * @version 2.4.5
86
  * @param array $new_instance The new options
87
  * @param array $old_instance The previous options
88
  */
89
  public function update( $new_instance, $old_instance ) {
90
  // processes widget options to be saved
91
  $instance = array();
92
+ $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
93
+ $instance['switcher_type'] = ( ! empty( $new_instance['switcher_type'] ) ) ? $new_instance['switcher_type'] : 'drop_down';
94
  return $instance;
95
  }
96
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: algoritmika,anbinder,solovjov
3
  Tags: woocommerce,booster for woocommerce,woocommerce jetpack,custom price labels,call for price,currency symbol,remove sorting,remove old product slugs,add to cart text,order number,sequential order numbering,email pdf invoice,pdf invoice,pdf invoices,already in cart,empty cart,redirect to checkout,minimum order amount,customize checkout fields,checkout fields,email,customize product tabs,product tabs,related products number,empty cart,redirect add to cart,redirect to checkout,product already in cart,custom payment gateway,payment gateway icon,auto-complete all orders,custom order statuses,custom order status,remove text from price,custom css,hide categories count,hide subcategories count,hide category count,hide subcategory count,display total sales,custom product tabs,remove product tab,payment gateway fee,vat,gateway by country,price by country,currency switcher
4
  Requires at least: 3.8
5
  Tested up to: 4.4
6
- Stable tag: 2.4.4
7
  License: GNU General Public License v3.0
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -51,6 +51,7 @@ Booster for WooCommerce is a WordPress plugin that supercharges your site with a
51
  * *Cart* - Add custom info to WooCommerce cart page. Add empty cart button.
52
  * *Checkout Core Fields* - Customize WooCommerce core checkout fields. Disable/enable fields, set required, change labels and/or placeholders.
53
  * *Checkout Custom Fields* - Add custom fields to WooCommerce checkout page.
 
54
  * *Checkout Custom Info* - Add custom info to WooCommerce checkout page.
55
  * *Empty Cart Button* - Add and customize "Empty Cart" button to cart page.
56
  * *Mini Cart* - Customize WooCommerce mini cart widget.
@@ -119,6 +120,29 @@ To unlock all Booster for WooCommerce features, please install additional [Boost
119
 
120
  == Changelog ==
121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  = 2.4.4 - 23/03/2016 =
123
  * Dev - "Booster Currencies Array" (wcj-currencies.php) updated.
124
  * Dev - `wcj_get_currencies_names_and_symbols()` and `wcj_get_currency_symbol()` functions modified.
3
  Tags: woocommerce,booster for woocommerce,woocommerce jetpack,custom price labels,call for price,currency symbol,remove sorting,remove old product slugs,add to cart text,order number,sequential order numbering,email pdf invoice,pdf invoice,pdf invoices,already in cart,empty cart,redirect to checkout,minimum order amount,customize checkout fields,checkout fields,email,customize product tabs,product tabs,related products number,empty cart,redirect add to cart,redirect to checkout,product already in cart,custom payment gateway,payment gateway icon,auto-complete all orders,custom order statuses,custom order status,remove text from price,custom css,hide categories count,hide subcategories count,hide category count,hide subcategory count,display total sales,custom product tabs,remove product tab,payment gateway fee,vat,gateway by country,price by country,currency switcher
4
  Requires at least: 3.8
5
  Tested up to: 4.4
6
+ Stable tag: 2.4.5
7
  License: GNU General Public License v3.0
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
51
  * *Cart* - Add custom info to WooCommerce cart page. Add empty cart button.
52
  * *Checkout Core Fields* - Customize WooCommerce core checkout fields. Disable/enable fields, set required, change labels and/or placeholders.
53
  * *Checkout Custom Fields* - Add custom fields to WooCommerce checkout page.
54
+ * *Checkout Files Upload* - Let customers upload files on WooCommerce checkout.
55
  * *Checkout Custom Info* - Add custom info to WooCommerce checkout page.
56
  * *Empty Cart Button* - Add and customize "Empty Cart" button to cart page.
57
  * *Mini Cart* - Customize WooCommerce mini cart widget.
120
 
121
  == Changelog ==
122
 
123
+ = 2.4.5 - 06/04/2016 =
124
+ * Dev - `K_TCPDF_THROW_EXCEPTION_ERROR` "is defined" check added to `tcpdf_config.php` file.
125
+ * Dev - Default type added to `WCJ_Module::create_meta_box()` (works for `text` type).
126
+ * Fix - Shortcodes - General - `[wcj_get_left_to_free_shipping]` bug fixed.
127
+ * Dev - Shortcodes - General - `[wcj_currency_select_link_list]` shortcode added.
128
+ * Dev - Shortcodes - General - `[wcj_currency_select_radio_list]` shortcode added.
129
+ * Fix - Shortcodes - Orders - `[wcj_order_checkout_field]` - `field_id` string conversion added.
130
+ * Fix - Widgets - Multicurrency Switcher - Default title value set to blank.
131
+ * Dev - Widgets - Multicurrency Switcher - "Switcher type" options added.
132
+ * Fix - PRICES & CURRENCIES - Prices and Currencies by Country - Wrong currency in emails bug fixed (again).
133
+ * Fix - PRICES & CURRENCIES - Prices and Currencies by Country - Main price empty (or Call for Price) bug fixed.
134
+ * Dev - PRODUCTS - SKU - Description tip added to "Variable Products Variations" option.
135
+ * Fix - PRODUCTS - Product Input Fields - File type field - "Leave blank to accept all files" bug fixed.
136
+ * Fix - PRODUCTS - Product Input Fields - File type field - Adding from archive bug fixed.
137
+ * Dev - PRODUCTS - Product Cost Price - "Affiliate commission" optional field added (also affected `WCJ_Product` class).
138
+ * Dev - PRODUCTS - Product Cost Price - Options to enable/disable fields added (also affected functions in `WCJ_Module` and `WCJ_Product` classes).
139
+ * Dev - PRODUCTS - Product Cost Price - `wcj_purchase_data_product_options` and `wcj_get_product_purchase_price` filters added (second filter added to `WCJ_Product` class).
140
+ * Dev - PRODUCTS - Product Cost Price - Variable products support added.
141
+ * Dev - PRODUCTS - Product Cost Price - Code refactoring.
142
+ * Dev - CART & CHECKOUT - Checkout Custom Fields - Custom fields added to user profile and to checkout page defaults.
143
+ * Dev - CART & CHECKOUT - Checkout Files Upload - Initial module release.
144
+ * Dev - EMAILS & MISC. - Emails - "New order (Status)" triggers added to custom emails.
145
+
146
  = 2.4.4 - 23/03/2016 =
147
  * Dev - "Booster Currencies Array" (wcj-currencies.php) updated.
148
  * Dev - `wcj_get_currencies_names_and_symbols()` and `wcj_get_currency_symbol()` functions modified.
woocommerce-jetpack.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Booster for WooCommerce
4
  Plugin URI: http://booster.io
5
  Description: Supercharge your WooCommerce site with these awesome powerful features.
6
- Version: 2.4.4
7
  Author: Algoritmika Ltd
8
  Author URI: http://www.algoritmika.com
9
  Copyright: © 2016 Algoritmika Ltd.
@@ -21,7 +21,7 @@ if ( ! class_exists( 'WC_Jetpack' ) ) :
21
  * Main WC_Jetpack Class
22
  *
23
  * @class WC_Jetpack
24
- * @version 2.4.4
25
  */
26
 
27
  final class WC_Jetpack {
@@ -395,7 +395,7 @@ final class WC_Jetpack {
395
  /**
396
  * Include modules and submodules
397
  *
398
- * @version 2.4.3
399
  */
400
  private function include_modules() {
401
  $settings = array();
@@ -422,6 +422,7 @@ final class WC_Jetpack {
422
  $settings[] = include_once( 'includes/class-wcj-mini-cart.php' );
423
  $settings[] = include_once( 'includes/class-wcj-checkout-core-fields.php' );
424
  $settings[] = include_once( 'includes/class-wcj-checkout-custom-fields.php' );
 
425
  $settings[] = include_once( 'includes/class-wcj-checkout-custom-info.php' );
426
  $settings[] = include_once( 'includes/class-wcj-payment-gateways.php' );
427
  $settings[] = include_once( 'includes/class-wcj-payment-gateways-icons.php' );
3
  Plugin Name: Booster for WooCommerce
4
  Plugin URI: http://booster.io
5
  Description: Supercharge your WooCommerce site with these awesome powerful features.
6
+ Version: 2.4.5
7
  Author: Algoritmika Ltd
8
  Author URI: http://www.algoritmika.com
9
  Copyright: © 2016 Algoritmika Ltd.
21
  * Main WC_Jetpack Class
22
  *
23
  * @class WC_Jetpack
24
+ * @version 2.4.5
25
  */
26
 
27
  final class WC_Jetpack {
395
  /**
396
  * Include modules and submodules
397
  *
398
+ * @version 2.4.5
399
  */
400
  private function include_modules() {
401
  $settings = array();
422
  $settings[] = include_once( 'includes/class-wcj-mini-cart.php' );
423
  $settings[] = include_once( 'includes/class-wcj-checkout-core-fields.php' );
424
  $settings[] = include_once( 'includes/class-wcj-checkout-custom-fields.php' );
425
+ $settings[] = include_once( 'includes/class-wcj-checkout-files-upload.php' );
426
  $settings[] = include_once( 'includes/class-wcj-checkout-custom-info.php' );
427
  $settings[] = include_once( 'includes/class-wcj-payment-gateways.php' );
428
  $settings[] = include_once( 'includes/class-wcj-payment-gateways-icons.php' );